Practice

Trail Camera SD Wake

A trail camera on Rowan Fell records foxes through the night. At dawn, it writes each night's photos to an SD card over SPI.

A fresh card powers up asleep in SD mode. It ignores normal SPI traffic until the host performs a fixed wake ritual.

The shipped firmware skipped that ritual and went straight to writing. The card ignored every command.

One morning, the keeper found twelve fox filenames in the directory, each with zero bytes.

Your task: build the sequencer that wakes the card. Supply its first clocks, send each command, and check each reply. Do not report ready until the card proves it can accept data.

Interface

PortDirectionTypeDescription
clkin1 bitSystem clock
rstin1 bitSynchronous reset, active high
startin1 bitRequest the wake ritual
misoin1 bitSerial data from the card
cs_nout1 bitCard chip select, active low and idle high
sclkout1 bitSerial clock, idle low
mosiout1 bitSerial data to the card, idle high
busyout1 bitHigh while the wake ritual runs
readyout1 bitHigh once the card is awake, then held high
errorout1 bitWake failure, pulsed for exactly one clock

Behavior

  • While idle, cs_n is high, sclk is low, mosi is high, and all three status outputs are low
  • A high start sampled while idle is accepted, and the sequence begins on the next clock
  • busy is high while the sequence runs
  • Any start assertion while busy is high is ignored
  • SPI uses mode 0
  • Each SPI bit uses exactly two clk cycles
  • During the first cycle, sclk is low and mosi is set for the next bit
  • During the second cycle, sclk rises and miso is sampled
  • Bytes are transferred most-significant bit first
  • Begin with at least 74 complete sclk cycles while cs_n and mosi remain high
  • Every command is a six-byte packet: 0x40 + index, four argument bytes most-significant byte first, then its fixed CRC byte
  • Lower cs_n before each command and keep it low through the command and its complete response
  • After the packet, send 0xFF while polling response bytes
  • The card may return zero through eight 0xFF filler bytes before its R1 response
  • The first received byte with bit 7 low is the R1 response
  • If no R1 arrives after the permitted filler bytes, abort with an error
  • After each response, raise cs_n and supply eight extra clocks while sending 0xFF before the next command
  • Send CMD0 with index 0, argument 0x00000000, and CRC byte 0x95; expect R1 0x01
  • Send CMD8 with index 8, argument 0x000001AA, and CRC byte 0x87
  • CMD8 returns R1 0x01, followed by four R7 bytes
  • The last two R7 bytes must be 0x01 and 0xAA; any other echo aborts with an error
  • Begin the ACMD41 loop by sending CMD55 with index 55, argument 0x00000000, and CRC byte 0x65; expect R1 0x01
  • Then send ACMD41 with index 41, argument 0x40000000, and CRC byte 0x77
  • Repeat the complete CMD55 and ACMD41 pair while ACMD41 returns R1 0x01
  • Leave the loop when ACMD41 returns R1 0x00
  • If another pair would exceed 64 ACMD41 rounds, abort with an error
  • Send CMD58 with index 58, argument 0x00000000, and CRC byte 0xFD; expect R1 0x00
  • Capture the four OCR bytes following CMD58 without comparing them to a constant
  • After the CMD58 response, raise cs_n, lower busy, and raise ready
  • Once raised, ready stays high until reset
  • Every failure lowers busy, leaves ready low, and pulses error for exactly one clock
  • After the error pulse, the sequencer returns to idle
  • rst high at any rising edge cancels all progress and returns the interface to idle
  • Reset sets cs_n high, sclk low, mosi high, and busy, ready, and error low

What the bench checks

  • It checks reset, idle pin levels, next-clock startup, and ignored requests while busy
  • It checks mode 0 timing and at least 74 warm-up clocks with cs_n high
  • It checks every command byte, argument order, and fixed CRC byte
  • It checks chip-select framing and the eight extra 0xFF clocks between commands
  • It varies filler delays and checks the missing-R1 timeout
  • It checks the CMD8 echo, ACMD41 loop exit, and 64-round limit
  • It checks CMD58 completion, status behavior, error pulses, and reset during active transfers

Constraints

TIMING

everything is synchronous to clk; inputs are sampled on rising edges, and all outputs are registered.

SCOPE

this targets one SDHC v2 card profile with bounded response delays. CRC7 generation, CRC16, data blocks, SDSC byte addressing, and native SD mode are out of scope. The two mandated CRC constants are the only CRCs involved.

Do not add ports.

Loading editor...

Click Run to execute your code. Output will appear here.