Mission 06 / 07
Slave Adventure
Four wires, one master, and data flowing both ways at once.
On this page
01The situation
Navigation core, sensor arrays, drives: the ship's devices have stopped listening to each other. Get master and slave talking again.
02Why this matters
When a chip needs to talk fast to the chips next to it, it uses SPI. It's the bus behind most storage and displays.
- SD cards & flashStorage chips stream their data over SPI.
- DisplaysSmall screens receive every pixel over SPI.
- RadiosWi-Fi and LoRa modules often hang off SPI.
03The idea in one picture
Think of it as: two people swapping cards across a table to a metronome only one of them (the master) controls. On every beat each hands over one card at the same moment; nobody waits for the other.
Go deeper
| Wire | Driven by | Job |
|---|---|---|
| SCK | Master | The clock: both sides shift on the same beat |
| MOSI | Master | Data from master to slave |
| MISO | Slave | Data from slave to master, at the same time |
| CS | Master | Chip Select: picks which slave is listening |
04Your mission
- OSCCONStart the clock. Any speed works.
- SSPCON0Switch the port on as the SPI master (Fosc/4).
- SSPCON1Switch the port on as the SPI slave (Fosc/4).
Hint 1
Hint 2
10 = Master at Fosc/4, 00 = Slave at Fosc/4.Show the solution
- 1Step 1 — OSCCON (0x20)Set it to
0x05(0000 0101). Switch the internal oscillator on at 4 MHz (any speed wins). - 2Step 2 — SSPCON0 (0x2D)Set it to
0x05(0000 0101). Enable the serial port as SPI Master, Fosc/4. - 3Step 3 — SSPCON1 (0x2E)Set it to
0x01(0000 0001). Enable the serial port as SPI Slave, Fosc/4. - 4Program & ExecutePress P to compile your configuration into machine code in ROM, then press E to run it. When every register matches you get Target Reached.
The same thing as a program (MOVLW loads a value into W, MOVWF copies W into a register):
MOVLW 0x05
MOVWF 0x20 ; OSCCONMOVLW 0x05
MOVWF 0x2D ; SSPCON0MOVLW 0x01
MOVWF 0x2E ; SSPCON1Bit-by-bit breakdown
OSCCON0x20= 0x05
Switch the internal oscillator on at 4 MHz (any speed wins). 0x05 = 0000 0101 = SCS0 = 1, IRCF = 10
| Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| Value | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 |
| Field | — | IRCF | SCS0 | |||||
- IRCF (bits 2:1) =
10→ 4 MHz - SCS0 (bit 0) =
1→ Internal oscillator on - Every remaining bit is
0: those bits are not needed for this level, but they must stay clear for the value to match.
SSPCON00x2D= 0x05
Enable the serial port as SPI Master, Fosc/4. 0x05 = 0000 0101 = SPEN = 1, SSPM = 10
| Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| Value | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 |
| Field | — | CKE | CKP | SSPM | SPEN | |||
- SSPM (bits 2:1) =
10→ SPI Master, Fosc/4 - SPEN (bit 0) =
1→ Serial port enabled - Every remaining bit is
0: those bits are not needed for this level, but they must stay clear for the value to match.
SSPCON10x2E= 0x01
Enable the serial port as SPI Slave, Fosc/4. 0x01 = 0000 0001 = SPEN = 1, SSPM = 00
| Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| Value | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| Field | — | CKE | CKP | SSPM | SPEN | |||
- SSPM (bits 2:1) =
00→ SPI Slave, Fosc/4 - SPEN (bit 0) =
1→ Serial port enabled - Every remaining bit is
0: those bits are not needed for this level, but they must stay clear for the value to match.
Try it: build the values
Flip the bits until each register matches the mission. It's practice only; nothing is saved.
0 of 3 registers match.
OSCCON 0x20
✗ Not yet – 2 bits differHex 0x00 Binary 0000 0000 Target 0x05 (0000 0101)
- IRCF (bits 2:1) = 00 → 1 MHz
- SCS0 (bit 0) = 0 → Internal oscillator not enabled
SSPCON0 0x2D
✗ Not yet – 2 bits differHex 0x00 Binary 0000 0000 Target 0x05 (0000 0101)
- CKE (bit 4) = 0 → Transmit edge: not part of the win value (leave 0)
- CKP (bit 3) = 0 → Clock idle level: not part of the win value (leave 0)
- SSPM (bits 2:1) = 00 → SPI Slave, Fosc/4
- SPEN (bit 0) = 0 → Serial port disabled
SSPCON1 0x2E
✗ Not yet – 1 bit differHex 0x00 Binary 0000 0000 Target 0x01 (0000 0001)
- CKE (bit 4) = 0 → Transmit edge: not part of the win value (leave 0)
- CKP (bit 3) = 0 → Clock idle level: not part of the win value (leave 0)
- SSPM (bits 2:1) = 00 → SPI Slave, Fosc/4
- SPEN (bit 0) = 0 → Serial port disabled
05How you know it worked
- 1Chip Select dropsThe master selects the slave and loads its byte into the shift register.Screenshot coming soon
- 2Both directions at onceOn every clock beat one bit leaves on MOSI and one comes back on MISO.Screenshot coming soon
- 3Bytes exchangedAfter 8 beats master and slave have swapped their bytes.TARGET REACHEDScreenshot coming soon
Simulation note
The game feeds the master's buffer itself (a repeating 0x00 → 0xFF sequence); you only set the roles.
Stuck?
- No clock, nothing movesThe master is set as a slave. SSPCON0 needs SSPM =
10. - Nobody answers on MISOTwo masters. SSPCON1 must be the slave (SSPM =
00). - Roles look right, but it's silentSPEN (bit 0) is off.
- It runs, but no Target ReachedSSPM =
11is Fosc/16. Use the Fosc/4 modes.
06Debrief
You just synced a whole ship.
SPI is how a microcontroller talks to the chips around it. The same master, slave and clock setup sits inside every SD-card driver.
// the same idea in CSSPCON0 = 0x05; // SPI master, Fosc/4SSPCON1 = 0x01; // SPI slave, Fosc/4On a real chip the same switches can sit at different bit positions; its datasheet has the map. The idea is identical.