Microchip MCP2517FD CAN-FD Tranceiver cannot write to chip registers? - Page 1
Forum section: electronics / general

author: Kawakneurder
author_rank: Contributor
timestamp: November 06, 2024, 01:03:01 am
content: 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)Code:ADDR;VAL0;0X600X1;0X70X2;0X98! 0X3;0X000X3;0X40X4;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)Code:// Read opmodeuint8_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 againuint8_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:Code:Read opmode before check mem:0XFF (0X3)ADDR;VAL0;0X600X1;0X70X2;0X98! 0X3;0X40X3;0X40X4;0XF0X5;0XF0X6;0X3E...0XE00;0X600XE01;0X40XE04;0X30XE06;0X10XE07;0X3Read 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.

author: IDEngineer
author_rank: Super Contributor
timestamp: November 06, 2024, 05:44:06 am
content: First suggestion: Stop using other people's SPI libraries and control the SPI hardware yourself. You're already questioning if the library "needs time" for... something. Do it yourself and eliminate an entire layer of unknowns.

author: Kawakneurder
author_rank: Contributor
timestamp: November 06, 2024, 12:20:11 pm
content: Quote from: IDEngineer on November 06, 2024, 05:44:06 amPersonally I don't think it is the SPI bus and/or K64F, but more related with the chip.I have also interfaced with some other SPI/SSI sensors and never had issues....Anyway, I have done some further digging this morning. After dusting off the logic analyzer, I managed to capture some traces to compare what the uC thinks its sending/receiving, and what's actually being seen on the bus. All communication is done at 100Ksps:Apologies that I didn't convert the decimal of the terminal into hex. I compared them manually, the result of which is in the right most columns.In conclusion, it seems to match. Also note here that address 0x03 produces the correct content 0x04.However, there is an excessive amount of print statements to retrieve the TX/RX bytes from the uC. So subsequently I removed these and only printed the results of registers (the addr/val combinations). Here a view of these:Note here that address 0x03 produces the WRONG content, and returns 0x00. But that it does so on the bus as well.There's some missing registry values, I think this is due to printf overflows or something else. Im not too worried about this.At least this seems to confirm that most likely the read/write values do work.And this makes me think, is this the MCP chip being weird with SPI read/writes? Or is it possibly a hardware issue? The latter would surprise me, as the hardware is extremely simple (just SPI connected straight through, a crystal which is confirmed working and some decoupling for the chip).I think I might try to solder a new chip on a board, perhaps it got damaged somehow.

author: IDEngineer
author_rank: Super Contributor
timestamp: November 06, 2024, 02:38:50 pm
content: Quote from: Kawakneurder on November 06, 2024, 12:20:11 pmSPI is mind-numbingly simple, which is a key strength over I2C. The only question is generally "which mode?" so the edges match between Master and Slave. You can bit-bang it in firmware to prove things work, if necessary.If you're able to read/write some of the registers, it's very likely the hardware is OK. Seems unlikely that "some" internal registers would be damaged and not others. I have interfaced via SPI to other Microchip standalone CAN chips and they work just fine. No surprises. I doubt it's the chip.Ideas:1) Re-study the chip spec sheet. See if there are any timing requirements you've missed. There weren't any in the other CAN parts I've used but who knows. I'm thinking here of EEPROM which often requires a delay after a write. These chips don't generally have EEPROM but I'm using this as an example.2) Confirm your SPI modes match. Again, if some registers work they all should work, but since nothing obvious has popped up it's time to check everything.3) Look carefully at how the SPI peripheral in your MCU works (again, RTFM). Also, are you handling the chip select signal properly? Are you coordinating it with the SPI exchange? I think of chip select as an SPI reset signal... when it's deselected the SPI hardware completely resets and you get a fresh start when you take CS active again. If the timing between CS and your SPI clock/bits is off lots of weird things can happen.Hope this helps!

author: Kawakneurder
author_rank: Contributor
timestamp: November 08, 2024, 03:40:51 pm
content: I've finally had some time to mess around again with the chip, and again hook the scope to the SPI bus.Looking at the SPI traces on the scope it seemed there was some potentially strange stuff going on during startup.Chip select is done with a GPIO, which was kept in active state on startup until configured.After some deliberation I had decided to put a pullup resistor on the CS line to force it to be deselected when the pin is tri-state.That seems to have fixed it!Register values are now consistent, and I can read/write to registers (confirmed by using the build in I/O of the chip).Can't get any messages out of the CAN bus yet, but that probably has to do with some configuration issues of the FIFO that I will need to have another look at.Thanks @IDEngineer for having a think, and for the suggestions.

author: IDEngineer
author_rank: Super Contributor
timestamp: November 08, 2024, 05:14:01 pm
content: Yep, those GPIO's can trip you up especially during reset before they've been configured. Pullups or pulldowns are often a good idea.Glad you've got it working!

author: AndyC_772
author_rank: Super Contributor
timestamp: November 08, 2024, 07:21:02 pm
content: So, what did happen during start-up, andwhydid it make a difference?For example, is the device configured in some way by the state of its pins at power-up? Is that feature documented?What are your CPOL and CPHA settings? Are they correct for both devices?I'd still be concerned; it really shouldn't be possible for a start-up condition to then prevent reliable I/O from being possible later. Letting the pins float or go to an invalid state might be bad practice, but you should still be able to reset the CAN device as part of your config process. If you can't, then you really should find out why. Unresolved questions like this have a habit of coming back to bite you later.

author: Kawakneurder
author_rank: Contributor
timestamp: November 09, 2024, 01:08:08 am
content: Quote from: IDEngineer on November 08, 2024, 05:14:01 pmQuote from: AndyC_772 on November 08, 2024, 07:21:02 pmApparently that was not only it! The problem was a lot more insidious... The problem came back, and after a lot of head-scratching I think I finally squashed it once and for all.After mucking about/checking SPI connections, initialization/register values and order of initialization, I tried to isolate the problem more. After scanning the reference manual again and looking at the states of the modes of operation, it seemed that it won't change to normal mode, if it does not detect that the bus is in recessive state. (Which by the way is never explicitly mentioned in the datasheet or reference manualit is only visible in fig 2-1 of the ref manual, as 'bus idle' between states). Considering I have just a 120 ohm termination resistor connected, I thought it would be fine. To further isolate the issue, I attempted to put the chip in internal loopback mode (it writes the transmit FIFO directly to its receive FIFO, without any transmissions involved).This behavior of the chip apparently holds not only for normal mode, but also for internal loopback modes (which is somewhat unexpected, as the bus is not involved in this mode at all).Checking the CAN H/L signals I suspected something was up, as they were both at 0V (instead of ~1.9V we expect). Doing some further digging, it seems that I had accidentally ordered the TCAN3403 drivers instead of the TCAN3404 (these chips share the same datasheet)...Now what is the difference between these chips? Pin 5 on the 3404 is a low-power shutdown pin, which should be grounded for normal operation. On the 3403 however, this very same pin is a supply pin that needs 3.3V!Alas, after hooking up that pin to 3.3V with a bodge, the MCP was happy to change modes.I suppose I would have found the issue sooner, if I would have followed the golden rule of trouble shooting: Thou shall check voltages!As to why the chip seems to have worked once after fixing CS... I have not a clue. Perhaps sometimes on power up you can glitch the TCAN chip to output a recessive state on the RXD pin, tricking the MCP? After all, that supply pin is not supposed to be grounded and could result in unexpected behavior.