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 master read function' on TIVA C TM4C123G.



Hi,

I am testing the SPI function of the TIVA board, and have a question about the SSI master read function.

At first, I have finished the 'master write function'. It works well.  The process is like this:

(1) configure SSI0 as master, SSI1 as slave. 

(2) write SSI0 register using SSIPUTDATA command,

(3) then read SSI1 register using SSIGETDATA command).


But ,the 'master read function' does not work after working on it for several days. The process is like this:

1) still configure SSI0 as master, SSI1 as slave

2) write SSI1 register using SSIPUTDATA command

3) read SSI0 register using SSIGETDATA command


There is no data readout out from SSI0 register, because I think there is no data in the SSI0 RX FIFO. Maybe the reason is: SSI0 doesn't read data from SSI0 by sending out fss and clock signals. But how should the SSI0 be triggered to read data, not using SSIGETDATA command?

Thanks! Waiting online.

Qi

  • Hello Qi,

    The SSI master Reads data by putting in Data. So if you want to do a Master read operation, then put a dummy byte in the Transmit FIFO. For every dummy byte you would receive a byte in the Receive FIFO. Also when using the Master in write mode, do make sure that the RXFIFO is also read after every transmit byte.

    Regards
    Amit
  • Hi, ,

    This is the sequence to read one byte?

    - SSIDataPut(SSIn_BASE, REG_ADD);

    - SSIDataPut(SSIn_BASE, DUMMY);

    - SSIDataGet(SSIn_BASE, &value);

  • You need a get for each put.

    Robert
  • I'm trying this, to read from 0x00 register in MAX31865, but doesn't work!

    It is right?

        SSIDataPut(SSI0_BASE, 0x00);
        //
        // Wait until SSI0 is done transferring all the data in the transmit FIFO.
        //
        while(SSIBusy(SSI0_BASE))
        {
        }
    
        //SysCtlDelay(80000);
    
        SSIDataGet(SSI0_BASE, &data);
    
        SSIDataPut(SSI0_BASE, 0xFF);
    
        while(SSIBusy(SSI0_BASE))
        {
        }
    
        SSIDataGet(SSI0_BASE, &data);

  • Well the busy checks are probably not necessary but they shouldn't necessarily cause a problem. However there's no indication of how you are performing the chip select and no screen shots.

    You don't show the init or whether you clear the FIFO before starting.

    Robert
  • Geez - WHAT a task-master!
  • qi wang said:
    I have finished the 'master write function'It works well.

    May we ask, "How you came to that "works well" conclusion?"     You provide no supporting data for, "working well" - yet "DO" supply "evidence to the contrary" (failed SPI reads!)    (as those "reads" may only result from the earlier arrival of "proper" SPI Writes!)     Such is, "within the realm of possibility" - is it not?

    Poster Robert (properly) asks for "earlier, vital, related code!"    While presently withheld - your selection of a, "mismatched SPI format" - is likely to "DOOM" all of your subsequent efforts!   And that "critical" code is NOT present.    Note that "view of a scope trace(s)" provides incomplete assurance that SPI Writes are properly formatted - unless you have carefully reviewed the Slave device's requirement - and the two "match."

    No information is presented re:

    • proper powering of your slave device
    • your checks for continuity between all connections - slave & MCU
    • the separation distance between slave & MCU
    • presence of noise sources, high speed digital signals, local RF/cell/tablets
    • proper ESD discipline - both at/around the MCU and Slave device

    The award of "working well" - in absence of most (perhaps all) of the above - may well be "premature."

    As a "guide" to you/others - SPI Transmission/Writes may be judged as "working well" when:

    • the MCU's: SPI clock, CS, & MOSI all (properly) match the MCU's Timing/Signal Diagram - for that particular SPI Format
    • that particular SPI Format "matches" the requirement imposed by the SPI Slave.   (the Slave is the "Boss of (me) and the MCU" - as the Slaves (usually) are less (format) flexible than the MCU)
    • users have "reasonably" complied w/the "5 point "laundry list" (above)"

  • Hello Allef,

    I believe the CS is toggling between the two writes. Could you please check that using a Scope or LA?
  • Hello cb1,

    Please note that qi wang - the original poster - went silent after his request, and Allef, the new poster, is the one making the new request. So the situations are not related.

  • Greetings Ralph,

    Good grief - you are correct.    (I'm (now) guilty of the (same) fault I've noted by vendor staff!)

    Yet - your claim, "situations are NOT related" - may in fact be incorrect!    The new poster reports a "NEAR IDENTICAL" inability to read SPI - does he not?     How then - are the "situations NOT related?"

    While my "quote" proves improper - is not ALL ELSE - especially ALL ELSE - fully focused & proper?

    (i.e. we find no presentation of "SPI format selection" and thus (still) our (NEWLY ARRIVING) poster's SPI Write (may) prove suspect.    Is that not true?)

    The guidelines I've provided (still) hold true - and of good value - are they not?

    My "poster targeted error" thus may not be (especially) significant - yet is acknowledged - and my "outsider efforts" will be more disciplined...

    Again - the situations - when properly/fully considered - are HIGHLY RELATED - are they not?     (the desire to "find outsider fault" may have caused "over-reaction" mais oui?)

  • Hello cb1,

    I wasn't intending to discount the efforts and information provided in any way, they are very much valid. I had just wanted to direct you to the fact that the OP's setup and configuration cannot be used as a baseline for Allef's setup and configuration and that the 'writing works well' portion isn't relevant as of the moment.

    I did poorly choose my words though, I should have rather said "The configurations and writing results are not identical" or something to that effect. Sorry about that!
  • Thank you - although it MUST be stated - there is "MUCH HIGHLY RELATED" between each poster's issue!    (Neither can "Read via SPI - how possibly is that NOT RELATED?)

    The earlier, "NOT RELATED" comment is far "off mark" - overly critical - and as NO VENDOR AGENT had made the time/effort to assist (the new poster) - highly unwarranted!

  • Hi, all!

    I don't have an oscillope at this moment. But with a multimeter I can see the voltage and continuity as expected.

    Also, I have tried forcing and without force the Fss.

    I know I'm trying to connect with a very specific device, but I just need to validate the read operation for one byte in SPI.

    There is some stupid mistake in this code?

    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/hw_memmap.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/ssi.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    
    
    uint32_t data;
    
    void main(void)
    {
        uint32_t ui32SysClock;
    
        // I don't have a crystal
        ui32SysClock = SysCtlClockFreqSet((SYSCTL_OSC_INT | SYSCTL_USE_PLL |
                                                SYSCTL_CFG_VCO_480), 120000000);
    
    
        // Enable Multiplexer CH4
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK);
        GPIOPinTypeGPIOOutput(GPIO_PORTK_BASE, GPIO_PIN_5 | GPIO_INT_PIN_6);
        GPIOPinWrite(GPIO_PORTK_BASE, GPIO_INT_PIN_5, ~0);
        GPIOPinWrite(GPIO_PORTK_BASE, GPIO_INT_PIN_6, ~0);
    
    
        //
        // The SSI0 peripheral must be enabled for use.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
    
        //
        // For this example SSI0 is used with PortA[5:2].  The actual port and pins
        // used may be different on your part, consult the data sheet for more
        // information.  GPIO port A needs to be enabled so these pins can be used.
        // TODO: change this to whichever GPIO port you are using.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
        //
        GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_3);
        //
    
        //
        // Configure the pin muxing for SSI0 functions on port A2, A3, A4, and A5.
        // This step is not necessary if your part does not support pin muxing.
        // TODO: change this to select the port/pin you are using.
        //
        GPIOPinConfigure(GPIO_PA2_SSI0CLK);
        //GPIOPinConfigure(GPIO_PA3_SSI0FSS);
        GPIOPinConfigure(GPIO_PA4_SSI0XDAT0);
        GPIOPinConfigure(GPIO_PA5_SSI0XDAT1);
    
        //
        // Configure the GPIO settings for the SSI pins.  This function also gives
        // control of these pins to the SSI hardware.  Consult the data sheet to
        // see which functions are allocated per pin.
        // The pins are assigned as follows:
        //      PA5 - SSI0Tx
        //      PA4 - SSI0Rx
        //      PA3 - SSI0Fss
        //      PA2 - SSI0CLK
        // TODO: change this to select the port/pin you are using.
        //
    //    GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 |
    //                   GPIO_PIN_2);
        GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_2);
    
        //
        // SPI Mode 3 for MAX31865
        //
        SSIConfigSetExpClk(SSI0_BASE, ui32SysClock, SSI_FRF_MOTO_MODE_3,
                           SSI_MODE_MASTER, 1000000, 8);
    
        //
        // Enable the SSI0 module.
        //
        SSIEnable(SSI0_BASE);
    
    
        //
        // Read any residual data from the SSI port.  This makes sure the receive
        // FIFOs are empty, so we don't read any unwanted junk.  This is done here
        // because the SPI SSI mode is full-duplex, which allows you to send and
        // receive at the same time.  The SSIDataGetNonBlocking function returns
        // "true" when data was returned, and "false" when no data was returned.
        // The "non-blocking" function checks if there is any data in the receive
        // FIFO and does not "hang" if there isn't.
        //
        while(SSIDataGetNonBlocking(SSI0_BASE, &data))
        {
        }
    
        GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3, ~0);
    
        for(;;) {
            //
            // Send the data using the "blocking" put function.  This function
            // will wait until there is room in the send FIFO before returning.
            // This allows you to assure that all the data you send makes it into
            // the send FIFO.
            //
    
            GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3, 0);
            SSIDataPut(SSI0_BASE, 0x01);
            //Depois de enviar tudo
            //
            // Wait until SSI0 is done transferring all the data in the transmit FIFO.
            //
            while(SSIBusy(SSI0_BASE))
            {
            }
    
            //SysCtlDelay(80000);
    
            SSIDataGet(SSI0_BASE, &data);
    
            SSIDataPut(SSI0_BASE, 0xFF); //Dummy
    
            while(SSIBusy(SSI0_BASE))
            {
            }
    
            SSIDataGet(SSI0_BASE, &data);
    
            GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3, ~0);
    
            //
            // Since we are using 8-bit data, mask off the MSB.
            //
            SysCtlDelay(60000000);
        }
            //
            // Return no errors
            //
    
    }
    

  • Allef Silva28 said:
    I don't have an oscillope at this moment.

    You need that, or at least a logic analyzer to verify the output.

    Allef Silva28 said:
    There is some stupid mistake in this code?

    Well, I don't have any info on your device (cb1's advice here is valid, start with something simple, like an FRAM or a shift register) but some possibilities are

    • chip select
    • clock speed
    • phasing/mode

    How do you know this isn't working? I don't see you checking your data anywhere.

    Robert

  • Hello Allef,

    From a pure peripheral steps configuration standpoint, you seem to be fine, but as Robert mentioned, we don't know about your target device so we can't comment if the SPI settings are correct for your use case.

    Please get access to an oscilloscope or logic state analyzer (LSA) and get captures of the SPI data output for us to review. You should also compare those results versus slave device datasheet on your end as well - you may find an answer easily and quicker that way.

    Debugging of communication protocols like SPI, I2C, etc. are almost impossible without access to the information that an o-scope or LSA can provide.
  • Hi all,

    The program is fine. It is an issue with the CS multiplexer in my custom board, combined with CS signal management for my sensor.
    Thanks.