cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with CAN on NUCLEOF091RC Board

florian239955_stm1
Associate
Posted on March 27, 2015 at 18:29

Dear all,

I'm currently trying to work around the CAN bus on the NUCLEOF091RC board, with the STD_Peripheral library. I have been facing some issues with the Can_Init function. It returns the following status: CAN_InitStatus_Failed After some research and tests, I found out that after setting the INRQ bit to 0 in order to leave Init mode, the INAK bit is never reset by hardware. I did the following modification to the code in the stmf0xx_can.c file for debug purposes (lines 280-295):

/* Request leave initialisation */
CANx->MCR &= ~CAN_MCR_INRQ;
/* Led on */
GPIO_WriteBit(GPIOC, GPIO_Pin_11, Bit_SET);
/* Wait the acknowledge */
wait_ack = 0;
while
(((CANx->MSR & CAN_MSR_INAK) == CAN_MSR_INAK))
// && (wait_ack != INAK_TIMEOUT))
{
wait_ack++;
}
/* An other led on */
GPIO_WriteBit(GPIOC, GPIO_Pin_12, Bit_SET);

As you can guess, the second led never brights up. Please find attached my source code. Also, I use pins PB8/9 as I'm not sure that I can use PA11/12 since they seem to be used for USB on Nucleo. Did anyone of you succeeded in working around the CAN bus on stm32F091? Did you encounter similar issues? Thank you for your answers! #can-stm32f091-can_init
2 REPLIES 2
florian239955_stm1
Associate
Posted on March 29, 2015 at 16:04

Finally, i found out the solution to solve my problem.

Using these two lines to put the GPIOB 8 and 9 in alternate function mode doesn't work.

GPIO_PinAFConfig(GPIOB, GPIO_Pin_8, GPIO_AF_4);
GPIO_PinAFConfig(GPIOB, GPIO_Pin_9, GPIO_AF_4);

Instead, I try it manually setting the GPIOB->AFR[1] register to 0x44 (GPIOB->AFR[1] |= 0x04 | (0x04 << ((9 - 8) * 4)); Code sample to put GPIO pin in alternate function can be found in the RM0091 Reference Manual p9 GPIO_PinAFConfig source code (from stm32f0xx_gpio.c) :

void
GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)
{
uint32_t temp = 0x00;
uint32_t temp_2 = 0x00;
/* Check the parameters */
assert_param(IS_GPIO_LIST_PERIPH(GPIOx));
assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));
assert_param(IS_GPIO_AF(GPIO_AF));
temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4));
GPIOx->AFR[GPIO_PinSource >> 0x03] &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4));
temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] | temp;
GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_2;
}

I don't explain why they apply a 0x07 mask to the GPIO_PinSource as it returns 0 (for GPIO_PinSource > 7). Definitely this function doesn't return the correct value in the AFR registers of GPIOB. Has anybody an answer to explain this ?
Posted on March 30, 2015 at 15:17

Pin is a bit vector, PinSource is an index.

You're calling with the wrong parameters, should be using

GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_4);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_4);

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