cancel
Showing results for 
Search instead for 
Did you mean: 

Cannot use CAN on alternate pins

DPlum
Associate II

Part is STM32L4Q5CG

If configured to use PA11 and PA12 on AF 9 works as described in programming reference.

When changing pins used to PB8 and PB9 CAN cannot be used and never leaves reset.

On my custom board I have PA11 and PA12 in use by USB so I cannot make it work by moving ports.

Has anyone seen this before or know a work around?

Works on PA11 and PA12:

	  GPIO_InitStruct.Pin = GPIO_PIN_11;
	  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(GPIOA, &GPIO_InitStruct);
	  
	  GPIO_InitStruct.Pin = GPIO_PIN_12;
	  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(GPIOA, &GPIO_InitStruct);

When changing to PB8 and PB9 it will not work.

	  GPIO_InitStruct.Pin = GPIO_PIN_8;
	  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);
	  
	  GPIO_InitStruct.Pin = 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);

This code will always hit the error handler

  if (HAL_CAN_Init(&hcan1) != HAL_OK)
  {
    Error_Handler();
  }

Looking closer at the CAN registers, MCR never leaves sleep or reset when on the alternate pins.

There is a CAN transceiver on PB8 and PB9, while PA11, and PA12 are used by USB and cannot be relocated. The foot of this part only supports these two locations for CAN.

4 REPLIES 4

Unpack the RCC and GPIO registers.

Make sure the GPIOB clock is enabled before trying to enable the pin configuration

AF9 looks to be correct.

The ST docs for these things whilst not always correct, are usually pretty consistent and accurate.

https://www.st.com/resource/en/datasheet/stm32l4q5cg.pdf

Secondary consideration would be what's hidden in the MSP code, could be conflicting/double configurations.

Unpack/dump registers and clock sources/paths to the diagnostic serial output.

Only example from GREP of repository, use PULLUP..

STM32Cube_FW_L4_V1.16.0\Projects\STM32L476G-EVAL\Examples\CAN\CAN_Networking\Src\stm32l4xx_hal_msp.c

/**
  * @brief CAN MSP Initialization
  *        This function configures the hardware resources used in this example:
  *           - Peripheral's clock enable
  *           - Peripheral's GPIO Configuration
  *           - NVIC configuration for DMA interrupt request enable
  * @param hcan: CAN handle pointer
  * @retval None
  */
void HAL_CAN_MspInit(CAN_HandleTypeDef *hcan)
{
  GPIO_InitTypeDef   GPIO_InitStruct;
 
  /*##-1- Enable peripherals and GPIO Clocks #################################*/
  /* CAN1 Periph clock enable */
  CANx_CLK_ENABLE();
  /* Enable GPIO clock ****************************************/
  CANx_GPIO_CLK_ENABLE();
 
  /*##-2- Configure peripheral GPIO ##########################################*/
  /* CAN1 TX GPIO pin configuration */
  GPIO_InitStruct.Pin = CANx_TX_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Alternate =  CANx_TX_AF;
 
  HAL_GPIO_Init(CANx_TX_GPIO_PORT, &GPIO_InitStruct);
 
  /* CAN1 RX GPIO pin configuration */
  GPIO_InitStruct.Pin = CANx_RX_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Alternate =  CANx_RX_AF;
 
  HAL_GPIO_Init(CANx_RX_GPIO_PORT, &GPIO_InitStruct);
 
  /*##-3- Configure the NVIC #################################################*/
  /* NVIC configuration for CAN1 Reception complete interrupt */
  HAL_NVIC_SetPriority(CANx_RX_IRQn, 1, 0);
  HAL_NVIC_EnableIRQ(CANx_RX_IRQn);
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Find a NUCLEO board you can use as a proxy to test on.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
TDK
Guru

There are reports of needing to increase the CAN_TIMEOUT_VALUE value used in HAL_Init.

If you feel a post has answered your question, please click "Accept as Solution".
DPlum
Associate II

Thanks for the suggestions I should have clarified all the things tried.

This started out with an issue in custom code (non-Cube) but I used HAL to reproduce the problem and is a good basis to discuss the issue from.

Yes __HAL_RCC_GPIOB_CLK_ENABLE(); is being called in the MSP code. I have even tried enabling all other clocks.

    __HAL_RCC_CAN1_CLK_ENABLE();
 
    __HAL_RCC_GPIOB_CLK_ENABLE();
 
	  GPIO_InitStruct.Pin = GPIO_PIN_8 ;
	  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
	  GPIO_InitStruct.Pull = GPIO_PULLUP;
	  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	  GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
	  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
	  
    GPIO_InitStruct.Pin = 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);

I originally prototyped this months ago on a Nucleo-L4(closest I could get to this part) but have implemented the same functions previously on different ST MCU's with no issue until now. To me this appears to be related to the STM32L4Q maybe the small package 48 pin.

Increasing the CAN_TIMEOUT has no effect CAN1 is never starting correctly when hooked to PB8, PB9

I have also tried changing the PB8 and PB9 HFP status in SYSCFG->CFGR1 but made no difference here.

	SET_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_I2C_PB8_FMP);
	SET_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_I2C_PB9_FMP);

I also tried initializing using PA11 and PA12 then immediately initializing PB8, PB9 this works as long as nothing is connected to PA11, PA12 but if USB is connected it will disrupt the USB connection and will not work on PB8,9.

Also tried enabling all clocks with no luck

Also tried all 16 possible AF to see if there was possibly an error in the Alternate function no luck I suspect AF9 is correct.

I have also studied all the RCC registers and CAN registers I will take a closer look at the GPIO registers. Note the CAN registers on PB8,9 are much different then they are on PA11,12 as MCR never leaves reset and MSR never responds to changes to sleep and init done in MCR.