Mission 05 / 07
Byte Buster
Reopen a dead serial line: one wire out, one wire in.
On this page
01The situation
An incoming craft is calling for docking. Nobody answers, because the station's serial line is dead. Reopen it before the signal fades.
02Why this matters
UART is the first thing an engineer connects on a brand-new board. If you can talk over UART, you can debug anything.
- Debug consoleEvery "printf" from a microcontroller travels over UART.
- GPS & BluetoothMost plug-in modules talk to the main chip over UART.
- Serial MonitorThe Arduino Serial Monitor? That's UART.
03The idea in one picture
Think of it as: two people reading aloud to each other at a pace they agreed in advance, with no metronome between them. Each can talk (TX) and listen (RX) at the same time, but a listener who isn't paying attention misses the words.
Go deeper
UART is asynchronous: no clock wire is shared, so both ends agree on the speed (the baud rate) beforehand. Transmit and receive are separate wires, so data can flow both ways at once. Two enables are needed: SPEN switches the serial port on, then TXEN wakes the transmitter and CREN opens the receiver.
04Your mission
- OSCCONStart the clock. Any speed works.
- TXSTASwitch the serial port on and wake the transmitter.
- RCSTASwitch the serial port on and open the receiver.
Hint 1
Hint 2
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 — TXSTA (0x2B)Set it to
0x03(0000 0011). Enable the serial port and the transmitter. - 3Step 3 — RCSTA (0x2C)Set it to
0x03(0000 0011). Enable the serial port and the receiver. - 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 0x03
MOVWF 0x2B ; TXSTAMOVLW 0x03
MOVWF 0x2C ; RCSTABit-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.
TXSTA0x2B= 0x03
Enable the serial port and the transmitter. 0x03 = 0000 0011 = SPEN = 1, TXEN = 1
| Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| Value | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
| Field | — | TX9 | BRGH | SYNC | TXEN | SPEN | ||
- TXEN (bit 1) =
1→ Transmitter enabled - 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.
RCSTA0x2C= 0x03
Enable the serial port and the receiver. 0x03 = 0000 0011 = SPEN = 1, CREN = 1
| Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| Value | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
| Field | — | RX9 | BRGH | SYNC | CREN | SPEN | ||
- CREN (bit 1) =
1→ Receiver enabled - 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
TXSTA 0x2B
✗ Not yet – 2 bits differHex 0x00 Binary 0000 0000 Target 0x03 (0000 0011)
- TX9 (bit 4) = 0 → 9-bit transmit bit: not part of the win value (leave 0)
- BRGH (bit 3) = 0 → BRGH bit: not part of the win value (leave 0)
- SYNC (bit 2) = 0 → SYNC bit: not part of the win value (leave 0)
- TXEN (bit 1) = 0 → Transmitter disabled
- SPEN (bit 0) = 0 → Serial port disabled
RCSTA 0x2C
✗ Not yet – 2 bits differHex 0x00 Binary 0000 0000 Target 0x03 (0000 0011)
- RX9 (bit 4) = 0 → 9-bit receive bit: not part of the win value (leave 0)
- BRGH (bit 3) = 0 → BRGH bit: not part of the win value (leave 0)
- SYNC (bit 2) = 0 → SYNC bit: not part of the win value (leave 0)
- CREN (bit 1) = 0 → Receiver disabled
- SPEN (bit 0) = 0 → Serial port disabled
05How you know it worked
- 1The transmitter wakesTXREG loads a byte and copies it into the shift register.Screenshot coming soon
- 2Bits ride the wireOne bit leaves per clock beat and travels to the pin.Screenshot coming soon
- 3The receiver rebuilds itAfter the 8th bit the byte lands in RXREG; the fault panel shows TX and RX.TARGET REACHEDScreenshot coming soon
Simulation note
The game feeds the transmitter itself (a repeating 0x00 → 0xFF sequence); you only switch the port on.
Stuck?
- Nothing leaves the TX roomSPEN is missing in TXSTA. Set bit 0.
- Bits leave, but the RX room stays emptyThe receiver is off. RCSTA needs CREN (bit 1).
- Port is on, but nothing is sentTXEN is off:
0x01enables the port but not the transmitter. - Everything moves, but no Target ReachedAn extra bit is set (e.g. BRGH). Use exactly
0x03.
06Debrief
You just did day one of every embedded job.
Bringing up a new board starts exactly here: clock on, serial port on, say hello.
// the same idea in CTXSTA = 0x03; // serial port + transmitter onRCSTA = 0x03; // serial port + receiver onOn a real chip the same switches can sit at different bit positions; its datasheet has the map. The idea is identical.