19 Commits

Author SHA1 Message Date
eeeck 5b5edc2ead Merge pull request 'Implement task for sending CAN data via UART' (#21) from dev_serial-send into main
Reviewed-on: erickahmed/j1939_logger#21
2026-06-18 15:35:22 +02:00
eeeck adcdc8b340 Fix spacing 2026-06-18 15:15:52 +02:00
eeeck 2880ae64dc Check semaphore acquire status 2026-06-18 15:05:50 +02:00
eeeck 33a2cc8fb4 Enable USART1 global interrupt 2026-06-18 15:02:19 +02:00
eeeck 41de3851f2 Implement better ciclical method for dummy CAN frame sent on debug 2026-06-18 14:06:00 +02:00
eeeck 6f8d2a12ea Merge branch 'stm_debug' into dev_serial-send 2026-06-18 13:43:23 +02:00
eeeck 5a91a56e27 Fix spacing 2026-06-18 13:25:07 +02:00
eeeck 9f1e7ba267 Move debugger connection check to main 2026-06-18 13:24:33 +02:00
eeeck 9086bf3efb Fix buffer overwrite while DMA is not completed 2026-06-18 13:08:11 +02:00
eeeck 3bf5a8cc19 Fix spacing 2026-06-18 13:05:54 +02:00
eeeck b9c371ed58 Initialize semaphore with count of 1 2026-06-18 13:05:43 +02:00
eeeck 9d96b3d4f2 Start 2026-06-18 12:50:50 +02:00
eeeck bb70e0675a Accept for standard IDs and extended IDs 2026-06-18 09:11:25 +02:00
eeeck 11e50b05e4 Make debug print safer by checking if ST-Link debugger is connected 2026-06-18 09:10:00 +02:00
eeeck e951eaef7c Fix debug prints 2026-06-18 09:07:09 +02:00
eeeck ce25cba61b Fix typo 2026-06-18 09:06:07 +02:00
eeeck 691d5dc1ea Fix baudrates
- They were wrongly calculated on 168MHz but APB1 bus is at 42 MHz (168
  / 4)
2026-06-18 08:49:52 +02:00
eeeck 052d3fc5c0 Enable CAN bus NVIC interrupts with higher priority
- This was blocking the CPU from vectoring to
  HAL_CAN_RxFifo0MsgPendingCallback
2026-06-18 08:44:25 +02:00
eeeck 4967cd9b32 Add USART DMA in Normal mode from CubeMX 2026-06-18 08:29:21 +02:00
7 changed files with 71 additions and 27 deletions
+1
View File
@@ -52,6 +52,7 @@ void MemManage_Handler(void);
void BusFault_Handler(void); void BusFault_Handler(void);
void UsageFault_Handler(void); void UsageFault_Handler(void);
void DebugMon_Handler(void); void DebugMon_Handler(void);
void USART1_IRQHandler(void);
void SDIO_IRQHandler(void); void SDIO_IRQHandler(void);
void TIM6_DAC_IRQHandler(void); void TIM6_DAC_IRQHandler(void);
void DMA2_Stream3_IRQHandler(void); void DMA2_Stream3_IRQHandler(void);
+7 -4
View File
@@ -51,11 +51,9 @@ void CAN_Logger_Init(CAN_HandleTypeDef *hcan1, CAN_HandleTypeDef *hcan2)
filter.FilterBank = 0; filter.FilterBank = 0;
if (HAL_CAN_ConfigFilter(hcan1, &filter) != HAL_OK) Error_Handler(); if (HAL_CAN_ConfigFilter(hcan1, &filter) != HAL_OK) Error_Handler();
if (HAL_CAN_Start(hcan1) != HAL_OK) Error_Handler();
filter.FilterBank = 14; filter.FilterBank = 14;
if (HAL_CAN_ConfigFilter(hcan2, &filter) != HAL_OK) Error_Handler(); if (HAL_CAN_ConfigFilter(hcan2, &filter) != HAL_OK) Error_Handler();
if (HAL_CAN_Start(hcan2) != HAL_OK) Error_Handler();
} }
/* END CAN_Logger_Init */ /* END CAN_Logger_Init */
@@ -77,7 +75,8 @@ void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
// TODO: manage the case of FIFO overflow // TODO: manage the case of FIFO overflow
if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rxHeader, data) != HAL_OK) return; if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rxHeader, data) != HAL_OK) return;
message.id = rxHeader.ExtId; if (rxHeader.IDE == CAN_ID_EXT) message.id = rxHeader.ExtId;
else message.id = rxHeader.StdId;
message.dlc = rxHeader.DLC; message.dlc = rxHeader.DLC;
message.isExtended = (rxHeader.IDE == CAN_ID_EXT); message.isExtended = (rxHeader.IDE == CAN_ID_EXT);
message.source = (hcan->Instance == CAN1) ? 1 : 2; message.source = (hcan->Instance == CAN1) ? 1 : 2;
@@ -113,15 +112,19 @@ void vCANListener(void *argument)
osMessageQueueId_t queue = (hcan->Instance == CAN1) ? xCAN1RxQueue : xCAN2RxQueue; osMessageQueueId_t queue = (hcan->Instance == CAN1) ? xCAN1RxQueue : xCAN2RxQueue;
CanMessage_t message; CanMessage_t message;
if (HAL_CAN_Start(hcan) != HAL_OK) Error_Handler();
HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING); HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
uint32_t irqn = (hcan->Instance == CAN1) ? CAN1_RX0_IRQn : CAN2_RX0_IRQn;
HAL_NVIC_SetPriority(irqn, 6, 0);
HAL_NVIC_EnableIRQ(irqn);
for (;;) for (;;)
{ {
if (osMessageQueueGet(queue, &message, NULL, 1000) == osOK) if (osMessageQueueGet(queue, &message, NULL, 1000) == osOK)
{ {
// J1939 decoding // J1939 decoding
// RELAY: Push to the UART queue
osMessageQueuePut(xUARTQueue, &message, 0U, 0U); osMessageQueuePut(xUARTQueue, &message, 0U, 0U);
} }
else DEBUG_PRINT("No CAN yet!\r\n"); else DEBUG_PRINT("No CAN yet!\r\n");
+26 -11
View File
@@ -101,8 +101,8 @@ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
*/ */
void vUARTLogger(void *argument) void vUARTLogger(void *argument)
{ {
CanMessage_t message; CanMessage_t message;
char tx_buffer[45]; char tx_buffer[45];
#ifdef DEBUG_DUMMY_FRAME #ifdef DEBUG_DUMMY_FRAME
CanMessage_t dummy_frame = { CanMessage_t dummy_frame = {
@@ -118,23 +118,38 @@ void vUARTLogger(void *argument)
{ {
DEBUG_PRINT("Waiting for CAN traffic...\r\n"); DEBUG_PRINT("Waiting for CAN traffic...\r\n");
#ifdef DEBUG_DUMMY_FRAME
uint32_t queue_timeout = 1000U;
#else
uint32_t queue_timeout = osWaitForever;
#endif
#ifdef DEBUG_DUMMY_FRAME #ifdef DEBUG_DUMMY_FRAME
osMessageQueuePut(xUARTQueue, &dummy_frame, 0U, 0U); osMessageQueuePut(xUARTQueue, &dummy_frame, 0U, 0U);
osDelay(1000); osDelay(1000);
#endif #endif
if (osMessageQueueGet(xUARTQueue, &message, NULL, osWaitForever) == osOK) if (osMessageQueueGet(xUARTQueue, &message, NULL, queue_timeout) == osOK)
{ {
DEBUG_PRINT("Waiting for CAN traffic...\r\n"); if (osSemaphoreAcquire(xUARTDMASemaphore, queue_timeout) == osOK)
if (osMessageQueueGet(xUARTQueue, &message, NULL, osWaitForever) == osOK)
{ {
DEBUG_PRINT("CAN frame detected\r\n");
int len = format_can_message(tx_buffer, message.source, &message); int len = format_can_message(tx_buffer, message.source, &message);
HAL_UART_Transmit_DMA(&huart1, (uint8_t*)tx_buffer, len);
osSemaphoreAcquire(xUARTDMASemaphore, osWaitForever); if (HAL_UART_Transmit_DMA(&huart1, (uint8_t*)tx_buffer, len) == HAL_OK)
DEBUG_PRINT("CAN frame sent via UART\r\n"); {
DEBUG_PRINT("CAN frame sent via UART\r\n");
}
else
{
osSemaphoreRelease(xUARTDMASemaphore);
DEBUG_PRINT("HAL error, CAN frame NOT sent!\r\n");
}
} }
} else
{
DEBUG_PRINT("ERROR: Semaphore timeout! UART might be stuck in BUSY state.\r\n");
}
}
} }
} }
/* END vUARTLoggerListen */ /* END vUARTLoggerListen */
+15 -12
View File
@@ -77,11 +77,10 @@ static void MX_SDIO_SD_Init(void);
static void MX_USART1_UART_Init(void); static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */ /* USER CODE BEGIN PFP */
int _write(int file, char *ptr, int len) { int _write(int file, char *ptr, int len)
for (int i = 0; i < len; i++) { {
ITM_SendChar((*ptr++)); for (int i = 0; i < len; i++) ITM_SendChar((*ptr++));
} return len;
return len;
} }
/* USER CODE END PFP */ /* USER CODE END PFP */
@@ -98,10 +97,14 @@ int main(void)
{ {
/* USER CODE BEGIN 1 */ /* USER CODE BEGIN 1 */
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; if (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk)
ITM->LAR = 0xC5ACCE55; {
ITM->TER = 1 << 0; CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
ITM->TCR = ITM_TCR_ITMENA_Msk | ITM_TCR_SYNCENA_Msk | ITM_TCR_SWOENA_Msk; ITM->LAR = 0xC5ACCE55;
ITM->TER = 1 << 0;
ITM->TCR = ITM_TCR_ITMENA_Msk | ITM_TCR_SYNCENA_Msk | ITM_TCR_SWOENA_Msk;
}
DEBUG_PRINT("Booting system\r\n"); DEBUG_PRINT("Booting system\r\n");
/* USER CODE END 1 */ /* USER CODE END 1 */
@@ -171,7 +174,7 @@ int main(void)
/* USER CODE END RTOS_MUTEX */ /* USER CODE END RTOS_MUTEX */
/* USER CODE BEGIN RTOS_SEMAPHORES */ /* USER CODE BEGIN RTOS_SEMAPHORES */
xUARTDMASemaphore = osSemaphoreNew(1, 0, NULL); xUARTDMASemaphore = osSemaphoreNew(1, 1, NULL);
if (xUARTDMASemaphore == NULL) Error_Handler(); if (xUARTDMASemaphore == NULL) Error_Handler();
/* USER CODE END RTOS_SEMAPHORES */ /* USER CODE END RTOS_SEMAPHORES */
@@ -277,7 +280,7 @@ static void MX_CAN1_Init(void)
/* USER CODE END CAN1_Init 1 */ /* USER CODE END CAN1_Init 1 */
hcan1.Instance = CAN1; hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 4; hcan1.Init.Prescaler = 8;
hcan1.Init.Mode = CAN_MODE_SILENT; hcan1.Init.Mode = CAN_MODE_SILENT;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ; hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_16TQ; hcan1.Init.TimeSeg1 = CAN_BS1_16TQ;
@@ -314,7 +317,7 @@ static void MX_CAN2_Init(void)
/* USER CODE END CAN2_Init 1 */ /* USER CODE END CAN2_Init 1 */
hcan2.Instance = CAN2; hcan2.Instance = CAN2;
hcan2.Init.Prescaler = 8; hcan2.Init.Prescaler = 16;
hcan2.Init.Mode = CAN_MODE_SILENT; hcan2.Init.Mode = CAN_MODE_SILENT;
hcan2.Init.SyncJumpWidth = CAN_SJW_1TQ; hcan2.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan2.Init.TimeSeg1 = CAN_BS1_16TQ; hcan2.Init.TimeSeg1 = CAN_BS1_16TQ;
+6
View File
@@ -392,6 +392,9 @@ void HAL_UART_MspInit(UART_HandleTypeDef* huart)
__HAL_LINKDMA(huart,hdmatx,hdma_usart1_tx); __HAL_LINKDMA(huart,hdmatx,hdma_usart1_tx);
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspInit 1 */ /* USER CODE BEGIN USART1_MspInit 1 */
/* USER CODE END USART1_MspInit 1 */ /* USER CODE END USART1_MspInit 1 */
@@ -424,6 +427,9 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
/* USART1 DMA DeInit */ /* USART1 DMA DeInit */
HAL_DMA_DeInit(huart->hdmatx); HAL_DMA_DeInit(huart->hdmatx);
/* USART1 interrupt DeInit */
HAL_NVIC_DisableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspDeInit 1 */ /* USER CODE BEGIN USART1_MspDeInit 1 */
/* USER CODE END USART1_MspDeInit 1 */ /* USER CODE END USART1_MspDeInit 1 */
+15
View File
@@ -59,6 +59,7 @@ extern DMA_HandleTypeDef hdma_sdio_rx;
extern DMA_HandleTypeDef hdma_sdio_tx; extern DMA_HandleTypeDef hdma_sdio_tx;
extern SD_HandleTypeDef hsd; extern SD_HandleTypeDef hsd;
extern DMA_HandleTypeDef hdma_usart1_tx; extern DMA_HandleTypeDef hdma_usart1_tx;
extern UART_HandleTypeDef huart1;
extern TIM_HandleTypeDef htim6; extern TIM_HandleTypeDef htim6;
/* USER CODE BEGIN EV */ /* USER CODE BEGIN EV */
@@ -163,6 +164,20 @@ void DebugMon_Handler(void)
/* please refer to the startup file (startup_stm32f4xx.s). */ /* please refer to the startup file (startup_stm32f4xx.s). */
/******************************************************************************/ /******************************************************************************/
/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
/** /**
* @brief This function handles SDIO global interrupt. * @brief This function handles SDIO global interrupt.
*/ */
+1
View File
@@ -124,6 +124,7 @@ NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:true\:false
NVIC.TIM6_DAC_IRQn=true\:15\:0\:false\:false\:true\:false\:false\:true\:true NVIC.TIM6_DAC_IRQn=true\:15\:0\:false\:false\:true\:false\:false\:true\:true
NVIC.TimeBase=TIM6_DAC_IRQn NVIC.TimeBase=TIM6_DAC_IRQn
NVIC.TimeBaseIP=TIM6 NVIC.TimeBaseIP=TIM6
NVIC.USART1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
PA10.Mode=Asynchronous PA10.Mode=Asynchronous
PA10.Signal=USART1_RX PA10.Signal=USART1_RX