2016-10-05 02:30 PM
/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¤tviews=523
#can #example #stm32f4292016-10-06 03:15 AM
Hif.mic,
I think that is related to an already reported bug. As workaround proposal , try the following andcome 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-
2016-10-06 11:02 AM
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?2016-10-08 08:29 AM
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.
2016-10-12 11:06 AM
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.2017-07-27 12:15 AM
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