WIFI_API_20150524e

Revision:
0:a2de37bf5f3d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WIFI_Driver/nordic/spi_flash.c	Tue Jun 09 06:04:13 2015 +0000
@@ -0,0 +1,462 @@
+/* 
+ *	Generated for windbond flash
+ */
+
+#include <string.h>
+#include <spi_flash.h>
+//#include "nrf_delay.h"
+#include "nrf_gpio.h"
+//#include "common.h"
+#include "spi_master_config.h" // This file must be in the application folder
+
+#include "simple_uart.h"
+
+#include "spi_master.h"
+
+#include "wait_api.h"
+
+#if 1	//marcus add for flash read/write
+#define MFG_ID_WINBOND (0xEF)
+#define DEVICE_ID_WINBOND_8M (0x5014)
+
+#define CMD_POWER_UP (0xAB)
+#define CMD_JEDEC_ID	(0x9F)
+#define CMD_POWER_DOWN	(0xB9)
+#define CMD_READ_STATUS	(0x05)
+#define CMD_WRITE_ENABLE (0x06)
+#define CMD_PAGE_PROG (0x02)
+#define CMD_READ_DATA (0x03)
+#define CMD_ERASE_4K (0x20)
+#define CMD_ERASE_64K (0xD8)
+#define CMD_DUMMY	(0xFF)
+
+// added by Tsungta
+#define CMD_READ_UNIQUE_ID (0x4B)
+#define CMD_ERASE_SECU (0x44)
+#define CMD_PAGE_PROG_SECU (0x42)
+#define CMD_READ_SECU (0x48)
+
+#define	THREE_BYTE_LENGTH	3
+#define WIFIDRI_LENGTH (136568)
+#define ERASEWIFI_LENGTH (2696)
+#define DEVICE_PAGE_SIZE (256)
+#define DEVICE_SECTOR_SIZE (4096)
+#define DEVICE_BLOCK_SIZE (65536)
+#ifdef WIFI_BOOT_NORDIC
+extern const unsigned char wifi_firmware[];
+#endif
+#endif
+
+#if 1	//marcus add for flash read/write
+static bool spi_flash_writeOneByte(uint32_t *spi_base_address, uint8_t DataBuffer)
+{
+		uint8_t rx_data;
+		uint32_t counter = 0;
+    /*lint -e{826} //Are too small pointer conversion */
+    NRF_SPI_Type *spi_base = (NRF_SPI_Type *)spi_base_address;
+
+		spi_base->TXD = (uint32_t) DataBuffer;
+	
+    /* Wait for the transaction complete or timeout (about 10ms - 20 ms) */
+    while ((spi_base->EVENTS_READY == 0U) && (counter < TIMEOUT_COUNTER))
+    {
+				counter++;
+    }
+
+    if (counter == TIMEOUT_COUNTER)
+		{
+				/* timed out, disable slave (slave select active low) and return with error */
+        return false;
+    }	else {
+				/* clear the event to be ready to receive next messages */
+        spi_base->EVENTS_READY = 0U;
+		}
+		
+		/* Marcus, need to move RXD to get the next transaction*/
+		rx_data = (uint8_t)spi_base->RXD;
+		
+		return true;
+}
+
+static uint8_t spi_flash_readOneByte(uint32_t *spi_base_address)
+{
+		uint32_t counter = 0;
+    /*lint -e{826} //Are too small pointer conversion */
+    NRF_SPI_Type *spi_base = (NRF_SPI_Type *)spi_base_address;
+		
+		spi_base->TXD = 0xFF; //put dont case data
+	
+    /* Wait for the transaction complete or timeout (about 10ms - 20 ms) */
+    while ((spi_base->EVENTS_READY == 0U) && (counter < TIMEOUT_COUNTER))
+    {
+				counter++;
+    }
+
+    if (counter == TIMEOUT_COUNTER)
+		{
+        return 0;
+    }	else {
+				/* clear the event to be ready to receive next messages */
+        spi_base->EVENTS_READY = 0U;
+		}	
+	
+		return (uint8_t)spi_base->RXD;
+}
+
+//#if !defined(TARGET_DELTA_DFCM_NNN40)
+bool spi_flash_init(void)
+{
+		uint8_t mfgId;
+		uint16_t deviceID;
+	
+    uint32_t * p_spi_base_address = spi_master_init(SPI0, SPI_MODE0, false);
+    if (p_spi_base_address == NULL)
+    {
+        return false;
+    }
+		
+    nrf_gpio_pin_clear(SPI_PSELSS1_flash);
+    spi_flash_writeOneByte(p_spi_base_address, CMD_POWER_UP);
+    nrf_gpio_pin_set(SPI_PSELSS1_flash);
+		
+		//wait for wake up
+		wait_us(30);//nrf_delay_us(30);
+		
+		nrf_gpio_pin_clear(SPI_PSELSS1_flash);
+		
+		spi_flash_writeOneByte(p_spi_base_address, CMD_JEDEC_ID);
+		
+		mfgId = spi_flash_readOneByte(p_spi_base_address);
+		deviceID = (uint16_t)(spi_flash_readOneByte(p_spi_base_address) << 8);
+		deviceID |= spi_flash_readOneByte(p_spi_base_address);
+		
+		nrf_gpio_pin_set(SPI_PSELSS1_flash);
+		
+		if (mfgId != MFG_ID_WINBOND || deviceID != DEVICE_ID_WINBOND_8M) {
+				return false;
+		}
+		
+		return true;
+}
+
+bool spi_flash_powerDown(void)
+{			
+    uint32_t * p_spi_base_address = spi_master_init(SPI0, SPI_MODE0, false);
+    if (p_spi_base_address == NULL)
+    {
+        return false;
+    }
+		
+    nrf_gpio_pin_clear(SPI_PSELSS1_flash);
+    spi_flash_writeOneByte(p_spi_base_address, CMD_POWER_DOWN);
+    nrf_gpio_pin_set(SPI_PSELSS1_flash);
+		
+		//wait for sleep
+		wait_us(3);//nrf_delay_us(3);
+		
+		return true;
+}
+//#endif
+
+bool spi_flash_waitBusy(void)
+{
+		uint8_t status;
+    uint32_t * p_spi_base_address = spi_master_init(SPI0, SPI_MODE0, false);
+    if (p_spi_base_address == NULL)
+    {
+        return false;
+    }
+		
+    nrf_gpio_pin_clear(SPI_PSELSS1_flash);
+    spi_flash_writeOneByte(p_spi_base_address, CMD_READ_STATUS);
+		status = spi_flash_readOneByte(p_spi_base_address);
+    nrf_gpio_pin_set(SPI_PSELSS1_flash);
+		
+		if ( (status & 0x01) == 0x01 )
+		{
+				return true;
+		} else {
+				return false;
+		}
+}
+
+void spi_flash_setWEL(void)
+{
+    uint32_t * p_spi_base_address = spi_master_init(SPI0, SPI_MODE0, false);
+    if (p_spi_base_address == NULL)
+    {
+        return;
+    }
+		
+    nrf_gpio_pin_clear(SPI_PSELSS1_flash);
+    spi_flash_writeOneByte(p_spi_base_address, CMD_WRITE_ENABLE);
+    nrf_gpio_pin_set(SPI_PSELSS1_flash);	
+}
+
+void spi_flash_writePage(uint32_t address, const uint8_t *data, uint16_t len)
+{
+		//wait busy
+		while(spi_flash_waitBusy()) {};
+		
+		//setWEL
+		spi_flash_setWEL();
+
+    uint32_t * p_spi_base_address = spi_master_init(SPI0, SPI_MODE0, false);
+    if (p_spi_base_address == NULL)
+    {
+        return;
+    }
+			
+		nrf_gpio_pin_clear(SPI_PSELSS1_flash);
+		
+    spi_flash_writeOneByte(p_spi_base_address, CMD_PAGE_PROG);
+		
+		spi_flash_writeOneByte(p_spi_base_address, ((address >> 16) & 0xFF));
+		spi_flash_writeOneByte(p_spi_base_address, ((address >> 8) & 0xFF));
+		spi_flash_writeOneByte(p_spi_base_address, (address & 0xFF));
+		
+		/* write data */
+		while(len--) {
+			spi_flash_writeOneByte(p_spi_base_address, *data++);
+		}			
+		
+    nrf_gpio_pin_set(SPI_PSELSS1_flash);
+		
+		return;
+}
+
+void spi_flash_eraseCmd(uint8_t command, uint32_t address)
+{
+    uint32_t * p_spi_base_address = spi_master_init(SPI0, SPI_MODE0, false);
+    if (p_spi_base_address == NULL)
+    {
+        return;
+    }	
+	
+    nrf_gpio_pin_clear(SPI_PSELSS1_flash);
+		
+    spi_flash_writeOneByte(p_spi_base_address, command);
+		
+		spi_flash_writeOneByte(p_spi_base_address, ((address >> 16) & 0xFF));
+		spi_flash_writeOneByte(p_spi_base_address, ((address >> 8) & 0xFF));
+		spi_flash_writeOneByte(p_spi_base_address, (address & 0xFF));
+    
+		nrf_gpio_pin_set(SPI_PSELSS1_flash);	
+}
+
+void spi_flash_erase(void)
+{
+		uint32_t address = 0;
+		uint32_t totalLength = WIFIDRI_LENGTH + ERASEWIFI_LENGTH;	//To map SECTOR size
+
+		//wait busy
+		while(spi_flash_waitBusy()) {};
+
+		//setWEL
+		spi_flash_setWEL();			
+
+		// handle any full blocks
+		while(totalLength >= DEVICE_BLOCK_SIZE) {
+			spi_flash_eraseCmd(CMD_ERASE_64K, address);
+			address += DEVICE_BLOCK_SIZE;
+			totalLength -= DEVICE_BLOCK_SIZE;
+		}	
+
+		// finally handle any trailing partial blocks
+		while(totalLength) {
+			spi_flash_eraseCmd(CMD_ERASE_4K, address);
+			address += DEVICE_SECTOR_SIZE;
+			totalLength -= DEVICE_SECTOR_SIZE;
+		}
+
+		return;
+}
+
+static bool m_spi_result = true;
+
+void spi_flash_readpage(uint32_t address, uint8_t *data, uint16_t len)
+{
+
+		uint16_t i = 0;	
+	
+		//wait busy
+		while(spi_flash_waitBusy()) {};
+			
+    uint32_t * p_spi_base_address = spi_master_init(SPI0, SPI_MODE0, false);
+    if (p_spi_base_address == NULL)
+    {
+				m_spi_result = false;
+        return;
+    }
+		
+    nrf_gpio_pin_clear(SPI_PSELSS1_flash);
+		
+    spi_flash_writeOneByte(p_spi_base_address, CMD_READ_DATA);
+		
+		spi_flash_writeOneByte(p_spi_base_address, ((address >> 16) & 0xFF));
+		spi_flash_writeOneByte(p_spi_base_address, ((address >> 8) & 0xFF));
+		spi_flash_writeOneByte(p_spi_base_address, (address & 0xFF));
+		
+		/* read data */
+		
+		for (i=0; i < len; i++){	// only totalLength bytes (<4096) left 
+				*data++ = spi_flash_readOneByte(p_spi_base_address);
+		}		
+		
+    nrf_gpio_pin_set(SPI_PSELSS1_flash);	
+}
+	#ifdef WIFI_BOOT_NORDIC
+void spi_flash_write(void)
+{
+	uint32_t totalLength = WIFIDRI_LENGTH;
+	uint32_t address = 0;
+	uint16_t len = DEVICE_PAGE_SIZE;
+
+	const uint8_t *data = wifi_firmware;
+
+
+  while(totalLength) {
+    spi_flash_writePage(address, data, len);
+    totalLength -= len;
+    address += len;
+    data += len;
+    len = (totalLength>DEVICE_PAGE_SIZE)? DEVICE_PAGE_SIZE : totalLength;
+  }	
+}
+#endif
+#endif
+
+// added by Tsungta
+void spi_flash_read_uniqueID(uint8_t *data)
+{
+		uint8_t dummy_len = 4;
+		uint8_t id_len = 8;
+		//wait busy
+		while(spi_flash_waitBusy()) {};
+			
+    uint32_t * p_spi_base_address = spi_master_init(SPI0, SPI_MODE0, false);
+    if (p_spi_base_address == NULL)
+    {
+        return;
+    }
+		
+    nrf_gpio_pin_clear(SPI_PSELSS1_flash);
+		
+    spi_flash_writeOneByte(p_spi_base_address, CMD_READ_UNIQUE_ID);
+		while(dummy_len--)
+			spi_flash_readOneByte(p_spi_base_address);		// there is four dummy bytes before real data
+		/* id data */
+		while(id_len--) 
+			*data++ = spi_flash_readOneByte(p_spi_base_address);			
+
+    nrf_gpio_pin_set(SPI_PSELSS1_flash);		
+}
+
+// added by Tsungta
+void spi_flash_erase_security(uint32_t address)
+{
+		//wait busy
+		while(spi_flash_waitBusy()) {};
+
+		//setWEL
+		spi_flash_setWEL();
+			
+		uint32_t * p_spi_base_address = spi_master_init(SPI0, SPI_MODE0, false);
+    if (p_spi_base_address == NULL)
+    {
+        return;
+    }	
+	
+    nrf_gpio_pin_clear(SPI_PSELSS1_flash);
+		
+    spi_flash_writeOneByte(p_spi_base_address, CMD_ERASE_SECU);
+		
+		spi_flash_writeOneByte(p_spi_base_address, ((address >> 16) & 0xFF));
+		spi_flash_writeOneByte(p_spi_base_address, ((address >> 8) & 0xFF));
+		spi_flash_writeOneByte(p_spi_base_address, (address & 0xFF));
+    
+		nrf_gpio_pin_set(SPI_PSELSS1_flash);	
+}
+
+// added by Tsungta
+void spi_flash_writePage_security(uint32_t address, const uint8_t *data, uint16_t len)
+{
+		//wait busy
+		while(spi_flash_waitBusy()) {};
+		
+		//setWEL
+		spi_flash_setWEL();
+
+    uint32_t * p_spi_base_address = spi_master_init(SPI0, SPI_MODE0, false);
+    if (p_spi_base_address == NULL)
+    {
+        return;
+    }
+			
+		nrf_gpio_pin_clear(SPI_PSELSS1_flash);
+		
+    spi_flash_writeOneByte(p_spi_base_address, CMD_PAGE_PROG_SECU);
+		
+		spi_flash_writeOneByte(p_spi_base_address, ((address >> 16) & 0xFF));
+		spi_flash_writeOneByte(p_spi_base_address, ((address >> 8) & 0xFF));
+		spi_flash_writeOneByte(p_spi_base_address, (address & 0xFF));
+		
+		/* write data */
+		while(len--) {
+			spi_flash_writeOneByte(p_spi_base_address, *data++);
+		}			
+		
+    nrf_gpio_pin_set(SPI_PSELSS1_flash);
+		
+		return;
+}
+
+// added by Tsungta
+void spi_flash_read_security(uint32_t address, uint8_t *data, uint16_t len)
+{
+
+#ifdef FLASHDEBUG
+		uint8_t data = 0;
+		uint8_t i = 1;	
+#endif
+	
+		//wait busy
+		while(spi_flash_waitBusy()) {};
+		
+//		//setWEL
+//		spi_flash_setWEL();
+			
+    uint32_t * p_spi_base_address = spi_master_init(SPI0, SPI_MODE0, false);
+    if (p_spi_base_address == NULL)
+    {
+        return;
+    }
+		
+    nrf_gpio_pin_clear(SPI_PSELSS1_flash);
+		
+    spi_flash_writeOneByte(p_spi_base_address, CMD_READ_SECU);
+		
+		spi_flash_writeOneByte(p_spi_base_address, ((address >> 16) & 0xFF));
+		spi_flash_writeOneByte(p_spi_base_address, ((address >> 8) & 0xFF));
+		spi_flash_writeOneByte(p_spi_base_address, (address & 0xFF));
+		
+		spi_flash_readOneByte(p_spi_base_address);		// there is a dummy byte before real data
+		/* read data */
+		while(len--) {
+#ifdef FLASHDEBUG			
+			data = spi_flash_readOneByte(p_spi_base_address);
+		  uint8_t buf[30];
+		  sprintf(buf,"0x%02X ",data);
+		  simple_uart_putstring(buf);
+			if(i == 11)
+			{
+				simple_uart_put('\n');
+				i = 0;
+			}
+			i++;
+#else
+			*data++ = spi_flash_readOneByte(p_spi_base_address);
+#endif			
+		}
+    nrf_gpio_pin_set(SPI_PSELSS1_flash);		
+}