/* write up a 256 byte page or partial page */ static void w25q80bv_page_program(w25q80bv_driver_t* const drv, const uint32_t addr, const uint16_t len, uint8_t* data) { /* do nothing if asked to write beyond a page boundary */ if (((addr & 0xFF) + len) > drv->page_len) return; /* do nothing if we would overflow the flash */ if (addr > (drv->num_bytes - len)) return; w25q80bv_write_enable(drv); w25q80bv_wait_while_busy(drv); uint8_t header[] = { W25Q80BV_PAGE_PROGRAM, (addr & 0xFF0000) >> 16, (addr & 0xFF00) >> 8, addr & 0xFF }; const spi_transfer_t transfers[] = { { header, ARRAY_SIZE(header) }, { data, len } }; spi_bus_transfer_gather(drv->bus, transfers, ARRAY_SIZE(transfers)); }
/* write an arbitrary number of bytes */ void w25q80bv_read(w25q80bv_driver_t* const drv, uint32_t addr, uint32_t len, uint8_t* const data) { /* do nothing if we would overflow the flash */ if ((len > drv->num_bytes) || (addr > drv->num_bytes) || ((addr + len) > drv->num_bytes)) return; w25q80bv_wait_while_busy(drv); uint8_t header[] = { W25Q80BV_FAST_READ, (addr & 0xFF0000) >> 16, (addr & 0xFF00) >> 8, addr & 0xFF }; const spi_transfer_t transfers[] = { { header, ARRAY_SIZE(header) }, { data, len } }; spi_bus_transfer_gather(drv->bus, transfers, ARRAY_SIZE(transfers)); }
/* write an arbitrary number of bytes */ void spiflash_read(spiflash_driver_t* const drv, uint32_t addr, uint32_t len, uint8_t* const data) { /* do nothing if we would overflow the flash */ if ((len > drv->num_bytes) || (addr > drv->num_bytes) || ((addr + len) > drv->num_bytes)) return; spiflash_wait_while_busy(drv); uint8_t header[] = { SPIFLASH_FAST_READ, (addr & 0xFF0000) >> 16, (addr & 0xFF00) >> 8, addr & 0xFF, 0x00 }; const spi_transfer_t transfers[] = { { header, ARRAY_SIZE(header) }, { data, len } }; spi_bus_transfer_gather(drv->target, transfers, ARRAY_SIZE(transfers)); }