|
| | Device (Spi &spi) noexcept |
| |
| | Device (const Device &)=delete |
| |
| Device & | operator= (const Device &)=delete |
| |
| uint8_t | LastRdsr () const noexcept |
| |
| Status | ReadStatus (uint8_t &sr) noexcept |
| |
| Status | Probe () noexcept |
| | Double RDSR. Present if both match, not 0xFF, not the 0x05 echo, and WIP is clear.
|
| |
| Status | Read (uint16_t addr, uint8_t *dst, uint16_t len) noexcept |
| | READ len bytes starting at addr (sequential read, any length).
|
| |
| Status | WaitReady (uint32_t timeout_ms=kWriteCycleTimeoutMs) noexcept |
| | Poll RDSR until RDY (bit 0) reads 0: the internal write cycle has ended.
|
| |
| Status | WriteEnable () noexcept |
| | WREN: set the write-enable latch (datasheet Table 6-1), before an instruction you send through your port. WritePage(), Write() and SetBlockProtection() send it themselves.
|
| |
| Status | WriteDisable () noexcept |
| | WRDI: clear the write-enable latch (datasheet Table 6-1), so no WRITE or WRSR is accepted until the next WREN. Independent of the WP pin.
|
| |
| Status | SetBlockProtection (BlockProtect level) noexcept |
| | WREN + WRSR: set BP1:BP0 (datasheet section 6, Write Status Register, Table 6-4), then wait for the write cycle: the bits are non-volatile and take tWC like a WRITE.
|
| |
| Status | GetBlockProtection (BlockProtect &level) noexcept |
| | RDSR, decoded: the current block protection level (datasheet Table 6-4).
|
| |
| Status | WritePage (uint16_t addr, const uint8_t *src, uint16_t len) noexcept |
| | WREN + WRITE of 1 to 8 bytes inside one 8-byte page, then wait for the write cycle.
|
| |
| Status | Write (uint16_t addr, const uint8_t *src, uint16_t len) noexcept |
| | Write any range inside the array: split at 8-byte page boundaries, one WritePage() (and one write cycle) per page.
|
| |
READ len bytes starting at addr (sequential read, any length).
The chip increments the address after every byte (datasheet 8707F, section 6, "Read Sequence"), so one READ can stream the whole array. The driver splits the request into READ transactions of at most kReadChunkBytes data bytes, so a port never sees more than 2 + kReadChunkBytes bytes, and recomputes A8 for each one.
- Returns
- Status::Arg for a null
dst, len == 0 or a range past 0x1FF (no transfer is made; the chip would roll over to 0x000). Status::Busy if RDSR shows a write cycle in progress (the chip would ignore the READ; nothing is read). Status::Timeout if a transfer failed: the bytes of the chunks before it are in dst.
Poll RDSR until RDY (bit 0) reads 0: the internal write cycle has ended.
The chip ignores every instruction except RDSR during a write cycle, and RDY = 1 while it runs (datasheet section 6, Write Sequence, and Table 6-3). If the port has an optional void delay_us(uint32_t us) member, the driver waits kPollIntervalUs between polls; otherwise it polls back to back, kPollsPerMsWithoutDelay times per millisecond of timeout_ms.
- Parameters
-
| timeout_ms | Budget; the default covers the 5 ms maximum tWC with margin. |
- Returns
- Status::Ok when ready, Status::Timeout if a transfer failed or RDY was still 1 (also what a floating MISO, which reads 0xFF, looks like) at the end of the budget.
WREN + WRITE of 1 to 8 bytes inside one 8-byte page, then wait for the write cycle.
Only the three low address bits increment during a WRITE, so bytes past the end of a page would wrap to its start (datasheet section 6, Write Sequence, p. 9): a range that crosses a page is refused. Programming starts when CS goes high; the call then polls RDSR (WaitReady()) and returns when the chip is ready again, so the next call is not ignored.
- Returns
- Status::Arg for a null
src, a length of 0 or above kPageSizeBytes, a page crossing or a range past the array (nothing is sent). Status::Busy if RDSR shows a write cycle already in progress (nothing is written). Status::Timeout if a transfer failed or the write cycle did not end within kWriteCycleTimeoutMs.