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 RECEIVE NOT WORKING

Other Parts Discussed in Thread: MSP430F5438

Hi Everyone,

 

I am new to the msp430 and I am trying to receive data back from a serial eeprom (m95128). I am not seeing any data on the UCA0RXBUF  after i send data. also there is no clock signal generated when i should be receiving data. The clock is generated when I send the data. What am I am doing wrong?

 

#include "msp430f5438.h"

void main (void){

WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT

P6DIR |= 0X10; // Enable P6.4 as output (eeprom) chip select

P6OUT |= 0X10; // Set High - Disable eeprom

init_spi_a0();

select_spi_device(EEPROM_DEVICE); // enables chip select on eeprom

USCI_A0_SPI(M95128_RDSR); // WRITE TO STATUS REGISTER

EEPROM_CS_DISABLE();

}

 

void init_spi_a0(void){

P6OUT |= 0x10;

P6DIR |= 0x10; // Slave Reset

P3SEL |= 0x31; // P3.5,4,0 option select

UCA0CTL1 |= UCSWRST; // **Put state machine in reset**

 UCA0CTL0 |= UCMST+UCSYNC+UCCKPL+UCMSB; // 3-pin, 8-bit SPI master

UCA0CTL1 |= UCSSEL_2; // SMCLK

UCA0BR0 = 0x02; // /2

UCA0BR1 = 0;

UCA0MCTL = 0; // No modulation

UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**

UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt

__bis_SR_register(GIE);       //  enable interrupts

}

 

unsigned char USCI_A0_SPI(unsigned char u1_txdata)

{

 unsigned char u1_rxdata;

 

while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready?

UCA0TXBUF = u1_txdata;                 // Send data

__delay_cycles(40); // Add time between transmissions to

                      // make sure slave can process information

   while(UCRXIFG==0); // USCI_A0 RX buffer ready?                                      

u1_rxdata = UCA0RXBUF; //

 return(u1_rxdata);

 

}

 

Does anyone know why i am not receiving data on UCA0RXBUF?

Thanks for any help.

  • You do not "read" the slave, you write a byte to the master buffer (UCA0TXBUF) which pushes the slave data back to the master. If you send data to the slave that must be processed before it is returned to the master you must then write a "dummy" word to the master's UCA0TXBUF to receive the processed data from the slave. In your code you are reading the slave data that was there before you wrote to it. Also you are looking for a second clock associated with the returned data which does not happen.

    SPI is fairly straightforward.

    There is a  shift register in the MSP430 (master in this example) and possibly a similar shift register  in the target device (slave) connected in a loop. Once you configure the SPI and write to the SPI buffer (UCA0TXBUF = u1_txdata; ) the SPI state machine takes over and clocks (UCLK) the data out on SIMO line into the SIMO (aka MOSI) of the slave. The data (if any) in the slave is simultaneously clocked out of its SOMI (aka MISO) pin into the  master's SOMI pin and into the SPI buffer (u1_rxdata = UCA0RXBUF; ) where you read it.

    A couple of take aways:


    SIMOI(master) is wired to SIMO(slave)  i.e. slave in  master out
    SOMI(slave) is wired to the SOMI(master)


    You do not "read" the slave, you write a byte to the master buffer, it is clocked out on SIMO, the same clock cycle causes the slave data to be clocked out on SOMI back to the Master's SOMI where it read from the UCA0RXBUF buffer.

    This is true even if SIMO was disconnected. Many ADC's with SPI are read this way. (ex AD7476)

    Many (most?) devices use the same buffer for Tx and Rx, you write to buff1, wait for the Tx complete flag, and read the returned data from buff1.

    The Master always drives the slave select (STE aka SS aka CE aka CSN aka SSN depending on the brand) on the slave with a GPIO pin and NOT the STE from the master.


    SPI has no overhead, and no handshake, you can send data into an open connection and never know it.

    You also do not know when the slave data is valid to push back to the master.

     

     

    aka = "also known as"

  • H Stewart said:
    SPI has no overhead, and no handshake, you can send data into an open connection and never know it.
    You also do not know when the slave data is valid to push back to the master.


    This is why many slaves emit a 'busy' byte (0x00 or any pattern other than 0xff) until they have processed the received command and are ready to answer. Usually, the first non-busy-byte is a token that tells whether the operation was successful or not and whether more data will follow. One of the most complex slaves in this respect are MMC cards. Of course the simpler slaves with always a result ready won't implement such a busy token. They just deliver the data. And yes, if 0xffff is a valid result, you'll never know whether the slave is there at all.

    Anyway, SPI is the easiest way to communicate. No timing requirements (other than a maximum speed), no low-level protocol (just chip-select the slave and begin clocking the data), multi-slave capabilities (you can connect as many slaves as you want with just one SPI, as long as you have enough I/O lines to do the chip selects). We have a setup where 32 slaves are connected using 20 lines (4*3 lines SPI and 8 chip select I/Os), with a maximum burst transfer speed of 2MB/s.

  • Thanks for your help guys!

    It turns out that the problem was hardware related. There was a spike on the chip select pin when a transmit operation was executed. This caused the chip to select/deselect several times during the transmit causing the eeprom unavailable. This occurred as I had not got the grounds connected from the MSP430f5438 development board to the ground from the power supply. Hope this might help someone else in the future.

     

    Thanks again.

  • :)

    It's easy to forget that a 3-wire SPI connection actually is a 4-wire connection.

    With other protocols not relying on common ground (such as RS485, which is real 2-wire), the required GND connection for other protocols is often made just coincidentally and not on purpose. Or sometimes forgotten totally, if both devices have a separate power supply.

    About spikes on the CS line: when using an MSP as SPI slave, one may not forget that the STE signal (the CS line) only en-/disables the SOMI transmitter and inhibits the reception of the SPI clock signal. It does not reset the current state of the shift register or reset a protocol. It just freezes the SPI in its current state. Unfortunately there's no interrupt flag that calls an ISR which could handle the protocol reset (and the SPI hardware reset). So connect the STE line with an interrupt capable port pin (if not already on one) and set up an ISR for handling STE transitions (mostly the low-to-high transistion which should reset the protocol and the SPI hardware).

  • hai,

    i want to ask about this SPI and i am new to this. here is my problem :

    i have ECU(master) and Sensor(slave) that communicate using 3lines SPI. my job is, i have to tab between the master and slave to bring and read the data from sensor to the PC using DSP processor from Texas Instrument. so from what i imagine, i just need to programm the receiving data (without transmit) for DSP. but i just got 0x0000 und 0xffff although from Osciloscope it is not 0x0000 und 0xffff. is that relating to what you guys talked about or there is an error on my configuration? because you all talked about transmit and then received back, and the slave emit 0x0000 or 0xffff, so i think maybe you all can help me.

    thanks if you can help me in this..=)

  • SPI is bidirectional-synchronous. This means that you'll receive while transmitting and transmit while receiving. If you just want to transmit, you'll get a byte for each one you send and you can just ignore/drop it. And if you want to receive something, you'll have to transmit  something, even if it is a dummy byte (or no connection at all).

    If you are the master, the transfer clock for both directions is started by starting a transmit operation, even if you just transmit a dummy value (and even if the output line is not connected at all with the slave).

    If you don't send something, there is no clock signal and you'll never receive something.

    If you are a slave, you get the clock from the master, and when the clock pulse comes, you'll have to be ready for both, sending and receiving. The master won't wait.
    Your tap, however, must not send anything. Instead, it has to receive on both lines. The bits are , however, sent in both directions at different clock edges. Also, the transmission is usually synchronized by the select signal which enables the slave and sets its shift register back to the first bit of a byte transmission. And enables its output drivers, as many slaves may be on one SPI line.

    That your softeware reads only 0x0000 and oxffff may be related to the send/receive flow (you're keeping the wrong byte as the answer byte or send not enough clock pulses) as well as to a programming or hardware error. With the information you provided about them, no-one can tell :)

  • what do you mean by receive on both lines? my SPI is just 3 lines so that means it has 1 line for MOSI and MISO = SISO. the master will send AAFFh and then 8 high bytes (FFFF...h) and slave will answer it with 2high bytes, 4data bytes and lastly 4high bytes. so is it probably because i just receive the MOSI line? so how can i receive the MISO line?

    i am not sure about the send/receive flow, but from what i saw on osziloscope, the SISO lines shows AAFFh and then 4Data bytes and 4high bytes. so i thought the communication is perfect, but i dont know whether the bits is shifting in or not.

    i am neither slave nor master, so i should not send anything to make the SISO flow right?

    programming error is hard to ask you because there is too many configuration of DSP from TI (TMS230c31) that i have to consider, and i have tried all the possibility from the configuration side, but it still came out with the same result.. but from your explanation, it brings me hope.. :-)  maybe i missed the important principles of SPI.. so great thanks for your explanation!!

    maybe i will try to send some dummy byte or then i will try to receive both lines like you said..=)

  • gen_sop said:
    what do you mean by receive on both lines?


    I thought that you need to read the communication between them, Then you'd have to sniff on both lines, SOMI and SIMO to get the communication.
    If you want to place your device as man-in-the-middle, of course there is only one listen line in each direction. But this is virtually impossible as the master will expect the answer while you are still sending the intercepted request byte to the slave.

    gen_sop said:
    my SPI is just 3 lines so that means it has 1 line for MOSI and MISO = SISO.

    No. SPI always has one SOMI and one SIMO. the third line is the masters clock. The (usually required) chip select line is not handled by the SPI master hardware and only partially implemented by teh SPI slave hardware (the STE pin only cotrols the clock pin and the output driver, it does not reset the shift state register or the software protocol - the slave needs to handle it by in software).

    Since the chip select is always needed to synchronize the first byte, and GND is needed too, SPI is always 5 lines plus one more line for each additional slave. Independently of the "3wire/4wire mode" in the hardware.

    gen_sop said:
    the master will send AAFFh and then 8 high bytes (FFFF...h) and slave will answer it with 2high bytes, 4data bytes and lastly 4high bytes


    While the master sends the 0xAAFF, the slave will send 0xffff or any other dummy byte, depending on its protocol (in your case the first 2 high bytes). When the master sends a clock, the slave will always transmit a bit and receive a bit. And so does the master itself.
    So the master keeps sending 8 high bytes while it receives the 4 data bytes and the 4 high bytes from the slave. Maybe the 4 final high bytes are just a 32 bit end-of-data marker.

    Some slaves will send out the last byte they received, while reeiving the next, so you can daisy-chain several slaves, some will always send a status byte (busy, ready, whatever) while receiving a command, others just send 0xff.

    gen_sop said:
    i am neither slave nor master, so i should not send anything to make the SISO flow right?

    Indeed, if you are just sniffing, you'll need to attach TWO SPI modules, both in slave mode, attach each ones SIMO line (input) to the SIMO and the SOMI line of the SPI, maybe intercept the CS signal too (e.g. on port1/2 with interrupt) and read both lines.

    And it might be necessary to alter the clock phase or clock level for one of the two lines, as the data on the SIMO line is take at one edge of the clock and tee data of the SOMI line on the other edge. Since on the SOMI line you're playing master without being master (using the slave mode), you're one edge off and need to correct it by a different phase and/or level setting for the clock.

    If all is set up properly, you'll get an interrupt for each byte on SIMO and immediately after (1/2 clock cycle later) another interrupt for the byte on the SOMI line. And you'll need to see both streams side-by-side and not one behind the other, as they are simultaneous transmissions.

    It's not easy to understand if one has the traditioal UART way in mind (send request, then receive the answer).

**Attention** This is a public forum