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.

SPI Data Transmission

Other Parts Discussed in Thread: TMS320F28027

Hi, First,

I apologize for my English, which is not very good.,

I'm having a little problem in my project. I am using a device called MAX3420 to make SPI/USB bridge, because I need speed in data transmission. Until then everything was ok.

The MAX3420 works as follows: the first byte of each transfer is a command byte (indicates the resgister to be accessed and will be read or written), and the next bytes are the data to be write (or read). So I'm operating my SPI using MISO and MOSI (for sending and receiving data), the SCLK (clock) and SPISTE.

The SPISTE is used as a "chip select" that will be set low while reading or writing operation is being performed. However, each data sending via SPI (SPITXBUFF) when the pin 19 is configured as SPISTE, this operation is now performed automatically.

Here is my problem: I need to put on low level "chip select" and keep it at a low level until the SPI send all data (command byte and subsequent data).

This is the function I created to perform this operation:

----------------------------------------------------------------------------------------------------
void wreg(char reg, char dat),
 {    GpioDataRegs.GPACLEAR.bit.GPIO19 = 1; // Clear SS (SPISTE)
      spi_xmit((reg+2)<<8);  // Send the register addres and the write byte (+2)
      spi_xmit(dat<<8); // Send data
      GpioDataRegs.GPASET.bit.GPIO19 = 1; // Set SS (SPISTE),
 }
----------------------------------------------------------------------------------------------------,

The pin GPIO19 is configured as I/O, and the SPI Delay Transmit is 0.

Using a logic analyzer, it was verified that the bits are being placed correctly in MOSI and the SCLK is also ok. The SS is set low at the correct time (1us before starting the transfer), however, he returns to high (disabling the slave device) before the end of the data transfer.

When I set the pin 19 directly as SPISTE and not GPIO, SS enables and disables correctly but the data that appear on MOSI is incorrect. The first 8 bits appear correctly, however the last 8 bits only appear as zeros.

Importantly, SPI configured to work with 8bits: SpiaRegs.SPICCR.bit.SPICHAR = 0x0007

I am working with TMS320F28027

I appreciate the help!

Thanks

  • I made some changes in function, but didn't work too:
     
    -----------------------------------------------------------------------------------------
    void wreg(char reg, char dat)
     {
     GpioDataRegs.GPACLEAR.bit.GPIO19 = 1;  
        spi_xmit((reg+2)<<8);           
     while (SpiaRegs.SPISTS.bit.BUFFULL_FLAG !=0){}
     while (SpiaRegs.SPISTS.bit.INT_FLAG !=0){}
     spi_xmit(dat<<8);
        while (SpiaRegs.SPISTS.bit.INT_FLAG !=0){}
     GpioDataRegs.GPASET.bit.GPIO19 = 1;
     }
    -------------------------------------------------------------------------------------------
     
    Now the data is sent correctly. There is a waiting period between one spi_xmit and another. However, the SPISTE is set at high between the two transfers, which is undesirable in this case.

  • Can anyone help me?

  • Hi Diego,

    I did not really know your c2000 device, but on f2812 you have to set the gpio used as chip select to output state

    here my example i used for 2812

       GpioMuxRegs.GPFMUX.bit.SPISTEA_GPIOF3  = 0;  // IO
       GpioMuxRegs.GPFDIR.bit.GPIOF3 = 1;            // Set as Output        
       GpioDataRegs.GPFSET.bit.GPIOF3 = 1;            // Init as '1'

    if not set as output, your pin is set high if you sent a message and will get low before you send the next.

    hope this helps

    regards

    Eggi

  • Eggi said:

    Hi Diego,

    I did not really know your c2000 device, but on f2812 you have to set the gpio used as chip select to output state

    here my example i used for 2812

       GpioMuxRegs.GPFMUX.bit.SPISTEA_GPIOF3  = 0;  // IO
       GpioMuxRegs.GPFDIR.bit.GPIOF3 = 1;            // Set as Output        
       GpioDataRegs.GPFSET.bit.GPIOF3 = 1;            // Init as '1'

    if not set as output, your pin is set high if you sent a message and will get low before you send the next.

    hope this helps

    regards

    Eggi

    Hi Eggi,...

    I had already done what you suggested, yet still i have the same problem.

    I don´t know what else to do.

    I believe there is some flag or something that could help me.

     

  • Hi Diego,

    you have to transmit two bytes, -> 16 bit.
    Why don't you use spi to transmit all the 16 bit ?
    In your code you use <<8 to just transmit 8 bits. But on C2000 devices, you can also transmit 16bit values, so chip select is once set low before transmission and  gets high after transmission.

     

  • Eggi

    I Had tried to do that, but still had some problems.

     

    But I'll try again and post a reply.

    However, I believe there is a flag that tells me when the SPI data transfer ends. When the flag is set (or cleared), the DSP set SS.

  • Eggi

    I use the 8bits transmission because the slave device (MAX3420) have their registers accessed through a command byte.

    When I put the SS at a low level, I must first send a command byte. Keeping the SS at a low level, I can start sending the data that I want to selected register.

  • Well, if the IO is under peripheral control, the ss is set automatically, but if you set it as an io, then you control the io-pin.

    Have you ever tried to use another output pin to select your slave?

     

  • Eggi said:

    Well, if the IO is under peripheral control, the ss is set automatically, but if you set it as an io, then you control the io-pin.

    Have you ever tried to use another output pin to select your slave?

     

    Eggi

    Still haven't used another pin. I thought about it this morning and I already do the tests and post the result.

    I made some new changes that have generated new results. One of these changes was to disable the SPI FIFO mode. Follow the new code:

    void wreg(char reg, char dat)
     {
     Uint16 movedata = 0;
     Uint16 movedata2 = 0;
     GpioDataRegs.GPACLEAR.bit.GPIO19 = 1; 
        spi_xmit((reg+2)<<8);          
     movedata = SpiaRegs.SPIRXBUF;
        while (SpiaRegs.SPISTS.bit.BUFFULL_FLAG !=0)
     while (SpiaRegs.SPISTS.bit.INT_FLAG !=1){}
     spi_xmit(dat<<8);
        movedata2 = SpiaRegs.SPIRXBUF<<8;
     while (SpiaRegs.SPISTS.bit.BUFFULL_FLAG !=0){}
        while (SpiaRegs.SPISTS.bit.INT_FLAG !=1){}
        movedata2 = (movedata)|(movedata2);
        GpioDataRegs.GPASET.bit.GPIO19 = 1;
     }

    I use the BUFFULL_FLAG and INT_FLAG to control the SPI data transfer. The SPI is configured for 8bits transmission.

    This new code solved the SS problem. Now, the SS pin is set and cleaned at the right time.

    However, there appeared another problem right now. The first byte is sent properly (I'm checking using an analyzer). However, the second byte is not sent correctly (I'm sending 0x00AA and 0x0000 is appearing in the output).

    Between sending the first byte and sending the second byte, appears on the clock a latent time (where the clock remains at its inactive level). I believed that this was the time needed to complete the SPI sending the first byte, await the transfer finished and then send the new byte. But, the second byte is incorrectly sent.

  • Let's review first how the SPI actually works:I

    In full duplex Master mode we are actually sending and receiving bits at the send time.

    Assuming that you start with everything reset, the first write will cause SS to go low. The word will be written through to the output shift register so you may never see a TXBUFFULL for this word. You will only see TXBUFFULL if you you write a second word before the first one is set. In this case, TXBUFFULL will be set until the first word has been completely sent and the shift register is loaded with the second word. In generally, you must have a second word ready before the first one completes. Otherwise, the SPI transmitter will return SS high which will end the cycle at the MAX3420E. However, when you end up actually writing the second word, SS will automatically be driven low and this byte will be taken by the MAX3420E as a new command word - you probably don't want this. If you want the piccolo to keep SS low for the entire cycle then you have to keep it fully supplied with data. Or, you can use GPIO for SS. GPIO may be necessary if you are using interrupts and cannot guarantee that you can service the SPI. In this case, GPIO may be a better choice.

    Receive data (and SPI INT) arrives when the first  word has be clocked in and loaded into the receive buffer. Note that you cannot read the first word immediately after sending the first word. You have to wait until the transmit word is fully clocked out and the received word is fully clocked in.

    So to write a single octet you need to:

    1. Write the Command Word
    2. Write the Data Word
    3. Wait for SPI INT to read the first word.
    4. Read the first word (which will be the 3420E status).
    5. Wait for SPI INT for the second word.
    6. Read the second word which will be zero for a 3420 write command. 

    To read an octet you need to:

    1. Write the Command Word
    2. Write a Dummy Data Word (to generate the clocks - this word will be ignored by the 3420)
    3. Wait for SPI INT to read the first word.
    4. Read the first word (which will be the 3420E status).
    5. Wait for SPI INT for the second word.
    6. Read the second word (which will be 3420E data).

    This will allow you to read and write an octet at a time. After you get this to work, you will probably want to read and write the 3420 FIFO's in complete N octet blocks. To do this you need to keep loading the next transmit octet (data or dummy data) after each read with TXBUFFULL low.

    Hope this helps!

     

  • Hello again

    I solved the problem of SS to be set and cleared in the right moments. But I discovered something strange that, I believe, is not caused by SPI.

    With the MAX3420 disconnected, and testing only the output of the SPI (SCLK, MOSI and SS), found that the data is being sent correctly, and everything is OK with the SCLK and SS. Now i´m working with SPI sending 16bits. But when I connect the MAX3420, the last 8bits simply "disappear" from MOSI (
    I'm sending 0xAA and in the output appears 0x00). believe that this is related with the MAX3420 and not with the SPI.

    Tomorrow I will try to solve this problem, although, until now, i have no solution for it.

    Nevertheless, I appreciate the help you are giving.

  • Hello Diego,

    I'm on working with the Max3420 and i meet the same problem which means the Max3420 seems to pull-down my second byte. I also ask for help from Maxim staff but they have no recomment on this product. Have you found a solution finally?