1
\$\begingroup\$

I am trying to let two uC talk to each other. Both chips are from dsPIC33EP family. The slave will respond according to what master has sent to it. My question is, since SPI is full-duplex, would it be too late to send data back to master in one communication cycle? Should I load one byte to transmit buffer before receiving one byte? Please see my code as I demonstrate my doubts.

void ISR() iv IVT_ADDR_SPIINTERRUPT{
    char data;
    SpiIntFlag=0;//clear interrupt flag
    data=SPIBUF;//read the incoming byte

    //send back one byte according to the received byte
    if(data==0x01){
        SPIBUF=0xF1;
    }
    else if(data==0x02){
        SPIBUF=0xF2;
    }
    else if(data==0x03){
        SPIBUF=0xF3;
    }
    else if(data==0x04){
        SPIBUF=0xF4;
    }

}

As you can see, a byte will be sent after the slave receives one. Does it mean receiving and sending do not happen at the same time? I have tried this code with ATmega32u4 at 5MHZ. But it looks like the master receives a corresponding byte according to the byte sent to the slave. Also, there is no additional bytes received so I think this communication process(read and send) happen at the same time. What about the delay that if() statements caused?

Is this the correct way to do SPI communication? All I want to achieve is master send one command byte and slave send back couple bytes back according to it.

\$\endgroup\$
1
\$\begingroup\$

With SPI the master generates the clock so there's not really a concept of being able to receive multiple bytes back from a slave automatically, you have to send additional dummy bytes to generate the clock. Say if you had a sensor and you wanted command 0x01 to send back the current temperature the pseudo-code for the master may look like:

spi_write(0x01);
t_lsb = spi_write(0x00); // These dummy bytes are just needed to generate a clock
t_msb = spi_write(0x00); // So that the slave gets a chance to send the results back

On and the slave it might look like:

cmd = spi_read();
if (cmd == 0x01) {
  spi_write(t_lsb);
  spi_write(t_msb);
}

You can technically send back a byte from the slave for each byte sent from the master, but for most protocols there probably isn't anything useful to send back until the slave has received and decoded the command. Hopefully you can understand that pseudo-code and the general concept OK, it's been a while since I've programmed PIC SPI at the register level but it sounds like you're on top of that side of things.

\$\endgroup\$
  • \$\begingroup\$ Thanks, I understand that code but I have a new problem. The master is sending command to the slave to do something which takes time. For example, the slave can respond to master's command by reading from different sensors and return information back. How does master know when slave is done reading from sensors and ready to send bytes back? Since the slave cannot drive CLK, performing spi_read() on the slave side does nothing right? I am having trouble figuring out what I should do in slave's interrupt routine. \$\endgroup\$ – Timtianyang Aug 29 '13 at 15:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.