// // Created by cfif on 16.09.22. // #include #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_DIV_BY1; 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_SetPriorityGrouping(NVIC_PRIORITY_GROUP_4); NVIC_SetPriority(DMA_Error_IRQn, IRQ_DMA_PRIORITY); 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; }