49 #include "dev/watchdog.h"
52 #define PRINTF(...) printf(__VA_ARGS__)
54 #define PRINTF(...) do {} while (0)
57 #define SPI_FLASH_INS_WREN 0x06
58 #define SPI_FLASH_INS_WRDI 0x04
59 #define SPI_FLASH_INS_RDSR 0x05
60 #define SPI_FLASH_INS_WRSR 0x01
61 #define SPI_FLASH_INS_READ 0x03
62 #define SPI_FLASH_INS_FAST_READ 0x0b
63 #define SPI_FLASH_INS_PP 0x02
64 #define SPI_FLASH_INS_SE 0xd8
65 #define SPI_FLASH_INS_BE 0xc7
66 #define SPI_FLASH_INS_DP 0xb9
67 #define SPI_FLASH_INS_RES 0xab
77 SPI_WRITE(SPI_FLASH_INS_WREN);
84 read_status_register(
void)
94 SPI_WRITE(SPI_FLASH_INS_RDSR);
113 u = read_status_register();
123 erase_sector(
unsigned long offset)
133 SPI_WRITE_FAST(SPI_FLASH_INS_SE);
134 SPI_WRITE_FAST(offset >> 16);
135 SPI_WRITE_FAST(offset >> 8);
136 SPI_WRITE_FAST(offset >> 0);
137 SPI_WAITFORTx_ENDED();
151 P4DIR |= BV(FLASH_CS);
152 P5DIR |= BV(FLASH_HOLD);
159 xmem_pread(
void *_p,
int size,
unsigned long offset)
161 unsigned char *p = _p;
162 const unsigned char *end = p + size;
166 ENERGEST_ON(ENERGEST_TYPE_FLASH_READ);
171 SPI_WRITE_FAST(SPI_FLASH_INS_READ);
172 SPI_WRITE_FAST(offset >> 16);
173 SPI_WRITE_FAST(offset >> 8);
174 SPI_WRITE_FAST(offset >> 0);
175 SPI_WAITFORTx_ENDED();
178 for(; p < end; p++) {
187 ENERGEST_OFF(ENERGEST_TYPE_FLASH_READ);
193 program_page(
unsigned long offset,
const unsigned char *p,
int nbytes)
195 const unsigned char *end = p + nbytes;
205 SPI_WRITE_FAST(SPI_FLASH_INS_PP);
206 SPI_WRITE_FAST(offset >> 16);
207 SPI_WRITE_FAST(offset >> 8);
208 SPI_WRITE_FAST(offset >> 0);
210 for(; p < end; p++) {
213 SPI_WAITFORTx_ENDED();
222 xmem_pwrite(
const void *_buf,
int size,
unsigned long addr)
224 const unsigned char *p = _buf;
225 const unsigned long end = addr + size;
226 unsigned long i, next_page;
228 ENERGEST_ON(ENERGEST_TYPE_FLASH_WRITE);
230 for(i = addr; i < end;) {
231 next_page = (i | 0xff) + 1;
232 if(next_page > end) {
235 p = program_page(i, p, next_page - i);
239 ENERGEST_OFF(ENERGEST_TYPE_FLASH_WRITE);
245 xmem_erase(
long size,
unsigned long addr)
247 unsigned long end = addr + size;
249 if(size % XMEM_ERASE_UNIT_SIZE != 0) {
250 PRINTF(
"xmem_erase: bad size\n");
254 if(addr % XMEM_ERASE_UNIT_SIZE != 0) {
255 PRINTF(
"xmem_erase: bad offset\n");
259 for (; addr < end; addr += XMEM_ERASE_UNIT_SIZE) {