43#include "../utilities.h"
53 template<board::DigitalPin CS>
72 BLOCK_UPPER_64KB = 0x01 << 2,
73 BLOCK_UPPER_128KB = 0x02 << 2,
74 BLOCK_UPPER_256KB = 0x03 << 2,
75 BLOCK_UPPER_512KB = 0x04 << 2,
77 BLOCK_LOWER_64KB = 0x09 << 2,
78 BLOCK_LOWER_128KB = 0x0A << 2,
79 BLOCK_LOWER_256KB = 0x0B << 2,
80 BLOCK_LOWER_512KB = 0x0C << 2,
81 BLOCK_ALL = 0x07 << 2,
83 BLOCK_UPPER_4KB = 0x11 << 2,
84 BLOCK_UPPER_8KB = 0x12 << 2,
85 BLOCK_UPPER_16KB = 0x13 << 2,
86 BLOCK_UPPER_32KB = 0x14 << 2,
88 BLOCK_LOWER_4KB = 0x19 << 2,
89 BLOCK_LOWER_8KB = 0x1A << 2,
90 BLOCK_LOWER_16KB = 0x1B << 2,
91 BLOCK_LOWER_32KB = 0x1C << 2
102 SOFTWARE_PROTECTION = 0x0000,
103 HARDWARE_PROTECTION = 0x0080,
104 POWER_SUPPLY_LOCKDOWN = 0x0100
120 bool write_enable_latch()
const
128 bool complement_protect()
const
132 bool suspend_status()
const
141 const uint16_t value;
147 static constexpr const uint8_t BUSY = 0;
148 static constexpr const uint8_t WEL = 1;
149 static constexpr const uint8_t BP0 = 2;
150 static constexpr const uint8_t BP1 = 3;
151 static constexpr const uint8_t BP2 = 4;
152 static constexpr const uint8_t TB = 5;
153 static constexpr const uint8_t SEC = 6;
154 static constexpr const uint8_t SRP0 = 7;
155 static constexpr const uint8_t SRP1 = 8;
156 static constexpr const uint8_t CMP = 14;
157 static constexpr const uint8_t SUS = 15;
167 return Status(read(READ_STATUS_1), read(READ_STATUS_2));
255 send(SECTOR_ERASE, address);
265 send(BLOCK_32K_ERASE, address);
275 send(BLOCK_64K_ERASE, address);
295 void write_page(uint32_t address, uint8_t* data, uint8_t size)
297 send(PAGE_PROGRAM, address, data, ((size == 0) ? (1U + UINT8_MAX) : size));
314 void read_data(uint32_t address, uint8_t* data, uint16_t size);
317 uint8_t read(uint8_t code);
318 void send(uint8_t code);
319 void send(uint8_t code, uint32_t address)
321 send(code, address,
nullptr, 0);
323 void send(uint8_t code, uint32_t address, uint8_t* data, uint16_t size);
326 static constexpr const uint8_t WRITE_STATUS = 0x01;
327 static constexpr const uint8_t PAGE_PROGRAM = 0x02;
328 static constexpr const uint8_t READ_DATA = 0x03;
329 static constexpr const uint8_t WRITE_DISABLE = 0x04;
330 static constexpr const uint8_t READ_STATUS_1 = 0x05;
331 static constexpr const uint8_t WRITE_ENABLE = 0x06;
332 static constexpr const uint8_t FAST_READ = 0x0B;
333 static constexpr const uint8_t SECTOR_ERASE = 0x20;
334 static constexpr const uint8_t READ_STATUS_2 = 0x35;
335 static constexpr const uint8_t READ_UNIQUE_ID = 0x4B;
336 static constexpr const uint8_t BLOCK_32K_ERASE = 0x52;
337 static constexpr const uint8_t DEVICE_ID = 0x90;
338 static constexpr const uint8_t POWER_UP = 0xAB;
339 static constexpr const uint8_t POWER_DOWN = 0xB9;
340 static constexpr const uint8_t CHIP_ERASE = 0xC7;
341 static constexpr const uint8_t BLOCK_64K_ERASE = 0xD8;
347 this->start_transfer();
350 this->end_transfer();
356 this->start_transfer();
357 this->transfer(READ_STATUS_1);
361 uint8_t status = this->transfer(0x00);
362 if ((status &
bits::BV8(Status::BUSY)) == 0)
367 if ((timeout_ms != 0) && (
time::since(start) > timeout_ms))
break;
370 this->end_transfer();
377 send(DEVICE_ID, 0, (uint8_t*) &device,
sizeof(device));
393 send(READ_UNIQUE_ID, 0, (uint8_t*) &buffer,
sizeof buffer);
396 return __builtin_bswap64(buffer.id);
402 read_data(address, &data, 1);
408 send(READ_DATA, address, data, size);
413 this->start_transfer();
414 this->transfer(code);
415 uint8_t result = this->transfer(0);
416 this->end_transfer();
420 template<board::DigitalPin CS>
void WinBond<CS>::send(uint8_t code)
422 this->start_transfer();
423 this->transfer(code);
424 this->end_transfer();
427 template<board::DigitalPin CS>
void WinBond<CS>::send(uint8_t code, uint32_t address, uint8_t* data, uint16_t size)
429 this->start_transfer();
430 this->transfer(code);
431 this->transfer(address >> 16);
434 this->transfer(data, size);
435 this->end_transfer();
SPI device driver for WinBond flash memory chips, like W25Q80BV (8 Mbit flash).
void set_status(uint16_t status)
Change the Status register (only writable bits, §6.2.9).
void disable_write()
Disable chip write mode (§6.2.7).
void erase_sector(uint32_t address)
Erase the sector (4KB) at address (§6.2.23).
void power_down()
Set the chip to low power mode (§6.2.29).
Status status()
Get the value of the chip's Status register (§6.1, §6.2.8).
uint64_t read_unique_ID()
Get chip unique ID (§6.2.34).
void power_up()
Release power-down mode (§6.2.30).
void write_page(uint32_t address, uint8_t *data, uint8_t size)
Write data (max 256 bytes) to a page (§6.2.21).
void erase_chip()
Erase the whole chip memory (§6.2.26).
StatusRegisterProtect
This enum provides information about the method of write protection of the Status register itself (bi...
void erase_block_32K(uint32_t address)
Erase the block (32KB) at address (§6.2.24).
void erase_block_64K(uint32_t address)
Erase the sector (64KB) at address (§6.2.25).
void enable_write()
Enable write mode for the chip (§6.2.5).
Device read_device()
Get device informaton §6.2.31).
BlockProtect
This enum provides information about block protection (bits BP0-2, TB and SEC of Status register,...
bool wait_until_ready(uint16_t timeout_ms)
Wait until any erase or write operation is finished.
WinBond()=default
Create a new device driver for a WinBond chip.
uint8_t read_data(uint32_t address)
Read one byte of flash memory (§6.2.10).
Base class for any SPI slave device.
static constexpr uint8_t HIGH_BYTE(uint16_t value)
Extract the high byte (aka Most Significant Byte, MSB) of a uint16_t value.
static constexpr uint8_t BV8(uint8_t bit)
Create a uint8_t bitmask for the given bit number.
static constexpr uint16_t BV16(uint8_t bit)
Create a uint16_t bitmask for the given bit number.
static constexpr uint8_t LOW_BYTE(uint16_t value)
Extract the low byte (aka Least Significant Byte, LSB) of a uint16_t value.
Defines all API for all external devices supported by FastArduino.
MILLIS_PTR millis
Count number of milliseconds elapsed since some time base reference (generally since MCU startup).
void delay_us(uint16_t us) INLINE
Delay program execution for the given amount of microseconds.
void yield()
Utility method used by many FastArduino API in order to "yield" some processor time; concretely it ju...
uint32_t since(uint32_t start_ms)
Compute the time elapsed, in milliseconds, since start_ms.
constexpr uint16_t as_uint16_t(uint8_t high, uint8_t low)
Convert 2 bytes into an unsigned int.
Device information (§6.2.31)
uint8_t manufacturer_ID
Manufacturer ID, always 0xEF.
uint8_t device_ID
Device ID.
This type maps WinBond Status register (§6.1) to more readable pieces.