Hi all!
In an effort to play around with CAN-FD I decided to play around with the MCP2517FD chip.
However after wrestling around a couple of days I have come to a bit of an impasse.
In short, it seems that I cannot write values to the registers of the chip.
For ease of discussion, please find the registry/memory map of the chip on page 7 (fig 3-1) here:
https://ww1.microchip.com/downloads/en/DeviceDoc/MCP2517FD-External-CAN-FD-Controller-with-SPI-Interface-20005688B.pdfTo use the CAN-FD chip, one needs to first reset it (which puts it in configuration mode), write appropriate values to a couple of registers (the details of which are not of importance in this case), and then put the chip in 'normal' operation mode.
If I however, read out the registry contents, do the registry manipulation and read back the registry contents afterwards, they have not changed. (evaluated address space is 0x000 to 0x2EC and 0xE00 to 0xE10, strangely registry space in this chip is split in half)
I can then put the chip in 'normal' mode, but the chip will never set the flag to indicate it is ready to receive data in its queue.
The particular microcontroller I use to talk to the chip is the NXP K64F, using mbed (yeah, I know, sometimes we have to use the cards we are dealt
)
What have I checked:
- Chip has a clock:
- signal on the crystal
- Clock output pin shows a nice square wave, with the correct frequency
- SPI seems to function as expected as well:
- Reading out the registers seems to yield valid 'default' initialization values of said registers, indicating reading works (which for SPI involves both sending out data as well as receiving)
- Also, changing SPI baudrates don't alter results (tried 100Kbps, 1Mbps and 10Mbps, no change)
- Mode changes are possible??
- Writing 'normal' opmode (0x00) to the appropriate register (cREGADDR_CiCON+3, addr 0x03) and then reading back the register, does seem to work, most of the time*.
- I have tried to get GPIO working, but could not get an output on the pins. This is not surprising if writing to registers seems borked.
Microchip has some sample code available. This contains a RAM and a registery test. Running these gives the following results:
- RAM (FIFO) manipulation seems to work
- RAM test (writing to data to and reading this data back from addr 0x400 to 0x46F) completes successfully
- Note that this address space is not the full space of memory, but is consistently good
- The registry test (writing data to and reading back from addr 0x1F0 to 0x22F) completes only partially (The first 8 bytes from addr 0x1f0 to 0x1f7 mismatch, the rest matches)
- The particular addresses evaluated are filter objects, of which the 31st bit is manipulated randomly (as this is unused by the chip)
- Note however, that these registry values do not overlap with the above configuration registries
* I noticed some weird behavior in my code as well. If I loop through the address space above (0x000 to 0x2EC) it would read the 'opmode' register as 0x00 (which would be incorrect, it should be 0x04):
(This is output printed to the terminal, where ADDR represents the memory address and VAL the associated contents)
ADDR;VAL
0;0X60
0X1;0X7
0X2;0X98
! 0X3;0X00
0X3;0X4
0X4;0XF
...
If I however add a specific read for the register BEFORE I loop through the address space, and check it again after, something funny happens:
(This is the particular change to the code)
// Read opmode
uint8_t sp = DRV_CANFDSPI_ReadByte(index, cREGADDR_CiCON + 3, &d);
printf("Read opmode before check mem:%#X (%#X)\n",d,(cREGADDR_CiCON + 3));
// .... Loop through address space
// Read opmode again
uint8_t sp = DRV_CANFDSPI_ReadByte(index, cREGADDR_CiCON + 3, &d);
printf("Read opmode after check mem:%#X (%#X)\n",d,(cREGADDR_CiCON + 3));
Will print:
Read opmode before check mem:0XFF (0X3)
ADDR;VAL
0;0X60
0X1;0X7
0X2;0X98
! 0X3;0X4
0X3;0X4
0X4;0XF
0X5;0XF
0X6;0X3E
...
0XE00;0X60
0XE01;0X4
0XE04;0X3
0XE06;0X1
0XE07;0X3
Read opmode after check mem:0X4 (0X3)
Note that it first shows an incorrect value of the memory address (0x30), but then during loop it DOES show the correct value (0x04).
For this to work it also NEEDS to have the print statement between. This makes me suspect it might have something to do with the internal mbed SPI libraries requiring some time to copy things over or doing weird stuff.
However, recompiling or changing some things around makes the result incorrect for both again. These non-deterministic issues...
It is quite late now, tomorrow I am hooking up the scope to the SPI bus to confirm whether the values I transmit and read back correspond with reality, or that perhaps it is something on a hardware level on the bus.
In the meantime, does this have something to do with the way Mbed SPI works? Or something with the stack?
Has anyone had similar issues before, or does anyone have any suggestions on what to check next?
It's a bit of a shot in the dark, but any help and pointers would be much appreciated.