Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 263b699662 | |||
| da0211ebd5 | |||
| d5fd649325 | |||
| 79ef4c5fdb | |||
| e32f501285 | |||
| 85c8cd4eed | |||
| 9a58e41d55 | |||
| 48aaaf7fb8 | |||
| 4236c204a6 | |||
| 2d7e7f514a | |||
| 600a4e24d8 | |||
| 6954fc5497 | |||
| 03fec5ff34 | |||
| 76f6526036 | |||
| ff1335b0dc | |||
| 397711e9fb | |||
| 4da8f59330 | |||
| c9f735acd9 | |||
| 30410f9b9e | |||
| e14a98eba4 |
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "main.h"
|
||||
|
||||
void uart_printf(const char *fmt, ...);
|
||||
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);
|
||||
void vUARTLogger(void *argument);
|
||||
|
||||
|
||||
+4
-6
@@ -18,6 +18,7 @@
|
||||
#include "main.h"
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "cansend.h"
|
||||
#include "cmsis_os.h"
|
||||
#include <string.h>
|
||||
/* USER CODE END Includes */
|
||||
@@ -93,10 +94,7 @@ void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
|
||||
led_task = xCAN2LedTask;
|
||||
}
|
||||
|
||||
if (osMessageQueuePut(queue, &message, 0U, 0U) == osOK)
|
||||
{
|
||||
osThreadFlagsSet(led_task, 0x01);
|
||||
}
|
||||
if (osMessageQueuePut(queue, &message, 0U, 0U) == osOK) osThreadFlagsSet(led_task, 0x01);
|
||||
}
|
||||
/* END HAL_CAN_RxFifo0MsgPendingCallback */
|
||||
|
||||
@@ -116,7 +114,7 @@ void vCANListener(void *argument)
|
||||
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_SetPriority(irqn, 5, 0);
|
||||
HAL_NVIC_EnableIRQ(irqn);
|
||||
|
||||
for (;;)
|
||||
@@ -133,7 +131,7 @@ void vCANListener(void *argument)
|
||||
|
||||
/* BEGIN vLEDHeartbeat */
|
||||
/**
|
||||
* @brief Blink a LED in heartbeat mode when CAN traffic is detected
|
||||
* @brief Turn on LED when CAN traffic is detected
|
||||
* @param argument: LED GPIO (port and pin)
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
+37
-15
@@ -50,13 +50,16 @@ void uart_printf(const char *fmt, ...)
|
||||
{
|
||||
if (osKernelGetState() == osKernelRunning && __get_IPSR() == 0)
|
||||
{
|
||||
if (osSemaphoreAcquire(xUARTDMASemaphore, osWaitForever) == osOK)
|
||||
if (osSemaphoreAcquire(xUARTDMASemaphore, 100U) == osOK)
|
||||
{
|
||||
HAL_UART_Transmit(&huart1, (uint8_t*)buf, len, HAL_MAX_DELAY);
|
||||
osSemaphoreRelease(xUARTDMASemaphore);
|
||||
}
|
||||
}
|
||||
else HAL_UART_Transmit(&huart1, (uint8_t*)buf, len, HAL_MAX_DELAY);
|
||||
else
|
||||
{
|
||||
HAL_UART_Transmit(&huart1, (uint8_t*)buf, len, HAL_MAX_DELAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* END uart_printf */
|
||||
@@ -121,22 +124,31 @@ static int format_can_message(char *buf, uint8_t source, const CanMessage_t *mes
|
||||
*/
|
||||
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
|
||||
{
|
||||
if (huart->Instance == USART1)
|
||||
{
|
||||
osSemaphoreRelease(xUARTDMASemaphore);
|
||||
}
|
||||
if (huart->Instance == USART1) osSemaphoreRelease(xUARTDMASemaphore);
|
||||
}
|
||||
/* END HAL_UART_TxCpltCallback */
|
||||
|
||||
/* BEGIN HAL_UART_ErrorCallback */
|
||||
/**
|
||||
* @brief Safely release UART semaphore inside ISR and yield task if possible.
|
||||
/**``MEN
|
||||
* @brief Handle UART errors
|
||||
* @param argument: UART handle
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
|
||||
{
|
||||
if (huart->Instance == USART1) osSemaphoreRelease(xUARTDMASemaphore);
|
||||
if (huart->Instance == USART1)
|
||||
{
|
||||
__HAL_UART_CLEAR_OREFLAG(huart);
|
||||
__HAL_UART_CLEAR_FEFLAG(huart);
|
||||
__HAL_UART_CLEAR_NEFLAG(huart);
|
||||
__HAL_UART_CLEAR_PEFLAG(huart);
|
||||
|
||||
HAL_UART_DMAStop(huart);
|
||||
|
||||
huart->gState = HAL_UART_STATE_READY;
|
||||
|
||||
osSemaphoreRelease(xUARTDMASemaphore);
|
||||
}
|
||||
}
|
||||
/* END HAL_UART_ErrorCallback */
|
||||
|
||||
@@ -149,15 +161,23 @@ void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
|
||||
void vUARTLogger(void *argument)
|
||||
{
|
||||
CanMessage_t message;
|
||||
char tx_buffer[45];
|
||||
static char tx_buffer[45];
|
||||
|
||||
#ifdef DEBUG_DUMMY_FRAME
|
||||
CanMessage_t dummy_frame = {
|
||||
.id = 0x0CF00400, // J1939 EEC1 ID
|
||||
.dlc = 8, // 8 bytes of data
|
||||
.isExtended = 1, // 29-bit Extended ID
|
||||
.source = 1, // CAN1
|
||||
.payload = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}
|
||||
};
|
||||
#endif
|
||||
|
||||
for (;;)
|
||||
{
|
||||
DEBUG_PRINT("[D] Waiting for CAN traffic...\r\n");
|
||||
|
||||
if (osMessageQueueGet(xUARTQueue, &message, NULL, osWaitForever) == osOK)
|
||||
if (osMessageQueueGet(xUARTQueue, &message, NULL, 1000U) == osOK)
|
||||
{
|
||||
if (osSemaphoreAcquire(xUARTDMASemaphore, osWaitForever) == osOK)
|
||||
if (osSemaphoreAcquire(xUARTDMASemaphore, 100U) == osOK)
|
||||
{
|
||||
int len = format_can_message(tx_buffer, message.source, &message);
|
||||
|
||||
@@ -167,7 +187,9 @@ void vUARTLogger(void *argument)
|
||||
DEBUG_PRINT("[E] HAL error, CAN frame NOT sent!\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else DEBUG_PRINT("[E] Semaphore timeout! UART might be stuck in BUSY state.\r\n");
|
||||
}
|
||||
else DEBUG_PRINT("[D] Waiting for CAN traffic...\r\n");
|
||||
}
|
||||
}
|
||||
/* END vUARTLogger */
|
||||
|
||||
+39
-17
@@ -127,12 +127,12 @@ int main(void)
|
||||
/* USER CODE END SysInit */
|
||||
|
||||
/* Initialize all configured peripherals */
|
||||
MX_GPIO_Init();
|
||||
MX_DMA_Init();
|
||||
MX_GPIO_Init();
|
||||
MX_USART1_UART_Init();
|
||||
MX_CAN1_Init();
|
||||
MX_CAN2_Init();
|
||||
MX_SDIO_SD_Init();
|
||||
MX_USART1_UART_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
DEBUG_PRINT("[L] Initializing CAN bus logger\r\n");
|
||||
CAN_Logger_Init(&hcan1, &hcan2);
|
||||
@@ -196,6 +196,9 @@ int main(void)
|
||||
xUartTask = osThreadNew(vUARTLogger, NULL, &UartLoggerAttributes);
|
||||
xCAN1LedTask = osThreadNew(vLEDHeartbeat, &led_can1, &LEDHeartbeatCAN1Attributes);
|
||||
xCAN2LedTask = osThreadNew(vLEDHeartbeat, &led_can2, &LEDHeartbeatCAN2Attributes);
|
||||
|
||||
if (xCAN1rxTask == NULL || xCAN2rxTask == NULL || xUartTask == NULL ||
|
||||
xCAN1LedTask == NULL || xCAN2LedTask == NULL) Error_Handler();
|
||||
/* USER CODE END RTOS_THREADS */
|
||||
|
||||
/* USER CODE BEGIN RTOS_EVENTS */
|
||||
@@ -282,7 +285,7 @@ static void MX_CAN1_Init(void)
|
||||
/* USER CODE END CAN1_Init 1 */
|
||||
hcan1.Instance = CAN1;
|
||||
hcan1.Init.Prescaler = 4;
|
||||
hcan1.Init.Mode = CAN_MODE_SILENT;
|
||||
hcan1.Init.Mode = CAN_MODE_NORMAL;
|
||||
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
|
||||
hcan1.Init.TimeSeg1 = CAN_BS1_16TQ;
|
||||
hcan1.Init.TimeSeg2 = CAN_BS2_4TQ;
|
||||
@@ -319,7 +322,7 @@ static void MX_CAN2_Init(void)
|
||||
/* USER CODE END CAN2_Init 1 */
|
||||
hcan2.Instance = CAN2;
|
||||
hcan2.Init.Prescaler = 8;
|
||||
hcan2.Init.Mode = CAN_MODE_SILENT;
|
||||
hcan2.Init.Mode = CAN_MODE_NORMAL;
|
||||
hcan2.Init.SyncJumpWidth = CAN_SJW_1TQ;
|
||||
hcan2.Init.TimeSeg1 = CAN_BS1_16TQ;
|
||||
hcan2.Init.TimeSeg2 = CAN_BS2_4TQ;
|
||||
@@ -391,7 +394,7 @@ static void MX_USART1_UART_Init(void)
|
||||
|
||||
/* USER CODE END USART1_Init 1 */
|
||||
huart1.Instance = USART1;
|
||||
huart1.Init.BaudRate = 1152000;
|
||||
huart1.Init.BaudRate = 1000000;
|
||||
huart1.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
huart1.Init.StopBits = UART_STOPBITS_1;
|
||||
huart1.Init.Parity = UART_PARITY_NONE;
|
||||
@@ -498,6 +501,22 @@ static void MX_GPIO_Init(void)
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
//*Configure CAN1 pins : PB8, PB9 */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
|
||||
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(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
//*Configure CAN2 pins : PB12, PB13 */
|
||||
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);
|
||||
|
||||
/* USER CODE BEGIN MX_GPIO_Init_2 */
|
||||
DEBUG_PRINT("[L] GPIO initialized\r\n");
|
||||
/* USER CODE END MX_GPIO_Init_2 */
|
||||
@@ -538,25 +557,28 @@ void Error_Handler(void)
|
||||
|
||||
/* USER CODE BEGIN Error_Handler_Debug */
|
||||
/* User can add his own implementation to report the HAL error return state */
|
||||
if (HAL_CAN_GetState(&hcan1) != HAL_CAN_STATE_READY)
|
||||
{
|
||||
DEBUG_PRINT("[E] CAN1 error code: 0x%08lX\r\n", (unsigned long)HAL_CAN_GetError(&hcan1));
|
||||
}
|
||||
if (HAL_CAN_GetState(&hcan2) != HAL_CAN_STATE_READY)
|
||||
{
|
||||
DEBUG_PRINT("[E] CAN2 error code: 0x%08lX\r\n", (unsigned long)HAL_CAN_GetError(&hcan2));
|
||||
}
|
||||
|
||||
// TODO: write error to SD
|
||||
|
||||
/* Disabling interrupts here (after reporting above) freezes the FreeRTOS
|
||||
scheduler for good, since it relies on SysTick/PendSV. */
|
||||
__disable_irq();
|
||||
|
||||
//TODO: check if it is necessary to stop FreeRTOS
|
||||
|
||||
uint32_t error_code_can1;
|
||||
uint32_t error_code_can2;
|
||||
|
||||
if (HAL_CAN_GetState(&hcan1) != HAL_CAN_STATE_READY) error_code_can1 = HAL_CAN_GetError(&hcan1);
|
||||
if (HAL_CAN_GetState(&hcan2) != HAL_CAN_STATE_READY) error_code_can2 = HAL_CAN_GetError(&hcan2);
|
||||
|
||||
// TODO: write error to SD and/or serial
|
||||
|
||||
HAL_GPIO_WritePin(led_can1.port, led_can1.pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(led_can2.port, led_can2.pin, GPIO_PIN_RESET);
|
||||
|
||||
while (1)
|
||||
{
|
||||
HAL_GPIO_TogglePin(led_error.port, led_error.pin);
|
||||
HAL_Delay(250);
|
||||
HAL_GPIO_TogglePin(led_error.port, led_error.pin);
|
||||
for(volatile uint32_t i = 0; i < 4000000; i++);
|
||||
}
|
||||
/* USER CODE END Error_Handler_Debug */
|
||||
}
|
||||
|
||||
+18
-1
@@ -41,7 +41,8 @@
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
extern CAN_HandleTypeDef hcan1;
|
||||
extern CAN_HandleTypeDef hcan2;
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
@@ -250,4 +251,20 @@ void DMA2_Stream7_IRQHandler(void)
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/**
|
||||
* @brief This function handles CAN1 RX0 interrupt.
|
||||
*/
|
||||
void CAN1_RX0_IRQHandler(void)
|
||||
{
|
||||
HAL_CAN_IRQHandler(&hcan1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles CAN2 RX0 interrupt.
|
||||
*/
|
||||
void CAN2_RX0_IRQHandler(void)
|
||||
{
|
||||
HAL_CAN_IRQHandler(&hcan2);
|
||||
}
|
||||
|
||||
/* USER CODE END 1 */
|
||||
|
||||
Reference in New Issue
Block a user