// // Created by cfif on 16.09.22. // #include #include "SerialPortFlagchip.h" #include "string.h" static const PCC_ClkSrcType s_ePccUartTable[] = { PCC_CLK_FCUART0, PCC_CLK_FCUART1, PCC_CLK_FCUART2, PCC_CLK_FCUART3, PCC_CLK_FCUART4, PCC_CLK_FCUART5, PCC_CLK_FCUART6, PCC_CLK_FCUART7 }; void vSerialPortInitDMA( tSerialPortFlagchip *env, FCUART_Type *uart, uint32_t BoundRate, uint8 UART_INDEX, // UART0 = 0 ... UART7 = 7 IRQn_Type IRQ_UART, // FCUART0_IRQn ... FCUART7_IRQn uint8 UART_PRIORITY, uint8_t *dataBufTransmit, uint32_t dataBufTransmitLen, DMA_ChannelType DMA_CHANNEL_RX, DMA_RequestSourceType DMA_CHANNEL_REQ_RX, uint8_t *DMA_BUF_RX, uint16_t DMA_BUF_LEN_RX, IRQn_Type IRQ_DMA_RX, uint8_t IRQ_DMA_PRIORITY_RX, uint8_t IRQ_DMA_CHANNEL_PRIORITY_RX, 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 = DMA_CHANNEL_RX; env->UART = uart; env->DMA_BUF_LEN = DMA_BUF_LEN_RX; env->UART_DMA_RECEIVED_LEN_BUF = 0; env->dataBufTransmit = dataBufTransmit; env->dataBufTransmitLen = dataBufTransmitLen; env->txAccessQueue = osMessageQueueNew(1, 1, NULL); env->rxDataQueue = osMessageQueueNew(rxBufferLength, 1, NULL); if (rxSnifferLength) { env->rxDataSnifferQueue = osMessageQueueNew(rxSnifferLength, 1, NULL); } else { env->rxDataSnifferQueue = 0; } //начало-----------------------------------DMA-RX------------------------------------------------------------------- //начало-----------------------------------DMA-RX------------------------------------------------------------------- //начало-----------------------------------DMA-RX------------------------------------------------------------------- env->chnCfg_RX.pSrcBuffer = &(uart->DATA); env->chnCfg_RX.pDestBuffer = DMA_BUF_RX; env->chnCfg_RX.u32BlockSize = 1U; env->chnCfg_RX.u16BlockCount = 1U; env->chnCfg_RX.u8ChannelPriority = IRQ_DMA_CHANNEL_PRIORITY_RX; env->chnCfg_RX.eSrcDataSize = DMA_TRANSFER_SIZE_1B; env->chnCfg_RX.eDestDataSize = DMA_TRANSFER_SIZE_1B; env->chnCfg_RX.eSrcIncMode = DMA_INCREMENT_DISABLE; env->chnCfg_RX.eDestIncMode = DMA_INCREMENT_DATA_SIZE; env->chnCfg_RX.bSrcBlockOffsetEn = false; env->chnCfg_RX.bDestBlockOffsetEn = false; env->chnCfg_RX.s32BlockOffset = 0; env->chnCfg_RX.bSrcAddrLoopbackEn = false; env->chnCfg_RX.bDestAddrLoopbackEn = false; env->chnCfg_RX.bAutoStop = false; env->chnCfg_RX.bSrcCircularBufferEn = false; env->chnCfg_RX.u32SrcCircBufferSize = 0U; env->chnCfg_RX.bDestCircularBufferEn = true; env->chnCfg_RX.u32DestCircBufferSize = DMA_BUF_LEN_RX; env->chnCfg_RX.eTriggerSrc = DMA_CHANNEL_REQ_RX; DMA_InitChannel(DMA_INSTANCE_0, DMA_CHANNEL_RX, &env->chnCfg_RX); env->interruptCfg_RX.bTransferCompleteIntEn = true; env->interruptCfg_RX.pTransferCompleteNotify = pTransferCompleteNotify; env->interruptCfg_RX.bTransferErrorIntEn = true; env->interruptCfg_RX.pTransferErrorNotify = pTransferErrorNotify; DMA_InitChannelInterrupt(DMA_INSTANCE_0, DMA_CHANNEL_RX, &env->interruptCfg_RX); DMA_StartChannel(DMA_INSTANCE_0, DMA_CHANNEL_RX); NVIC_SetPriority(DMA_Error_IRQn, IRQ_DMA_PRIORITY_RX); NVIC_SetPriority(IRQ_DMA_RX, IRQ_DMA_PRIORITY_RX); NVIC_EnableIRQ(IRQ_DMA_RX); //конец-----------------------------------DMA-RX-------------------------------------------------------------------- //конец-----------------------------------DMA-RX-------------------------------------------------------------------- //конец-----------------------------------DMA-RX-------------------------------------------------------------------- //начало------------------------------------UART-------------------------------------------------------------------- //начало------------------------------------UART-------------------------------------------------------------------- //начало------------------------------------UART-------------------------------------------------------------------- FCUART_ErrorType tRetVal; uint32_t u32PccFuncClk; FCUART_InitMemory(UART_INDEX); u32PccFuncClk = PCC_GetPccFunctionClock(s_ePccUartTable[UART_INDEX]); if (u32PccFuncClk != 0U) { env->tInitCfg.bEnRxFullDma = true; // UART receiver full DMA disable env->tInitCfg.bEnTxFifo = true; env->tInitCfg.u8TxFifoWaterMark = 0U; env->tInitCfg.bEnRxFifo = true; env->tInitCfg.u8RxFifoWaterMark = 0U; 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->dataBufTransmit; // 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 = false; env->tInterruptCfg.pTxEmptyNotify = FCUART_TxEmptyInterrupt_CallBack; env->tInterruptCfg.pTxCompleteNotify = FCUART_TxCompleteInterrupt_CallBack; tRetVal = FCUART_BufTransmitted(UART_INDEX, &env->tInterruptCfg); tRetVal = FCUART_SetInterrupt(UART_INDEX, &env->tInterruptCfg); NVIC_SetPriority(IRQ_UART, UART_PRIORITY); NVIC_EnableIRQ(IRQ_UART); tRetVal = FCUART_StartReceive(UART_INDEX); } } //конец------------------------------------UART--------------------------------------------------------------------- //конец------------------------------------UART--------------------------------------------------------------------- //конец------------------------------------UART--------------------------------------------------------------------- } 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 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, env->dataBufTransmit, 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_TxEndTransmitted(tSerialPortFlagchip *env, uint8_t data) { osMessageQueuePut(env->txAccessQueue, &data, 0x0, 0U); } 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_POINTER_BUF += env->UART_DMA_RECEIVED_LEN_BUF; env->UART_DMA_RECEIVED_LEN_BUF = 0; if (env->UART_DMA_RECEIVED_POINTER_BUF >= env->DMA_BUF_LEN) env->UART_DMA_RECEIVED_POINTER_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; }