Lab 7
I2C and SPI
Talk to three parts on two buses, working from their datasheets: read the clock's time registers by hand before you use any library, show the time on a display, and read an analog sensor through an ADC. The logic analyser shows you what really went over the wires.
Modules this lab uses
What you need
- Your station's board, booted to Linux
- From your station's parts: the DS3231 real-time clock, the SSD1306 OLED display, the MCP3008 ADC, the 10 kΩ potentiometer and the analog sensor, with the breadboard and jumper wires
- Each part's datasheet
- The bench logic analyser
Before you start
Read the rules that keep the board alive. Power every part from a 3.3 V pin so its signals stay at the header's 3.3 V, and wire with the board unplugged.
The Das Frite GPIO pinout shows which header pins carry I2C and SPI: select a bus in its legend to relabel the header. Pins 3, 5 and 6 carry your serial console.
The Solitude GPIO pinout shows which header pins carry I2C and SPI: select a bus in its legend to relabel the header.
Steps: I2C
- Enable the I2C bus on header pins 27 (SDA) and 28 (SCL) with
sudo ldto enable H40P_I2C_1, as in lab 6. - With the board unplugged, wire the DS3231 and the SSD1306 to pins 27 and 28, to 3.3 V and to ground, and clip the logic analyser to pins 27 and 28 and its ground to a ground pin on the header. Then boot and enable the bus again.
- Find both devices with
i2cdetectfromi2c-tools. - Using the DS3231 datasheet's register map, read the time registers by hand with
i2cgetori2cdump, and decode them into a time. Capture the transaction on the logic analyser and decode it. - Drive the OLED from a program of your own, and show the time you read from the clock.
Steps: SPI
- Enable the SPI bus with a
spidevdevice usingsudo ldto enable H40P_SPI_0_1CS_DEV, and check that aspidevdevice appears in/dev. - With the board unplugged, wire the MCP3008 to header pins 19 (MOSI to its DIN), 21 (MISO to its DOUT), 23 (SCLK to its CLK) and 24 (CS0 to its CS), its VDD and VREF pins to 3.3 V, and its AGND and DGND pins to ground; move the logic analyser's channels to pins 19, 21, 23 and 24, its ground staying on a ground pin. Connect the potentiometer's two ends to 3.3 V and ground and its wiper to one input, and the sensor to another input: a thermistor or light sensor is a resistor, so wire it as a voltage divider with the station's 10 kΩ resistor, sensor and resistor in series between 3.3 V and ground, and their midpoint to the input; boot and enable the bus again.
- From the datasheet, work out the SPI mode, the bytes a conversion needs and the fastest clock the part allows at 3.3 V (it is lower than at 5 V); set the
spidevspeed at or below about 1 MHz, then read both inputs throughspidevfrom a program of your own. - Capture one conversion on the logic analyser and decode it.
- Calibrate the sensor: take readings at known conditions, and turn the ADC's counts into the sensor's unit.
What to measure
- The time read from the DS3231's registers, and the same transaction as the logic analyser decoded it.
- The potentiometer's reading across its travel, and the sensor's calibrated reading.
What you hand in
- Decoded I2C and SPI captures.
- The time on the OLED (a photo).
- A calibrated sensor reading, with how you calibrated it.
- Your own short report: what you did, what you measured, and one problem you met and how you solved it.
If it goes wrong
If i2cdetect finds nothing, check that the bus's overlay is applied, that the part has 3.3 V and ground, and the two wires on the logic analyser. If the board stops booting, work down when it will not boot on your bench page.