AnsweredAssumed Answered

STM32F072RB CAN bus

Question asked by Yogesh Khedkar on Apr 18, 2018
Latest reply on Apr 19, 2018 by Yogesh Khedkar

Hi Guys,

I will explain issue of CAN bus case wise

1) Loop back mode:  

I'm using the Discovery STM32F072RBT6 board. On that board i'm using the CAN bus (PIN no. PA11 , PA12).

When i configure the CAN in loopback mode and checked it on board it is working fine. If i connect the Tx (PA12) pin to DSO there is no sign of signal (As per datasheet in loopback mode, signal transmission can be observed on the Tx Pin).

 

2) Normal mode 

When i configure the CAN bus in Normal mode and send the data on Tx (PA12) pin there is no sign of signal on the Tx pin when i observed it on Oscilloscope. 

Below is the code 

 

 

Clive Oneafonso.luis.002barkin.tyler.001karakoc.yalcin.001Roberto Giovinetti@

 

#include "CAN_HAL_Drivers.h"
////////////////////////////////////////////////// MACRO DEFINE //////////////////////////////////////////////////
#define CMD_TOGGLE (0xDA) /* Single byte of Data to send on the bus */
#define CAN_ID_MASK (0xFF70U) /* CAN ID mask */
#define CAN_ID1 (0x651U) /* CAN identifier 1 */
#define CAN_ID2 (0x652U) /* CAN identifier 1 */
#define FILTER_LIST (0) /* 0: filter mode = identifier mask, 1: filter mode = identifier list */

///////////////////////////////////////////////// STRUCTURE DEFINE ///////////////////////////////////////////////


uint8_t Tx_data[8]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
static uint8_t counter;

void CAN_init(void)
{
Configure_GPIO_LED();
Configure_GPIO_CAN();
Configure_CAN();
Configure_GPIO_Button();
Configure_EXTI();

}

 

////////////////////////////////////////////////////////////// Configure_GPIO_LED //////////////////////////////////////////////////////////////
/**
* @brief This function :
- Enables GPIO clock
- Configures the Green LED pin on GPIO PC9
- Configures the Orange LED pin on GPIO PC8
* @param None
* @retval None
*/
__INLINE void Configure_GPIO_LED(void)
{
/* Enable the peripheral clock of GPIOC port */
/* RCC -> Reset clock control */
/* RCC->AHBENR = peripheral clock enable 32 bit regisetr register */

RCC->AHBENR |= RCC_AHBENR_GPIOCEN; //((uint32_t)0x00080000U)

/* Select output mode (01) on PC8 and PC9 */
GPIOC->MODER = (GPIOC->MODER & ~(GPIO_MODER_MODER8 | GPIO_MODER_MODER9 | GPIO_MODER_MODER6 | GPIO_MODER_MODER7)) \
| (GPIO_MODER_MODER8_0 | GPIO_MODER_MODER9_0 | GPIO_MODER_MODER6_0 | GPIO_MODER_MODER7_0 );


/*
(GPIOC->MODER & ~(GPIO_MODER_MODER8 | GPIO_MODER_MODER9)) => This instruction will clear the GPIOC->MODER value to 0x00000000h

GPIO_MODER_MODER8 => 00 => Input mode (reset state)
01 => General purpose output mode
10 => Alternate function mode
11 => Alternate function mode

In above application we have interfaced the LED on the port so pin we have configure in the OUTPUT mode i.e 01 => General purpose output mode

#define GPIO_MODER_MODER8 ((uint32_t)0x00030000U)
#define GPIO_MODER_MODER8_0 ((uint32_t)0x00010000U)
#define GPIO_MODER_MODER8_1 ((uint32_t)0x00020000U)

#define GPIO_MODER_MODER9 ((uint32_t)0x000C0000U)
#define GPIO_MODER_MODER9_0 ((uint32_t)0x00040000U)
#define GPIO_MODER_MODER9_1 ((uint32_t)0x00080000U) */


}

 

////////////////////////////////////////////////////////////// Configure_GPIO_CAN //////////////////////////////////////////////////////////////
/**
* @brief This function :
- Enables GPIO clock
- Configures the CAN pins on GPIO PA11 PA12
* @param None
* @retval None
*/
__INLINE void Configure_GPIO_CAN(void)
{
/* Enable the peripheral clock of GPIOA */
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;

/* GPIO configuration for CAN signals */
/* (1) Select AF mode (10) on PA11 and PA12 */
/* (2) AF4 for CAN signals */

GPIOA->MODER = (GPIOA->MODER & ~(GPIO_MODER_MODER11 | GPIO_MODER_MODER12))\
| (GPIO_MODER_MODER11_1 | GPIO_MODER_MODER12_1); /* (1) */


GPIOA->AFR[1] = (GPIOA->AFR[1] &~ (GPIO_AFRH_AFRH3 | GPIO_AFRH_AFRH4))\
| (4 << (3 * 4)) | (4 << (4 * 4)); /* (2) */


/* AFR[0] -> Access the lower 32 bit register
AFR[1] -> Access the Higher 32 bit register */

}


////////////////////////////////////////////////////////////// Configure_CAN //////////////////////////////////////////////////////////////

/**
* @brief This function configures CAN.
* @param None
* @retval None
*/
__INLINE void Configure_CAN(void)
{
/* Enable the peripheral clock CAN */
RCC->APB1ENR |= RCC_APB1ENR_CANEN; //((uint32_t)0x02000000U) /*!< CAN clock enable */

/* Configure CAN */
/* (1) Enter CAN init mode to write the configuration */
/* (2) Wait the init mode entering */
/* (3) Exit sleep mode */
/* (4) Loopback mode, set timing to 1Mb/s: BS1 = 4, BS2 = 3, prescaler = 6 */
/* (5) Leave init mode */
/* (6) Wait the init mode leaving */
/* (7) Enter filter init mode, (16-bit + mask, filter 0 for FIFO 0) */
/* (8) Acivate filter 0 */
/* (9) Identifier list mode */
/* (11) Set the Id list */
/* (12) Set the Id + mask (all bits of standard id will care) */
/* (13) Leave filter init */
/* (14) Set FIFO0 message pending IT enable */

 

CAN->MCR |= CAN_MCR_INRQ; // CAN init
while((CAN->MSR & CAN_MSR_INAK)!=CAN_MSR_INAK) // Wait to set the init mode
{
/* add time out here for a robust application */
}

CAN->MCR &=~ CAN_MCR_SLEEP; // Exit sleep mode

// CAN bit timing register
// Baud rate and bit timing changed during the init mode only
// Mode : 1) Normal mode
// 2) Loop back mode
// 3) Sailent mode

// CAN->BTR |= CAN_BTR_LBKM | 2 << 20 | 3 << 16 | 5 << 0; // Commented on 4 April 2018

CAN->BTR |= 2 << 20 | 3 << 16 | 11 << 0; // baud rate is chnaged to 500kbps
CAN->BTR &= ~(CAN_BTR_LBKM|CAN_BTR_SILM); // setting the CAN in Normal operating mode

CAN->MCR &=~ CAN_MCR_INRQ; /* (5) */
while((CAN->MSR & CAN_MSR_INAK)==CAN_MSR_INAK) /* (6) */
{
/* add time out here for a robust application */
}

CAN->FMR = CAN_FMR_FINIT; /* (7) */
CAN->FA1R = CAN_FA1R_FACT0; /* (8) */
#if (FILTER_LIST)
CAN->FM1R = CAN_FM1R_FBM0; /* (9) */
CAN->sFilterRegister[0].FR1 = CAN_ID2 << 5 | CAN_ID1 << (16+5); /* (10) */
#else
CAN->sFilterRegister[0].FR1 = CAN_ID1 << 5 | CAN_ID_MASK << 16; /* (11) */
#endif /* FILTER_LIST */

CAN->FMR &=~ CAN_FMR_FINIT; /* (12) */
CAN->IER |= CAN_IER_FMPIE0; /* (13) */

/* Configure IT */
/* (14) Set priority for CAN_IRQn */
/* (15) Enable CAN_IRQn */
NVIC_SetPriority(CEC_CAN_IRQn, 0); /* (16) */
NVIC_EnableIRQ(CEC_CAN_IRQn); /* (17) */
}

 

 

 

////////////////////////////////////////////////////////////// Configure_GPIO_Button //////////////////////////////////////////////////////////////

/**
* @brief This function :
- Enables GPIO clock
- Configures the Push Button GPIO PA0
* @param None
* @retval None
*/
__INLINE void Configure_GPIO_Button(void)
{
/* Enable the peripheral clock of GPIOA */
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;

/* Select mode */
/* Select input mode (00) on PA0 */
GPIOA->MODER = (GPIOA->MODER & ~(GPIO_MODER_MODER0));
}

 

 


////////////////////////////////////////////////////////////// Configure_EXTI //////////////////////////////////////////////////////////////

 

/**
* @brief This function configures EXTI.
* @param None
* @retval None
*/
__INLINE void Configure_EXTI(void)
{
/* Configure Syscfg, exti and nvic for pushbutton PA0 */
/* (1) PA0 as source input */
/* (2) unmask port 0 */
/* (3) Rising edge */
/* (4) Set priority */
/* (5) Enable EXTI0_1_IRQn */
SYSCFG->EXTICR[0] = (SYSCFG->EXTICR[0] & ~SYSCFG_EXTICR1_EXTI0) | SYSCFG_EXTICR1_EXTI0_PA; /* (1) */
EXTI->IMR |= EXTI_IMR_MR0; /* (2) */
EXTI->RTSR |= EXTI_RTSR_TR0; /* (3) */
NVIC_SetPriority(EXTI0_1_IRQn, 0); /* (4) */
NVIC_EnableIRQ(EXTI0_1_IRQn); /* (5) */
}

 

////////////////////////////////////////////////////////////// NMI_Handler //////////////////////////////////////////////////////////////

/******************************************************************************/
/* Cortex-M0 Processor Exceptions Handlers */
/******************************************************************************/

/**
* @brief This function handles NMI exception.
* @param None
* @retval None
*/
void NMI_Handler(void)
{
}

 

 

////////////////////////////////////////////////////////////// HardFault_Handler //////////////////////////////////////////////////////////////


/**
* @brief This function handles Hard Fault exception.
* @param None
* @retval None
*/
void HardFault_Handler(void)
{
/* Go to infinite loop when Hard Fault exception occurs */
while (1)
{
}
}


////////////////////////////////////////////////////////////// SVC_Handler //////////////////////////////////////////////////////////////

/**
* @brief This function handles SVCall exception.
* @param None
* @retval None
*/
void SVC_Handler(void)
{
}

 

////////////////////////////////////////////////////////////// PendSV_Handler //////////////////////////////////////////////////////////////

/**
* @brief This function handles PendSVC exception.
* @param None
* @retval None
*/
void PendSV_Handler(void)
{
}

 

////////////////////////////////////////////////////////////// SysTick_Handler //////////////////////////////////////////////////////////////

/**
* @brief This function handles SysTick Handler.
* @param None
* @retval None
*/
void SysTick_Handler(void)
{
}


/**
* @brief This function handles EXTI 0 1 interrupt request.
* @param None
* @retval None
*/

 


////////////////////////////////////////////////////////////// EXTI0_1_IRQHandler //////////////////////////////////////////////////////////////
void EXTI0_1_IRQHandler(void)

{

EXTI->PR |= 1;

if((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0)/* check mailbox 0 is empty */
{
CAN->sTxMailBox[0].TDTR = 1; /* fill data length = 1 */
CAN->sTxMailBox[0].TDLR = CMD_TOGGLE; /* fill 8-bit data */
CAN->sTxMailBox[0].TIR = (uint32_t)(CAN_ID1 << 21 | CAN_TI0R_TXRQ); /* fill Id field and request a transmission */

// GPIOC->ODR ^= GPIO_ODR_6; /* Toggle orange LED */
// GPIOC->ODR ^= GPIO_ODR_7; /* Toggle orange LED */

}
else
{
CAN->TSR |= CAN_TSR_ABRQ0; /* abort transmission if not empty */
}
}

 

////////////////////////////////////////////////////////////// Configure_CAN //////////////////////////////////////////////////////////////
/**
* @brief This function handles CAN interrupt request.
* @param None
* @retval None
*/
void CEC_CAN_IRQHandler(void)
{
uint32_t CAN_ReceiveMessage = 0;

if((CAN->RF0R & CAN_RF0R_FMP0)!=0)/* check if a message is filtered and received by FIFO 0 */
{
CAN_ReceiveMessage = CAN->sFIFOMailBox[0].RDLR; /* read data */
CAN->RF0R |= CAN_RF0R_RFOM0; /* release FIFO */
if((CAN_ReceiveMessage & 0xFF) == CMD_TOGGLE)
{
GPIOC->ODR ^= GPIO_ODR_8; /* Toggle orange LED */
GPIOC->ODR ^= GPIO_ODR_9; /* Toggle orange LED */
GPIOC->ODR ^= GPIO_ODR_6; /* Toggle orange LED */
GPIOC->ODR ^= GPIO_ODR_7; /* Toggle orange LED */
}
}
}

Outcomes