Embedded knowledge: Basic communications protocol – SPI

Embedded_SPI_Feature
admin

Embedded knowledge:
Basic communication protocol - SPI

Share on facebook
Share on twitter
Share on linkedin

Foreword

Let’s continue with the “Embedded knowledge: Basic communication” series. Today, we are going to discuss about another common protocol: Serial Peripheral Bus or SPI.

Here are 3 blogs in “Embedded knowledge: Basic communications” series in case you’ve missed any of them:

1. Embedded knowledge: Basic communication protocol – UART.

2. Embedded knowledge: Basic communication protocol – SPI.

3. Embedded knowledge: Basic communication protocol – I2C.

In this series, I also share my working experience with these protocols.

Now, let’s get started!

Introduction

Let’s get back to Ted and Marshall who are in a conversation.

Figure 01: Ted and Marshall are in a conversation

With SPI, we still have the same principle as shown in figure 02.

Figure 02: SPI

As can be seen in the figure above, SPI tends to use more wires than UART. I will explain why we need these lines in the SPI along with the pros and cons in the next section. However, at the end of the day, no matter how many wires a protocol is using, the main purpose is still to make two or several devices talking with each other.

 

Connection

In SPI, we will have 4 signal lines:

  1. SCKL (Signal Clock)
  2. MOSI (Master Out Slave In)
  3. MISO (Master In Slave Out)
  4. CS (Chip Select)

Figure 03: 4 signal lines in SPI

SCLK – Signal Clock:

  • Unlike UART, SPI is a Synchronous protocol so it needs a clock signal to synchronize between Master and Slave while transferring data.
  • The clock signal is only generated by Master.
  • By using one more line for the clock signal, the transfer speed is pretty high in comparison with other protocol. SPI protocol itself theoretically does not define any limitation for the transferring speed and the implementation can reach over 10Mbps. However, in the production line, there are still a couple of things that need to be concerned. I will talk about this in section 2.5.

MISO – Master In Slave Out

  • The data output from Slave will go to Master on this line.

MOSI – Master Out Slave In

  • The data output from Master will go to Slave on this line.

CS – Chip Select (or SS – Slave Select)

  • Master chooses which slave to communication by pulling low that slave’s CS pin.

Basically, the simplest form of SPI will have both MISO and MOSI line, which makes SPI is a full-duplex protocol or in other words, it can send and receive data at the same time.

SPI is a Master-Slave protocol or moreover, Single Master-Slave protocol. That’s why we need the CS pin, thus, Master will pull low the CS pin of the slave it would like to communicate with. We will talk more about single master – multiple slaves in section 2.4.

Clock signal plays an important role in SPI protocol. In the SPI configuration process, there are 2 things about clock should be considered: polarity and phase. 

 

 

Clock polarity and clock phase

Clock polarity – CPOL: define the polarity of the clock.
Clock phase – CPHA: define when you would like to sample.

Figure 04: Different clock polarity and clock phase

We have 4 SPI Mode in total, all are shown in the table below

Figure 05: Different clock polarity and clock phase in SPI modes.

Some devices and sensors only support some of the SPI modes above so we have to choose the correct mode before using. The supported modes can be found in the datasheet. Overall, the SPI mode only affects the compatibility between master and slave, not the efficiency.

In addition, we also need to care about the data order (least significant bit first or most significant bit first).

 

Operation

Let’s take a look at how SPI works. In this example, I will use the SPI mode 0 (CPOL = 0, CPHA = 0) in full-duplex.

Figure 06: SPI in full duplex with CPOL = 0 and CPHA = 0

Purpose:
Master 1 wants to transfer 8 bits “1 0 1 1 0 0 1 0” to Slave and expect  8 bits “0 1 1 0 1 0 1 0 ” from slave

Pre-condition:
1. Master-CS connects with Slave-CS
2. Master-MISO connects with Slave-MISO
3. Master-MOSI connects with Slave-MOSI
4. Master-SCLK connects with Slave-SCLK
5. Slave supports SPI Mode 0 (CPOL=0, CPHA=0)

Process flow:
Step 1: Master pulls CS low to start communicating with the slave.
Step 2: Slave starts sampling data at rising edge of the clock and Master starts shifting data at falling edge of the clock. (CPOL = 0, CPHA = 0)
Step 3: After sampling all 8 bits, slave receives “1 0 1 1 0 0 1 0” from master.
Step 4: Master will continue to generate clock until slave responses if the master expects a response after sending a command through MOSI.
Step 5: Master receives all 8 bits from the slave.
Step 6: Master pulls CS line high to stop the transfer session.

Notes
In some cases, there will a delay between sending and receiving bytes (right before step 4). It is caused by the code execution time (interrupt, …) right after master finishes sending its first command. You might also encounter this while sending or reading multiple bytes through SPI and it’s called “inter-byte gap”

In full duplex mode like figure 06, the master can send and receive data at the same time. In this case, the master will shift data to the MOSI line at the clock’s falling edge and sampling data on the MISO line at the clock’s rising edge.

 

Different mode

Quad-SPI:

Overall:

Figure 07: Quad-SPI connection

  • Instead of using MISO and MOSI, we will take 2 more wires and change to a 4-bit data bi-directional bus.
  • Data transfer speed will be 4 times higher than the standard 4-wire SPI interface.
  • Often used in flash memories.

Quad-SPI operation

Figure 08: Quad-SPI operation

Here is the link to the Quad-SPI operation I’ve referenced: link.

Each command in Quad-SPI can include 5 phases: instruction, address, alternate byte, dummy, and data. Any phases can be skipped but at least 1 of them must be present.

Figure 09: 5 phase in Quad-SPI operation

  1. Instruction phase:
    8-bit instruction is sent, specifying the type of operation to be performed.
    Most flash memories can only receive instruction 1 bit at a time through DQ0.
    You can still send 2 bit at a time (through DQ0, DQ1) or 4 bit at a time (DQ0->DQ3) if the slave supports.

  2. Address phase:
    From 1 to 4 bytes address are sent, indicating the address of the operation.

  3. Alternate-bytes phase
    From 1 to 4 bytes are sent, generally to control the mode of operation.

  4. Dummy-cycles phase:
    From 1 to 31 cycles are given without any data being sent or received to allow the slave time to prepare for the data phase.
    The number of clock cycles in this phase can be configured in the register.
    At least 1 dummy cycle when using dual or quad mode.

  5. Data phase: 
    Any number of bytes can be sent to or received from slave.
    Depends on the mode we are using, data can be transfered either 1 bit at a time (DQ0, 3-wire mode), 2 bit at a time (DQ0-DQ1, dual SPI mode) or 4 bit at a time (DQ0-DQ3, quad SPI mode).

From Quad-SPI mode, by changing the number of data line (DQ0->DQ3) and the way we sampling data, there are 5 more different SPI protocol modes:

  1. 3-wire SPI mode
  2. Dual SPI mode
  3. Quad SPI mode
  4. Single data rate (SDR) mode
  5. Doule data rate (DDR) mode

3-wire SPI:

One thing can be noticed from section 2.3 is that MOSI and MISO signals are not always used at the same time. As a result, we can combine them to save 1 pin for other purposes.
In general, if your application does not need to transfer and receive data at the same time, we can switch to SPI 3-wire mode. 

Figure 10: 3-wire SPI

  • MISO and MOSI lines are mixed to a single bi-directional data line.
  • The operation is just the same with standard 4-wire mode instead of it needs time to swap from MISO to MOSI.
  • SPI now becomes half duplex.
  • Can be applied when we don’t need to transfer and receive data at the same time.

3-wire SPI operation:

Figure 11: 3-wire SPI operation

  • The 3-wire SPI operates mostly the same as the standard one (as described in section 2.3) except having a bus direction swap phase.
  • Number of the clock cycle in the swap phase can be determined in the MCU SPI-related register and must be at least 1. 

Dual-SPI:

Figure 12: Dual SPI

  • Just like the quad-SPI but only DQ0 and DQ1 bi-directional 2-bit data will be used.

Dual-SPI operation:

Figure 13: Dual SPI operation

Single data rate (SDR):

In SDR mode, the data is shifted only on one edge (either falling or rising edge). This is the default mode.
When the slave receives data in SDR mode, it has to response the data using the same edge as the master.

Double data rate (DDR):

In DDR mode, a bit is sent on both falling and rising edge expect the instruction phase. The instruction phase is always sent using one clock edge.

Figure 14: Double data rate in quad mode

 

Other type of SPI connection

Multiple slave

Figure 15: Multiple slaves 

Should have a pull-up register on the chip select line for each slave to reduce cross-talk between devices.

SPI master will pull low the selected slave’s CS pin to start communication. At this time, all other slaves’ CS pin are still in their normal state (high).

In systems with many slave devices, the MCU will need as many active-low SS outputs as the number of slaves. This architecture increases hardware and layout complexity. Therefore, daisy chain configuration

Daisy chain configuration

Figure 16: Daisy chain wiring

Figure 17: Daisy chain operation

 

Coming up next!

So we’ve just finished the second article in the Basic Communication Protocol series. In the next post, we will discuss the I2C protocol

Have fun!

 

WRITTEN BY

Trung Do

Firmware engineer, blogger and a makerholic 

Related Articles

Embedded knowledge: Basic communications protocol – UART

Embedded_01_Figure_08
admin

Embedded knowledge:
Basic communication protocol - UART

Share on facebook
Share on twitter
Share on linkedin

Foreword

Anyone who first enter to the embedded world are either taught or at least heard about the 3 most basic communication protocols: UART, SPI and I2C. These protocols, in other words, are as important as languages in human world.

Basically, different embedded hardwares (micro-controller, sensor, etc) support different ways to interact with. Some of them are only support one protocol, like people who can only speak in their mother language, while other supports several ones. Therefore, having a deep knowledge about them definitely help you a lot in building your own projects, especially if you are an embedded engineer.

Here are 3 all my blogs in “Embedded knowledge: Basic communications” series in case you’ve missed any of them:

1. Embedded knowledge: Basic communication protocol – UART.

2. Embedded knowledge: Basic communication protocol – SPI.

3. Embedded knowledge: Basic communication protocol – I2C.

In this series, I also share my working experience with these protocols.

Each section is arranged in order, includes explanation why we need to have this and that.

Now, let’s get started!

Introduction

Let’s begin with a simple case: Ted and Marshall are in a conversation.

Figure 01: Ted and Marshall are in a conversation

In the simplest case, there are 3 pre-conditions for a successful communication:

a. A or B or both are able to speak and hear.

b. A and B are speaking the same language (aka. protocol)

c. An environment for the conversation. This is air in this case.

The exact same things happen when we deal with the microcontroller. In order to transfer data between 2 devices:

a. One or both are able to transfer data (through a logic pin, antenna, …)

b. Both are using the same protocol (UART, I2C, SPI…)

c. Environment:

  • Wire: UART, I2C, SPI… . The number of wires depends on each protocol.
  • Wireless: bluetooth, wifi, NFC, …

Therefore, with UART, we will have

Figure 2: UART

Figure 02: UART

Connection

There are many ways to connect 2 microcontrollers in UART protocol themselves. Let’s take a look at some most popular.

Connection - Simplex

Figure 03: Simplex connection

  • Data transmission goes only in 1 direction.
  • Use 1 wire for data transferring (2 wires if having flow control)

Connection - Half-duplex

Figure 04: Half-duplex connection

  • Data transmission goes in both directions but not simultaneously.
  • Use 1 wire (2 wires if having flow control).
  • 1 pin will be either TX (transmit data) pin or RX (receive data) pin.
  • If flow control is enabled, it will be either CTS if its side would like to transfer data or RTS if receiving data. (We will talk about this in section 2.5)

Connection - Full-duplex

Figure 05: Full-duplex connection

  • Data transmission goes in both directions and simultaneously.
  •  Use 2 wires (4 wires if having flow control).

Notes

  • About flow control, I will explain what this is and why we need it in section 2.5
  • The most common way to set up UART is using the full-duplex without flow control.

Figure 06: Full-duplex, no flow control

Protocol

To make sure the data is correct, A and B must have to have the same 5 configures as below:

Figure 07: UART configurations

Why do we need Start bit and Stop bit?

UART stands for Universal Asynchronous Receiver/Transmitter. Asynchronous means that we are not using a clock signal to synchronize the transmission. 
→ Need another way to know when to read the data and when to stop transferring data.
→ Start bit and stop bit: these bits define the beginning and end of the data packet. Therefore, the receiving UART knows when to start reading the bits. 

Why do we need Baudrate?

When receiver detect start bit, it will start reading the incoming bits at a specified frequency called BAUD RATE (unit: bit per second) (aka sampling the data on the line with the frequency BAUD RATE)
→ Both UART have to at about the same Baudrate. If not, the data after sampling will return false value leading to wrong data.

Moreover, there is always an error rate when transferring data through UART. The baud rate between the transmitting and receiving UARTs can only differ by about 10% before the timing of bits gets too far off and cause an unacceptable error rate.

Here is an example of UART error rate corresponding to each Baudrate (picture is taken from MSP430FR userguide, pg.579)

Figure 07.1: UART Baudrate and error rate

As can be seen in the table, as Baudrate increases, the error rate is also increased. This is the trade-off between speed and efficiency you will have to accept.

Why do we need parity bit?

What if you want to have a high transfer bit but still want the received data correct? 

We will need an error detection method. By using this, we know when the data is wrong and therefore, request the TX side to re-send that data.

The parity bit is the simplest form of error detecting code and only can detect a single bit error. In the production code, we usually implement other methods like CRC, MD5,… to make sure our data is preserved.

I have another article here talking about hashing mechanism (CRC, MD5,..) in case you would like to know more.


Operation

And here is the whole communication process between A and B

Figure 08: Full UART transmission process

Purpose:
MCU 1 wants to transfer 8 bits “1 0 1 1 0 0 1 0” to MCU2

Pre-condition:
1. Transmit pin of MCU1 has to be connected with the Receive pin of MCU2.
2. Both sides has to be config as the same Start bit, Baud rate, Parity and Stop bit.

Process flow:
Step 1: MCU1 has 8bits needed to be sent out.

Step 2: MCU1 creates a full data frame with Start bit – Data – Parity – Stop bit.

Step 3: MCU1 starts generating the signal on its TX pin accordingly to the data frame. Bit width is 1/BAUDRATE.

Step 4: Right at the time MCU2 receives the falling edge on the line, it will start the clock signal to start sampling data. The clock period on MCU2 = bit width on MCU1 = 1/BAUDRATE. That’s why we have to has the same baud rate on both side or MCU2 cannot sampling at the correct frequency, leading to failure in reading data.

There are several ways to config sampling: sampled at the rising edge of the clock (as shown on the picture), sampled at the falling edge or sampled at the middle of the pulse.

Step 5: MCU2 stops the clock which is used to sampling data rafter receiving stop bit. The data will be processed after this step.

In the microcontroller, the UART peripheral will do all for us from step 2 to step 5. All we have to do is the “precondition” and step 1 (which is deciding what we want to send out). 

 

UART Bit-bang

What is UART Bit-bang?

So what if the MCU does not have enough UART module to use? or we want to use another pin for UART which is not supported by the UART peripherals. 
We have to create our own UART module, in another word, UART bit-bang.

In UART bit-bang, we have to do all step from 1 to 5 (section 2.3) by ourselves, from either 1 or both sides of 2 MCUs.

Advantages:

  • Can use other pins supporting GPIO.
  • Fully-control, actually we can do some modifications to make UART protocol more reliable. Considering the case that we are able to change the duration of start-bit from 1 bit to more than 1 bit. This is because sometimes the data line is accidentally pulled to low by some disturbance, long wiring, etc… By doing this we can make it more stable to the disturbance.

Disadvantages:

  • Complicated and can have potential bugs.
 

Flow control

What is flow control ?

Let’s consider about another case:

MCU1 transfers data to MCU2. However, MCU2’s processing time is slower than MCU1s.

At some point, MCU2 cannot keep up with this anymore. It either processes data or somehow empty its receive buffer before continuing to receive data. If not, it can be ended up by losing data while MCU1 continues to send out the message while MCU2 are busy with the old data.
→ Using flow control to handle this issue.

Flow control is the method to handle the UART communication between a fast and slow device without the risk of losing data.
MCU2 will use flow-control to create a signal back to MCU1 to stop/pause or resume the transmission.

There are severals way to implement flow-control to our UART protocol, either by using hardware flow-control or software flow-control.

Hardware flow control

Let’s take a look at how we config the hardware flow control in figure 09 and 10.

Figure 09: UART flow control config

Figure 10: UART flow control

A would like to transfer data to B, before sending data, A will check A_CTS (aka B_RTS). If that line is low → B is asserted it → B is still ready to receive more data → A continue to send.

Whenever B want to stop receiving data to process something else, it will de-assert the B_RTS (A_CTS) → A will check that line and stop sending.

Software flow control

Instead of using additional wires for flow control, software flow control start/stop by sending special flow control character on the TX/RX line.

The special flow control characters are usually the ASCII code XON and XOFF (0x11 and 0x13).

When A send XOFF to B, B will stop the transmission until receiving XON from A.

Coming up next!

So we’ve just finished the first article in the Basic Communication Protocol series. We will talk about the SPI protocol in the next article.

Have fun!

WRITTEN BY

Trung Do

Firmware engineer, blogger and a makerholic 

Related Articles

Make a wireless charging dock for iPhone and Apple watch

02
admin

MAKE A WIRELESS CHARGING DOCK FOR IPHONE AND APPLE WATCH

Share on facebook
Share on twitter
Share on linkedin

Foreword

I need to have a station to charge my phone and watch at the same time. It needs to be neat as much as possible because I want to place it on my working desk. 

I realize that I can make use of the Nightstand mode on apple watch to turn it into a clock. As a result, I will have a charging station, where I can read all notifications without touching my phone, and a clock to see the time whenever I want. 

Now, let’s get started!

1. Design

Here are my 3D design for the charging station:

2. Materials and printed parts

Please find in the list below all the materials needed for this project:

Printed parts:

You can find all the printed parts here: https://www.thingiverse.com/thing:2936442

  • 1x Part_1_Charge_Wire or 1x Part_1_Charge_Writeless (depends on your need).
  • 1x Part_2
  • 1x Part_3

You only need to print with 0.2mm/layer and 5% infill for the part_1. It will take approximately 3h30m to print it.

3. Print settings

You can print multiple parts at the same times without the need for support. Here are my print settings for your reference:
  • Material: PLA
  • Support: No
  • Resolution: 0.2mm/layer
  • Infill: 20%
  • Temperature: 190 (C)

4. Assemble

  • Print all parts and assemble as in the picture below.

5. Result

And here is what we got after all these steps:

With my design, you are able to hide all spare wires in the bottom of the station.

It took me around 4 hours to print all these parts and the result is absolutely satisfied.

Have fun!

WRITTEN BY

Trung Do

Firmware engineer, blogger and a makerholic 

Related Articles

Make an SD/microSD card holder using 3D printer

pic01
admin

MAKE AN SD/MICRO-SD CARD HOLDER USING 3D PRINTER

Share on facebook
Share on twitter
Share on linkedin

Foreword

SD and microSD cards are commonly using nowadays for many things from cameras to miniPCs but how to keep all of them in place is such a pain with most of us. Therefore, I came up with a design to solve this problem. Now, let’s get started!

1. Design

Here is my final design.

2. Materials and printed parts

 Please find in the list below all the materials needed for this project:

Materials:

  • 1x Transparent acrylic (WxLxH = 111×73.5x2mm)
  • 1x Black acrylic (WxLxH = 114.5×75.5x2mm)

Printed parts:

You can find all the printed parts here: https://www.thingiverse.com/thing:2911250

  • 1x Part_01
  • 2x Part_02
  • 1x Part_03
  • 1x Part_04
  • 1x Part_05
  • 1x Part_06

3. Print settings

You can print multiple parts at the same times without the need for support. Here are my print settings for your reference:
  • Material: PLA
  • Support: No
  • Resolution: 0.2mm/layer
  • Infill: 20%
  • Temperature: 190 (C)

4. Assemble

  • Print all parts and assemble as in the picture below.

5. Result

And here is what we got after all these steps:

Let’s take a look with this video below

With this design, your SD and micro SD cards will be kept safely. One of the cool features is you have the place to label each of them. 

This box can keep up to 6 SD cards and 5 micro SD cards and you can hold it in your hand. 

Have fun!

WRITTEN BY

Trung Do

Firmware engineer, blogger and a makerholic 

Related Articles

Light up your 3D printer

16
admin

Light up your 3D printer

Share on facebook
Share on twitter
Share on linkedin

Foreword

Let’s continue with the upgrades series for the Kossel 3D printer. Today I decided to light up my delta by using LED strips. Therefore, it will make my print job overnight be easier.

1. Design

Here is the draft design for this project. First of all, the frames, which are marked as blue on the picture, are 3D printed. The all LED strips are going to be attached on them. In addition, our frame will have a specify angle to make sure all light directions will point directly to the center of the heatbed.

2. Materials and printed parts

Please find in the list below all the materials needed for this project:

Materials:

  • 6x LED stripes (12VDC, width: 1cm, length: 15cm each)
  • M3x10mm bolts
  • M3 T-nuts Wires

Printed parts: 

You can find all the printed parts here: www.thingiverse.com/thing:2943798

  • 6x Part01
  • 6x Part02
  • 6x Part02_Mirror

Part 01

Part 02

Part 02

Assemble

3. Print settings

You can print multiple parts at the same times without the need for support. Here are my print settings for your reference:
  • Material: PLA
  • Support: No
  • Resolution: 0.2mm/layer
  • Infill: 20%
  • Temperature: 190 (C)

4. Assemble

  • Step 01: Using 12V LED strip (1cm in width) and cut it into 6 pieces (15cm each)

  • Step 02: Soldering all 6 LED strips.

  • Step 03: Wire out all LED strips.

  • Step 04: Make a small board to attach all LED strips, 12VDC power supply and ON/OFF switch.

  • Step 04 (cont.): Make a small board to attach all LED strips, 12VDC power supply and ON/OFF switch.

  • Step 05: Connect and test all LED strips
  • Step 06: Using a piece of tape to cover all circuit board

  • Step 07: Use M3 T-nut and bolts to attach the board to the frame (below the heated bed).

  • Step 08: Attach the board to the frame (below the heated bed).

  • Step 09: Print 6xPart01, 6xPart02 and 6xPart02_Mirror to make 6 LED strips holder.

  • Step 10: Using super glue to attach LED stripe into LED stripe holder (Part01). Remember to attach the Part02 and Part02_Mirror to Part02 before doing this step.

  • Step 11: Attach all LED strips to 3d printer frame with M3 T-Nuts.

  • Step 11 (cont.): Here is what we have after installing all of LED strips

  • Step 12: Remove the heated bed and connect all LED stripes to the small board we’ve made before. For the 12VDC input, you can use directly from 3d printer power supply.

  • Step 13: For the ON/OFF switch, you can place it in front.

5. Result

And here is what we got after all these steps:

Let’s take a look with this video below

If you want to cover your 3D printer like I do, please refer a tutorial here: How to enclose your Kossel 3D printer

Have fun!

WRITTEN BY

Trung Do

Firmware engineer, blogger and a makerholic 

Related Articles