diff --git a/Inc/CanSerialPortFrame.h b/Inc/CanSerialPortFrame.h index 33a3cf0..ca196f7 100644 --- a/Inc/CanSerialPortFrame.h +++ b/Inc/CanSerialPortFrame.h @@ -41,10 +41,9 @@ typedef struct { #define COUNT_QUEUE 4 -typedef struct -{ - FLEXCAN_IdType eRxFrameType; /**< FLEXCAN ID type, 0 STD, 1 EXT */ - uint32_t u32RxCanId; /**< FLEXCAN received ID */ +typedef struct { + FLEXCAN_IdType eRxFrameType; /**< FLEXCAN ID type, 0 STD, 1 EXT */ + uint32_t u32RxCanId; /**< FLEXCAN received ID */ uint32_t u32RxCanIdMask; uint8_t filter; } FilterTo_FLEXCAN_RxMbFilterType; @@ -62,7 +61,7 @@ typedef struct { bool reInit; - uint8_t CountSoftFilter_RX; + uint8_t CountHardSoftFilter_RX; FLEXCAN_BaudType canBaudRate; @@ -91,6 +90,15 @@ typedef struct { can_rx_message_type rx_message_struct; + IRQn_Type IRQ_CAN; + + FLEXCAN_ErrorInterruptCallBackType CAN_ErrorInterrupt_CallBack; + FLEXCAN_RxInterruptCallBackType CAN_RxInterrupt_CallBack; + FLEXCAN_RxInterruptCallBackType CAN_RxFifoInterrupt_CallBack; + FLEXCAN_TxInterruptCallBackType CAN_TxInterrupt_CallBack; + DMA_TransferCompleteCallbackType DMA_TransferCompleteCallback; + DMA_TransferErrorCallbackType DMA_ErrorCallback; + } tCanSerialPortFrameFlagchip; bool vCanSerialPortFrameDMAInit( @@ -130,6 +138,7 @@ bool vCanSerialPortFrameDMAInit( void CAN_RxInterrupt_CallBack_Handler(tCanSerialPortFrameFlagchip *env, uint8_t u8CanIndex, FLEXCAN_RxMsgType *pRxCfg); void CanSerialPortFrameIrqRxProcessing(tCanSerialPortFrameFlagchip *env, uint32_t *pBuf); + void CanSerialPortFrameIrqRxProcessingNO_DMA(tCanSerialPortFrameFlagchip *env, FLEXCAN_RxMsgType *pRxCfg); void CanSerialPortFrameSetId(tCanSerialPortFrameFlagchip *env, uint32_t id); @@ -140,4 +149,6 @@ tSerialPortFrameIO CanPortFrame_GetIo(tCanSerialPortFrameFlagchip *env); tSerialPortFrameIO CanPortFrame_GetSnifferIo(tCanSerialPortFrameFlagchip *env); +bool vCanSerialPortSetMaskCount(tCanSerialPortFrameFlagchip *env, uint8_t maskCount); + #endif //FLAGCHIP_CAN_MODULE_CAN_FRAME_H diff --git a/Src/CanSerialPortFrame.c b/Src/CanSerialPortFrame.c index ead780a..40a6951 100644 --- a/Src/CanSerialPortFrame.c +++ b/Src/CanSerialPortFrame.c @@ -106,7 +106,18 @@ bool vCanSerialPortFrameDMAInit( env->CAN_INDEX = CAN_INDEX; env->DMA_BUF_LEN_RX = DMA_BUF_LEN_RX; env->IdHardSoftFilter_RX = (FilterTo_FLEXCAN_RxMbFilterType *) IdHardSoftFilter_RX; - env->CountSoftFilter_RX = CountHardSoftFilter_RX; + env->CountHardSoftFilter_RX = CountHardSoftFilter_RX; + env->canBaudRate = canBaudRate; + env->IRQ_CAN = IRQ_CAN; + + env->CAN_ErrorInterrupt_CallBack = CAN_ErrorInterrupt_CallBack; + env->CAN_RxInterrupt_CallBack = CAN_RxInterrupt_CallBack; + env->CAN_RxFifoInterrupt_CallBack = CAN_RxFifoInterrupt_CallBack; + env->CAN_TxInterrupt_CallBack = CAN_TxInterrupt_CallBack; + env->DMA_TransferCompleteCallback = DMA_TransferCompleteCallback; + env->DMA_ErrorCallback = DMA_ErrorCallback; + + env->access = osMutexNew(NULL); @@ -247,7 +258,7 @@ bool vCanSerialPortFrameDMAInit( env->tIntCfg.bEnRxMBInterrupt = 1U; env->tIntCfg.pRxMBNotify = CAN_RxInterrupt_CallBack; - env->tIntCfg.bEnRxFifoInterrupt = 1U; + env->tIntCfg.bEnRxFifoInterrupt = 0U; env->tIntCfg.pRxFifoNotify = CAN_RxFifoInterrupt_CallBack; } @@ -288,6 +299,73 @@ bool vCanSerialPortFrameDMAInit( //конец------------------------------------CAN---------------------------------------------------------------------- } + + +bool vCanSerialPortSetMaskCount(tCanSerialPortFrameFlagchip *env, uint8_t maskCount) +{ + FLEXCAN_ErrorType tRetVal; + uint8_t i; + + + // Отключаем прерывания CAN + NVIC_DisableIRQ(env->IRQ_CAN); + + // Останавливаем CAN модуль (переводим в режим заморозки) + tRetVal = FLEXCAN_Stop(env->CAN_INDEX); + if (tRetVal != FLEXCAN_ERROR_OK) { + NVIC_EnableIRQ(env->IRQ_CAN); + return false; + } + + // Обновляем список фильтров в рабочем буфере (первые maskCount элементов) + for (i = 0; i < maskCount; i++) { + env->pRxMbFilterList[i].eRxFrameType = env->IdHardSoftFilter_RX[i].eRxFrameType; + env->pRxMbFilterList[i].u32RxCanId = env->IdHardSoftFilter_RX[i].u32RxCanId; + env->pRxMbFilterList[i].u32RxCanIdMask = env->IdHardSoftFilter_RX[i].u32RxCanIdMask; + } + + for (i = maskCount; i < 32; i++) { + env->pRxMbFilterList[i].eRxFrameType = env->IdHardSoftFilter_RX[0].eRxFrameType; + env->pRxMbFilterList[i].u32RxCanId = env->IdHardSoftFilter_RX[0].u32RxCanId; + env->pRxMbFilterList[i].u32RxCanIdMask = env->IdHardSoftFilter_RX[0].u32RxCanIdMask; + } + + + // Обновляем конфигурационную структуру для драйвера +// env->CountHardSoftFilter_RX = maskCount; + env->tMbCfg.pRxFilterMBList = env->pRxMbFilterList; +// env->tMbCfg.u8RxFilterMBCnt = maskCount; + + // Убеждаемся, что в tMbCfg сохранены правильные настройки TX + // (они были установлены при инициализации и не должны измениться) + // Если нужно, можно перечитать их из глобальной таблицы драйвера + // но обычно они уже корректны. + + // Переконфигурируем фильтры (без полной деинициализации CAN) + tRetVal = FLEXCAN_RxFilterConfig(env->CAN_INDEX, &env->tMbCfg); + + if (tRetVal != FLEXCAN_ERROR_OK) { + // В случае ошибки пытаемся восстановить предыдущее состояние + // (можно также попробовать перечитать старые фильтры) + FLEXCAN_Start(env->CAN_INDEX); + NVIC_EnableIRQ(env->IRQ_CAN); + return false; + } + + // Запускаем CAN снова (выход из режима заморозки) + tRetVal = FLEXCAN_Start(env->CAN_INDEX); + if (tRetVal != FLEXCAN_ERROR_OK) { + NVIC_EnableIRQ(env->IRQ_CAN); + return false; + } + + // Включаем прерывания обратно + NVIC_EnableIRQ(env->IRQ_CAN); + + return true; +} + + static void CanSerialPortFrameAddDataQueue(tCanSerialPortFrameFlagchip *env, can_rx_message_type *rx_message_struct, uint8_t filter) { osStatus_t status = osMessageQueuePut(env->rxDataQueue[filter], rx_message_struct, 0x0, 0U); @@ -325,20 +403,19 @@ void CanSerialPortFrameIrqRxProcessingNO_DMA(tCanSerialPortFrameFlagchip *env, F // Быстрый поиск по ID (можно использовать switch или бинарный поиск) uint8_t filter_index = 0xFF; - const uint8_t count = env->CountSoftFilter_RX; + const uint8_t count = env->CountHardSoftFilter_RX; - // Самый быстрый вариант: если ID совпадает с UDS - if (rx_id == Diag_To_CCU_CANID || rx_id == Diag_Functional_CANID) { - filter_index = PROTOCOL_CAN_UDS; - pMsg->filter_index = filter_index; - } else { - // Линейный поиск по остальным ID (только если нужно) - for (uint8_t i = 0; i < count; i++) { - if (rx_id == env->IdHardSoftFilter_RX[i].u32RxCanId) { - filter_index = env->IdHardSoftFilter_RX[i].filter; - pMsg->filter_index = filter_index; - break; + // Линейный поиск ID + for (uint8_t i = 0; i < count; i++) { + if (rx_id == env->IdHardSoftFilter_RX[i].u32RxCanId) { + filter_index = env->IdHardSoftFilter_RX[i].filter; + pMsg->filter_index = filter_index; + + if (i> 2) { + asm("nop"); } + + break; } } @@ -371,7 +448,7 @@ void CanSerialPortFrameIrqRxProcessing(tCanSerialPortFrameFlagchip *env, uint32_ uint8_t index = 0xFF; - for (uint8_t i = 0; i < env->CountSoftFilter_RX; ++i) { + for (uint8_t i = 0; i < env->CountHardSoftFilter_RX; ++i) { if ((env->rx_message_struct.id_type == FLEXCAN_ID_STD) && (env->IdHardSoftFilter_RX[i].eRxFrameType == FLEXCAN_ID_STD)) { @@ -415,7 +492,7 @@ void CanSerialPortFrameIrqRxProcessing(tCanSerialPortFrameFlagchip *env, uint32_ } - if (env->CountSoftFilter_RX == 0) { + if (env->CountHardSoftFilter_RX == 0) { // message buffer 3th word uint32_t *pSrc = (uint32_t *) FLEXCAN_MB_WORDN_ADDR(&pBuf[env->pBufCounter << 2], 0U, 8U, 8U); uint32_t *pDest = (uint32_t *) &env->rx_message_struct.data[0];