Stm32 dual can 사용 문제

stm32407vetx 에서 두 개의 can속도를 동시에 받고자 can1, can2를 모두 사용하려 합니다. can1는 250kbps, can2는 500kbps로 설정해주었습니다.
그런데 can2로는 어떤 can 메시지도 수신되지 않고 있습니다.
can2에서 사용한 can 트랜시버를 can1에 연결하고 500kbps으로 설정하여 can1에서 테스트해보니 can 메시지가 잘 수신됩니다.

각 필터들은 아래와 같이 설정해주었습니다.
혹시 can2를 사용하기 위해 추가적으로 필요한 설정이 있을까요?

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    can.c
  * @brief   This file provides code for the configuration
  *          of the CAN instances.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "can.h"

/* USER CODE BEGIN 0 */
extern LOG syslog;
extern SYSTEM_STATE sys_state;

#ifdef ENABLE_MONITOR_CAN
extern CAN_RxHeaderTypeDef can_rx_header;
extern uint8_t can_rx_data[8];
uint8_t test1[1]={0};

#define LWS_CAN_ID_STANDARD 0x2B0
#define LWS_CAN_ID_CONFIG 0x7C0

// CCW 명령 코드
#define CCW_SET_ANGLE_ZERO 0x03
#define CCW_RESET_CALIBRATION 0x05


/* CAN message received */
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {
  int ret = HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &can_rx_header, can_rx_data);


  if (ret != HAL_OK) {
      sys_state.CAN = false;
      HAL_GPIO_WritePin(GPIOE, LED_CAN_Pin, GPIO_PIN_RESET);

      DEBUG_MSG("[%8lu] [ERR] CAN RX failed: %d\r\n", HAL_GetTick(), ret);


      syslog.value[0] = (uint8_t)ret;
      SYS_LOG(LOG_ERROR, CAN, CAN_ERR);
    }

    if (sys_state.CAN != true) {
      sys_state.CAN = true;
      HAL_GPIO_WritePin(GPIOE, LED_CAN_Pin, GPIO_PIN_SET);
    }


  *(uint64_t *)syslog.value = *(uint64_t *)can_rx_data;
  SYS_LOG(LOG_INFO, CAN, can_rx_header.StdId);
}



/* CAN error occured */
void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) {
  sys_state.CAN = false;
  HAL_GPIO_WritePin(GPIOE, LED_CAN_Pin, GPIO_PIN_RESET);

  DEBUG_MSG("[%8lu] [ERR] CAN ERROR occured\r\n", HAL_GetTick());


  *(uint32_t *)syslog.value = HAL_CAN_GetError(hcan);
  SYS_LOG(LOG_ERROR, CAN, CAN_ERR);

  HAL_CAN_ResetError(hcan);
}

/* CAN RX FIFO full */
void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan) {
  sys_state.CAN = false;
  HAL_GPIO_WritePin(GPIOE, LED_CAN_Pin, GPIO_PIN_RESET);

  DEBUG_MSG("[%8lu] [ERR] CAN RX FIFO full\r\n", HAL_GetTick());



  *(uint32_t *)syslog.value = HAL_CAN_GetState(hcan);
  SYS_LOG(LOG_ERROR, CAN, CAN_ERR);

  HAL_CAN_ResetError(hcan);
}

void HAL_CAN_RxFifo0OverrunCallback(CAN_HandleTypeDef *hcan) {
    HAL_GPIO_WritePin(GPIOE, LED_ERR_SYS_Pin, GPIO_PIN_SET);
}



int CAN_SETUP(void) {


  CAN_FilterTypeDef CAN_FILTER;
  CAN_FILTER.FilterBank = 0;
  CAN_FILTER.FilterMode = CAN_FILTERMODE_IDMASK;
  CAN_FILTER.FilterScale = CAN_FILTERSCALE_32BIT;
  CAN_FILTER.FilterIdHigh = 0x0;
  CAN_FILTER.FilterMaskIdHigh = 0x0;
  CAN_FILTER.FilterIdLow = 0x0;
  CAN_FILTER.FilterMaskIdLow = 0x0;
  CAN_FILTER.FilterFIFOAssignment = CAN_RX_FIFO0;
  CAN_FILTER.FilterActivation = ENABLE;
  CAN_FILTER.SlaveStartFilterBank = 14; // CAN1과 CAN2의 필터 뱅크 분할 지점 설정



  CAN_FilterTypeDef CAN_FILTER1;
  CAN_FILTER1.FilterBank = 14;
  CAN_FILTER1.FilterMode = CAN_FILTERMODE_IDMASK;
  CAN_FILTER1.FilterScale = CAN_FILTERSCALE_32BIT;
  CAN_FILTER1.FilterIdHigh = 0x0;
  CAN_FILTER1.FilterMaskIdHigh = 0x0;
  CAN_FILTER1.FilterIdLow = 0x0;
  CAN_FILTER1.FilterMaskIdLow = 0x0;
  CAN_FILTER1.FilterFIFOAssignment = CAN_RX_FIFO0;
  CAN_FILTER1.FilterActivation = ENABLE;
  CAN_FILTER1.SlaveStartFilterBank = 14; // CAN1과 CAN2의 필터 뱅크 분할 지점 설정




  int ret = HAL_CAN_ConfigFilter(&hcan1, &CAN_FILTER);
    if (ret != HAL_OK) {
      return 1;
    }

    ret = HAL_CAN_Start(&hcan1);
    if (ret != HAL_OK) {
      return 2;
    }

    ret = HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
    if (ret != HAL_OK) {
      return 3;
    }

    ret = HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_FULL);
    if (ret != HAL_OK) {
      return 4;
    }

    ret = HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_OVERRUN);
    if (ret != HAL_OK) {
      return 5;
    }

    ret = HAL_CAN_ActivateNotification(&hcan1, CAN_IT_BUSOFF);
    if (ret != HAL_OK) {
      return 6;
    }

    ret = HAL_CAN_ActivateNotification(&hcan1, CAN_IT_ERROR);
    if (ret != HAL_OK) {
      return 7;
    }



     ret = HAL_CAN_ConfigFilter(&hcan2, &CAN_FILTER1);
        if (ret != HAL_OK) {
          return -1;
        }

        ret = HAL_CAN_Start(&hcan2);
        if (ret != HAL_OK) {
          return -2;
        }

        ret = HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO0_MSG_PENDING);
        if (ret != HAL_OK) {
          return -3;
        }

        ret = HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO0_FULL);
        if (ret != HAL_OK) {
          return -4;
        }

        ret = HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO0_OVERRUN);
        if (ret != HAL_OK) {
          return -5;
        }

        ret = HAL_CAN_ActivateNotification(&hcan2, CAN_IT_BUSOFF);
        if (ret != HAL_OK) {
          return -6;
        }


        ret = HAL_CAN_ActivateNotification(&hcan2, CAN_IT_ERROR);
        if (ret != HAL_OK) {
          return -7;
        }


        HAL_StatusTypeDef CAN_SendMessage(uint32_t id, uint8_t *data, uint8_t length) {
        	    CAN_TxHeaderTypeDef txHeader;
        	    uint32_t txMailbox;

        	    txHeader.DLC = length;
        	    txHeader.StdId = id;
        	    txHeader.IDE = CAN_ID_STD;
        	    txHeader.RTR = CAN_RTR_DATA;

        	    return HAL_CAN_AddTxMessage(&hcan2, &txHeader, data, &txMailbox);
        	}

        	// 보정 상태 확인 및 보정 수행 함수
        	void Calibrate_Sensor() {
        	    uint8_t canData[8] = {0};

        	    // 보정 상태 초기화
        	    canData[0] = CCW_RESET_CALIBRATION;
        	    if (CAN_SendMessage(LWS_CAN_ID_CONFIG, canData, 8) != HAL_OK) {
        	        // 에러 처리
        	    }

        	    HAL_Delay(100); // 보정 초기화 후 약간의 지연

        	    // 보정 수행
        	    canData[0] = CCW_SET_ANGLE_ZERO;
        	    if (CAN_SendMessage(LWS_CAN_ID_CONFIG, canData, 8) != HAL_OK) {
        	        // 에러 처리
        	    }

        	}

        	    CAN_TxHeaderTypeDef TxHeader;
        	    uint8_t TxData1[8] = {0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};  // CCW 값이 0x03인 메시지
        	        uint8_t TxData[8] = {0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};  // CCW 값이 0x03인 메시지
        	        uint32_t TxMailbox;

        	        TxHeader.StdId = 0x7C0;  // CAN ID 설정
        	        TxHeader.ExtId = 0x01;
        	        TxHeader.RTR = CAN_RTR_DATA;
        	        TxHeader.IDE = CAN_ID_STD;
        	        TxHeader.DLC = 8;  // 데이터 길이 (8바이트)
        	        TxHeader.TransmitGlobalTime = DISABLE;

        	        if (HAL_CAN_AddTxMessage(&hcan2, &TxHeader, TxData1, &TxMailbox) != HAL_OK) {
        	                    // 전송 실패 처리
        	                    Error_Handler();
        	                }

        	        // 메시지 전송 시도
        	        if (HAL_CAN_AddTxMessage(&hcan2, &TxHeader, TxData, &TxMailbox) != HAL_OK) {
        	            // 전송 실패 처리
        	            Error_Handler();
        	        }


        	      Calibrate_Sensor();



        	if (HAL_CAN_IsTxMessagePending(&hcan2, TxMailbox) == 0) {
        	    // 송신이 성공적으로 완료됨
        	    HAL_GPIO_WritePin(GPIOE, LED_SD_Pin, GPIO_PIN_SET); 
        	}




  return SYS_OK;
}
#endif

/* USER CODE END 0 */

CAN_HandleTypeDef hcan1;
CAN_HandleTypeDef hcan2;

/* CAN1 init function */
void MX_CAN1_Init(void)
{

  /* USER CODE BEGIN CAN1_Init 0 */

  /* USER CODE END CAN1_Init 0 */

  /* USER CODE BEGIN CAN1_Init 1 */

  /* USER CODE END CAN1_Init 1 */
  hcan1.Instance = CAN1;
  hcan1.Init.Prescaler = 12;
  hcan1.Init.Mode = CAN_MODE_NORMAL;
  hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan1.Init.TimeSeg1 = CAN_BS1_11TQ;
  hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;
  hcan1.Init.TimeTriggeredMode = DISABLE;
  hcan1.Init.AutoBusOff = DISABLE;
  hcan1.Init.AutoWakeUp = ENABLE;
  hcan1.Init.AutoRetransmission = DISABLE;
  hcan1.Init.ReceiveFifoLocked = DISABLE;
  hcan1.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN CAN1_Init 2 */

  /* USER CODE END CAN1_Init 2 */

}
/* CAN2 init function */
void MX_CAN2_Init(void)
{

  /* USER CODE BEGIN CAN2_Init 0 */

  /* USER CODE END CAN2_Init 0 */

  /* USER CODE BEGIN CAN2_Init 1 */

  /* USER CODE END CAN2_Init 1 */
  hcan2.Instance = CAN2;
  hcan2.Init.Prescaler = 6;
  hcan2.Init.Mode = CAN_MODE_NORMAL;
  hcan2.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan2.Init.TimeSeg1 = CAN_BS1_11TQ;
  hcan2.Init.TimeSeg2 = CAN_BS2_2TQ;
  hcan2.Init.TimeTriggeredMode = DISABLE;
  hcan2.Init.AutoBusOff = DISABLE;
  hcan2.Init.AutoWakeUp = ENABLE;
  hcan2.Init.AutoRetransmission = DISABLE;
  hcan2.Init.ReceiveFifoLocked = DISABLE;
  hcan2.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN CAN2_Init 2 */

  /* USER CODE END CAN2_Init 2 */

}

static uint32_t HAL_RCC_CAN1_CLK_ENABLED=0;

void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(canHandle->Instance==CAN1)
  {
  /* USER CODE BEGIN CAN1_MspInit 0 */

  /* USER CODE END CAN1_MspInit 0 */
    /* CAN1 clock enable */
    HAL_RCC_CAN1_CLK_ENABLED++;
    if(HAL_RCC_CAN1_CLK_ENABLED==1){
      __HAL_RCC_CAN1_CLK_ENABLE();
    }

    __HAL_RCC_GPIOD_CLK_ENABLE();
    /**CAN1 GPIO Configuration
    PD0     ------> CAN1_RX
    PD1     ------> CAN1_TX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

    /* CAN1 interrupt Init */
    HAL_NVIC_SetPriority(CAN1_TX_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(CAN1_TX_IRQn);
    HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
    HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
    HAL_NVIC_SetPriority(CAN1_SCE_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn);
  /* USER CODE BEGIN CAN1_MspInit 1 */

  /* USER CODE END CAN1_MspInit 1 */
  }
  else if(canHandle->Instance==CAN2)
  {
  /* USER CODE BEGIN CAN2_MspInit 0 */

  /* USER CODE END CAN2_MspInit 0 */
    /* CAN2 clock enable */
    __HAL_RCC_CAN2_CLK_ENABLE();
    HAL_RCC_CAN1_CLK_ENABLED++;
    if(HAL_RCC_CAN1_CLK_ENABLED==1){
      __HAL_RCC_CAN1_CLK_ENABLE();
    }

    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**CAN2 GPIO Configuration
    PB12     ------> CAN2_RX
    PB13     ------> CAN2_TX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_CAN2;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* CAN2 interrupt Init */
    HAL_NVIC_SetPriority(CAN2_TX_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(CAN2_TX_IRQn);
    HAL_NVIC_SetPriority(CAN2_RX0_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn);
    HAL_NVIC_SetPriority(CAN2_RX1_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(CAN2_RX1_IRQn);
    HAL_NVIC_SetPriority(CAN2_SCE_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(CAN2_SCE_IRQn);
  /* USER CODE BEGIN CAN2_MspInit 1 */

  /* USER CODE END CAN2_MspInit 1 */
  }
}

void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
{

  if(canHandle->Instance==CAN1)
  {
  /* USER CODE BEGIN CAN1_MspDeInit 0 */

  /* USER CODE END CAN1_MspDeInit 0 */
    /* Peripheral clock disable */
    HAL_RCC_CAN1_CLK_ENABLED--;
    if(HAL_RCC_CAN1_CLK_ENABLED==0){
      __HAL_RCC_CAN1_CLK_DISABLE();
    }

    /**CAN1 GPIO Configuration
    PD0     ------> CAN1_RX
    PD1     ------> CAN1_TX
    */
    HAL_GPIO_DeInit(GPIOD, GPIO_PIN_0|GPIO_PIN_1);

    /* CAN1 interrupt Deinit */
    HAL_NVIC_DisableIRQ(CAN1_TX_IRQn);
    HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn);
    HAL_NVIC_DisableIRQ(CAN1_RX1_IRQn);
    HAL_NVIC_DisableIRQ(CAN1_SCE_IRQn);
  /* USER CODE BEGIN CAN1_MspDeInit 1 */

  /* USER CODE END CAN1_MspDeInit 1 */
  }
  else if(canHandle->Instance==CAN2)
  {
  /* USER CODE BEGIN CAN2_MspDeInit 0 */

  /* USER CODE END CAN2_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_CAN2_CLK_DISABLE();
    HAL_RCC_CAN1_CLK_ENABLED--;
    if(HAL_RCC_CAN1_CLK_ENABLED==0){
      __HAL_RCC_CAN1_CLK_DISABLE();
    }

    /**CAN2 GPIO Configuration
    PB12     ------> CAN2_RX
    PB13     ------> CAN2_TX
    */
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_12|GPIO_PIN_13);

    /* CAN2 interrupt Deinit */
    HAL_NVIC_DisableIRQ(CAN2_TX_IRQn);
    HAL_NVIC_DisableIRQ(CAN2_RX0_IRQn);
    HAL_NVIC_DisableIRQ(CAN2_RX1_IRQn);
    HAL_NVIC_DisableIRQ(CAN2_SCE_IRQn);
  /* USER CODE BEGIN CAN2_MspDeInit 1 */

  /* USER CODE END CAN2_MspDeInit 1 */
  }
}

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

일단 먼저 STM32F407의 CAN은 실제 peripheral은 1개 뿐이고 CAN1, CAN2는 같은 하드웨어를 공유하는 인스턴스입니다. 그래서 CAN1, CAN2에 필터 설정을 따로 적용해도 실제로는 CAN1의 필터 값이 CAN2에 적용되는 것으로 알고 있어요.

CAN2의 작동 여부 자체가 의심스러운 상황이니 우선 루프백 모드를 끄고 메시지를 보내서 CANH, CANL에서 무슨 신호가 나오고 있기는 한지 확인을 해봐야 할 것 같아요. CANDapter나 그냥 오실로 사용해서 실제 전기적 신호가 나오고 있는지 확인해 보시면 좋을 것 같네요.

CAN filter 설정 중 FMI 개념에 대해 찾아보시기 바랍니다.