Anybus Compactcom 40 SPI CRC received does not match CRC calculated

I am using the Anybus Compactcom 40 with a host application running on a Freescale/NXP Kinetis ARM processor. I am using the generic C driver given from HMS. currently, I can’t get past setup because the received CRC does not match the calculated CRC. I have verified the calculated CRC using the supplied test table in doc 216-125. I have also verified that the CRC i receive from my compactcom module in software matches what was sent on the hardware via a logic analyzer on the SPI lines. I’m at a loss to why the CRCs do not match. Is it possible for the module to send the wrong CRC?

I am developing a host application for a CompactCom 40 using the SPI interface. I am currently stuck in the Startup state. I can see that the response I get from the module has an incorrect CRC. I have verified using a logic analyzer on the SPI lines that my application is receiving the message correctly. I have also verified that the host code for calculating the CRC32 is correct according to the example arrays in the document HMSI-216-125 (v 3.9). I don’t know hoe to solve this issue since the incorrect CRC is coming from the module.
The frame I receive back from the module is:
00 00 00 00 00 06 04 39 A1 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 EA 3A E0 B7
Meaning the 32 bit CRC is 0xB7E03AEA

The software calculates the CRC to be 0x481F3AEA

I verified this calculation result with an external CRC calculator and got the same result. I’ve tried running the SPI clock at 5 MHz and 1 MHz. My data is based on the leading edge of the clock.

I find it interesting that the lower word matches in the received and calculated but I don’t know what to make of it. Is it possible for the module to calculate and send the wrong CRC?

Hello,

Did you already verify these examples for calculating with the algorithm?

image

Hi Tim,

Yes I verified those examples from the HMS document HMSI-216-125

After talking with some colleagues, you may be running into a “NAK” condition by the ABCC. Figure 13 of the Software design guide shows:


Can you also check that the host’s (MOSI) packet is valid too.

That would make sense but I feel pretty sure that I have the MOSI frame sent correctly.

The values I’m given are:
SpiControl - 0x85
Reserved - assumed to be 0x00
MsgLen - 0x0008
PdLen - 0x0000
IntMaskAppStatus - 0x0000
Data (including CRC) - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF874, 0x5751

So because the transfer is little endian I fill the buffer with the following bytes (in hex):
85 00 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 74 F8 51 57

Can you confirm this is correct?

After further analysis I think that this is the problem but I’m having a hard time finding the root cause. I see that the first message to be sent initially has information in the header but when the driver gets to sending the message in ABCC_DrvSpiRunDriverTx(), the iData part of the MOSI frame is all 0s except for the CRC. I can’t figure out where the data is getting lost though

I very much need confirmation on what the first frame should look like while transmitted. I see that while the before it’s put in the MOSI frame, the data header is:
iDataSize = 0x0000 (16 bit)
iReserved = 0x0000 (16 bit)
bSourceID = 0x01 (8 bit)
bDestObj = 0x03 (8 bit)
iInstance = 0x0001 (16 bit)
bCmd = 0x41 (8 bit)
bReserved = 0x00 (8 bit)
bCmdExt0 = 0x03 (8 bit)
bCmdExt1 = 0x00 (8 bit)

Once the program gets to ABCC_DrvSpiRunDriverTx(), the following values are set for the header of the MOSI frame:
iSpiCtrl = 0x009D (16 bit)
iMsgLen = 0x0010 (16 bit)
iPdLen = 0x0000 (16 bit)
and the CRC is 0x63C822C2

At this point, the MOSI frame (formatted as words) is the following:
009D 0010 0000 0000 0000 0000 0301 0001 0041 0003 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 22C2 63C8 0000

So because the host implementation guide specifies Little Endian byte order I would assume the frame should be converted to the following before sending (as a byte array):
9D 00 10 00 00 00 00 00 00 00 00 00 01 03 01 00 41 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C2 22 C8 63 00 00

When I send this frame exactly I get the same CRC issue initially described that I believe is due to the transmit frame being incorrect.

I need to know what the correct frame format is based on the driver code and functions mentioned

Hello,

One of my colleagues was recommending that you take a look at the SPI analyzer that he developed.

The code should have everything you’ll need to know though:

typedef struct drv_SpiMosiFrameType

{

UINT16 iSpiControl;

UINT16 iMsgLen;

UINT16 iPdLen;

UINT16 iIntMaskAppStatus;

UINT16 iData[ MAX_PAYLOAD_WORD_LEN ];

UINT16 dummy;

} drv_SpiMosiFrameType;

That is the definition of the MOSI packet.

Similar to the miso validation below (which exists in abcc_spi_drv.c), he can validate against the mosi packet

lCalculatedCrc =CRC_Crc32( (UINT16*)&spi_drv_sMisoFrame, spi_drv_iSpiFrameSize*2-4 );

There is one thing that seems a little interesting, the control byte is advertising that process data is valid. I am not sure if there is any problem with doing that, but since the process data field is zero it seems incorrect to advertise this.

Using the values mentioned (copied below) I computed a CRC of:
0x44896C3D

iSpiControl = 0x009D
iMsgLen = 0x0010
iPdLen = 0x0000
iIntMaskAppStatus = 0x0000

iDataSize = 0x0000
iReserved = 0x0000
bSourceID = 0x01
bDestObj = 0x03
iInstance = 0x0001
bCmd = 0x41
bReserved = 0x00
bCmdExt0 = 0x03
bCmdExt1 = 0x00

All other data fields are 0

-Jon

I would like to use this SPI analyzer but I do not have toe Saleae logic analyzer. Do you have any more documentation with finer detail on the startup procedure of the CC M40?

And as for the drv_SpiMosiFrameType struct, those are all 16 bit values that are transmitted as bytes in Little Endian order. With my example listed above, what would be the correct send order? Or should I not manipulate the byte order once the data is in the struct and just send it as is?

Hi Kevin,

Even if you don’t own the analyzer, the plugin should support a basic simulation of CompactCom communication with the host filesystem interface object. Can you take a look at the capture below using the Saleae Logic Analyzer? It will give you an example of sending packets in general, you should be able to see the different startup messages that are exchanged with the host and the compactcom

image

EtherCAT_Startup_16W_MsgField.logicdata (801.1 KB)

Hi Kevin,

If you have some questions on the example capture we sent please feel free to give us a call at 312-893-5636

Thanks,
-Tim

I’m more concerned with the info that I posted in my support case. Here is the info that seems to have been ignored a couple of times:

The first message to be sent comes in with the command bit set but will fail this condition if( !ABCC_IsCmdMsg( psWriteMsg ) ) in the function ABCC_LinkWriteMessage() resulting in it going into the else and then failing the condition if( !link_fDrvWriteMsgLock &&
( ( link_sCmdQueue.bNumInQueue + link_sRespQueue.bNumInQueue ) == 0 ) &&
pnABCC_DrvISReadyForCmd() ) failing because pnABCC_DrvISReadyForCmd() will return 0. I don’t see how it is supposed to get past this

Hi Kevin,

I’m going to escalate this with some colleagues in Sweden and get back to you in the morning

I have an update: I diffed my modified files with those just downloaded from HMS for the driver and found there was a “1” that had been typoed into the CRC calculation for the MOSI frame. I fixed this and now on the response I do get a valid CRC. However, the other issue still persists and then the frame after this gets stuck re-transmitting

Hi Kevin,

My colleage was asking for the following information

  • Can you give us the modified source code, especially the file /abcc_adapt/abcc_sys_adapt.c where he has ported the ABCC_SYS_SpiRegDataReceived() function and the ABCC_SYS_SpiSendReceive() function).
  • Are there activities on both MISO and MOSI when the first message is sent to the CompactCom?
  • Is he using a 3-wires or 4-wires for the SPI interface?
  • Is the Slave Select signal low during the whole SPI transmission?

He also gave me the following info

The first SPI frames from the host application does probably not include any CompactCom messages, just empty frames.

If he wants to try something without the driver running, he can try sending the following from his SPI functions:

MOSI: 85 00 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 6A 77 3E 1C 00 00

The MISO should then look something like this (not necessarily exactly like this but at least not completely different):

MISO: 00 00 00 00 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 D8 6B A3 33

Talking about the contents/details in the CompactCom message part of the frame can be saved for later when he has the above SPI running.

Thanks,

-Tim

To be more specific about retransmitting, after the first (and only) successful send and receive, the compactcom module starts responding with the same word repeated for the entire length of the message for every retransmission from the host. For example if the first message had a CRC response of 0xC4735F53 then on the next message the entire response is 0xC473 repeated for the whole length

files? I attached all that were modified

Is there activity on both MISO & MOSI during 1st? Yes

3-wire or 4-wire? 3-wire, no slave select

slave select low during entire transmission? not connected to host, pulled to ground at CC module

That is very good to know about the first frame because that’s what I’m seeing being sent. On the response I see the 06 in the SPI status byte. The main difference is the “Net Time” bytes, these are non zero.

I posted this to my forum thread earlier but now that the CRCs match and the second message goes out, the module responds with the upper 2 bytes of the previous CRC for the entirety of the response. So if the first response from the module had the CRC 0xC4735F53 then the second response from the module is made of 0xC473 repeating and every retransmission gets response this as well
abcc_sw_port.h (8.6 KB)
abcc_sys_adapt.c (7.4 KB)
abcc_drv_cfg.h (11.7 KB)
abcc_obj_cfg.h (46.3 KB)

Hi Kevin,

I remember that you said you don’t have the logic analyzer that we were talking about earlier but we were wondering if you have a scope to do some measurements. We’d like to check and make sure that the SPI transfer is respecting the timing requirement for the 3-wire option

according to the Hardware design guide There must be an idle period of at least 10 µs between two transfers in this mode, and the SCLKsignal must never remain high for more than 5 µs during a transfer.

image

We’re wondering if the transmissions between each SPI transfer (usually this is an 8-bit or 16-bit interface) are done such that the clock is not left idling high for 5us or more while transmitting a SPI packet