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.
Hello,
I am studying how this TI micronctroller works and I am having problems understanding how the FIFO feature functions when trying to setting an SPI communication.
I am interfacing the 2 SPI interface of my launchpad and I would like to transfer an array of 8 elements of uint16_t type using the FIFO interrupts from the master (controller) to the slave (peripheral). My configuration and code are the following (I am using sysconfig):
// Included Files /************************************************************************/ #include "driverlib.h" #include "device.h" #include "board.h" #include "c2000ware_libraries.h" /******************************************************************************************/ // Defines /*******************************************************************************/ /******************************************************************************************/ // Prototypes /****************************************************************************/ __interrupt void INT_mySPI0_TX_ISR(); __interrupt void INT_mySPI1_RX_ISR(); __interrupt void INT_mySPI0_RX_ISR(); __interrupt void INT_mySPI1_TX_ISR(); /******************************************************************************************/ // Global Variables /**********************************************************************/ uint16_t dim = 8; uint16_t rx_B[8]; uint16_t tx_A[8]; uint16_t tracker = 0; /******************************************************************************************/ // Main /**********************************************************************************/ void main(void) { // Local Variable uint16_t i; // Initialization of data for(i = 0; i < dim; i++) { tx_A[i] = i; rx_B[i]= 0; } // Initialize device clock and peripherals Device_init(); // Initialize PIE and clear PIE registers. Disables CPU interrupts. Interrupt_initModule(); // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). Interrupt_initVectorTable(); // PinMux and Peripheral Initialization Board_init(); // Enable Global Interrupt (INTM) and real time interrupt (DBGM) EINT; ERTM; // Infinite Loop while(1) { } } /******************************************************************************************/ // Interrupts /****************************************************************************/ __interrupt void INT_mySPI0_TX_ISR(){ // Local Variable uint16_t i; // TX for(i=0;i<dim;i++){ SPI_writeDataBlockingFIFO(mySPI0_BASE, tx_A[i]); } // Update Data for(i=0;i<dim;i++){ tx_A[i] += 1; } // Clear Interrupt SPI_clearInterruptStatus(mySPI0_BASE, SPI_INT_TXFF); Interrupt_clearACKGroup(INT_mySPI0_TX_INTERRUPT_ACK_GROUP); } __interrupt void INT_mySPI1_RX_ISR(){ // Local Variable uint16_t i; // TX for(i=0;i<dim;i++){ rx_B[i] = SPI_readDataBlockingFIFO(mySPI1_BASE); } // Check for(i=0;i<dim;i++){ if(rx_B[i] != (tracker + i)){ ESTOP0; } } // Update tracker tracker ++; // Clear Interrupt SPI_clearInterruptStatus(mySPI1_BASE, SPI_INT_RXFF); Interrupt_clearACKGroup(INT_mySPI1_RX_INTERRUPT_ACK_GROUP); } __interrupt void INT_mySPI1_TX_ISR(){ } __interrupt void INT_mySPI0_RX_ISR(){ } /******************************************************************************************/ // End of File
I hope the code is clear (it kinda follows the examples spi_ex4 drivelib example). I am calling a TX ISR where I write all the data using the command WriteDataBlockingFIFO and then, after transmitting, I update by one each element of the buffer. Then in the RX ISR I want to read all the data I sent (using ReadDataBlockingFIFO) and save it in an array of the same dimensions of the one I sent, then I check that the elements I received are the expected ones using the "tracker" variable.
I have set a bit rate of 10MHz because I am also trying to achieve a fast communication for a future project.
(the names of the interrupts ISR follow the first one in the last image)
What I am expecting is that the interrupts are triggered as follows:
- TX ISR is triggered when 8/16 places are occupied in the TX FIFO since I set that the SPI0 (controller) "Transmitt Interrrupt Level" on "8/16 FIFO";
- RX ISR is triggered when 8/16 places are free in the RX FIFO since I set that the SPI1 (peripheral) "Receive Interrrupt Level" on "8/16 FIFO".
The results I get when I debug are that only the TX ISR is triggered while the RX ISR nevers kicks in. I have read the reference manual section of the SPI but I don't know where I am doing wrong. I attach a picture of my debug perspective:
I don't know if I have misunderstood how the interrupts are called, or the read and write functions I am using in the code, or even just the code-flow of the protocol. Could you please help me understand where I am wrong and how FIFO buffers work?
Thank you in advance .
Best regards,
Edoardo
Edoardo,
I'm assuming that you are trying to get SPIA and SPIB within the same device to communication with each other. Correct?
If so, this is exactly what spi_ex4_external_loopback_fifo_interrupts code does? Were you able to get this example code working in launchpad? If not, that would be the first step. One you understand the example enough, you can modify the code to your requirement.
Regards,
Manoj
Dear Manoj,
Yes, you assume correctly, I want to make the two interface of the same device communicate. I was also able to get the example you mention to work and I think I understood it. Nevertheless, I have some question that I would like to ask you to check if I got everything correctly:
1) The FIFO is able to contain maximum 16 elements of maximum 16 bits (which should be the data width you configure in sysconfig). So depending on the amout of data you need to transmit you can set accordingly the FIFO Interrupt Levels. Considering a uint16 array of n dimension: for the transmission the interrupt level has to be set at (16 - n) this means that the TX interrupt is called when the TX_FIFO has (n) places occupied and so (16 - n) places free. For the receipt the level has to be set to (n) which means that the RX interrupt is called when the RX_FIFO has (array_dimension) places free while the rest of the places can be still occupied from the previous transmission for example. Am I correct?
2) Following the previous point, this means that the SPI is able to send bit by bit packets of maximum 16 elements of 16 bits within a single FIFO interrupt transmission or it's possible to send even bigger amount of elements (for example a uint16 array of 64 elements)?
3) The difference between the functions that are "NonBlocking" and "BlockingFIFO" is that in the first case the data is wrote/read in SPITXBUF/SPITXBUF while in the other case in the FIFOTXBUF/FIFORXBUF?
Also, I want to say that I found that if I reduce the bit rate the communication I set up works correctly. The problem is that the maximum value of bit rate I can achieve in this case is 1MHz and I would like to have instead a 10MHz bit rate communication and it should be possible in principle. Do you have an idea on why I have problems achieveing that speed? Could it be because I am interfacing 2 SPIs of the same board?
Thank you very much in advance.
Kind Regards,
Edoardo
Also, I want to say that I found that if I reduce the bit rate the communication I set up works correctly. The problem is that the maximum value of bit rate I can achieve in this case is 1MHz and I would like to have instead a 10MHz bit rate communication and it should be possible in principle. Do you have an idea on why I have problems achieveing that speed? Could it be because I am interfacing 2 SPIs of the same board?
What is your LSPCLK speed?
Dear Manoj,
Here there's the picture of my clock tree. The lspclk is set to 100MHz and I have also activated the "Device Support" feature as you can see in the previous pictures.
I want to add also that if I look the SPICLK pin on the board of both controller or peripheral with the oscilloscope i can effectively see a 10MHz waveform. So in the end, referring to the last picture of the first post, i was wondering if the fact that only the tx_A variable updates it's a debugger visualization problem.
Thank you.
Kind regards,
Edoardo
Edoardo,
Are you able to transmit / receive 16 bytes of data @ 10 MHz without any problem? Your earlier post suggest so.
Regards,
Manoj
Dear Manoj,
In the end, from the oscilloscope it seems so. However not being able to see any variation on the received data variable in the debugger makes me still question if I actually receive data. In your opinion could it be that the debugger is not able to display the received data because of the high bitrate? Or could it be another reason?
Thank you in advance.
Best regards,
Edoardo
Edaordo,
It looks like what you are observing is SPICLK signals. Observe all the SPI signals in the bus.
Regards,
Manoj
Dear Manoj,
Yes I can see some data and it seems correct, so probably in this cases the debugger is not able to keep the rate of the communication.
Thank you for the support.
Regards,
Edoardo
Dear Manoj,
I can see data in that buffer however it seems that the update of the SPIRXBUFF is very slow compared to the actual transmission and indeed I can see it change its value quiete slowly. Nevertheless, I think it should work.
I will let you know when I will be able to visualize better the data in my further project.
Thank you very much for your help.
I wish you a good day.
Kind regards,
Edoardo
At 10 MHz, your RX buffer is getting filled at high speed. The refresh rate in CCS is much much slower compared to RX buffer fill rate. As long as your RX buffer is filled with right data. That is all that matters.
I'm closing this thread for now.
Regards,
Manoj