cancel
Showing results for 
Search instead for 
Did you mean: 

CAN message transmission problem

sunilkasar7
Associate II
Posted on September 18, 2015 at 08:43

Hello all,

I wrote code for CAN message transmission using STM32F429ZI board. Message is not getting transferred. It is displaying only error frames in CANanalyzer. Please suggest me solution for this problem. I have attached the code for your convenience. Even I have attached a snapshot of CAN analyzer result.

Thanking you.

&sharpinclude ''stm32f4xx.h''

uint32_t SysClk;

uint32_t HClk;

uint32_t PClk1;

uint32_t PClk2;

int main(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

RCC_ClocksTypeDef RCC_Clocks;

CAN_InitTypeDef CAN_InitStructure;

CAN_FilterInitTypeDef CAN_FilterInitStructure;

CanTxMsg TxMessage;

RCC_GetClocksFreq(&RCC_Clocks);

SysClk = RCC_Clocks.SYSCLK_Frequency;

HClk = RCC_Clocks.HCLK_Frequency;

PClk1 = RCC_Clocks.PCLK1_Frequency;

PClk2 = RCC_Clocks.PCLK2_Frequency;

/* CAN GPIOs configuration **************************************************/

/* Enable GPIO clock */

//RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

/* Connect CAN pins */

// GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);

// GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);

GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_CAN1);

GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_CAN1);

/* Configure CAN RX and TX pins */

/*

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

GPIO_Init(GPIOD, &GPIO_InitStructure);

*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//GPIO_PuPd_UP;

GPIO_Init(GPIOB, &GPIO_InitStructure);

/* CAN configuration ************************************************** ******/

/* Enable CAN clock */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

/* CAN register init */

CAN_DeInit(CAN1);

CAN_StructInit(&CAN_InitStructure);

/* CAN cell init */

CAN_InitStructure.CAN_TTCM = DISABLE;

CAN_InitStructure.CAN_ABOM = DISABLE;

CAN_InitStructure.CAN_AWUM = DISABLE;

CAN_InitStructure.CAN_NART = DISABLE;

CAN_InitStructure.CAN_RFLM = DISABLE;

CAN_InitStructure.CAN_TXFP = DISABLE;

CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;

/* quanta 1+6+7 = 14, 14 * 3 = 42, 42000000 / 42 = 1000000 */

/* CAN Baudrate = 1Mbps (CAN clocked at 42 MHz) Prescale = 3 */

/* Requires a clock with integer division into APB clock */

CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; // 1+6+7 = 14, 1+14+6 = 21, 1+15+5 = 21

CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;

CAN_InitStructure.CAN_BS2 = CAN_BS2_7tq;

CAN_InitStructure.CAN_Prescaler = RCC_Clocks.PCLK1_Frequency / (14 * 1000000); // quanta by baudrate

CAN_Init(CAN1, &CAN_InitStructure);

/* CAN filter init */

CAN_FilterInitStructure.CAN_FilterNumber = 0; // CAN1 [ 0..13]

CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; // IdMask or IdList

CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; // 16 or 32

CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000; // Everything, otherwise 11-bit in top bits

CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;

CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;

CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;

CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0; // Rx

CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;

CAN_FilterInit(&CAN_FilterInitStructure);

// transmit */

TxMessage.StdId = 0x123;

TxMessage.ExtId = 0x00;

TxMessage.RTR = CAN_RTR_DATA;

TxMessage.IDE = CAN_ID_STD;

TxMessage.DLC = 8;

TxMessage.Data[0] = 0x02;

TxMessage.Data[1] = 0x11;

TxMessage.Data[2] = 0x11;

TxMessage.Data[3] = 0x11;

while(1) // Do not want to exit

{

volatile uint32_t i;

static int j = 0;

uint8_t TransmitMailbox = 0;

TxMessage.Data[4] = (j >> 0) & 0xFF; // Cycling

TxMessage.Data[5] = (j >> 8) & 0xFF;

TxMessage.Data[6] = (j >> 16) & 0xFF;

TxMessage.Data[7] = (j >> 24) & 0xFF;

j++;

TransmitMailbox = CAN_Transmit(CAN1, &TxMessage);

i = 0;

while((CAN_TransmitStatus(CAN1, TransmitMailbox) != CANTXOK) && (i != 0xFFFFFF)) // Wait on Transmit

{

i++;

}

}

}

&sharpifdef 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\r\n'', file, line) */

/* Infinite loop */

while (1)

{

}

}

&sharpendif

#can_esr
3 REPLIES 3
jpeacock
Associate III
Posted on September 18, 2015 at 14:04

Since it appears to be a bus issue you have to look at both nodes.  What are you using as the second node (CAN requires a minimum of 2 nodes to work), and does the other node show bus errors?   Look at the CAN_ESR register on the 'F429, what does it tell you?  Are you getting bus errors before you even try to transmit?

  Jack Peacock

sunilkasar7
Associate II
Posted on September 23, 2015 at 07:11

Dear peacock.jack.003,

Here I am attaching CAN_ESR status image. I am stuck in this since 5 days. Still I am unable to solve the issue.

________________

Attachments :

ESR.PNG : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I1Ks&d=%2Fa%2F0X0000000blT%2FK4Xkio3VlErefx8PmFzI4IL6aty98P9OUvEA.5tmVMw&asPdf=false
jpeacock
Associate III
Posted on September 23, 2015 at 14:22

The ESR shows a high number of TX errors (TEC = 251) due to bit dominant errors (LEC = 5).  Typically this is the signature of a bus with only one node attached.  Do you have two nodes on the bus and is the cable terminated at both ends?  Do both nodes restart at the same time?

Your transmit fails because the bus has disconnected (BOFF asserted) due to excessive errors.  This is a requirement for CAN bus in order to prevent a failed node from flooding the bus with bad messages.

Check your other node to see if it has the same errors.  One of the complications of CAN when bringing up the first two nodes is avoiding a race condition where the first node sees no other node and disconnects, then the second node does the same when it starts because the first node is disconnected.  You need several retries on both nodes to ensure you hit a window where both nodes are connected in order to establish a working network.

After the first two are running additional nodes aren't a problem because a working bus has been established.  Additional nodes will always see a bit dominant before transmitting.

The way I handle this is to set up a retry timer after a BOFF bus disconnect event.  The node logically disconnects, waits for the timer, then connects and attempts to transmit again.  The retry delay is shorter than the time to reach the TEC cutoff point where the bus disconnects.  This ensures an overlapping window with two nodes using the same retry algorithm.  Sorry, no code, I don't own it.

If your second node is something other than another STM32 then you will have to figure out how that device handles bus retries (not a simple task) and implement the same strategy on the 'F429.

  Jack Peacock