cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_CAN_Transmit timeout on STM32F429 using CubeF4 example

16513584
Associate II
Posted on October 05, 2016 at 23:30

I'm having trouble implementing the STM32CubeF4 CAN example on my STM32F429I-Disco board. I'm using the CAN Network example provided with the STM324x9_Eval which in the readme.txt says: This example runs on STM32F429xx/STM32F439xx devices.

My problem lies with the HAL_CAN_Transmit() function which returns a HAL_CAN_Transmit_TIMEOUT status whenever I'm trying to transmit a message. I can't read any output with on the CAN_tx pins with an oscilloscope.

I tried testing the program with two STM32F429 boards using a MCP2551 CAN Transceiver for each.

I haven't done much with the example code except change the GPIO pins for CAN1 pins PB8 (CAN rx) and PB9 (CAN tx).

I read in this earlier post that there might be a bug with the HAL_CAN_Transmit() function and was wondering if anyone knows of a workaround?

Here's an earlier post about someone having similar problems:

/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/HAL_CAN_Transmit%20timeout%20error&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=523

#can #example #stm32f429
5 REPLIES 5
Walid FTITI_O
Senior II
Posted on October 06, 2016 at 12:15

Hif.mic,

I think that is related to an already reported bug. As workaround proposal , try the following and

come back to tell us if that resolve your issue:

You should cancel CAN transmission when timeout is reached by setting the correspondent ABRQx bit. See below (on bold):

/* Check End of transmission flag */

while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))

{

/* Check for the Timeout */

if(Timeout != HAL_MAX_DELAY)

{

if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))

{

hcan->State = HAL_CAN_STATE_TIMEOUT;

/* Process unlocked */

__HAL_UNLOCK(hcan);

__HAL_CAN_CANCEL_TRANSMIT(hcan, transmitmailbox);

return HAL_TIMEOUT;

}

}

}

-Hannibal-

16513584
Associate II
Posted on October 06, 2016 at 20:02

I'll try this tomorrow, I use two STM32F429 boards and a custom made CAN Transceiver network using MCP2551's. I'll let you know tomorrow if the test was successful.

As a side, I just want to confirm that I don't have to make any physical alterations to my boards to get the CAN working on all pins?

16513584
Associate II
Posted on October 08, 2016 at 17:29

Goodday Hannibal

I'm still struggling to transmit messages with can, I tried the workaround but it did not work. I get the following errors in my registers: TSR: 0x1c000009 IER: 0x8f02 ESR: 0xf80057 When I replaced HAL_CAN_Transmit() with HAL_CAN_Transmit_IT() my TSR register has a different error code: 0x52000008 I wonder if some of my problems might not be the result of faulty clock initialisation. here follows my main.c code:

#include ''main.h''
/** @addtogroup STM32F4xx_HAL_Examples
* @{
*/
/** @addtogroup CAN_Networking
* @{
*/ 
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define KEY_PRESSED 0x01
#define KEY_NOT_PRESSED 0x00
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint8_t ubKeyNumber = 0x0;
CAN_HandleTypeDef CanHandle;
/* Private function prototypes -----------------------------------------------*/
static void SystemClock_Config(void);
static void Error_Handler(void);
static void CAN_Config(void);
static void LED_Display(uint8_t LedStatus);
/* Private functions ---------------------------------------------------------*/
/**
* @brief Main program
* @param None
* @retval None
*/
int main(void)
{
/* STM32F4xx HAL library initialization:
- Configure the Flash prefetch, instruction and Data caches
- Configure the Systick to generate an interrupt each 1 msec
- Set NVIC Group Priority to 4
- Global MSP (MCU Support Package) initialization
*/
HAL_Init();
/* Configure the system clock to 180 MHz */
SystemClock_Config();
/* Configure LED1, LED2, LED3 and LED4 */
//BSP_LED_Init(LED1);
//BSP_LED_Init(LED2);
BSP_LED_Init(LED3);
BSP_LED_Init(LED4);
/* Configure Key Button */ 
BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_GPIO);
/*##-1- Configure the CAN peripheral #######################################*/
CAN_Config();
/*##-2- Start the Reception process and enable reception interrupt #########*/
if(HAL_CAN_Receive_IT(&CanHandle, CAN_FIFO0) != HAL_OK)
{
fprintf(stderr, ''Error_Handler active in CAN_Receive'');
Error_Handler();
}
/* Infinite loop */
while(1)
{
while(BSP_PB_GetState(BUTTON_KEY) == KEY_PRESSED)
{
if(ubKeyNumber == 0x4) 
{
ubKeyNumber = 0x00;
}
else
{
LED_Display(++ubKeyNumber);
/* Set the data to be transmitted */
CanHandle.pTxMsg->Data[0] = ubKeyNumber;
CanHandle.pTxMsg->Data[1] = 0xAD;
/*##-3- Start the Transmission process ###############################*/
if(HAL_CAN_Transmit(&CanHandle, 10) != HAL_OK)
{
/* Transmition Error */
fprintf(stderr, ''Error_Handler active in CAN Transmit'');
Error_Handler();
}
HAL_Delay(10);
while(BSP_PB_GetState(BUTTON_KEY) != KEY_NOT_PRESSED)
{
}
}
}
} 
}
/**
* @brief System Clock Configuration
* The system Clock is configured as follow : 
* System Clock source = PLL (HSE)
* SYSCLK(Hz) = 180000000
* HCLK(Hz) = 180000000
* AHB Prescaler = 1
* APB1 Prescaler = 4
* APB2 Prescaler = 2
* HSE Frequency(Hz) = 25000000
* PLL_M = 25
* PLL_N = 360
* PLL_P = 2
* PLL_Q = 7
* VDD(V) = 3.3
* Main regulator output voltage = Scale1 mode
* Flash Latency(WS) = 5
* @param None
* @retval None
*/
static void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
/* Enable Power Control clock */
__HAL_RCC_PWR_CLK_ENABLE();
/* The voltage scaling allows optimizing the power consumption when the device is 
clocked below the maximum system frequency, to update the voltage scaling value 
regarding system frequency refer to product datasheet. */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/* Enable HSE Oscillator and activate PLL with HSE as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 25;
RCC_OscInitStruct.PLL.PLLN = 360;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
/* Activate the Over-Drive mode */
HAL_PWREx_EnableOverDrive();
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 
clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; 
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; 
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
}
/**
* @brief This function is executed in case of error occurrence.
* @param None
* @retval None
*/
static void Error_Handler(void)
{
while(1)
{
}
}
/**
* @brief Configures the CAN.
* @param None
* @retval None
*/
static void CAN_Config(void)
{
CAN_FilterConfTypeDef sFilterConfig;
static CanTxMsgTypeDef TxMessage;
static CanRxMsgTypeDef RxMessage;
/*##-1- Configure the CAN peripheral #######################################*/
CanHandle.Instance = CAN1;
CanHandle.pTxMsg = &TxMessage;
CanHandle.pRxMsg = &RxMessage;
CanHandle.Init.TTCM = DISABLE;
CanHandle.Init.ABOM = DISABLE;
CanHandle.Init.AWUM = DISABLE;
CanHandle.Init.NART = DISABLE;
CanHandle.Init.RFLM = DISABLE;
CanHandle.Init.TXFP = DISABLE;
CanHandle.Init.Mode = CAN_MODE_NORMAL;
CanHandle.Init.SJW = CAN_SJW_1TQ;
CanHandle.Init.BS1 = CAN_BS1_6TQ;
CanHandle.Init.BS2 = CAN_BS2_8TQ;
CanHandle.Init.Prescaler = 2;
if(HAL_CAN_Init(&CanHandle) != HAL_OK)
{
/* Initialization Error */
fprintf(stderr, ''Error_Handler active in CAN Config Init'');
Error_Handler();
}
/*##-2- Configure the CAN Filter ###########################################*/
sFilterConfig.FilterNumber = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = 0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.BankNumber = 14;
if(HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig) != HAL_OK)
{
/* Filter configuration Error */
fprintf(stderr, ''Error_Handler active CAN Config Filter'');
Error_Handler();
}
/*##-3- Configure Transmission process #####################################*/
CanHandle.pTxMsg->StdId = 0x321;
CanHandle.pTxMsg->ExtId = 0x01;
CanHandle.pTxMsg->RTR = CAN_RTR_DATA;
CanHandle.pTxMsg->IDE = CAN_ID_STD;
CanHandle.pTxMsg->DLC = 2;
}
/**
* @brief Transmission complete callback in non blocking mode 
* @param CanHandle: pointer to a CAN_HandleTypeDef structure that contains
* the configuration information for the specified CAN.
* @retval None
*/
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* CanHandle)
{
if ((CanHandle->pRxMsg->StdId == 0x321)&&(CanHandle->pRxMsg->IDE == CAN_ID_STD) && (CanHandle->pRxMsg->DLC == 2))
{
LED_Display(CanHandle->pRxMsg->Data[0]);
ubKeyNumber = CanHandle->pRxMsg->Data[0];
}
/* Receive */
if(HAL_CAN_Receive_IT(CanHandle, CAN_FIFO0) != HAL_OK)
{
/* Reception Error */
Error_Handler();
}
}
/**
* @brief Turns ON/OFF the dedicated LED.
* @param LedStatus: LED number from 0 to 3
* @retval None
*/
void LED_Display(uint8_t LedStatus)
{
/* Turn OFF all LEDs */
BSP_LED_On(LED3);
BSP_LED_On(LED4);
switch(LedStatus)
{
case(1):
/* Turn ON LED1 */
BSP_LED_Toggle(LED3);
break;
case(2): 
/* Turn ON LED2 */
BSP_LED_Toggle(LED4);
break;
case(3): 
/* Turn ON LED3 */
BSP_LED_Toggle(LED3);
break;
case(4): 
/* Turn ON LED4 */
BSP_LED_Toggle(LED4);
break;
default:
break;
}
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{ 
/* User can add his own implementation to report the file name and line number,
ex: printf(''Wrong parameters value: file %s on line %d

'', file, line) */
/* Infinite loop */
while (1)
{
}
}

As mentioned earlier, I use an STM32F429-discovery, so I edited some code and have added the stm32f429i_discovery.h and .c files from the SPI example with the base project generated with gnu-arm-eclipse plugin. In the meantime, I will rebuild my project using a clean base from st32cubef4 and try tests again.
16513584
Associate II
Posted on October 12, 2016 at 20:06

I managed to get CAN communication working. I decreased the baud rate by increasing the CAN_Config() prescaler to 80. I can now transmit and receiver frames between two STM32F429 boards.

I think the problem might have been my CAN bus which I build on a PCB using two MCP2551 CAN Transceivers. The bus length is very short (3cm). Maybe to short to use termination resistances and baud rate to high to use without termination resistances.

Anyway, I can continue with testing at a lower baud rate.

Posted on July 27, 2017 at 07:15

Hi 

Hannibal, i use stm32f429+tcan334/g and face the same problem and i had added '__HAL_CAN_CANCEL_TRANSMIT(hcan, transmitmailbox);'

BUT, of no avail. Is there any other solution to deal with this phenomenon

Thanks

Havens