diff --git a/firmware/common/w25q80bv.c b/firmware/common/w25q80bv.c index 2b391d9d..f49ffe3f 100644 --- a/firmware/common/w25q80bv.c +++ b/firmware/common/w25q80bv.c @@ -243,3 +243,25 @@ void w25q80bv_program(uint32_t addr, uint32_t len, const uint8_t* data) w25q80bv_page_program(addr, len, data); } } + +void w25q80bv_read(uint32_t addr, uint32_t len, uint8_t* const data) +{ + uint32_t i; + + /* do nothing if we would overflow the flash */ + if ((len > W25Q80BV_NUM_BYTES) || (addr > W25Q80BV_NUM_BYTES) + || ((addr + len) > W25Q80BV_NUM_BYTES)) + return; + + w25q80bv_wait_while_busy(); + + gpio_clear(PORT_SSP0_SSEL, PIN_SSP0_SSEL); + ssp_transfer(SSP0_NUM, W25Q80BV_FAST_READ); + ssp_transfer(SSP0_NUM, (addr >> 16) & 0xFF); + ssp_transfer(SSP0_NUM, (addr >> 8) & 0xFF); + ssp_transfer(SSP0_NUM, (addr >> 0) & 0xFF); + ssp_transfer(SSP0_NUM, 0xFF); + for (i = 0; i < len; i++) + data[i] = ssp_transfer(SSP0_NUM, 0xFF); + gpio_set(PORT_SSP0_SSEL, PIN_SSP0_SSEL); +} diff --git a/firmware/common/w25q80bv.h b/firmware/common/w25q80bv.h index b11a466a..5eda749d 100644 --- a/firmware/common/w25q80bv.h +++ b/firmware/common/w25q80bv.h @@ -27,6 +27,8 @@ #define W25Q80BV_NUM_PAGES 4096U #define W25Q80BV_NUM_BYTES 1048576U +#define W25Q80BV_READ_DATA 0x03 +#define W25Q80BV_FAST_READ 0x0b #define W25Q80BV_WRITE_ENABLE 0x06 #define W25Q80BV_CHIP_ERASE 0xC7 #define W25Q80BV_READ_STATUS1 0x05 @@ -51,5 +53,6 @@ void w25q80bv_chip_erase(void); void w25q80bv_program(uint32_t addr, uint32_t len, const uint8_t* data); uint8_t w25q80bv_get_device_id(void); void w25q80bv_get_unique_id(w25q80bv_unique_id_t* unique_id); +void w25q80bv_read(uint32_t addr, uint32_t len, uint8_t* const data); #endif//__W25Q80BV_H__