class: title, smokescreen, shelf, bottom, no-footer background-image: url(images/spi_block.jpg) # 181U Spring 2020 ### Hardware Communication --- layout: true .footer[ - Geoffrey Brown, 2020 - 181U ] <style> h1 { border-bottom: 8px solid rgb(32,67,143); border-radius: 2px; width: 90%; } .smokescreen h1 { border-bottom: none; } .small.remark-slide-content.compact {font-size:1.2rem} .smaller.remark-slide-content.compact {font-size:1.1rem} .small-code.remark-slide-content.compact code {font-size:1.0rem} .very-small-code.remark-slide-content.compact code {font-size:0.9rem} .line-numbers{ /* Set "line-numbers-counter" to 0 */ counter-reset: line-numbers-counter; } .line-numbers .remark-code-line::before { /* Increment "line-numbers-counter" by 1 */ counter-increment: line-numbers-counter; content: counter(line-numbers-counter); text-align: right; width: 20px; border-right: 1px solid #aaa; display: inline-block; margin-right: 10px; padding: 0 5px; } </style> --- class: compact # Agenda * Serial - Examples * SPI - Examples * I2C - Examples * Analog --- class: compact # Serial Protocol ![](images/serial-topology.png# w-40pct fr) * Oldest protocol but still widely used. * Depends upon local clocks to decode digital waveform * Used for - UART (in lab, the serial interface is through a UART) - GPS receivers - Cell phone modules ![](images/space.png# w-20pct) ![](images/serial-frame.png# w-60pct) --- class: compact # Typical Configuration of Serial Device ![](images/space.png# w-30pct) ![](images/uart-wiring.png# w-40pct) --- class: compact # Decoding Serial Protocol ![](images/serial-decoding.png# w-50pct fr) * Sender and Receiver each have local clocks that are within ~2% * Sender and Receiver programmed to use the same "baud rate" (9600-115200 baud) * Sender transmits a frame, making transitions at bit boundaries - frame has start bit (0), 8 bits, at least one stop bit (1) * Receiver samples the input signal looking for a start bit - after seeing start bit, skip 1.5 baud times to bit 0 - then skip 1 baud time for each bit --- class: compact # Serial Driver Software * Serial (UART) hardware typically has - a send buffer - a receive buffer - a status register - a configuration register * Driver - configures baud rate and protocol (configuration register) - sending - write one byte to send buffer - wait for byte to be transmitted (check status register) - receiving - wait for byte to be received - read byte from receive buffer --- class: compact # Serial Drivers (cont.) * Two types of drivers - Polling -- busy waiting. This is **very** inefficient - Interrupt driven -- interrupt handler keeps uart busy from queues fed/emptied by OS ![](images/space.png# w-20pct) ![](images/interrupt-queues.png# w-60pct) --- class: very-small-code,compact,hljs-tomorrow-night-eighties,line-numbers,col-2 # UART Interrupt Handler ```C void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { uint8_t data; // buffer the data (or toss it if there's no room // Flow control will prevent this data = USART_ReceiveData(USART1) & 0xff; if (!Enqueue(&UART1_RXq, data)) RxOverflow = 1; } ``` <br> ```C if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET) { uint8_t data; /* Write one byte to the transmit data register */ if (Dequeue(&UART1_TXq, &data)){ USART_SendData(USART1, data); } else { // if we have nothing to send, // disable the interrupt // and wait for a kick USART_ITConfig(USART1, USART_IT_TXE, DISABLE); TxPrimed = 0; } } } ``` --- class: very-small-code,compact,hljs-tomorrow-night-eighties,line-numbers # Interrupt Driven UART User Code ![](images/circular-queue.png# w-50pct fr) ```C int getchar(void) { uint8_t data; while (!Dequeue(&UART1_RXq, &data)); return data; } int putchar(int c) { while (!Enqueue(&UART1_TXq, c)); if (!TxPrimed) { TxPrimed = 1; USART_ITConfig(USART1, USART_IT_TXE, ENABLE); } } ``` --- class: compact # SPI ![](images/spi-topology.png# w-40pct fr) * SPI is a point-to-point *synchronous* protocol with a single *master* and one or more *slaves* * In contrast, the serial protocol is point-to-point *asynchronous* (but with a specified time base) * Signals: - SCK : clock from master to slave - MOSI : data from master to slave ("Master Out Slave In") - MISO : data from slave to master ("Slave Out Master In") - SS : slave select (one for each slave) --- class: compact # SPI Logical Architecture ![](images/space.png# w-20pct) ![](images/spi-logical.png# w-60pct) * On every clock event (typically 0->1 transition), the Master and Slave registers are "shifted" `master[0],master[1:7],slave[0],slave[1:7] = slave[7],master[0:6],master[7],slave[0:6]` --- class: compact # SPI Protocol ![](images/space.png# w-30pct) ![](images/spi-logical.png# w-40pct) ![](images/space.png# w-20pct) ![](images/spi-timing.png# w-60pct) --- class: compact # SPI Example -- serial EEPROM (memory) ![](images/eeprom-pinout.png# w-20pct) ![](images/space.png# 40-pct) ![](images/eeprom-read-status.png# w-30pct) * SPI protocol implements byte (or word) transfer * Every device has a message protocol implemented on top of this * For example, with serial eproms, the master sends a command followed by 0xFF and the slave responds with a value | Instruction | Description | Code | | -- | -- | -- | | WRSR | Write Status Register | 0x01 | | WRITE | Write Data | 0x02 | | READ | Read Data | 0x03 | | RDSR | Read Status Register | 0x05 | --- class: compact # SPI Example -- color LCD display ![](images/space.png# w-30pct) ![](images/lcd-model.png# w-40pct) --- class: compact # SPI Example -- SD Card ![](images/space.png# w-30pct) ![](images/sd-card.png# w-40pct) --- class: compact # SPI Example -- SD Card Transactions ![](images/sd-transactions.png# w-50pct fr) * CMD0 : Reset the SD card * CMD1 : Initialize the card * CMD13 : Request card status * CMD16 : Set block length * CMD17 : Read single block * CMD24 : Write single block --- class: compact # SPI Example -- Display/SD card reader ![](images/space.png# w-30pct) ![](images/display-sd-module.png# w-40pct) --- class: compact # I2C -- 2 wire broadcast bus ![](images/space.png# w-20pct) ![](images/I2C-configuration.png# w-60pct) --- class: compact # I2C -- transactions ![](images/space.png# w-20pct) ![](images/i2c-transactions.png# w-60pct) --- class: compact # I2C Example -- Wii Nunchuck ![](images/nunchuck-drawing.png# w-40pct) ![](images/space.png# w-2-12th) ![](images/nunchuck-data.png# w-40pct) --- class: compact # Analog Signals (digital <-> voltage) * Analog to Digital Converter (ADC) : samples analog signal an produces digital representation * Digital to Analog Converter (DAC) : converts digital representation into analog voltage * These may be integral to processor (e.g. STM32L476) or external devices * Frequently, the conversion must be "triggered" at regular intervals (for example sampling a continuous signal or converting an audio file to an analog signal). * Example architecture of a DAC channel: ![](images/space.png# w-30pct) ![](images/dac-channel.png# w-40pct) --- class: compact # Analog Conversion -- Successive approximation ![](images/successive-approx.png# w-50pct) ![](images/space.png# w-1-12th) ![](images/sample-hold.png# w-40pct) --- class: compact # Analog to Digital Converter Example * STM32 ADC is complicated - multiple input sources including internal references - mulitple trigger conditions - complex programming ![](images/space.png# w-30pct) ![](images/adc-architecture.png# w-40pct) --- class: compact # Summary * Common hardware communication protocols - Serial (asynchronous point-to-point) - SPI (synchronous point-to-point) - I2C (synchronous master/slave bus)