This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F2800157: SPI Confusion

Part Number: TMS320F2800157
Other Parts Discussed in Thread: SYSCONFIG, C2000WARE

Hi, 

I am trying to understand the SPI Configuration settings. After reading the Technical Reference Manual for SPI, I still have no idea what I'm doing. 

Im using a LaunchpadXL-TMS320F2800157 directly connected to my Salae LA. 

  1. Specifically, the interrupts for SPI and how exactly the transmit interrupt is triggered in this example "spi_ex2_lookback_fifo_interrupts" since there is nothing in the program to fill the transmit FIFO thus how is it possible for the ISR to trigger?
  2. Additionally, has anyone fixed the SPI driver for "SPI_pollingNonFIFOTransaction". I still have erratic clock behavior that others see here when using that: https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1248486/tms320f280025c-issues-with-manual-control-of-cs-pin-in-spi-when-using-driverlib-functions/4726334?tisearch=e2e-sitesearch&keymatch=SPI_pollingNonFIFOTransaction#4726334
  3. It would be super helpful if someone could share an interrupt-based SPI project that works with sending multiple bytes and using GPIO as Chip Select Pin.

Best - Gray

Code snippet from default project: (How does the Transmit ISR trigger to send data when there is nothing to fill the FIFO and trigger an interrupt) 

Thank you so much for your help in advance. Sorry Im a novice to programming, SPI, and Embedded software.

  • Hi Gray! Please see my responses in blue below:

    1. Specifically, the interrupts for SPI and how exactly the transmit interrupt is triggered in this example "spi_ex2_lookback_fifo_interrupts" since there is nothing in the program to fill the transmit FIFO thus how is it possible for the ISR to trigger?

    The advantage of using both FIFO mode and interrupts is that the interrupts are triggered based on the level of "fullness" of the transmit and receive FIFOs. This is all triggered by the hardware rather than the software - hence why you may be confused as to how the transmit interrupt (SPI TX ISR) is actually being called (because there is no software action needed to initiate calling of the interrupt).

    When you configure the SPI module, you can define the SPI TXFIFO and RXFIFO levels. The "level" refers to how much data is present in the FIFO (and also indicates how much space is available in that FIFO). When you select a FIFO level, this means the respective transmit/receive interrupt will automatically be triggered (by the hardware) when the FIFO is at that level. So in the case of the example2 from C2000Ware, when you open the SysConfig file, you can see that the TX and RX FIFO levels are both set to 2:

    For the transmit side: the TX interrupt will be triggered when the TXFIFO has 2 or less words in it (meaning it has at least 14 or more spots available in the TXFIFO since the FIFOs are 16 levels deep). See the register description from the device TRM below:

    For the receive side, the RX interrupt will be triggered when the RXFIFO has 2 or more words in it (meaning the receive FIFO has at least 2 spots full of data). See the register description from the device TRM below:

    So as soon as you start your program, the SPI module recognizes the TXFIFO is empty (or, rather, has 2 or less words in it) and triggers a TX interrupt where you should be writing to the transmit buffer to send out data. Let me know if there is still confusion here!

    2. Additionally, has anyone fixed the SPI driver for "SPI_pollingNonFIFOTransaction". I still have erratic clock behavior that others see here when using that: https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1248486/tms320f280025c-issues-with-manual-control-of-cs-pin-in-spi-when-using-driverlib-functions/4726334?tisearch=e2e-sitesearch&keymatch=SPI_pollingNonFIFOTransaction#4726334

    Yes, this has been fixed in the latest C2000Ware version 5.02.00.00! Please download the latest version and be sure your project is using this version of the drivers instead. 

     

    3. It would be super helpful if someone could share an interrupt-based SPI project that works with sending multiple bytes and using GPIO as Chip Select Pin.

    If you use the dedicated SPI_PTE signal, it automatically toggles low with transmissions from the controller/master device. But I assume you mean manually controlling a GPIO; We don't have a project like this readily available in C2000Ware, but the only thing needed to use the GPIO as a chip select pin manually is for you to configure the correct muxing in the GPIO registers to simply set a GPIO as an 'output' pin and then be sure to manually right a '0' or '1' to that GPIO before/after writing to the transmit buffer to transmit out data (assuming you are referring to the device in master/controller mode controlling the chip select pin). Let me know if you are able to implement this ok. 

    Lastly,

    If you are wanting to understand SPI a bit better, there is also a section on it in C2000 Academy here that might be helpful (I'm also in the process of adding to it to be clearer about some items I get questions on more often)  - there are also two resource links listed at the bottom of that page if you are interested. The video is an overview of SPI; the document is not precisely how our SPI module functions, but if you read more so for a high-level understanding of how SPI works, I think it can be very helpful! If you have further confusion on any of the items above please let me know- hope this helps!

    Best Regards,

    Allison

  • wow, thank you so much! 

  • No problem! Hope the above resolves your questions. If not, feel free to post back here or create another thread Slight smile

    Best Regards,

    Allison

  • I spent so much time fighting the broken HAL transmit byte. Updated to 5.02 C2000Ware and it literally just works. Thanks again so much. 

  • Looks like im not out of the woods yet. 

    For some reason the SPI Controller is not properly transmitting data still. As you can see I get a value of 0x0C for WREN in the EEPROM example but it is 0x06. I see the same behavior throughout all function calls to transmit as well as trying to use GPIO for Chip select.  Im out of ideas. 

    Attached are pictures of the problem: 

    I make sure that both Phase and Clock Mode settings are the same: 

    Any ideas here?

  • Worked on this all weekend with no success. The SPI driver functions like to send the data I want x2. 

  • Hi Gray,

    Could you try changing the clock mode to be Polarity = 0 and Phase = 0 in SysConfig? I see the clock settings for the other device state that the "data is valid on clock trailing edge" which I interpret as it is expecting data is being latched (read in) on the trailing edge of the clock (in this case, trailing edge is the falling edge since the clock is idle low and the leading edge is a rising edge).

    This would correspond to rising edge without delay:

    Best Regards,

    Allison

  • I could send and receive data but couldn't seem to get FIFOs to work so I used blocking transactions. 

    I am trying to get FIFO to work

    Currently, the logic for trying to get Fifo working is sending data to the FIFO buffer, waiting for the RX buffer to be filled using the FFST register level status, and then clearing the RX register after it has been sent (since I am writing an address). It runs once through the main while(1) loop but halts the next loop and waits indefinitely for an FFST register level status that is cleared even though it should be full.

    Hope this makes sense please let me know if I can provide any more information to make it easier to troubleshoot

    Thank you

    Gray

      

  • Hi Gray,

    Did the change in clock phase help at all?

    And if I'm understanding correctly, the issue is that the RXFIFO is not being filled when you would expect it to be?

    Keep in mind that SPI is a full-duplex communication protocol, so you have to transmit data in order to receive data. Is the problem that you are transmitting data from the controller device but not receiving properly on the controller device? Or is the issue that the program is not initiating the next transmission of data from controller to peripheral?

    Best Regards,

    Allison

  • Hi big headway. Many issues of the spi were caused by hardware problems (totally my faulty).

    In the hope of making everything more simple I got rid of the FIFO enhancements and looked at the EEPROM Sysconfig and C code as reference and looks like SPI_receiveByte() is still not working. Im getting a 0xD1 on MOSI (sorry its off screen in the screenshot below) but nothing stored in temp variable. Im on the latest version of C2000ware.

     

  • Hi Gray,

    Glad to hear of the progress!

    Could you explain a bit more of the context of the issue? Are you sending/receiving other data and it is correct but only 0xD1 is incorrect? Is the F280015x the controller/master device? The SPI_receiveByte is supposed to receive data that is sent to F280015x and store it into the temp variable; if you are seeing it on the MOSI (master out, slave in) line, then are you saying the data is being sent out from F280015x? What is on the MISO line?

    Best Regards,

    Allison

  • I am able to successfully transmit to my SPI devices to configure registers - this works. The problem is reading back from the SPI controller. My Salaea can see the receiving bits being shifted out using receiveByte and dummyData but the return of this function is not what I am seeing on my logic analyzer. 

    Could you explain a bit more of the context of the issue?

    -> The F280015x is transmitting data successfully now using SPI_trasmitByte HAL but SPI_recieveByte doesnt return the received value that I am observing using a logic analyzer.

    Are you sending/receiving other data and it is correct but only 0xD1 is incorrect? Is the F280015x the controller/master device?

    -> Yes The F280015x is the MASTER device. The 0XD1 is being received by the Logic analyzer from the slave device (successfully) but the reiceveByte HAL doesn't return this value. This does mean that the dummybytes being shifted out reiceveByte successfully so this is somewhat working.

    The SPI_receiveByte is supposed to receive data that is sent to F280015x and store it into the temp variable

    -> This is exactly what I am doing with it right now but its not working. In the end I need to receive 18 bytes and Im trying to use reiceveByte in a little FOR loop to do this. But for testing, I'm trying to just Receive one byte which isn't working.

    Keep in mind that I am using GPIO Chipseelct control (Which is working great btw!)

    As always thanks so much for your support.

    Best,

    Gray 

  • Hi Gray,

    How are you defining the "temp" variable?

    One thing to help double check would be to set a break point at (or before) that line 236 where you have the SPI_receiveByte(), then run the program to/before that line and then use the "Step into" and "Step over" buttons to look at what is happening. Please try to go line by line through the receiveByte function (should jump to the spi.c file to do so when you "Step into" the function and into the SPI_pollingNonFIFOTransaction() since that is what receiveByte() uses). 

    You are still using the latest C2000Ware driverlib, right? Recall that there was a bug with the old version of the SPI_pollingNonFIFOTransaction(). The corrected version should look like this:

    Glad the GPIO chip select is going smoothly!

    Best Regards,

    Allison

  • Temp variable is a Uint16_t type. I just checked the SPI_pollingNonFIFOTransaction() in new Driverlib 5.0.02 and its the same as your screenshot. I can step through it and I still get nothing RX. 

    Any other ideas?

     

  • Hmm strange - to clarify, you are seeing the correct activity on the MISO line, but it's just not getting saved into the temp variable? When you check the SPI RXEMU register during run time, do you still see the correct data being received in the SPI RX buffer?

  • Yes exactly my logic analyzer is hooked up to the SPI lines so its seeing the same bus as the C2000 but SPI RXEMU is 0x0000 weirdly enough.

  • Some rudimentary questions I feel I must ask just in case Slight smile:

    • Just want to clarify that you see the corrected function (that I screenshotted above) when stepping into/through the receiveByte in your actual program? Sometimes what happens is even if you download the latest C2000ware, CCS doesn't pull in the driverlib changes unless you manually rebuild the driverlib library in the CCS workspace, so I just want to be sure this isn't the issue.
    • Another quick check- you have the continuous refresh turned on when you are checking the registers and expressions?
    • Are you receiving data at any other time during the program that you can check to verify that the RX line is functioning otherwise?

    Another idea would be to try using loopback mode (where RX and TX are tied together internally) and send test data and check that it is received correctly to verify at least the software configurations are ok and perhaps hint at some hardware issue.

    Best Regards,

    Allison

    • Here is a screenshot of the first

    • Continuous refresh is enabled. 

    • Here is a picture of the SPIEMU register. its RXing 0 while logic analyzer is seeing 0x64. Yes I am able to RX values 

    RX never works. Its either 0xFF or 0x00. 

    The loopback test works great on the chip. Ive tried both driver lib examples. I don't see how it could be hardware if I can read it on saleae right? 

  • Its hardware. The diodes I used for the shared MISO SPI bus are not capable of switching fast enough. My old rigol scope is broken - it wouldn't ever trigger so I could never see it but I finally can see it by enabling the analog view in Saleae. The Saleae spi decoder is MUCH more sensitive than the SPI controller in the C2000 and that's why I could see valid data otherwise.

    Thanks for your support. I think its fair to say that the SPI controller works but my hardware doesn't :( sorry to waste your time.   

  • Ah I see! Glad you were able to find the culprit! And for what its worth, debugging is never a waste of time here - only more lessons learned and wisdom gained Slight smile

    If everything seems to be in order we can mark this as resolved and close the thread! But feel free to open another thread should you run into further issues at all.

    Best Regards,

    Allison