📄 m25lc512.c
字号:
//// $Id: m25lc512.c 331 2008-11-09 16:59:47Z jcw $// $Revision: 331 $// $Author: jcw $// $Date: 2008-11-09 11:59:47 -0500 (Sun, 09 Nov 2008) $// $HeadURL: http://tinymicros.com/svn_public/arm/lpc2148_demo/trunk/spi/m25lc512.c $//#include <string.h>#include "FreeRTOS.h"#include "task.h"#include "spi.h"#include "m25lc512.h"//////#define M25LC512_Select() GPIO0_FIOCLR = GPIO_IO_P7#define M25LC512_Deselect() GPIO0_FIOSET = GPIO_IO_P7#define SR_WPEN 0x80 // Write Protect Enable#define SR_NU6 0x40 // Not used, returns 0#define SR_NU5 0x20 // Not used, returns 0#define SR_NU4 0x10 // Not used, returns 0#define SR_BP1 0x08 // Block Protect 1#define SR_BP0 0x04 // Block Protect 0#define SR_WEL 0x02 // Write Enable Latch#define SR_WIP 0x01 // Write In Progress//////typedef enum{ MC25LC_WRSR = 0x01, // Write STATUS register MC25LC_WRITE = 0x02, // Write data to memory array beginning at selected address MC25LC_READ = 0x03, // Read data from memory array beginning at selected address MC25LC_WRDI = 0x04, // Reset the write enable latch MC25LC_RDSR = 0x05, // Read STATUS register MC25LC_WREN = 0x06, // Set the write enable latch MC25LC_PE = 0x42, // Page erase (pages are 128 bytes) MC25LC_RDID = 0xab, // Release from Deep power-down and read electronic signature MC25LC_DPD = 0xb9, // Deep Power-Down mode MC25LC_CE = 0xc7, // Chip erase (0x0000-0xffff) MC25LC_SE = 0xd8 // Sector erase (0x0000-0x3fff, 0x4000-0x7fff, 0x8000-0xbfff, 0xc000-0xffff)}mc25lc_e;typedef struct m25lc512ErrorList_s{ m25lc_e e; const char *t;}m25lc512ErrorList_t;//////static U32 rwAddress;static const m25lc512ErrorList_t m25lc512ErrorList [] ={ { M25LC_OK, "OK" }, { M25LC_TIMEOUT, "Timeout" }, { M25LC_NODEVICE, "No device present" }, { M25LC_ADDRERR, "Address range error" }, { M25LC_SECTORERR, "Sector range error" }, { M25LC_PAGEERR, "Page range error" }, { M25LC_WP, "Write protected" }, { M25LC_WIP, "Write in progress" }, { M25LC_LAST, "Unknown error" },};//////static U8 m25lc512SendByte (U8 byte){ M25LC512_Select (); byte = spiPut (byte); M25LC512_Deselect (); return byte;}static m25lc_e m25lc512CheckWriteInProgress (void){ U8 status; m25lc512StatusRead (&status); if ((status & (SR_NU6 | SR_NU5 | SR_NU4 | SR_WIP)) == SR_WIP) return M25LC_WIP; return M25LC_OK;}static m25lc_e m25lc512WaitNotWriting (void){ if (m25lc512CheckWriteInProgress () == M25LC_WIP) { int i; for (i = 0; i < 10; i++) { vTaskDelay (10 / portTICK_RATE_MS); if (m25lc512CheckWriteInProgress () == M25LC_OK) return M25LC_OK; } return M25LC_TIMEOUT; } return M25LC_OK;}static m25lc_e m25lc512SendByteEx (U8 byte){ m25lc_e r; if ((r = m25lc512WaitNotWriting ()) != M25LC_OK) return r; m25lc512SendByte (byte); return M25LC_OK;}static m25lc_e m25lc512CheckWriteEnabled (void){ U8 status; m25lc512StatusRead (&status); if ((status & (SR_NU6 | SR_NU5 | SR_NU4 | SR_WEL)) != SR_WEL) return M25LC_WP; return M25LC_OK;}//// m25lc512Init() never called because main() does spiInit(). But you *could*// call it...//void m25lc512Init (void){ spiInit ();}const char *m25lc512Strerror (m25lc_e e){ m25lc_e i; for (i = 0; m25lc512ErrorList [i].e != M25LC_LAST; i++) if (e == m25lc512ErrorList [i].e) return m25lc512ErrorList [i].t; return m25lc512ErrorList [i].t;}m25lc_e m25lc512ReadID (U8 *id){ U8 rdid; m25lc_e r; if ((r = m25lc512WaitNotWriting ()) != M25LC_OK) return r; M25LC512_Select (); spiPut (MC25LC_RDID); spiPut (0); spiPut (0); rdid = spiPut (0); M25LC512_Deselect (); if (!rdid || (rdid == 0xff)) return M25LC_NODEVICE; *id = rdid; return M25LC_OK;}m25lc_e m25lc512DeepPowerDown (void){ return m25lc512SendByteEx (MC25LC_DPD);}m25lc_e m25lc512StatusRead (U8 *rdsr){ M25LC512_Select (); spiPut (MC25LC_RDSR); *rdsr = spiPut (0); M25LC512_Deselect (); return M25LC_OK;}m25lc_e m25lc512StatusWrite (U8 wrsr){ m25lc_e r; if ((r = m25lc512WaitNotWriting ()) != M25LC_OK) return r; M25LC512_Select (); spiPut (MC25LC_WRSR); spiPut (wrsr); M25LC512_Deselect (); return M25LC_OK;}m25lc_e m25lc512WriteEnable (void){ return m25lc512SendByteEx (MC25LC_WREN);}m25lc_e m25lc512WriteDisable (void){ return m25lc512SendByteEx (MC25LC_WRDI);}m25lc_e m25lc512ErasePage (U32 page){ if (page > M25LC512_LASTPAGE) return M25LC_PAGEERR; page *= M25LC512_PAGESIZE; M25LC512_Select (); spiPut (MC25LC_PE); spiPut (page >> 8); spiPut (page & 0xff); M25LC512_Deselect (); return M25LC_OK;}m25lc_e m25lc512EraseSector (U32 sector){ if (sector > M25LC512_LASTSECTOR) return M25LC_SECTORERR; sector *= M25LC512_SECTORSIZE; M25LC512_Select (); spiPut (MC25LC_SE); spiPut (sector >> 8); spiPut (sector & 0xff); M25LC512_Deselect (); return M25LC_OK;}m25lc_e m25lc512EraseChip (void){ return m25lc512SendByteEx (MC25LC_CE);}m25lc_e m25lc512SetAddress (U32 address){ if (address >= M25LC512_SIZE) return M25LC_ADDRERR; rwAddress = address; return M25LC_OK;}int m25lc512GetAddress (void){ return rwAddress;}m25lc_e m25lc512Read (U8 *buffer, U32 bufferLength){ U32 i; m25lc_e r; if ((r = m25lc512WaitNotWriting ()) != M25LC_OK) return r; M25LC512_Select (); spiPut (MC25LC_READ); spiPut (rwAddress >> 8); spiPut (rwAddress & 0xff); for (i = 0; i < bufferLength; i++) buffer [i] = spiPut (0); M25LC512_Deselect (); rwAddress += bufferLength; return M25LC_OK;}m25lc_e m25lc512ReadAddress (U32 address, U8 *buffer, U32 bufferLength){ m25lc_e r; if ((r = m25lc512SetAddress (address)) != M25LC_OK) return r; return m25lc512Read (buffer, bufferLength);}m25lc_e m25lc512Write (U8 *buffer, U32 bufferLength){ U32 i; m25lc_e r; if ((r = m25lc512WaitNotWriting ()) != M25LC_OK) return r; M25LC512_Select (); spiPut (MC25LC_WRITE); spiPut (rwAddress >> 8); spiPut (rwAddress & 0xff); for (i = 0; i < bufferLength; i++) spiPut (buffer [i]); M25LC512_Deselect (); rwAddress += bufferLength; return M25LC_OK;}m25lc_e m25lc512WriteAddress (U32 address, U8 *buffer, U32 bufferLength){ int r; if ((r = m25lc512SetAddress (address)) != M25LC_OK) return r; return m25lc512Write (buffer, bufferLength);}static m25lc_e m25lc512FillAddressCommon (U32 address, U8 *buffer, U32 bufferLength){ m25lc_e r; if ((r = m25lc512WriteEnable ()) == M25LC_OK) if ((r = m25lc512SetAddress (address)) == M25LC_OK) r = m25lc512Write (buffer, bufferLength); return r;}m25lc_e m25lc512FillAddress (U32 address, U32 length, U8 fillValue){ m25lc_e r; U32 l; U32 i; U8 buffer [M25LC512_PAGESIZE]; if (address + length > M25LC512_SIZE) return M25LC_ADDRERR; if ((r = m25lc512CheckWriteEnabled ()) != M25LC_OK) return r; memset (buffer, fillValue, sizeof (buffer)); l = (M25LC512_PAGESIZE - ((address + M25LC512_PAGESIZE) % M25LC512_PAGESIZE)) % M25LC512_PAGESIZE; l = MIN (l, length); if (l && ((r = m25lc512FillAddressCommon (address, buffer, l)) != M25LC_OK)) if (((r = m25lc512FillAddressCommon (address, buffer, l)) != M25LC_OK)) return r; address += l; length -= l; l = length - (length % M25LC512_PAGESIZE); for (i = 0; i < l; i += M25LC512_PAGESIZE, address += sizeof (buffer), length -= sizeof (buffer)) if ((r = m25lc512FillAddressCommon (address, buffer, sizeof (buffer))) != M25LC_OK) return r; if (length && ((r = m25lc512FillAddressCommon (address, buffer, length)) != M25LC_OK)) if (((r = m25lc512FillAddressCommon (address, buffer, length)) != M25LC_OK)) return r; return M25LC_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -