Добавлены интерфейсы и драйверы

This commit is contained in:
cfif 2025-09-29 11:21:51 +03:00
commit 30534e7bf7
3 changed files with 482 additions and 0 deletions

174
Inc/SerialPortFlagchip.h Normal file
View File

@ -0,0 +1,174 @@
//
// Created by cfif on 16.09.22.
//
#ifndef SERIALPORT_SERIALPORT_FLAHCHIP_H
#define SERIALPORT_SERIALPORT_FLAHCHIP_H
#include "SerialPort.h"
#include "cmsis_os2.h"
#include "stdbool.h"
#include "interrupt_manager.h"
#include "fc7xxx_driver_fcuart.h"
#include "fc7xxx_driver_pcc.h"
#include "fc7xxx_driver_port.h"
#include "fc7xxx_driver_scg.h"
#include "fc7xxx_driver_gpio.h"
#include "fc7xxx_driver_dma.h"
typedef struct {
uint8_t UART_INDEX;
DMA_ChannelType RX_DMA_CHANNEL;
FCUART_Type *UART;
uint32_t DMA_BUF_LEN;
uint32_t UART_DMA_RECEIVED_LEN_BUF;
uint8 s_SampleTmp[4];
FCUART_DataType s_tFCUART_TxMsg;
FCUART_InitType tInitCfg;
FCUART_InterruptType tInterruptCfg;
DMA_InitType dmaInitCfg;
DMA_ChannelCfgType chnCfg;
DMA_InterruptCfgType interruptCfg;
osMessageQueueId_t txAccessQueue;
osMessageQueueId_t rxDataQueue;
osMessageQueueId_t rxDataSnifferQueue;
osMessageQueueId_t rxDataSnifferSecondQueue;
} tSerialPortFlagchip;
void vSerialPortInitDMA(
tSerialPortFlagchip *env,
FCUART_Type *uart,
PCC_ClkSrcType uartClock,
uint32_t BoundRate,
uint8 UART_INDEX, // UART0 = 0 ... UART7 = 7
IRQn_Type IRQ_UART, // FCUART0_IRQn ... FCUART7_IRQn
uint8 UART_PRIORITY,
DMA_ChannelType RX_DMA_CHANNEL,
DMA_RequestSourceType RX_DMA_CHANNEL_REQ,
uint8_t *DMA_BUF,
uint16_t DMA_BUF_LEN,
IRQn_Type IRQ_DMA,
uint8_t IRQ_DMA_PRIORITY,
uint8_t IRQ_DMA_CHANNEL_PRIORITY,
uint32_t rxBufferLength,
uint32_t rxSnifferLength,
DMA_TransferCompleteCallbackType pTransferCompleteNotify,
DMA_TransferErrorCallbackType pTransferErrorNotify,
FCUART_IdleInterrupt_CallBackType FCUART_IldeInterrupt_CallBack,
FCUART_ErrorInterrupt_CallBackType FCUART_ErrorInterrupt_CallBack,
FCUART_TxRxInterrupt_CallBackType FCUART_TxEmptyInterrupt_CallBack,
FCUART_TxRxInterrupt_CallBackType FCUART_TxCompleteInterrupt_CallBack
);
tSerialPortIO vSerialPortGetIo(tSerialPortFlagchip *env);
void SerialPort_RxDmaBufToQueue(tSerialPortFlagchip *env, const void *pSrcBuffer);
/*
#define vSerialPortInitDMAName(ENV, NAME, DMA, RX_DMA_CHANNEL, RX_DMA_CHANNEL_MUX, RX_DMAMUX_DMAREQ_ID, RX_DMA_Channel_IRQ, RX_DMA_FDT_FLAG, DMA_BUF, DMA_BUF_LEN, TX_DMA_CHANNEL, TX_DMA_CHANNEL_MUX, TX_DMAMUX_DMAREQ_ID, TX_DMA_Channel_IRQ, TX_DMA_FDT_FLAG, SWAP, BOUND_RATE, PRIORITY, LEN) \
vSerialPortInitDMA(ENV, NAME, DMA, RX_DMA_CHANNEL, RX_DMA_CHANNEL_MUX, RX_DMAMUX_DMAREQ_ID, RX_DMA_Channel_IRQ, RX_DMA_FDT_FLAG, DMA_BUF, DMA_BUF_LEN, TX_DMA_CHANNEL, TX_DMA_CHANNEL_MUX, TX_DMAMUX_DMAREQ_ID, TX_DMA_Channel_IRQ, TX_DMA_FDT_FLAG, SWAP, BOUND_RATE, NAME##_IRQn, CRM_##NAME##_PERIPH_CLOCK, PRIORITY, LEN, 0)
#define vSerialPortInitDMANameWithSniffer(ENV, NAME, DMA, RX_DMA_CHANNEL, RX_DMA_CHANNEL_MUX, RX_DMAMUX_DMAREQ_ID, RX_DMA_Channel_IRQ, RX_DMA_FDT_FLAG, DMA_BUF, DMA_BUF_LEN, TX_DMA_CHANNEL, TX_DMA_CHANNEL_MUX, TX_DMAMUX_DMAREQ_ID, TX_DMA_Channel_IRQ, TX_DMA_FDT_FLAG, SWAP, BOUND_RATE, PRIORITY, LEN, SNIFFER_LEN) \
vSerialPortInitDMA(ENV, NAME, DMA, RX_DMA_CHANNEL, RX_DMA_CHANNEL_MUX, RX_DMAMUX_DMAREQ_ID, RX_DMA_Channel_IRQ, RX_DMA_FDT_FLAG, DMA_BUF, DMA_BUF_LEN, TX_DMA_CHANNEL, TX_DMA_CHANNEL_MUX, TX_DMAMUX_DMAREQ_ID, TX_DMA_Channel_IRQ, TX_DMA_FDT_FLAG, SWAP, BOUND_RATE, NAME##_IRQn, CRM_##NAME##_PERIPH_CLOCK, PRIORITY, LEN, SNIFFER_LEN)
#define DMANONE_CHANNELNONE NULL
#define DMANONE NULL
#define DMANONEMUX_CHANNELNONE NULL
#define DMANONE_FDTNONE_FLAG (uint32_t)0
#define DMANONE_ChannelNONE_IRQn (IRQn_Type)0
#define vSerialPortInitDmaWithNameAndSniffer(\
ENV, NAME, BOUND_RATE, \
RX_DMA, RX_CH, \
TX_DMA, TX_CH, \
SWAP, PRIORITY, \
RX_DMA_BUF, RX_DMA_BUF_LEN, \
QUEUE_LEN, SNIFFER_LEN \
) \
vSerialPortInitDMA(\
ENV, NAME, DMA##RX_DMA, DMA##TX_DMA, \
DMA##RX_DMA##_CHANNEL##RX_CH, DMA##RX_DMA##MUX_CHANNEL##RX_CH, DMAMUX_DMAREQ_ID_##NAME##_RX, DMA##RX_DMA##_Channel##RX_CH##_IRQn, DMA##RX_DMA##_FDT##RX_CH##_FLAG,\
RX_DMA_BUF, RX_DMA_BUF_LEN, \
DMA##TX_DMA##_CHANNEL##TX_CH, DMA##TX_DMA##MUX_CHANNEL##TX_CH, DMAMUX_DMAREQ_ID_##NAME##_TX, DMA##TX_DMA##_Channel##TX_CH##_IRQn, DMA##TX_DMA##_FDT##TX_CH##_FLAG,\
SWAP, BOUND_RATE, NAME##_IRQn, CRM_##NAME##_PERIPH_CLOCK, \
PRIORITY, QUEUE_LEN, SNIFFER_LEN\
)
#define vSerialPortInitDmaExtWithNameAndSniffer(\
ENV, NAME, BOUND_RATE, \
RX_DMA, RX_CH, \
TX_DMA, TX_CH, \
SWAP, FLOW, PRIORITY, \
RX_DMA_BUF, RX_DMA_BUF_LEN, \
QUEUE_LEN, SNIFFER_LEN \
) \
vSerialPortInitDMAExt(\
ENV, NAME, DMA##RX_DMA, DMA##TX_DMA, \
DMA##RX_DMA##_CHANNEL##RX_CH, DMA##RX_DMA##MUX_CHANNEL##RX_CH, DMAMUX_DMAREQ_ID_##NAME##_RX, DMA##RX_DMA##_Channel##RX_CH##_IRQn, DMA##RX_DMA##_FDT##RX_CH##_FLAG,\
RX_DMA_BUF, RX_DMA_BUF_LEN, \
DMA##TX_DMA##_CHANNEL##TX_CH, DMA##TX_DMA##MUX_CHANNEL##TX_CH, DMAMUX_DMAREQ_ID_##NAME##_TX, DMA##TX_DMA##_Channel##TX_CH##_IRQn, DMA##TX_DMA##_FDT##TX_CH##_FLAG,\
SWAP, FLOW, BOUND_RATE, NAME##_IRQn, CRM_##NAME##_PERIPH_CLOCK, \
PRIORITY, QUEUE_LEN, SNIFFER_LEN\
)
#define vSerialPortInitName(ENV, NAME, SWAP, BOUND_RATE, PRIORITY, LEN) \
vSerialPortInit(ENV, NAME, SWAP, BOUND_RATE, NAME##_IRQn, CRM_##NAME##_PERIPH_CLOCK, PRIORITY, LEN, 0)
#define vSerialPortExtInitName(ENV, NAME, SWAP, FLOW, BOUND_RATE, PRIORITY, LEN) \
vSerialPortInit(ENV, NAME, SWAP, FLOW, BOUND_RATE, NAME##_IRQn, CRM_##NAME##_PERIPH_CLOCK, PRIORITY, LEN, 0)
#define vSerialPortInitNameWithSniffer(ENV, NAME, SWAP, BOUND_RATE, PRIORITY, LEN, SNIFFER_LEN) \
vSerialPortInit(ENV, NAME, SWAP, BOUND_RATE, NAME##_IRQn, CRM_##NAME##_PERIPH_CLOCK, PRIORITY, LEN, SNIFFER_LEN)
#define vSerialPortExtInitNameWithSniffer(ENV, NAME, SWAP, FLOW, BOUND_RATE, PRIORITY, LEN, SNIFFER_LEN) \
vSerialPortInit(ENV, NAME, SWAP, FLOW, BOUND_RATE, NAME##_IRQn, CRM_##NAME##_PERIPH_CLOCK, PRIORITY, LEN, SNIFFER_LEN)
void vSerialPortIrqProcessing(tSerialPortArtery *env);
void vSerialPortIrqProcessingDMA(tSerialPortArtery *env);
//void vSerialPortIrqProcessingDMAloop(tSerialPortArtery *env, uint32_t len);
void SerialPort_IrqProcessing_UartIdle(tSerialPortArtery *env);
void SerialPort_IrqProcessing_DmaRxLoop(tSerialPortArtery *env);
void SerialPort_IrqProcessingFilter_UartIdle(tSerialPortArtery *env, tSerialPortIO *virtualPort, uint16_t *counterBufFilterStr, uint8_t *bufStrFilter, uint16_t maxBufStrFilter, const char *FilterStr[], uint8_t countFiler);
void SerialPort_IrqProcessingFilter_DmaRxLoop(tSerialPortArtery *env, tSerialPortIO *virtualPort, uint16_t *counterBufFilterStr, uint8_t *bufStrFilter, uint16_t maxBufStrFilter, const char *FilterStr[], uint8_t countFiler);
void SerialPort_IrqProcessing_DmaTx(tSerialPortArtery *env);
tSerialPortIO vSerialPortGetIo(tSerialPortArtery *env);
tSerialPortIO vSerialPortGetSnifferIo(tSerialPortArtery *env);
tSerialPortIO SerialPort_GetSnifferSecondIo(tSerialPortArtery *env);
uint16_t vSerialPortTransmit(tSerialPortArtery *env, uint8_t *data, uint16_t size, uint32_t timeout);
uint16_t vSerialPortBlindTransmit(tSerialPortArtery *env, uint8_t *data, uint16_t size, uint32_t timeout);
void SerialPort_IrqProcessing_DmaTxBlind(tSerialPortArtery *env);
*/
#endif //SERIALPORT_SERIALPORT_FLAHCHIP_H

286
Src/SerialPortFlagchip.c Normal file
View File

@ -0,0 +1,286 @@
//
// Created by cfif on 16.09.22.
//
#include <SystemDelayInterface.h>
#include "SerialPortFlagchip.h"
#include "string.h"
void vSerialPortInitDMA(
tSerialPortFlagchip *env,
FCUART_Type *uart,
PCC_ClkSrcType uartClock,
uint32_t BoundRate,
uint8 UART_INDEX, // UART0 = 0 ... UART7 = 7
IRQn_Type IRQ_UART, // FCUART0_IRQn ... FCUART7_IRQn
uint8 UART_PRIORITY,
DMA_ChannelType RX_DMA_CHANNEL,
DMA_RequestSourceType RX_DMA_CHANNEL_REQ,
uint8_t *DMA_BUF,
uint16_t DMA_BUF_LEN,
IRQn_Type IRQ_DMA,
uint8_t IRQ_DMA_PRIORITY,
uint8_t IRQ_DMA_CHANNEL_PRIORITY,
uint32_t rxBufferLength,
uint32_t rxSnifferLength,
DMA_TransferCompleteCallbackType pTransferCompleteNotify,
DMA_TransferErrorCallbackType pTransferErrorNotify,
FCUART_IdleInterrupt_CallBackType FCUART_IldeInterrupt_CallBack,
FCUART_ErrorInterrupt_CallBackType FCUART_ErrorInterrupt_CallBack,
FCUART_TxRxInterrupt_CallBackType FCUART_TxEmptyInterrupt_CallBack,
FCUART_TxRxInterrupt_CallBackType FCUART_TxCompleteInterrupt_CallBack
) {
env->UART_INDEX = UART_INDEX;
env->RX_DMA_CHANNEL = RX_DMA_CHANNEL;
env->UART = uart;
env->DMA_BUF_LEN = DMA_BUF_LEN;
env->UART_DMA_RECEIVED_LEN_BUF = 0;
env->txAccessQueue = osMessageQueueNew(1, 1, NULL);
env->rxDataQueue = osMessageQueueNew(rxBufferLength, 1, NULL);
if (rxSnifferLength) {
env->rxDataSnifferQueue = osMessageQueueNew(rxSnifferLength, 1, NULL);
} else {
env->rxDataSnifferQueue = 0;
}
FCUART_InitMemory(UART_INDEX);
PCC_CtrlType bSP_PCC_Config;
bSP_PCC_Config.eClockName = uartClock;
bSP_PCC_Config.bEn = true;
bSP_PCC_Config.eClkSrc = PCC_CLKGATE_SRC_FOSCDIV;
bSP_PCC_Config.eDivider = PCC_CLK_UNINVOLVED;
PCC_SetPcc(&bSP_PCC_Config);
env->dmaInitCfg.eArbitrationAlgorithm = DMA_ARBITRATION_ALGORITHM_FIXED_PRIORITY;
env->dmaInitCfg.bHaltOnError = false;
DMA_Init(DMA_INSTANCE_0, &env->dmaInitCfg);
env->chnCfg.pSrcBuffer = &(uart->DATA);
env->chnCfg.pDestBuffer = DMA_BUF;
env->chnCfg.u32BlockSize = 1U;
env->chnCfg.u16BlockCount = 1U;
env->chnCfg.u8ChannelPriority = IRQ_DMA_CHANNEL_PRIORITY;
env->chnCfg.eSrcDataSize = DMA_TRANSFER_SIZE_1B;
env->chnCfg.eDestDataSize = DMA_TRANSFER_SIZE_1B;
env->chnCfg.eSrcIncMode = DMA_INCREMENT_DISABLE;
env->chnCfg.eDestIncMode = DMA_INCREMENT_DATA_SIZE;
env->chnCfg.bSrcBlockOffsetEn = false;
env->chnCfg.bDestBlockOffsetEn = false;
env->chnCfg.s32BlockOffset = 0;
env->chnCfg.bSrcAddrLoopbackEn = false;
env->chnCfg.bDestAddrLoopbackEn = false;
env->chnCfg.bAutoStop = false;
env->chnCfg.bSrcCircularBufferEn = false;
env->chnCfg.u32SrcCircBufferSize = 0U;
env->chnCfg.bDestCircularBufferEn = false;
env->chnCfg.u32DestCircBufferSize = 0U;
env->chnCfg.eTriggerSrc = RX_DMA_CHANNEL_REQ;
DMA_InitChannel(DMA_INSTANCE_0, RX_DMA_CHANNEL, &env->chnCfg);
env->interruptCfg.bTransferCompleteIntEn = true;
env->interruptCfg.pTransferCompleteNotify = pTransferCompleteNotify;
env->interruptCfg.bTransferErrorIntEn = true;
env->interruptCfg.pTransferErrorNotify = pTransferErrorNotify;
DMA_InitChannelInterrupt(DMA_INSTANCE_0, RX_DMA_CHANNEL, &env->interruptCfg);
DMA_StartChannel(DMA_INSTANCE_0, RX_DMA_CHANNEL);
NVIC_SetPriority(IRQ_DMA, IRQ_DMA_PRIORITY);
NVIC_EnableIRQ(IRQ_DMA);
FCUART_ErrorType tRetVal;
uint32_t u32PccFuncClk;
u32PccFuncClk = PCC_GetPccFunctionClock(uartClock);
if (u32PccFuncClk != 0U) {
env->tInitCfg.bEnRxFullDma = true; // UART receiver full DMA disable
env->tInitCfg.bEnRxFifo = false; // UART fifo disable
env->tInitCfg.bEnTxFifo = true; // UART tx fifo enable
env->tInitCfg.u8TxFifoWaterMark = 0U; // UART tx fifo 16 bytes trigger
env->tInitCfg.eIdleCharNum = FCUART_IDLE_CHARCTER_64; // UART idle character number 64
env->tInitCfg.eIdleStart = FCUART_START_AFTER_STOPBIT; // UART idle character type
env->tInitCfg.u32Baudrate = BoundRate; // UART baud-rate
env->tInitCfg.eBitMode = UART_BITMODE_8; // UART bit mode
env->tInitCfg.bParityEnable = false; // UART parity check enable
env->tInitCfg.eStopBit = UART_STOPBIT_NUM_1; // UART stop bit number
env->tInitCfg.u32ClkSrcHz = u32PccFuncClk; // UART function clock
env->tInitCfg.u32TransmitTimeout = 0xFFFFFFFFU; // Transmit timeout tick
// start initial UART
tRetVal = FCUART_Init(UART_INDEX, &env->tInitCfg);
if (tRetVal == FCUART_ERROR_OK) {
env->s_tFCUART_TxMsg.pDatas = (uint8_t *) env->s_SampleTmp; // data buffer must set an array address
env->s_tFCUART_TxMsg.u32DataLen = 0;
env->tInterruptCfg.pTxBuf = &env->s_tFCUART_TxMsg;
env->tInterruptCfg.bEnIdleInterrupt = true;
env->tInterruptCfg.pIdleNotify = FCUART_IldeInterrupt_CallBack;
env->tInterruptCfg.bEnErrorInterrupt = true;
env->tInterruptCfg.pErrorNotify = FCUART_ErrorInterrupt_CallBack;
env->tInterruptCfg.bEnRxInterrupt = false;
env->tInterruptCfg.pRxNotify = NULL;
env->tInterruptCfg.bEnTxInterrupt = true;
env->tInterruptCfg.pTxEmptyNotify = FCUART_TxEmptyInterrupt_CallBack;
env->tInterruptCfg.pTxCompleteNotify = FCUART_TxCompleteInterrupt_CallBack;
tRetVal = FCUART_SetInterrupt(UART_INDEX, &env->tInterruptCfg);
NVIC_SetPriority(IRQ_UART, UART_PRIORITY);
NVIC_EnableIRQ(IRQ_UART);
tRetVal = FCUART_StartReceive(UART_INDEX);
}
}
}
static uint16_t vSerialPortReceiveQueue(tSerialPortFlagchip *env, uint8_t *data, uint16_t size, uint32_t timeout,
osMessageQueueId_t queueId) {
PROCESS_UNUSED_VAR(env)
uint16_t received = 0;
if (timeout) {
uint32_t endMs = SystemGetMs() + timeout;
uint32_t leftMs;
while (size && ((timeout == SystemWaitForever) || (endMs > SystemGetMs()))) {
leftMs = endMs - SystemGetMs();
if (osMessageQueueGet(queueId, data, NULL, leftMs) == osOK) {
--size;
++received;
++data;
}
}
} else {
while (size) {
if (osMessageQueueGet(queueId, data, NULL, 0) == osOK) {
--size;
++received;
++data;
} else {
return received;
}
}
}
return received;
}
static uint16_t vSerialPortReceive(tSerialPortFlagchip *env, uint8_t *data, uint16_t size, uint32_t timeout) {
return vSerialPortReceiveQueue(env, data, size, timeout, env->rxDataQueue);
}
static uint16_t vSerialPortReceiveSniffer(tSerialPortFlagchip *env, uint8_t *data, uint16_t size, uint32_t timeout) {
return env->rxDataSnifferQueue
? vSerialPortReceiveQueue(env, data, size, timeout, env->rxDataSnifferQueue)
: 0;
}
static uint16_t
vSerialPortReceiveSnifferSecond(tSerialPortFlagchip *env, uint8_t *data, uint16_t size, uint32_t timeout) {
return env->rxDataSnifferSecondQueue
? vSerialPortReceiveQueue(env, data, size, timeout, env->rxDataSnifferSecondQueue)
: 0;
}
static uint16_t
vSerialPortTransmitOverCore(tSerialPortFlagchip *env, uint8_t *data, uint16_t size, uint32_t timeout) {
uint16_t sent = 0;
FCUART_ErrorType tRetVal;
tRetVal = FCUART_AssignTxInterruptData(env->UART_INDEX, (uint8 *) data, size);
tRetVal = FCUART_StartTransmit(env->UART_INDEX);
PROCESS_UNUSED_VAR(tRetVal)
uint8_t res;
sent = (osMessageQueueGet(env->txAccessQueue, &res, 0, timeout) == osOK) ? size : 0;
return sent;
}
void SerialPort_RxDmaBufToQueue(tSerialPortFlagchip *env, const void *pSrcBuffer) {
for (uint32_t i = 0; i < env->UART_DMA_RECEIVED_LEN_BUF; ++i) {
osMessageQueuePut(env->rxDataQueue, &((uint8 *)pSrcBuffer)[i], 0x0, 0U);
if (env->rxDataSnifferQueue) {
osMessageQueuePut(env->rxDataSnifferQueue, &((uint8 *)pSrcBuffer)[i], 0x0, 0U);
}
}
env->UART_DMA_RECEIVED_LEN_BUF = 0;
}
static SerialPortIOTransaction vSerialPortTransmitterGet(tSerialPortFlagchip *env) {
PROCESS_UNUSED_VAR(env)
return (SerialPortIOTransaction) vSerialPortTransmitOverCore;
}
tSerialPortIO vSerialPortGetIo(tSerialPortFlagchip *env) {
tSerialPortIO io = {
.env = env,
.receive = (SerialPortIOTransaction) vSerialPortReceive,
.transmit = vSerialPortTransmitterGet(env)
};
return io;
}
tSerialPortIO vSerialPortGetSnifferIo(tSerialPortFlagchip *env) {
tSerialPortIO io = {
.env = env,
.receive = (SerialPortIOTransaction) vSerialPortReceiveSniffer,
.transmit = vSerialPortTransmitterGet(env)
};
return io;
}
tSerialPortIO SerialPort_GetSnifferSecondIo(tSerialPortFlagchip *env) {
tSerialPortIO io = {
.env = env,
.receive = (SerialPortIOTransaction) vSerialPortReceiveSnifferSecond,
.transmit = vSerialPortTransmitterGet(env)
};
return io;
}

22
modular.json Normal file
View File

@ -0,0 +1,22 @@
{
"dep": [
{
"type": "git",
"provider": "HVAC_M7",
"repo": "SerialPort"
},
{
"type": "git",
"provider": "HVAC_M7",
"repo": "SystemDelayInterface"
}
],
"cmake": {
"inc_dirs": [
"Inc"
],
"srcs": [
"Src/**.c"
]
}
}