SPI communication question

Thread Starter

Gajyamadake

Joined Oct 9, 2019
310
Hi,
I want to create SPI communication flow chart to get basics of communication. I have already created one for I2C https://forum.allaboutcircuits.com/...ication-flow-chart.165271/page-2#post-1456361

I do not want to mix SPI and I2C in single thread that's the reason I am creating new thread for SPI communications

The master sends and receives byte simultaneously in SPI communication

I have create an example to write data form master to slave

1575721963344.png
If master has binary 1111 0000 And slave has 0000 1111. After 8 clocks the master will hold 0000 1111 and the slave will hold 1111 0000

@JohnInTX @jpanhalt @BobaMosfet
 
Last edited:

BobaMosfet

Joined Jul 1, 2009
2,113
@Gajyamadake
SPI is much simpler in a basic way, than i2c/twi. SPI was created by Motorola, circa 68K CPUs. There is no upper speed limit on SPI, and it uses 4 lines. Since SPI is controlled entirely by Slave Select going low to a given slave, and a master-generated clock-pulse, you can go as fast or slow as you can set up your data, and pulse your clock.

You have to decide whether the master and slave work on leading edge or trailing edge, and then signal and watch for signal accordingly (pin transition). You can easily support bi-directional comm this way.

Stop thinking about the communication as binary, and start thinking about it in terms of high or low on a signal line, in relation to a simultaneous high or low on the clock line. Because that is all a device understands at a time- serial communication, not parallel.

1575727818843.png
The above chart is really easy to read. MOSI and MISO show high & low in each time slow, because they don't know what you're data is, the signal can be either eay depending on what's being sent. At any given moment in time, SCLK, SS#, MOSI, and MISO are represented as a nybble (parallel) on 4 pins on the MCU. Doesn't matter which pins. The end result is serial, 1 bit at 1 clock pulse at a time on each of the signal lines.

If you look at the 4 signal lines above, the first change you see is SS# dropping, followed by SCLK (clock) starting, with data (MOSI and/or MISO) simultaneously with SCLK being loaded. When the data bits are sent, the SCLK/MOSI/MISO signal lines return to their default 'non' doing anything setting (0V), and then SS# goes high to signify the communication is ended.

The master must watch MISO even while sending, in case the slave returns data during a M -> S send.
 

Thread Starter

Gajyamadake

Joined Oct 9, 2019
310
If you look at the 4 signal lines above, the first change you see is SS# dropping, followed by SCLK (clock) starting, with data (MOSI and/or MISO) simultaneously with SCLK being loaded. When the data bits are sent, the SCLK/MOSI/MISO signal lines return to their default 'non' doing anything setting (0V), and then SS# goes high to signify the communication is ended.

The master must watch MISO even while sending, in case the slave returns data during a M -> S send.
Hi BobaMosfet

1. Set Clock pin to Low
2. Set CS pin to low . This enable SPI communication
3. ?

We send first bit (A0) to slave I do not understand What should be third point ?

Edit

1575737557668.png
 
Last edited:

JohnInTX

Joined Jun 26, 2012
4,787
Are you using an SPI peripheral that sends one byte at a time (like your I2C exercise) or are you bit banging i.e. writing each bit and generating the clock for each 8 bit byte?

For a peripheral you would do something like:
Drop CE/
For N bytes{
Write the data to the SPI buffer
Wait for a flag that says the byte has been sent on MOSI (and a byte has been received on MISO, too).
Read the SPI buffer to get the returned byte
}
Raise CE/

If you are bit-banging, the process is the same but you have the additional step of shifting out the byte and clocking it yourself:

Drop CE/
For N bytes{

for 8 bits{
output data bit on MOSI
clock=1
read the data bit on MISO
clock=0
shift the TX byte and RX byte to make room for the next bit
}
}
Raise CE/

The diagram in #3 is misleading. While most SPI is implemented as shown, SPI itself is FULL-DUPLEX i.e. it sends and receives bytes at the same time. You have to send something to get something and if you are using an SPI peripheral in a uC, you usually have to read the data back, even if you don't care what it is.


Hope that helps a bit.
 

Thread Starter

Gajyamadake

Joined Oct 9, 2019
310
Are you using an SPI peripheral that sends one byte at a time (like your I2C exercise) or are you bit banging i.e. writing each bit and generating the clock for each 8 bit byte?
I want to understand both but first I will start with bit banging


If you are bit-banging, the process is the same but you have the additional step of shifting out the byte and clocking it yourself:

Drop CE/
For N bytes{

for 8 bits{
output data bit on MOSI
clock=1
read the data bit on MISO
clock=0
shift the TX byte and RX byte to make room for the next bit
}
}
Raise CE/
I am trying to draw flow chart for bit banging. When CS pin is low transmission would be start and each bit will be transfer/receive at at one time

I got following information from page https://electronics.stackexchange.com/questions/44670/what-is-bit-banging

C:
Make Slave Select low
Short delay
Do 8 times
  Make the SCK (Serial Clock) pin low
  Make the MOSI (Master-Out-Slave-In) pin high or low depending on bit 7 of the data
  Add brief delay
  Make the SCK output high
  Read MISO (Master-In-Slave-Out) pin
  Shift received data left, and shift the bit just read in as bit 0  
  Add brief delay
  Shift the data byte 1 bit left
Make Slave Select high again
When MOSI pin should high and When it should be low ?
 
Last edited:

JohnInTX

Joined Jun 26, 2012
4,787
When MOSI pin should high and When it should be low ?
MOSI is the serial data out to the slave. For an 8-bit byte, you clock 8 times right? So.. before each clock, you set MOSI to whatever the current bit of the data is. If the data is 1001 0000 for example:
On the first bit you set
MOSI = 1 then clock it by SCK=1 then SCK=0. That's the first bit (MSbit).
For the next 7 bits you set:
MOSI = 0
MOSI = 0
MOSI = 1
MOSI = 0
MOSI = 0
MOSI = 0
MOSI = 0
And clock each bit one by one.

In bit-banging, I use a shift operation to move each bit into the MSbit location of a byte then output the MSbit. That makes it easy to do the 8 bit output in a loop.

Example: for the same data 1001 0000 in a byte called 'DataOut':

C:
//bit bang one byte output
for 8 bits{
   if ((DataOut & 0x80) == 1) // sample the bit to output - the test is TRUE if the MSbit of DataOut is a 1
     MOSI = 1;  // test TRUE, output 1
  else
    MOSI = 0;  // test FALSE, output 0

  SCK = 1;    // clock the data bit out
  delay();
  SCK = 0;

  DataOut = DataOut << 1;     Shift the data left one bit so that the next data bit in is now in the MSbit of DataOut.
}// loop to output 8 bits
The value in DataOut will change for each shift:
10010000 ; MSbit ==1 which will be output on MOSI on the first clock
0010000x ; After shift, MSbit = 0 which will be output on MOSI on the next clock - note 'x' means data shifted in, it is not used.
010000xx ; continue for 8 bits, outputting the MSbit on MOSI and clocking for each shift
10000xxx
0000xxxx
000xxxxx
00xxxxxx
0xxxxxxx
xxxxxxxx

The result is that the data 10010000 gets output on MOSI one clock at a time.

Nice.

EDIT: Note that this shows only data transmitted from master to slave on MOSI. In SPI, the slave sends data back, bit for bit on each clock cycle on MISO. Where in the pseudo-code above would you sample MISO to shift in data from the slave at the same time that you are shifting data out? How would you store it?
 
Last edited:

Thread Starter

Gajyamadake

Joined Oct 9, 2019
310
MOSI is the serial data out to the slave. For an 8-bit byte, you clock 8 times right? So.. before each clock, you set MOSI to whatever the current bit of the data is. If the data is 1001 0000 for example:
If the data is 1010 0000 for example:

1575984156370.png

Edit :
I have one question ADC ship support SPI

We can send or receive data via SPI communication but What happen if we have ADC that work on the SPI It can only transfer data ADC will never receive data back from microcontroller

If we are using SPI communication, Does ADC chip get data back from the microcontroller?
 
Last edited:

JohnInTX

Joined Jun 26, 2012
4,787
#9:
Depends on the ADC but yes you usually need bidirectional communication. You send commands to the ADC to configure it, start the conversion etc. You read the ADC to get the conversion results. The particular data and protocols needed are device dependent and covered in the data sheet.

I mentioned in #8 that so far we are only sending data to the slave and asked where you thought reading MISO should go in the example code. When you have that, you’ll have the bidirectional SPI that you need.
 
Last edited:

Thread Starter

Gajyamadake

Joined Oct 9, 2019
310
I mentioned in #8 that so far we are only sending data to the slave and asked where you thought reading MISO should go in the example code. When you have that, you’ll have the bidirectional SPI that you need.
I found one example program https://circuitdigest.com/article/i...-spi-communication-in-arduino-via-bit-banging I don't know arduino programming and I think that is not complete program to follow

Simultaneously transmit and receive a byte on the SPI.
C:
int bitBangData(int Send)  // This function transmit the data via bitbanging
{
  int Receive = 0;

  for(int i = 0; i < 8; i++)  // 8 bits in a byte
  {
     
    if ((Send & 0x80) == 1) // sample the bit to output - the test is TRUE if the MSbit of DataOut is a 1
         MOSI = 1;  // test TRUE, output 1
    else
         MOSI = 0;  // test FALSE, output 0

    SCK = 1;    // clock the data bit out
    delay();
    SCK = 0;

    Send = Send << 1;
     
  }
  return Receive;        // Return the received data
}
 

JohnInTX

Joined Jun 26, 2012
4,787
Yeah.. let’s not go searching around the web. It doesn’t hurt to study a working solution to learn how it’s done but trying to mash your approach with some other one usually just results in a mess.

So consider that the data MOSI and MISO is valid when SCK is high, where would you add code to sample MISO in the code you have? How would you store the bits as they are clocked in? Hint: the solution will look a lot like how you shift data out on MOSI.
 

JohnInTX

Joined Jun 26, 2012
4,787
It should look something like this. SPI sends and receives simultaneously so this sends the byte passed and returns the byte received.
There are several optimizations I left out to make the process easier to understand. Can you suggest ways to make it better?
Note where the shifts are. Send is shifted after the MSbit is used but Receive is shifted before the MISO bit is input. There's a reason for that.

C:
unsigned char TxRxSPI(unsigned char Send)  // This function transmits one byte and returns data received via bitbanging on SPI
{
  unsigned char Receive = 0;  // the receive register

  for(int i = 0; i < 8; i++)  // 8 bits in a byte
  {   
    if ((Send & 0x80) == 1) // sample the bit to output - the test is TRUE if the MSbit of DataOut is a 1
         MOSI = 1;  // test TRUE, output 1
    else
         MOSI = 0;  // test FALSE, output 0

    Send = Send << 1;          // shift the next bit to transmit up to MSbit of Send
    Receive = Receive << 1;  // make room for the bit input on MISO in the LSbit of Receive

    SCK = 1;    // clock the data bit out and get bit in
    delay();      // after delay, MISO is valid so read it in to Receive

    if(MISO == 1)
     Receive |= 0x01;  // MISO == 1, set the LS bit in Receive
   else
     Receive &= 0xfe; // MISO == 0, clear the LS bit in Receive

    SCK = 0;    // drop clock to complete one bit
  }// for
  return Receive;        // Return the received data
}
Have fun!
 

Thread Starter

Gajyamadake

Joined Oct 9, 2019
310
It should look something like this. SPI sends and receives simultaneously so this sends the byte passed and returns the byte received.
Thank you JohnInTX , Now I have clear idea on SPI bit banging

I will read about hardware SPI. I will continue this thread further If I don't understand anything about Hardware SPI,
 
Last edited:
Top