Lecture10_SerialCommunication
Lecture10_SerialCommunication
© 2021 Arm
Learning Objectives
At the end of this lecture, you should be able to:
• Outline the concepts of both serial and parallel communication and give examples of
their applications.
• Explain the difference between synchronous and asynchronous serial communication.
• Compare serial and parallel communication including their advantages and
disadvantages.
• Outline the difference between synchronous half-duplex and full-duplex serial buses
• Describe UART and its communication protocol.
• Describe SPI communication protocol.
• Describe I2C communication protocol.
2 © 2021 Arm
Overview
• Serial communications
• Concepts
• Tools
• Software: polling, interrupts, and buffering
• Protocols:
• UART
• SPI
• I2C
3 © 2021 Arm
Why Communicate Serially?
• Native word size is multi-bit (8, 16, 32, etc.)
• Often it’s not feasible to support sending all the word’s bits at the same time
• Cost and weight: more wires needed, larger connectors needed
• Mechanical reliability: more wires => more connector contacts to fail
• Timing Complexity: some bits may arrive later than others due to variations in capacitance and
resistance across conductors
• Circuit complexity and power: may not want to have 16 different radio transmitters + receivers in the
system
4 © 2021 Arm
Example System: Voyager Spacecraft
• Launched in 1977
• Constraints: Reliability, power, size, weight, reliability, reliability, etc.
• “Uplink communications are via S-band (16-bits/sec command rate) while an X-band transmitter provides
downlink telemetry at 160 bits/sec normally and 1.4kbps for playback of high-rate plasma wave data. All
data are transmitted from and received at the spacecraft via the 3.7 meters high-gain antenna (HGA).”
http://voyager.jpl.nasa.gov/spacecraft/index.html
• Uplink – to spacecraft
• Downlink – from spacecraft
5 © 2021 Arm
Example System
6 © 2021 Arm
Parallel Buses
• All devices use buses to share data, read, and write signals
• MCU uses individual select lines to address each peripheral
• MCU requires fewer pins for data, but still one per data bit
• MCU can communicate with only one peripheral at a time
7 © 2021 Arm
Synchronous Serial Data Transmission
Clock
Serial Data
Data Sampling Time at Receiver
• Use shift registers and a clock signal to convert between serial and parallel formats
• Synchronous: an explicit clock signal is along with the data signal
8 © 2021 Arm
Synchronous Full-Duplex Serial Data Bus
• Now can use two serial data lines - one for reading, one for writing.
• Allows simultaneous send and receive full-duplex communication
9 © 2021 Arm
Synchronous Half-Duplex Serial Data Bus
10 © 2021 Arm
Asynchronous Serial Communication
Data bits
Start bit Stop bit
Time Zero
Tbit*1.5
Tbit*2.5
Tbit*3.5
Tbit*4.5
Tbit*5.5
Tbit*6.5
Tbit*7.5
Tbit*8.5
Tbit*9.5
Data Sampling
Time at Receiver
12 © 2021 Arm
Error Detection
• Can send additional information to verify data was received correctly
• Need to specify which parity to expect: even, odd or none.
• Parity bit is set so that total number of “1” bits in data and parity is even (for even
parity) or odd (for odd parity)
• 01110111 has 6 “1” bits, so parity bit will be 1 for odd parity, 0 for even parity
• 01100111 has 5 “1” bits, so parity bit will be 0 for odd parity, 1 for even parity
• Single parity bit detects if 1, 3, 5, 7 or 9 bits are corrupted, but doesn’t detect an even
number of corrupted bits
• Stronger error detection codes (e.g. Cyclic Redundancy Check) exist and use multiple
bits (e.g. 8, 16), and can detect many more corruptions.
• Used for CAN, USB, Ethernet, Bluetooth, etc.
13 © 2021 Arm
Tools for Serial Communications Development
• Tedious and slow to debug serial protocols • Saelae 8-Channel Logic Analyzer
with just an oscilloscope • $150 (www.saelae.com)
• Plugs into PC’s USB port
• Instead use a logic analyzer to decode bus • Decodes SPI, asynchronous serial, I2C, 1-Wire,
traffic CAN, etc.
• Worth its weight in gold! • Build your own: with Logic Sniffer or
related open-source project
14 © 2021 Arm
Software Structure –
Handling asynchronous
Communication
© 2021 Arm
Software Structure
• Communication is asynchronous to program
• Don’t know what code the program will be executing …
▪ when the next item arrives
▪ when current outgoing item completes transmission
▪ when an error occurs
• Need to synchronize between program and serial communication interface somehow
• Options
• Polling
▪ Wait until data is available
▪ Simple but inefficient of processor time
• Interrupt
▪ CPU interrupts program when data is available
▪ Efficient, but more complex
16 © 2021 Arm
Serial Communications and Interrupts
Main Program or
• Want to provide multiple threads of control in the other threads
program
• Main program (and subroutines it calls)
send_string get_string
• Transmit ISR – executes when serial interface is ready to send
another character
• Receive ISR – executes when serial interface receives a
character
• Error ISR(s) – execute if an error occurs
17 © 2021 Arm
Code to Implement Queues newer
older
data data
• Enqueue at tail: tail is the index of the next free entry
• Dequeue from head: head is the index of the item to remove
• Queue size is initialized and stored in size
• One queue per direction read data write data
• tx ISR unloads tx_q from head to tail
• rx ISR loads rx_q
• Other threads (e.g. main) load tx_q and unload rx_q send_string get_string
18 © 2021 Arm
Defining the Queues
typedef struct {
uint8_t *data; //!< Array of data, stored on the heap.
uint32_t head; //!< Index in the array of the oldest element.
uint32_t tail; //!< Index in the array of the youngest element.
uint32_t size; //!< Size of the data array.
} Queue;
19 © 2021 Arm
Initialization and Status Inquiries
int queue_init(Queue *queue, uint32_t size) {
queue->data = (uint8_t*)malloc(sizeof(uint8_t) * size);
queue->head = 0;
queue->tail = 0;
queue->size = size;
queue_enqueue(…, c)
• Receiving data:
queue_dequeue(…, &c)
22 © 2021 Arm
Software Structure –
Parsing Messages
© 2021 Arm
Decoding Messages
• Two types of messages
• Actual binary data sent
– First identify message type
– Second, based on this message type, copy binary data from message fields into variables
▪ May need to use pointers and casting to get code to translate formats correctly and safely
• ASCII text characters representing data sent
▪ First identify message type
▪ Second, based on this message type, translate (parse) the data from the ASCII message format into a binary format
▪ Third, copy the binary data into variables
24 © 2021 Arm
Example Binary Serial Data: TSIP
25 © 2021 Arm
Example ASCII Serial Data: NMEA-0183
$IDMSG,D1,D2,D3,D4,…,Dn*CS\r\n
• $ denotes the start of a message
• ID is a two letter mnemonic to describe the source of data, e.g. GP signifies GPS
• MSG is a three letter mnemonic to describe the message content.
• Commas are used to delaminate the data fields.
• Dn represents each of the data fields.
• * is used to separate the data from the checksum.
• CS contains two ASCII characters representing the hex value of the checksum.
• \r\n is the carriage return character followed by the new line character to denote the
end of a message.
26 © 2021 Arm
State Machine for Parsing NMEA-0183
Any char. except *, \r or \n
Start $ Append char to buf.
Append char to buf. Talker + Inc. counter
*, \r or \n, Sentence
non-text, or Type
buf==$SDDBT, $VWVHW, or $YXXDR
counter>6 Enqueue all chars. from buf
/r or /n
Sentence
Body Any char. except *
Enqueue char
*
Enqueue char
Checksum
1
Any char.
Save as checksum1
Checksum
2
Any char.
27 © 2021 Arm Save as checksum2
Parsing
switch (parser_state) {
case TALKER_SENTENCE_TYPE:
switch (msg[i]) {
‘*’:
‘\r’:
‘\n’:
parser_state = START;
break;
default:
if (Is_Not_Character(msg[i]) || n>6) {
parser_state = START;
} else {
buf[n++] = msg[i];
}
break;
}
if ((n==6) & … ){
parser_state = SENTENCE_BODY;
}
break;
case SENTENCE_BODY:
break;
28 © 2021 Arm
Asynchronous serial
(UART)
Communications
© 2021 Arm
Transmitter Basics
Data
bits
Data Sampling
Time Zero
Time at Receiver
Tbit
Tbit
Tbit
Tbit
Tbit
Tbit
Tbit
Tbit
Tbit
Tbit
Tbit
• If no data to send, keep sending 1 (stop bit) – idle line
• When there is a data word to send
• Send a 0 (start bit) to indicate the start of a word
• Send each data bit in the word (use a shift register for the transmit buffer)
• Send a 1 (stop bit) to indicate the end of the word
30 © 2021 Arm
Receiver Basics
Data
bits
Data Sampling
Zero
Time
Tbit*10.5
Tbit*1.5
Tbit*2.5
Tbit*3.5
Tbit*4.5
Tbit*5.5
Tbit*6.5
Tbit*7.5
Tbit*8.5
Tbit*9.5
Time at
Receiver
31 © 2021 Arm
For this to work…
• Transmitter and receiver must agree on several things (protocol)
• Order of data bits
• Number of data bits
• What a start bit is (1 or 0)
• What a stop bit is (1 or 0)
• How long a bit lasts
▪ Transmitter and receiver clocks must be reasonably close, since the only timing reference is the start of the start bit
32 © 2021 Arm
Input Data Oversampling
33 © 2021 Arm
Baud Rate
• Need to divide high frequency clock down to desired baud rate * oversampling factor
• Example
• 24MHz -> 4800 baud with 16x oversampling
• Division factor = 24E6/(4800*16) = 312.5. Must round to closest integer value ( 312 or 313), will have a
slight frequency error.
34 © 2021 Arm
Using the UART
• When can we transmit? • When can we receive a byte?
• Transmit peripheral must be ready for data • Receive peripheral must have data
• Can poll the status register • Can poll the status register
• Or we can use an interrupt, in which case we • Or we can use an interrupt, and again we will
will need to queue up data need to queue the data
35 © 2021 Arm
Software for Polled Serial Comm.
void test_polled() {
uart_init(9600);
uart_enable();
while(1) {
uart_tx(uart_rx()); // echoes the received character back
}
}
36 © 2021 Arm
Example Receiver: Display Data on LCD
line = col = 0;
while (1) {
c = uart_rx();
lcd_set_cursor(col, line);
lcd_put_char(c);
col++;
if (col > 7) {
col = 0;
line++;
if (line > 1) {
line = 0;
}
}
}
37 © 2021 Arm
Software for Interrupt-Driven Serial Comm.
• Use interrupts
38 © 2021 Arm
Interrupt Handler
Queue rx_queue;
void uart_rx_isr(uint8_t rx) {
// Store the received character
queue_enqueue(&rx_queue, rx);
}
int main() {
queue_init(&rx_queue, 128);
uart_init(9600);
uart_set_rx_callback(uart_rx_isr);
uart_enable();
…
}
39 © 2021 Arm
USB to UART Interface
• PCs haven’t had external asynchronous serial interfaces for a while, so how do we
communicate with a UART? USB UART
TX RX
D+ / D- USB to
PC UART MCU
bridge
• USB to UART interface RX TX
• USB connection to PC
• Logic level (0-3.3V) to microcontroller’s UART (not RS232 voltage levels)
• USB01A USB to serial adapter
• http://www.pololu.com/catalog/product/391
• Can also supply 5V, 3.3V from USB
40 © 2021 Arm
Building on Asynchronous Comm.
• Problem #1
• Logic-level signals (0 to 1.65V, 1.65V to 3.3V) are sensitive to noise and signal degradation
• Problem #2
• Point-to-point topology does not support a large number of nodes well
▪ Need a dedicated wire to send information from one device to another
▪ Need a UART channel for each device the MCU needs to talk to
▪ Single transmitter, single receiver per data wire
41 © 2021 Arm
Solution to Noise: Higher Voltages
• Use higher voltages to improve noise margin:
+3 V to +15 V, -3 V to -15 V
• Example IC (Maxim MAX3232) uses charge pumps to generate higher voltages from
3.3V supply rail
42 © 2021 Arm
Solution to Noise: Differential Signaling
43 © 2021 Arm
Solutions to Poor Scaling
• Approaches
• Allow one transmitter to drive multiple receivers (multi-drop)
• Connect all transmitters and all receivers to same data line (multi-point network). Need to add a
medium access control technique so all nodes can share the wire
• Example Protocols
• RS-232: higher voltages, point-to-point
• RS-422: higher voltages, differential data transmission, multi-drop
• RS-485: higher voltages, multi-point
44 © 2021 Arm
SPI Communications
© 2021 Arm
Hardware Architecture
• All chips share bus signals
• Clock SCK
• Data lines MOSI (master out, slave in) and MISO
(master in, slave out)
46 © 2021 Arm
Serial Data Transmission
• Use shift registers and a clock signal to convert between serial and parallel formats
• Synchronous: an explicit clock signal is along with the data signal
47 © 2021 Arm
SPI Example: Secure Digital Card Access
• SD cards have two CMD / CLK /
GND VDD SCLK
communication modes DAT3 / DI GND DAT0/
• Native 4-bit CS DO
DAT2 /
• Legacy SPI 1-bit X DAT1/
• VDD from 2.7 V to 3.6 V X
• CS: Chip Select (active-LOW)
48 © 2021 Arm
I2C Communications
© 2021 Arm
I2C Bus Overview
• “Inter-Integrated Circuit” bus
• Multiple devices connected by a shared serial bus
• Bus is typically controlled by master device, subordinates respond when addressed
• I2C bus has two signal lines
• SCL: Serial clock
• SDA: Serial data
• Full details available in “The I2C-bus Specification”
50 © 2021 Arm
I2C Bus Connections
51 © 2021 Arm
Master Writing Data to Subordinate
Start
ACK
Write ACK
Address Data
Repeated
Start
52 © 2021 Arm
Master Reading Data from Subordinate
SDA
SCL
Start Stop
ACK
Read ACK NACK
Address Data Data
53 © 2021 Arm
I2C Addressing
• Each device (IC) has seven-bit address
• Different types of device have different default addresses
• Sometimes can select a secondary default address by tying a device pin to a different logic level
54 © 2021 Arm
Enabling i2c
void temperature_init(void) {
i2c_init();
i2c_enable();
}
void temperature_enable(void) {
// Start conversion.
i2c_start();
i2c_tx(subordinate_ADDRESS | WRITE);
i2c_tx(START_CONVERT_T);
i2c_stop();
}
55 © 2021 Arm
Reading 12 bits from a temperature sensor
float temperature_read(void) {
short temp;
i2c_start();
i2c_tx(subordinate_ADDRESS | WRITE);
i2c_tx(READ_TEMPERATURE);
i2c_start();
i2c_tx(subordinate_ADDRESS | READ);
temp = i2c_rx() << 8;
i2c_ack();
temp |= i2c_rx();
i2c_nack();
i2c_stop();
// Sign extend from 16-bit to 12-bit.
temp >>= 4;
// Convert from fixed-point to floating point.
return temp / (float)16;
56
} © 2021 Arm
PROTOCOL COMPARISON
57 © 2021 Arm
Factors to Consider
• How fast can the data get through?
• Depends on raw bit rate, protocol overhead in packet
• How many hardware signals do we need?
• May need clock line, chip select lines, etc.
• How do we connect multiple devices (topology)?
• Dedicated link and hardware per device - point-to-point
• One bus for manager transmit/subordinate receive, one bus for subordinate transmit/manager receive
• All transmitters and receivers connected to same bus – multi-point
58 © 2021 Arm
Protocol Trade-Offs
Protocol Speed Signals Req. for Bidirectional Device Addressing Topology
Communication with N devices
UART (Point to Fast – Tens of Mbit/s 2*N (TxD, RxD) None Point-to-point full
Point) duplex
UART Fast – Tens of Mbit/s 2 (TxD, RxD) Added by user in Multi-drop
(Multi-drop) software
SPI Fast – Tens of Mbit/s 3+N for SCLK, MOSI, MISO, and Hardware chip select Multi-point
one SS per device signal per device full-duplex,
multi-drop
half-duplex buses
I2C Moderate – 100kbit/s, 400 2 (SCL, SDA) In packet Multi-point
kbit/s, 1Mbit/s, 3.4Mbit/s. half-duplex bus
Packet overhead.
59 © 2021 Arm
The Arm trademarks featured in this presentation are registered
trademarks or trademarks of Arm Limited (or its subsidiaries) in
the US and/or elsewhere. All rights reserved. All other marks
featured may be trademarks of their respective owners.
www.arm.com/company/policies/trademarks
© 2021 Arm