cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 CAN data problem

hermanv
Associate II
Posted on July 09, 2013 at 08:49

Hi all,

I am using the CAN interface on the STM3240G-EVAL for a CanOpen implementation. All works fine up until the point where I need to transfer data via CanOpen PDOs which are more than 6 bytes in length. The last 2 bytes are always corrupt. I performed debugging up to the point where the data values are loaded into theTDLR andTDHR registers and all is fine. The receiving node however receives all the data correctly except for the lat 2 bytes that are random values and not what I sent. These values also change with every transmission and there is also no pattern, the values are random. I also used a PEAK CAN device to listen on the bus to ensure that the problem is not on my receiving node software. The PEAK CAN device confirms the last 2 bytes being corrupt. I now don't know what can cause this. Here is the configuration I use to set up the CAN bus on all my devices. Can anyone give me an idea as to what might be wrong or what I might be missing in the configuration?


/* PCLK = 42MHz */
/* 10kbps */

can_struct.CAN_Mode = CAN_Mode_Normal;

can_struct.CAN_Prescaler = 199;

can_struct.CAN_BS1 = 13;

can_struct.CAN_BS2 = 5;

can_struct.CAN_SJW = 3;

can_struct.CAN_ABOM = DISABLE;

can_struct.CAN_TTCM = ENABLE;

can_struct.CAN_AWUM = DISABLE;

can_struct.CAN_NART = ENABLE;

can_struct.CAN_RFLM = ENABLE;

can_struct.CAN_TXFP = ENABLE;


/* Attempt to initialize the CAN bus until the bus is ready */

do

{

retstat = CAN_Init(CAN1, &can_struct);

}

while
(retstat != CAN_InitStatus_Success);


if
(retstat == CAN_InitStatus_Failed)

{

return
(CO_E_INIT_HARD_RES_ACTIVE);

} 
/* end ''if (retstat == CAN_InitStatus_Failed)'' */


/* initialize filter structure for use in filter banks */

can_filt.CAN_FilterActivation = ENABLE;

can_filt.CAN_FilterIdHigh = 0xFFFE;

can_filt.CAN_FilterIdLow = 1;

can_filt.CAN_FilterMaskIdHigh = 0xFFFE;

can_filt.CAN_FilterMaskIdLow = 1;

can_filt.CAN_FilterMode = CAN_FilterMode_IdMask;

can_filt.CAN_FilterNumber = 1;

can_filt.CAN_FilterScale = CAN_FilterScale_16bit;


can_filt.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;


/* assign half of filter banks to FIFO 0 */

for
(loop = 0; loop < (14 / 2); loop++)

{

can_filt.CAN_FilterNumber = loop;


CAN_FilterInit(&can_filt);

} 
/* end ''for (loop = 0; loop < (14 / 2); loop++)'' */


can_filt.CAN_FilterFIFOAssignment = CAN_Filter_FIFO1;


/* assign half of filter banks to FIFO 1 */

for
(loop = (14 / 2); loop < 14; loop++)

{

can_filt.CAN_FilterNumber = loop;


CAN_FilterInit(&can_filt);

} 
/* end ''for (loop = (14 / 2); loop < 14; loop++)'' */

Thanks, H #canopen #can #can #can-canopen #canopen #c #can-stm32f2-stm32f4 #can-stm32f2-stm32f4
9 REPLIES 9
Posted on July 09, 2013 at 13:21

I don't see any transmission code.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
hermanv
Associate II
Posted on July 09, 2013 at 14:00

Hi Clive,

Here is the code. You will see that I print the values just before they are transmitted and at that stage all the data is correct. The other devices on the CAN bus read the last 2 bytes as garbage. The return code of the CAN_Transmit function never reports an instance where no mailbox is available. As you can see, I am using the STM32F4 standard peripheral libraries.

CanTxMsg tx_mes;
tx_mes.StdId = cobId;
tx_mes.IDE = CAN_Id_Standard;
tx_mes.DLC = tmpLength;
tx_mes.ExtId = 0;
/* send TX message or a RTR response */
if
((BUFFER_READ(TX, eType) & CO_COB_DIR_MASK) == CO_COB_TX)
{
tx_mes.RTR = CAN_RTR_Data;
/* copy data to CAN buffer to TX */
for
(loop = 0; loop < tmpLength; loop++)
{
tx_mes.Data[loop] = BUFFER_READ(TX, pData[loop]);
} 
/* end ''for (loop = 0; loop < tmpLength; loop++)'' */
}
/* send RTR request */
else
if
((BUFFER_READ(TX, eType) & CO_COB_DIR_RTR_MASK) == CO_COB_RX_RTR)
{
tx_mes.RTR = CAN_RTR_Remote;
}
printThis(
''T

X''
);
printThis(
''ExtId %08

X''
, tx_mes.ExtId);
printThis(
''IDE %08

X''
, tx_mes.IDE);
printThis(
''RTR %08

X''
, tx_mes.RTR);
printThis(
''StdID %08

X''
, tx_mes.StdId);
for
(loop = 0; loop < tx_mes.DLC; loop++)
{
printThis(
'' %02X''
, tx_mes.Data[loop]);
}
printLn();
retstat = CAN_Transmit(CAN1, &tx_mes);
if
(retstat == CAN_TxStatus_NoMailBox)
{
retstat = FUNC_FAILURE;
} 
/* end ''if (retstat == CAN_TxStatus_NoMailBox)'' */

hermanv
Associate II
Posted on July 09, 2013 at 16:39

Nevermind,

Faulty hardware!! Nothing wrong with the software.

Thanks

valeriogiampa
Associate II
Posted on October 05, 2013 at 00:20

Which is the Canopen Library that you have used?

It is open source/free?

hermanv
Associate II
Posted on October 18, 2013 at 14:45

Unfortunately the CANOpen software is not free. We bought the library from port. (www.port.de)

hermanv
Associate II
Posted on October 18, 2013 at 14:49

Okay, so this problem occurred again on a newly manufactured board.

I managed to solve the problem in software by setting the CAN_TTCM = DISABLE;

But this means that I won't be able to use the timestamping functionality in future.

Does anyone know why the data might be corrupted when CAN_TTCM = DISABLE;?

Are there other registers that need to be set in accordance with the CAN_TTCM register to allow it to work properly?

Any advise please.

Thanks,
jpeacock2399
Associate II
Posted on October 18, 2013 at 15:50

Enabling TTCM causes the CAN controller to insert the timestamp in the last 2 bytes of data.  This is incompatible with the CANopen protocol, which often uses all 8 data bytes for, uhh, data.  If you want to use time triggered communications and the timestamp you will need to find a CAN protocol that supports it.

  Jack Peacock
jj2
Associate II
Posted on October 18, 2013 at 16:17

Kudos to Jack for that, ''timestamp'' where/when. 

Might your creation of a 2nd, 8 byte CAN transmission (to immediately follow the first 8 bytes) enable the passage of 6 additional data bytes (i.e. often more is better) and the (offending) timestamp data.

Earlier, ''faulty hardware'' (w/out any detail) continues to concern!  Difficult to imagine how 6 bytes pass successfully - and hardware alone corrupts the last two...  Would you be so good as to briefly describe?
hermanv
Associate II
Posted on October 21, 2013 at 08:10

Thanks Jack, that was exactly the problem. 

As you said, CANOpen does not support it by default. At this stage we don't need it, but at least I now know what is going on.

The reason why I suspected a hardware problem earlier was caused by not explicitly resetting the CPU after errors occur as the board was connected to the debugger. Thus the register did not always go into their reset states, causing the registers to be in the correct values sometimes and incorrect values at other times. No hardware error, just human error 🙂

Thanks guys,

Herman