/*---------------------------------------------------------------------------*/ static const char * program_page(unsigned long offset, const unsigned char *p, int nbytes) { const unsigned char *end = p + nbytes; int s; wait_ready(); write_enable(); s = splhigh(); SPI_FLASH_ENABLE(); SPI_WRITE_FAST(SPI_FLASH_INS_PP); SPI_WRITE_FAST(offset >> 16); /* MSB */ SPI_WRITE_FAST(offset >> 8); SPI_WRITE_FAST(offset >> 0); /* LSB */ for(; p < end; p++) { SPI_WRITE_FAST(~*p); } SPI_WAITFORTx_ENDED(); SPI_FLASH_DISABLE(); splx(s); return p; }
/*---------------------------------------------------------------------------*/ int xmem_pread(void *_p, int size, unsigned long offset) { unsigned char *p = _p; const unsigned char *end = p + size; int s; wait_ready(); ENERGEST_ON(ENERGEST_TYPE_FLASH_READ); s = splhigh(); SPI_FLASH_ENABLE(); SPI_WRITE_FAST(SPI_FLASH_INS_READ); SPI_WRITE_FAST(offset >> 16); /* MSB */ SPI_WRITE_FAST(offset >> 8); SPI_WRITE_FAST(offset >> 0); /* LSB */ SPI_WAITFORTx_ENDED(); SPI_FLUSH(); for(; p < end; p++) { unsigned char u; SPI_READ(u); *p = ~u; } SPI_FLASH_DISABLE(); splx(s); ENERGEST_OFF(ENERGEST_TYPE_FLASH_READ); return size; }
/* * Initialize external flash *and* SPI bus! */ void xmem_init(void) { int s; spi_init(); P4DIR |= BV(FLASH_CS) | BV(FLASH_HOLD) | BV(FLASH_PWR); P4OUT |= BV(FLASH_PWR); /* P4.3 Output, turn on power! */ /* Release from Deep Power-down */ s = splhigh(); SPI_FLASH_ENABLE(); SPI_WRITE_FAST(SPI_FLASH_INS_RES); SPI_WAITFORTx_ENDED(); SPI_FLASH_DISABLE(); /* Unselect flash. */ splx(s); SPI_FLASH_UNHOLD(); }
/* * Erase 64k bytes of data. It takes about 1s before WIP goes low! */ static void erase_sector(unsigned long offset) { int s; wait_ready(); write_enable(); s = splhigh(); SPI_FLASH_ENABLE(); SPI_WRITE_FAST(SPI_FLASH_INS_SE); SPI_WRITE_FAST(offset >> 16); /* MSB */ SPI_WRITE_FAST(offset >> 8); SPI_WRITE_FAST(offset >> 0); /* LSB */ SPI_WAITFORTx_ENDED(); SPI_FLASH_DISABLE(); splx(s); }