Обновление

This commit is contained in:
cfif 2026-04-20 17:36:49 +03:00
parent cd30cb58d9
commit 3d40d436b4
2 changed files with 109 additions and 21 deletions

View File

@ -41,8 +41,7 @@ typedef struct {
#define COUNT_QUEUE 4 #define COUNT_QUEUE 4
typedef struct typedef struct {
{
FLEXCAN_IdType eRxFrameType; /**< FLEXCAN ID type, 0 STD, 1 EXT */ FLEXCAN_IdType eRxFrameType; /**< FLEXCAN ID type, 0 STD, 1 EXT */
uint32_t u32RxCanId; /**< FLEXCAN received ID */ uint32_t u32RxCanId; /**< FLEXCAN received ID */
uint32_t u32RxCanIdMask; uint32_t u32RxCanIdMask;
@ -62,7 +61,7 @@ typedef struct {
bool reInit; bool reInit;
uint8_t CountSoftFilter_RX; uint8_t CountHardSoftFilter_RX;
FLEXCAN_BaudType canBaudRate; FLEXCAN_BaudType canBaudRate;
@ -91,6 +90,15 @@ typedef struct {
can_rx_message_type rx_message_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; } tCanSerialPortFrameFlagchip;
bool vCanSerialPortFrameDMAInit( bool vCanSerialPortFrameDMAInit(
@ -130,6 +138,7 @@ bool vCanSerialPortFrameDMAInit(
void CAN_RxInterrupt_CallBack_Handler(tCanSerialPortFrameFlagchip *env, uint8_t u8CanIndex, FLEXCAN_RxMsgType *pRxCfg); void CAN_RxInterrupt_CallBack_Handler(tCanSerialPortFrameFlagchip *env, uint8_t u8CanIndex, FLEXCAN_RxMsgType *pRxCfg);
void CanSerialPortFrameIrqRxProcessing(tCanSerialPortFrameFlagchip *env, uint32_t *pBuf); void CanSerialPortFrameIrqRxProcessing(tCanSerialPortFrameFlagchip *env, uint32_t *pBuf);
void CanSerialPortFrameIrqRxProcessingNO_DMA(tCanSerialPortFrameFlagchip *env, FLEXCAN_RxMsgType *pRxCfg); void CanSerialPortFrameIrqRxProcessingNO_DMA(tCanSerialPortFrameFlagchip *env, FLEXCAN_RxMsgType *pRxCfg);
void CanSerialPortFrameSetId(tCanSerialPortFrameFlagchip *env, uint32_t id); void CanSerialPortFrameSetId(tCanSerialPortFrameFlagchip *env, uint32_t id);
@ -140,4 +149,6 @@ tSerialPortFrameIO CanPortFrame_GetIo(tCanSerialPortFrameFlagchip *env);
tSerialPortFrameIO CanPortFrame_GetSnifferIo(tCanSerialPortFrameFlagchip *env); tSerialPortFrameIO CanPortFrame_GetSnifferIo(tCanSerialPortFrameFlagchip *env);
bool vCanSerialPortSetMaskCount(tCanSerialPortFrameFlagchip *env, uint8_t maskCount);
#endif //FLAGCHIP_CAN_MODULE_CAN_FRAME_H #endif //FLAGCHIP_CAN_MODULE_CAN_FRAME_H

View File

@ -106,7 +106,18 @@ bool vCanSerialPortFrameDMAInit(
env->CAN_INDEX = CAN_INDEX; env->CAN_INDEX = CAN_INDEX;
env->DMA_BUF_LEN_RX = DMA_BUF_LEN_RX; env->DMA_BUF_LEN_RX = DMA_BUF_LEN_RX;
env->IdHardSoftFilter_RX = (FilterTo_FLEXCAN_RxMbFilterType *) IdHardSoftFilter_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); env->access = osMutexNew(NULL);
@ -247,7 +258,7 @@ bool vCanSerialPortFrameDMAInit(
env->tIntCfg.bEnRxMBInterrupt = 1U; env->tIntCfg.bEnRxMBInterrupt = 1U;
env->tIntCfg.pRxMBNotify = CAN_RxInterrupt_CallBack; env->tIntCfg.pRxMBNotify = CAN_RxInterrupt_CallBack;
env->tIntCfg.bEnRxFifoInterrupt = 1U; env->tIntCfg.bEnRxFifoInterrupt = 0U;
env->tIntCfg.pRxFifoNotify = CAN_RxFifoInterrupt_CallBack; env->tIntCfg.pRxFifoNotify = CAN_RxFifoInterrupt_CallBack;
} }
@ -288,6 +299,73 @@ bool vCanSerialPortFrameDMAInit(
//конец------------------------------------CAN---------------------------------------------------------------------- //конец------------------------------------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, static void CanSerialPortFrameAddDataQueue(tCanSerialPortFrameFlagchip *env, can_rx_message_type *rx_message_struct,
uint8_t filter) { uint8_t filter) {
osStatus_t status = osMessageQueuePut(env->rxDataQueue[filter], rx_message_struct, 0x0, 0U); osStatus_t status = osMessageQueuePut(env->rxDataQueue[filter], rx_message_struct, 0x0, 0U);
@ -325,20 +403,19 @@ void CanSerialPortFrameIrqRxProcessingNO_DMA(tCanSerialPortFrameFlagchip *env, F
// Быстрый поиск по ID (можно использовать switch или бинарный поиск) // Быстрый поиск по ID (можно использовать switch или бинарный поиск)
uint8_t filter_index = 0xFF; uint8_t filter_index = 0xFF;
const uint8_t count = env->CountSoftFilter_RX; const uint8_t count = env->CountHardSoftFilter_RX;
// Самый быстрый вариант: если ID совпадает с UDS // Линейный поиск ID
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++) { for (uint8_t i = 0; i < count; i++) {
if (rx_id == env->IdHardSoftFilter_RX[i].u32RxCanId) { if (rx_id == env->IdHardSoftFilter_RX[i].u32RxCanId) {
filter_index = env->IdHardSoftFilter_RX[i].filter; filter_index = env->IdHardSoftFilter_RX[i].filter;
pMsg->filter_index = filter_index; pMsg->filter_index = filter_index;
break;
if (i> 2) {
asm("nop");
} }
break;
} }
} }
@ -371,7 +448,7 @@ void CanSerialPortFrameIrqRxProcessing(tCanSerialPortFrameFlagchip *env, uint32_
uint8_t index = 0xFF; 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) && if ((env->rx_message_struct.id_type == FLEXCAN_ID_STD) &&
(env->IdHardSoftFilter_RX[i].eRxFrameType == 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 // message buffer 3th word
uint32_t *pSrc = (uint32_t *) FLEXCAN_MB_WORDN_ADDR(&pBuf[env->pBufCounter << 2], 0U, 8U, 8U); 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]; uint32_t *pDest = (uint32_t *) &env->rx_message_struct.data[0];