Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 }
Generated on Mon Jul 25 2022 10:33:26 by
1.7.2