From: R. Steve McKown Date: Thu, 4 Oct 2012 23:22:18 +0000 (-0600) Subject: tmimsp family: flash is now working X-Git-Url: https://oss.titaniummirror.com/gitweb/?p=tinyos-2.x.git;a=commitdiff_plain;h=46696d41fef125e00b09b24a378f106d1347526f tmimsp family: flash is now working The AT25DF family, on power up or reset (not reset of the board, but the AT25DF part itself) has by default write protection active for its sectors. This code change in MotePlatformC for both parts in the family globally unprotects all sectors. At this point, the AT25DF family are functionally equivalent to the ST/Numonyx/whomever M25P family, so the latter's driver works for the former. --- diff --git a/tos/platforms/tmimsp/common/MotePlatformC.nc b/tos/platforms/tmimsp/common/MotePlatformC.nc index 2199adfe..4f7a5392 100644 --- a/tos/platforms/tmimsp/common/MotePlatformC.nc +++ b/tos/platforms/tmimsp/common/MotePlatformC.nc @@ -35,6 +35,115 @@ module MotePlatformC @safe() { provides interface Init; } implementation { + inline void uwait(uint16_t u) + { + uint16_t t0 = TAR; + while((TAR - t0) <= u); + } + + inline void TOSH_wait() + { + nop(); nop(); + } + + /* Initialize the SPI pins to allow bit-bang communication with the AT25DF */ + void at25df_init() + { + TOSH_MAKE_UC_SIMO_OUTPUT(); + TOSH_MAKE_UC_SCK_OUTPUT(); + TOSH_MAKE_FLH_CS_OUTPUT(); + TOSH_SET_FLH_CS_PIN(); + TOSH_SET_UC_SCK_PIN(); + TOSH_SET_UC_SIMO_PIN(); + TOSH_wait(); + } + + /* Send a bit */ + void at25df_wbit(bool set) + { + if (set) + TOSH_SET_UC_SIMO_PIN(); + else + TOSH_CLR_UC_SIMO_PIN(); + TOSH_SET_UC_SCK_PIN(); + TOSH_CLR_UC_SCK_PIN(); + } + + /* Send a byte */ + void at25df_wbyte(uint8_t byte) + { + /* Bits of a byte are sent most significant bit first */ + uint8_t mask = 0x80; + + while (mask) { + at25df_wbit(byte & mask); + mask >>= 1; + } + } + + /* Begin a communications transaction */ + void at25df_begin() + { + TOSH_wait(); + TOSH_CLR_FLH_CS_PIN(); + TOSH_CLR_UC_SCK_PIN(); + } + + /* End a communiations transaction */ + void at25df_end() + { + TOSH_SET_FLH_CS_PIN(); + TOSH_SET_UC_SCK_PIN(); + TOSH_SET_UC_SIMO_PIN(); + } + + /* Send the Write Enable command */ + void at25df_wren() + { + at25df_begin(); + at25df_wbyte(0x06); /* WREN */ + at25df_end(); + } + + /* Zero all bits in the status register */ + void at25df_wrsr(uint8_t value) + { + at25df_begin(); + at25df_wbyte(0x01); /* WRSR */ + at25df_wbyte(value); + at25df_end(); + } + + /* Globally unprotect all sectors. */ + void at25df_unprotect() + { + /* After power-up or AT25DF reset, all sectors of the AT25DF are write + * protected. The first WRSR clears the SPRL bit, the second WRSR clears + * the sector protect bits, globally unprotecting all sectors and making + * them writeable. + */ + at25df_wren(); + at25df_wrsr(0); + at25df_wren(); + at25df_wrsr(0); + } + + /* Put the flash chip into deep power down mode */ + void at25df_dpd() + { + at25df_begin(); + at25df_wbyte(0xb9); /* DPD */ + at25df_end(); + } + + /* Resume from deep power-down */ + void at25df_rdpd() + { + at25df_begin(); + at25df_wbyte(0xab); /* RDPD */ + at25df_end(); + } + command error_t Init.init() { /* reset all of the ports to be input and using i/o functionality */ atomic @@ -90,6 +199,16 @@ implementation { P1IE = 0; P2IE = 0; + + /* wait 10ms for the flash to startup */ + uwait(1024*10); + /* Initialize the flash part by unprotecting all sectors, then putting + * it into deep sleep. + */ + at25df_init(); + at25df_rdpd(); + at25df_unprotect(); + at25df_dpd(); } return SUCCESS; } diff --git a/tos/platforms/tmimsp/common/hardware.h b/tos/platforms/tmimsp/common/hardware.h index c556ef08..ecaa2a79 100644 --- a/tos/platforms/tmimsp/common/hardware.h +++ b/tos/platforms/tmimsp/common/hardware.h @@ -6,6 +6,11 @@ //#include "CC2420Const.h" //#include "AM.h" +TOSH_ASSIGN_PIN(UC_SIMO, 3, 1); +TOSH_ASSIGN_PIN(UC_SOMI, 3, 2); +TOSH_ASSIGN_PIN(UC_SCK, 3, 3); +TOSH_ASSIGN_PIN(FLH_CS, 4, 4); + // need to undef atomic inside header files or nesC ignores the directive #undef atomic diff --git a/tos/platforms/tmimsp/tmirws/MotePlatformC.nc b/tos/platforms/tmimsp/tmirws/MotePlatformC.nc index 39b45c96..b1b0040d 100644 --- a/tos/platforms/tmimsp/tmirws/MotePlatformC.nc +++ b/tos/platforms/tmimsp/tmirws/MotePlatformC.nc @@ -35,6 +35,115 @@ module MotePlatformC @safe() { provides interface Init; } implementation { + inline void uwait(uint16_t u) + { + uint16_t t0 = TAR; + while((TAR - t0) <= u); + } + + inline void TOSH_wait() + { + nop(); nop(); + } + + /* Initialize the SPI pins to allow bit-bang communication with the AT25DF */ + void at25df_init() + { + TOSH_MAKE_UC_SIMO_OUTPUT(); + TOSH_MAKE_UC_SCK_OUTPUT(); + TOSH_MAKE_FLH_CS_OUTPUT(); + TOSH_SET_FLH_CS_PIN(); + TOSH_SET_UC_SCK_PIN(); + TOSH_SET_UC_SIMO_PIN(); + TOSH_wait(); + } + + /* Send a bit */ + void at25df_wbit(bool set) + { + if (set) + TOSH_SET_UC_SIMO_PIN(); + else + TOSH_CLR_UC_SIMO_PIN(); + TOSH_SET_UC_SCK_PIN(); + TOSH_CLR_UC_SCK_PIN(); + } + + /* Send a byte */ + void at25df_wbyte(uint8_t byte) + { + /* Bits of a byte are sent most significant bit first */ + uint8_t mask = 0x80; + + while (mask) { + at25df_wbit(byte & mask); + mask >>= 1; + } + } + + /* Begin a communications transaction */ + void at25df_begin() + { + TOSH_wait(); + TOSH_CLR_FLH_CS_PIN(); + TOSH_CLR_UC_SCK_PIN(); + } + + /* End a communiations transaction */ + void at25df_end() + { + TOSH_SET_FLH_CS_PIN(); + TOSH_SET_UC_SCK_PIN(); + TOSH_SET_UC_SIMO_PIN(); + } + + /* Send the Write Enable command */ + void at25df_wren() + { + at25df_begin(); + at25df_wbyte(0x06); /* WREN */ + at25df_end(); + } + + /* Zero all bits in the status register */ + void at25df_wrsr(uint8_t value) + { + at25df_begin(); + at25df_wbyte(0x01); /* WRSR */ + at25df_wbyte(value); + at25df_end(); + } + + /* Globally unprotect all sectors. */ + void at25df_unprotect() + { + /* After power-up or AT25DF reset, all sectors of the AT25DF are write + * protected. The first WRSR clears the SPRL bit, the second WRSR clears + * the sector protect bits, globally unprotecting all sectors and making + * them writeable. + */ + at25df_wren(); + at25df_wrsr(0); + at25df_wren(); + at25df_wrsr(0); + } + + /* Put the flash chip into deep power down mode */ + void at25df_dpd() + { + at25df_begin(); + at25df_wbyte(0xb9); /* DPD */ + at25df_end(); + } + + /* Resume from deep power-down */ + void at25df_rdpd() + { + at25df_begin(); + at25df_wbyte(0xab); /* RDPD */ + at25df_end(); + } + command error_t Init.init() { /* reset all of the ports to be input and using i/o functionality */ atomic @@ -93,6 +202,16 @@ implementation { P1IE = 0; P2IE = 0; + + /* wait 10ms for the flash to startup */ + uwait(1024*10); + /* Initialize the flash part by unprotecting all sectors, then putting + * it into deep sleep. + */ + at25df_init(); + at25df_rdpd(); + at25df_unprotect(); + at25df_dpd(); } return SUCCESS; }