Marco Hsu / WIFI_API_32kRAM
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers spi_flash.c Source File

spi_flash.c

00001 /* 
00002  *  Generated for windbond flash
00003  */
00004 
00005 #include <string.h>
00006 #include <spi_flash.h>
00007 //#include "nrf_delay.h"
00008 #include "nrf_gpio.h"
00009 //#include "common.h"
00010 #include "spi_master_config.h" // This file must be in the application folder
00011 
00012 #include "simple_uart.h"
00013 
00014 #include "spi_master.h"
00015 
00016 #include "wait_api.h"
00017 
00018 #if 1   //marcus add for flash read/write
00019 #define MFG_ID_WINBOND (0xEF)
00020 #define DEVICE_ID_WINBOND_8M (0x5014)
00021 
00022 #define CMD_POWER_UP (0xAB)
00023 #define CMD_JEDEC_ID    (0x9F)
00024 #define CMD_POWER_DOWN  (0xB9)
00025 #define CMD_READ_STATUS (0x05)
00026 #define CMD_WRITE_ENABLE (0x06)
00027 #define CMD_PAGE_PROG (0x02)
00028 #define CMD_READ_DATA (0x03)
00029 #define CMD_ERASE_4K (0x20)
00030 #define CMD_ERASE_64K (0xD8)
00031 #define CMD_DUMMY   (0xFF)
00032 
00033 // added by Tsungta
00034 #define CMD_READ_UNIQUE_ID (0x4B)
00035 #define CMD_ERASE_SECU (0x44)
00036 #define CMD_PAGE_PROG_SECU (0x42)
00037 #define CMD_READ_SECU (0x48)
00038 
00039 #define THREE_BYTE_LENGTH   3
00040 #define WIFIDRI_LENGTH (136568)
00041 #define ERASEWIFI_LENGTH (2696)
00042 #define DEVICE_PAGE_SIZE (256)
00043 #define DEVICE_SECTOR_SIZE (4096)
00044 #define DEVICE_BLOCK_SIZE (65536)
00045 #ifdef WIFI_BOOT_NORDIC
00046 extern const unsigned char wifi_firmware[];
00047 #endif
00048 #endif
00049 
00050 #if 1   //marcus add for flash read/write
00051 static bool spi_flash_writeOneByte(uint32_t *spi_base_address, uint8_t DataBuffer)
00052 {
00053         uint8_t rx_data;
00054         uint32_t counter = 0;
00055     /*lint -e{826} //Are too small pointer conversion */
00056     NRF_SPI_Type *spi_base = (NRF_SPI_Type *)spi_base_address;
00057 
00058         spi_base->TXD = (uint32_t) DataBuffer;
00059     
00060     /* Wait for the transaction complete or timeout (about 10ms - 20 ms) */
00061     while ((spi_base->EVENTS_READY == 0U) && (counter < TIMEOUT_COUNTER))
00062     {
00063                 counter++;
00064     }
00065 
00066     if (counter == TIMEOUT_COUNTER)
00067         {
00068                 /* timed out, disable slave (slave select active low) and return with error */
00069         return false;
00070     }   else {
00071                 /* clear the event to be ready to receive next messages */
00072         spi_base->EVENTS_READY = 0U;
00073         }
00074         
00075         /* Marcus, need to move RXD to get the next transaction*/
00076         rx_data = (uint8_t)spi_base->RXD;
00077         
00078         return true;
00079 }
00080 
00081 static uint8_t spi_flash_readOneByte(uint32_t *spi_base_address)
00082 {
00083         uint32_t counter = 0;
00084     /*lint -e{826} //Are too small pointer conversion */
00085     NRF_SPI_Type *spi_base = (NRF_SPI_Type *)spi_base_address;
00086         
00087         spi_base->TXD = 0xFF; //put dont case data
00088     
00089     /* Wait for the transaction complete or timeout (about 10ms - 20 ms) */
00090     while ((spi_base->EVENTS_READY == 0U) && (counter < TIMEOUT_COUNTER))
00091     {
00092                 counter++;
00093     }
00094 
00095     if (counter == TIMEOUT_COUNTER)
00096         {
00097         return 0;
00098     }   else {
00099                 /* clear the event to be ready to receive next messages */
00100         spi_base->EVENTS_READY = 0U;
00101         }   
00102     
00103         return (uint8_t)spi_base->RXD;
00104 }
00105 
00106 //#if !defined(TARGET_DELTA_DFCM_NNN40)
00107 bool spi_flash_init(void)
00108 {
00109         uint8_t mfgId;
00110         uint16_t deviceID;
00111     
00112     uint32_t * p_spi_base_address = spi_master_init(SPI0, SPI_MODE0, false);
00113     if (p_spi_base_address == NULL)
00114     {
00115         return false;
00116     }
00117         
00118     nrf_gpio_pin_clear(SPI_PSELSS1_flash);
00119     spi_flash_writeOneByte(p_spi_base_address, CMD_POWER_UP);
00120     nrf_gpio_pin_set(SPI_PSELSS1_flash);
00121         
00122         //wait for wake up
00123         wait_us(30);//nrf_delay_us(30);
00124         
00125         nrf_gpio_pin_clear(SPI_PSELSS1_flash);
00126         
00127         spi_flash_writeOneByte(p_spi_base_address, CMD_JEDEC_ID);
00128         
00129         mfgId = spi_flash_readOneByte(p_spi_base_address);
00130         deviceID = (uint16_t)(spi_flash_readOneByte(p_spi_base_address) << 8);
00131         deviceID |= spi_flash_readOneByte(p_spi_base_address);
00132         
00133         nrf_gpio_pin_set(SPI_PSELSS1_flash);
00134         
00135         if (mfgId != MFG_ID_WINBOND || deviceID != DEVICE_ID_WINBOND_8M) {
00136                 return false;
00137         }
00138         
00139         return true;
00140 }
00141 
00142 bool spi_flash_powerDown(void)
00143 {           
00144     uint32_t * p_spi_base_address = spi_master_init(SPI0, SPI_MODE0, false);
00145     if (p_spi_base_address == NULL)
00146     {
00147         return false;
00148     }
00149         
00150     nrf_gpio_pin_clear(SPI_PSELSS1_flash);
00151     spi_flash_writeOneByte(p_spi_base_address, CMD_POWER_DOWN);
00152     nrf_gpio_pin_set(SPI_PSELSS1_flash);
00153         
00154         //wait for sleep
00155         wait_us(3);//nrf_delay_us(3);
00156         
00157         return true;
00158 }
00159 //#endif
00160 
00161 bool spi_flash_waitBusy(void)
00162 {
00163         uint8_t status;
00164     uint32_t * p_spi_base_address = spi_master_init(SPI0, SPI_MODE0, false);
00165     if (p_spi_base_address == NULL)
00166     {
00167         return false;
00168     }
00169         
00170     nrf_gpio_pin_clear(SPI_PSELSS1_flash);
00171     spi_flash_writeOneByte(p_spi_base_address, CMD_READ_STATUS);
00172         status = spi_flash_readOneByte(p_spi_base_address);
00173     nrf_gpio_pin_set(SPI_PSELSS1_flash);
00174         
00175         if ( (status & 0x01) == 0x01 )
00176         {
00177                 return true;
00178         } else {
00179                 return false;
00180         }
00181 }
00182 
00183 void spi_flash_setWEL(void)
00184 {
00185     uint32_t * p_spi_base_address = spi_master_init(SPI0, SPI_MODE0, false);
00186     if (p_spi_base_address == NULL)
00187     {
00188         return;
00189     }
00190         
00191     nrf_gpio_pin_clear(SPI_PSELSS1_flash);
00192     spi_flash_writeOneByte(p_spi_base_address, CMD_WRITE_ENABLE);
00193     nrf_gpio_pin_set(SPI_PSELSS1_flash);    
00194 }
00195 
00196 void spi_flash_writePage(uint32_t address, const uint8_t *data, uint16_t len)
00197 {
00198         //wait busy
00199         while(spi_flash_waitBusy()) {};
00200         
00201         //setWEL
00202         spi_flash_setWEL();
00203 
00204     uint32_t * p_spi_base_address = spi_master_init(SPI0, SPI_MODE0, false);
00205     if (p_spi_base_address == NULL)
00206     {
00207         return;
00208     }
00209             
00210         nrf_gpio_pin_clear(SPI_PSELSS1_flash);
00211         
00212     spi_flash_writeOneByte(p_spi_base_address, CMD_PAGE_PROG);
00213         
00214         spi_flash_writeOneByte(p_spi_base_address, ((address >> 16) & 0xFF));
00215         spi_flash_writeOneByte(p_spi_base_address, ((address >> 8) & 0xFF));
00216         spi_flash_writeOneByte(p_spi_base_address, (address & 0xFF));
00217         
00218         /* write data */
00219         while(len--) {
00220             spi_flash_writeOneByte(p_spi_base_address, *data++);
00221         }           
00222         
00223     nrf_gpio_pin_set(SPI_PSELSS1_flash);
00224         
00225         return;
00226 }
00227 
00228 void spi_flash_eraseCmd(uint8_t command, uint32_t address)
00229 {
00230     uint32_t * p_spi_base_address = spi_master_init(SPI0, SPI_MODE0, false);
00231     if (p_spi_base_address == NULL)
00232     {
00233         return;
00234     }   
00235     
00236     nrf_gpio_pin_clear(SPI_PSELSS1_flash);
00237         
00238     spi_flash_writeOneByte(p_spi_base_address, command);
00239         
00240         spi_flash_writeOneByte(p_spi_base_address, ((address >> 16) & 0xFF));
00241         spi_flash_writeOneByte(p_spi_base_address, ((address >> 8) & 0xFF));
00242         spi_flash_writeOneByte(p_spi_base_address, (address & 0xFF));
00243     
00244         nrf_gpio_pin_set(SPI_PSELSS1_flash);    
00245 }
00246 
00247 void spi_flash_erase(void)
00248 {
00249         uint32_t address = 0;
00250         uint32_t totalLength = WIFIDRI_LENGTH + ERASEWIFI_LENGTH;   //To map SECTOR size
00251 
00252         //wait busy
00253         while(spi_flash_waitBusy()) {};
00254 
00255         //setWEL
00256         spi_flash_setWEL();         
00257 
00258         // handle any full blocks
00259         while(totalLength >= DEVICE_BLOCK_SIZE) {
00260             spi_flash_eraseCmd(CMD_ERASE_64K, address);
00261             address += DEVICE_BLOCK_SIZE;
00262             totalLength -= DEVICE_BLOCK_SIZE;
00263         }   
00264 
00265         // finally handle any trailing partial blocks
00266         while(totalLength) {
00267             spi_flash_eraseCmd(CMD_ERASE_4K, address);
00268             address += DEVICE_SECTOR_SIZE;
00269             totalLength -= DEVICE_SECTOR_SIZE;
00270         }
00271 
00272         return;
00273 }
00274 
00275 static bool m_spi_result = true;
00276 
00277 void spi_flash_readpage(uint32_t address, uint8_t *data, uint16_t len)
00278 {
00279 
00280         uint16_t i = 0; 
00281     
00282         //wait busy
00283         while(spi_flash_waitBusy()) {};
00284             
00285     uint32_t * p_spi_base_address = spi_master_init(SPI0, SPI_MODE0, false);
00286     if (p_spi_base_address == NULL)
00287     {
00288                 m_spi_result = false;
00289         return;
00290     }
00291         
00292     nrf_gpio_pin_clear(SPI_PSELSS1_flash);
00293         
00294     spi_flash_writeOneByte(p_spi_base_address, CMD_READ_DATA);
00295         
00296         spi_flash_writeOneByte(p_spi_base_address, ((address >> 16) & 0xFF));
00297         spi_flash_writeOneByte(p_spi_base_address, ((address >> 8) & 0xFF));
00298         spi_flash_writeOneByte(p_spi_base_address, (address & 0xFF));
00299         
00300         /* read data */
00301         
00302         for (i=0; i < len; i++){    // only totalLength bytes (<4096) left 
00303                 *data++ = spi_flash_readOneByte(p_spi_base_address);
00304         }       
00305         
00306     nrf_gpio_pin_set(SPI_PSELSS1_flash);    
00307 }
00308     #ifdef WIFI_BOOT_NORDIC
00309 void spi_flash_write(void)
00310 {
00311     uint32_t totalLength = WIFIDRI_LENGTH;
00312     uint32_t address = 0;
00313     uint16_t len = DEVICE_PAGE_SIZE;
00314 
00315     const uint8_t *data = wifi_firmware;
00316 
00317 
00318   while(totalLength) {
00319     spi_flash_writePage(address, data, len);
00320     totalLength -= len;
00321     address += len;
00322     data += len;
00323     len = (totalLength>DEVICE_PAGE_SIZE)? DEVICE_PAGE_SIZE : totalLength;
00324   } 
00325 }
00326 #endif
00327 #endif
00328 
00329 // added by Tsungta
00330 void spi_flash_read_uniqueID(uint8_t *data)
00331 {
00332         uint8_t dummy_len = 4;
00333         uint8_t id_len = 8;
00334         //wait busy
00335         while(spi_flash_waitBusy()) {};
00336             
00337     uint32_t * p_spi_base_address = spi_master_init(SPI0, SPI_MODE0, false);
00338     if (p_spi_base_address == NULL)
00339     {
00340         return;
00341     }
00342         
00343     nrf_gpio_pin_clear(SPI_PSELSS1_flash);
00344         
00345     spi_flash_writeOneByte(p_spi_base_address, CMD_READ_UNIQUE_ID);
00346         while(dummy_len--)
00347             spi_flash_readOneByte(p_spi_base_address);      // there is four dummy bytes before real data
00348         /* id data */
00349         while(id_len--) 
00350             *data++ = spi_flash_readOneByte(p_spi_base_address);            
00351 
00352     nrf_gpio_pin_set(SPI_PSELSS1_flash);        
00353 }
00354 
00355 // added by Tsungta
00356 void spi_flash_erase_security(uint32_t address)
00357 {
00358         //wait busy
00359         while(spi_flash_waitBusy()) {};
00360 
00361         //setWEL
00362         spi_flash_setWEL();
00363             
00364         uint32_t * p_spi_base_address = spi_master_init(SPI0, SPI_MODE0, false);
00365     if (p_spi_base_address == NULL)
00366     {
00367         return;
00368     }   
00369     
00370     nrf_gpio_pin_clear(SPI_PSELSS1_flash);
00371         
00372     spi_flash_writeOneByte(p_spi_base_address, CMD_ERASE_SECU);
00373         
00374         spi_flash_writeOneByte(p_spi_base_address, ((address >> 16) & 0xFF));
00375         spi_flash_writeOneByte(p_spi_base_address, ((address >> 8) & 0xFF));
00376         spi_flash_writeOneByte(p_spi_base_address, (address & 0xFF));
00377     
00378         nrf_gpio_pin_set(SPI_PSELSS1_flash);    
00379 }
00380 
00381 // added by Tsungta
00382 void spi_flash_writePage_security(uint32_t address, const uint8_t *data, uint16_t len)
00383 {
00384         //wait busy
00385         while(spi_flash_waitBusy()) {};
00386         
00387         //setWEL
00388         spi_flash_setWEL();
00389 
00390     uint32_t * p_spi_base_address = spi_master_init(SPI0, SPI_MODE0, false);
00391     if (p_spi_base_address == NULL)
00392     {
00393         return;
00394     }
00395             
00396         nrf_gpio_pin_clear(SPI_PSELSS1_flash);
00397         
00398     spi_flash_writeOneByte(p_spi_base_address, CMD_PAGE_PROG_SECU);
00399         
00400         spi_flash_writeOneByte(p_spi_base_address, ((address >> 16) & 0xFF));
00401         spi_flash_writeOneByte(p_spi_base_address, ((address >> 8) & 0xFF));
00402         spi_flash_writeOneByte(p_spi_base_address, (address & 0xFF));
00403         
00404         /* write data */
00405         while(len--) {
00406             spi_flash_writeOneByte(p_spi_base_address, *data++);
00407         }           
00408         
00409     nrf_gpio_pin_set(SPI_PSELSS1_flash);
00410         
00411         return;
00412 }
00413 
00414 // added by Tsungta
00415 void spi_flash_read_security(uint32_t address, uint8_t *data, uint16_t len)
00416 {
00417 
00418 #ifdef FLASHDEBUG
00419         uint8_t data = 0;
00420         uint8_t i = 1;  
00421 #endif
00422     
00423         //wait busy
00424         while(spi_flash_waitBusy()) {};
00425         
00426 //      //setWEL
00427 //      spi_flash_setWEL();
00428             
00429     uint32_t * p_spi_base_address = spi_master_init(SPI0, SPI_MODE0, false);
00430     if (p_spi_base_address == NULL)
00431     {
00432         return;
00433     }
00434         
00435     nrf_gpio_pin_clear(SPI_PSELSS1_flash);
00436         
00437     spi_flash_writeOneByte(p_spi_base_address, CMD_READ_SECU);
00438         
00439         spi_flash_writeOneByte(p_spi_base_address, ((address >> 16) & 0xFF));
00440         spi_flash_writeOneByte(p_spi_base_address, ((address >> 8) & 0xFF));
00441         spi_flash_writeOneByte(p_spi_base_address, (address & 0xFF));
00442         
00443         spi_flash_readOneByte(p_spi_base_address);      // there is a dummy byte before real data
00444         /* read data */
00445         while(len--) {
00446 #ifdef FLASHDEBUG           
00447             data = spi_flash_readOneByte(p_spi_base_address);
00448           uint8_t buf[30];
00449           sprintf(buf,"0x%02X ",data);
00450           simple_uart_putstring(buf);
00451             if(i == 11)
00452             {
00453                 simple_uart_put('\n');
00454                 i = 0;
00455             }
00456             i++;
00457 #else
00458             *data++ = spi_flash_readOneByte(p_spi_base_address);
00459 #endif          
00460         }
00461     nrf_gpio_pin_set(SPI_PSELSS1_flash);        
00462 }