2015-03-27 10:29 AM
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
2015-03-29 07:04 AM
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 ?
2015-03-30 06:17 AM
Pin is a bit vector, PinSource is an index.
You're calling with the wrong parameters, should be usingGPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_4);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_4);