43 #define NAND_POWER_PORT 1
44 #define NAND_POWER_PIN (1 << 15)
45 #define NAND_READY_PORT 3
46 #define NAND_READY_PIN (1 << 15)
47 #define NAND_CE_PORT 3
48 #define NAND_CE_PIN (1 << 14)
49 #define NAND_WP_PORT 3
50 #define NAND_WP_PIN (1 << 13)
51 #define NAND_ALE_BIT 24
52 #define NAND_CLE_BIT 25
55 #define NAND256W3A_SIGNATURE 0x7520
56 #define NAND256W3A_SIZE (32 * 1024 * 1024)
57 #define NAND256W3A_PAGESIZE 512
58 #define NAND256W3A_BLOCKSIZE (16 * 1024)
61 #define NAND_PAGEADDR_MASK (NAND256W3A_PAGESIZE - 1)
62 #define NAND_BLOCKADDR_MASK (NAND256W3A_BLOCKSIZE - 1)
64 #define NAND_RDA_CMD 0x00
65 #define NAND_RDB_CMD 0x01
66 #define NAND_RDC_CMD 0x50
67 #define NAND_RDSIGN_CMD 0x90
68 #define NAND_RDSTATUS_CMD 0x70
69 #define NAND_PAGEPROG1_CMD 0x80
70 #define NAND_PAGEPROG2_CMD 0x10
71 #define NAND_CPBPROG1_CMD 0x00
72 #define NAND_CPBPROG2_CMD 0x8A
73 #define NAND_CPBPROG3_CMD 0x10
74 #define NAND_BLOCKERASE1_CMD 0x60
75 #define NAND_BLOCKERASE2_CMD 0xD0
76 #define NAND_RST_CMD 0xFF
78 #define NAND_STATUS_SR7 0x80
79 #define NAND_STATUS_SR6 0x40
80 #define NAND_STATUS_SR0 0x01
83 #define NAND_DATA8 *pNandData8
84 #define NAND_DATA16 *pNandData16
85 #define NAND_DATA32 *pNandData32
86 #define NAND_ADDR *pNandAddr
87 #define NAND_CMD *pNandCmd
93 .controlBlock = dmaControlBlock
124 static bool flashInitialized =
false;
126 static uint8_t
volatile *pNandData8;
127 static uint16_t
volatile *pNandData16;
128 static uint32_t
volatile *pNandData32;
129 static uint8_t
volatile *pNandAddr;
130 static uint8_t
volatile *pNandCmd;
133 __STATIC_INLINE
void chipEnable(
bool enable);
134 static int flashInterrogate(
void);
135 __STATIC_INLINE
void powerEnable(
bool enable);
136 static uint16_t readSignature(
void);
137 static uint8_t readStatus(
void);
138 static void reset(
void);
139 static void dmaRead(uint8_t *dst,
int count);
140 static void dmaWrite(uint8_t *src,
int count);
141 __STATIC_INLINE
void waitReady(
void);
142 __STATIC_INLINE
void writeProtect(
bool enable);
158 if (flashInitialized)
192 if (!flashInitialized)
198 dstAddr &= ~NAND_PAGEADDR_MASK;
199 srcAddr &= ~NAND_PAGEADDR_MASK;
204 ((dstAddr & (1 << 24)) != (srcAddr & (1 << 24))))
213 NAND_CMD = NAND_CPBPROG1_CMD;
214 NAND_ADDR = (uint8_t) srcAddr;
216 NAND_ADDR = (uint8_t)(srcAddr >> 9);
217 NAND_ADDR = (uint8_t)(srcAddr >> 17);
221 NAND_CMD = NAND_CPBPROG2_CMD;
222 NAND_ADDR = (uint8_t) dstAddr;
224 NAND_ADDR = (uint8_t)(dstAddr >> 9);
225 NAND_ADDR = (uint8_t)(dstAddr >> 17);
226 NAND_CMD = NAND_CPBPROG3_CMD;
230 status = (readStatus() & NAND_STATUS_SR0) ?
250 if (flashInitialized)
278 #define ECC_MASK24 0x00FFFFFF
279 #define ECC_MASK 0x00555555
282 int count, bitNum, byteAddr;
288 syndrome = (generatedEcc ^ readEcc) & ECC_MASK24;
293 eccPn = syndrome & ECC_MASK;
294 eccP = (syndrome >> 1) & ECC_MASK;
296 if ((eccPn ^ eccP) == ECC_MASK)
298 bitNum = (eccP & 0x01) |
299 ((eccP >> 1) & 0x02) |
300 ((eccP >> 2) & 0x04);
302 byteAddr = ((eccP >> 6) & 0x001) |
303 ((eccP >> 7) & 0x002) |
304 ((eccP >> 8) & 0x004) |
305 ((eccP >> 9) & 0x008) |
306 ((eccP >> 10) & 0x010) |
307 ((eccP >> 11) & 0x020) |
308 ((eccP >> 12) & 0x040) |
309 ((eccP >> 13) & 0x080) |
310 ((eccP >> 14) & 0x100);
312 data[ byteAddr ] ^= 1 << bitNum;
357 if (!flashInitialized)
363 address &= ~NAND_BLOCKADDR_MASK;
374 NAND_CMD = NAND_BLOCKERASE1_CMD;
376 NAND_ADDR = (uint8_t)(address >> 9);
377 NAND_ADDR = (uint8_t)(address >> 17);
378 NAND_CMD = NAND_BLOCKERASE2_CMD;
382 status = (readStatus() & NAND_STATUS_SR0) ?
415 flashInfo.
dmaCh = dmaCh;
423 return flashInterrogate();
444 if (!flashInitialized)
450 address &= ~NAND_BLOCKADDR_MASK;
461 NAND_CMD = NAND_RDC_CMD;
462 NAND_CMD = NAND_PAGEPROG1_CMD;
463 NAND_ADDR = (uint8_t) address;
465 NAND_ADDR = (uint8_t)(address >> 9);
466 NAND_ADDR = (uint8_t)(address >> 17);
469 NAND_DATA32 = 0xFFFFFFFF;
470 NAND_DATA16 = 0x00FF;
471 NAND_CMD = NAND_PAGEPROG2_CMD;
502 uint32_t i, readEcc, *p;
504 if (!flashInitialized)
510 address &= ~NAND_PAGEADDR_MASK;
520 NAND_CMD = NAND_RDA_CMD;
521 NAND_ADDR = (uint8_t) address;
523 NAND_ADDR = (uint8_t)(address >> 9);
524 NAND_ADDR = (uint8_t)(address >> 17);
528 EBI_StartNandEccGen();
530 if (flashInfo.
dmaCh == -1)
532 p = (uint32_t*) buffer;
533 for (i = 0; i < flashInfo.
pageSize / 4; i++)
540 dmaRead(buffer, flashInfo.
pageSize);
543 flashInfo.
ecc = EBI_StopNandEccGen();
545 if (flashInfo.
dmaCh == -1)
547 p = (uint32_t*) flashInfo.
spare;
548 for (i = 0; i < flashInfo.
spareSize / 4; i++)
585 if (!flashInitialized)
591 address &= ~NAND_PAGEADDR_MASK;
601 NAND_CMD = NAND_RDC_CMD;
602 NAND_ADDR = (uint8_t) address;
604 NAND_ADDR = (uint8_t)(address >> 9);
605 NAND_ADDR = (uint8_t)(address >> 17);
609 if (flashInfo.
dmaCh == -1)
611 p = (uint32_t*) buffer;
612 for (i = 0; i < flashInfo.
spareSize / 4; i++)
651 if (!flashInitialized)
657 address &= ~NAND_PAGEADDR_MASK;
668 NAND_CMD = NAND_RDA_CMD;
669 NAND_CMD = NAND_PAGEPROG1_CMD;
670 NAND_ADDR = (uint8_t) address;
672 NAND_ADDR = (uint8_t)(address >> 9);
673 NAND_ADDR = (uint8_t)(address >> 17);
676 while (EBI->STATUS & EBI_STATUS_AHBACT)
679 EBI_StartNandEccGen();
681 if (flashInfo.
dmaCh == -1)
683 p = (uint32_t*) buffer;
684 for (i = 0; i < flashInfo.
pageSize / 4; i++)
691 dmaWrite(buffer, flashInfo.
pageSize);
695 while (EBI->STATUS & EBI_STATUS_AHBACT)
698 flashInfo.
ecc = EBI_StopNandEccGen();
701 NAND_DATA32 = 0xFFFFFFFF;
702 NAND_DATA16 = 0xFFFF;
703 NAND_DATA8 = flashInfo.
ecc;
704 NAND_DATA8 = flashInfo.
ecc >> 8;
705 NAND_DATA8 = flashInfo.
ecc >> 16;
706 NAND_CMD = NAND_PAGEPROG2_CMD;
710 status = (readStatus() & NAND_STATUS_SR0) ?
724 __STATIC_INLINE
void chipEnable(
bool enable)
728 GPIO->P[NAND_CE_PORT].DOUTCLR = NAND_CE_PIN;
732 GPIO->P[NAND_CE_PORT].DOUTSET = NAND_CE_PIN;
739 static int flashInterrogate(
void)
741 flashInfo.
baseAddress = EBI_BankAddress(EBI_BANK0);
743 pNandData8 = (uint8_t
volatile*) flashInfo.
baseAddress;
744 pNandData16 = (uint16_t
volatile*) pNandData8;
745 pNandData32 = (uint32_t
volatile*) pNandData8;
746 pNandAddr = pNandData8 + (1 << NAND_ALE_BIT);
747 pNandCmd = pNandData8 + (1 << NAND_CLE_BIT);
754 if (readSignature() != NAND256W3A_SIGNATURE)
763 flashInfo.
deviceCode = (uint8_t)(NAND256W3A_SIGNATURE >> 8);
765 flashInfo.
pageSize = NAND256W3A_PAGESIZE;
767 flashInfo.
blockSize = NAND256W3A_BLOCKSIZE;
769 flashInitialized =
true;
777 __STATIC_INLINE
void powerEnable(
bool enable)
781 GPIO->P[NAND_POWER_PORT].DOUTSET = NAND_POWER_PIN;
785 GPIO->P[NAND_POWER_PORT].DOUTCLR = NAND_POWER_PIN;
792 static uint16_t readSignature(
void)
794 NAND_CMD = NAND_RDSIGN_CMD;
801 static uint8_t readStatus(
void)
803 NAND_CMD = NAND_RDSTATUS_CMD;
810 static void reset(
void)
812 NAND_CMD = NAND_RST_CMD;
819 static void dmaRead(uint8_t *dst,
int count)
832 static void dmaWrite(uint8_t *src,
int count)
845 __STATIC_INLINE
void waitReady(
void)
848 while (EBI->STATUS & EBI_STATUS_AHBACT)
852 while ((
GPIO->P[NAND_READY_PORT].DIN & NAND_READY_PIN) == 0)
860 __STATIC_INLINE
void writeProtect(
bool enable)
864 GPIO->P[NAND_WP_PORT].DOUTCLR = NAND_WP_PIN;
868 GPIO->P[NAND_WP_PORT].DOUTSET = NAND_WP_PIN;
#define NAND_SPARE_ECC2_POS
#define DMA_CTRL_CYCLE_CTRL_INVALID
DMA_DataInc_TypeDef dstInc
uint8_t spare[NAND256W3A_SPARESIZE]
int NANDFLASH_WritePage(uint32_t address, uint8_t *buffer)
Write a page in nand device. The ECC generated while writing the page data is written in the spare ar...
CMSIS Cortex-M Peripheral Access Layer for Silicon Laboratories microcontroller devices.
int NANDFLASH_MarkBadBlock(uint32_t address)
Mark a block as bad.
#define NAND_SPARE_ECC1_POS
int NANDFLASH_CopyPage(uint32_t dstAddr, uint32_t srcAddr)
Copy a page within the device to a new location.
EFM32GG_STK3700 nandflash driver.
External Bus Iterface (EBI) peripheral API.
int NANDFLASH_ReadSpare(uint32_t address, uint8_t *buffer)
Read the spare area content of a page.
void DMA_Init(DMA_Init_TypeDef *init)
Initializes DMA controller.
void DMA_CfgChannel(unsigned int channel, DMA_CfgChannel_TypeDef *cfg)
Configure a DMA channel.
int NANDFLASH_Init(int dmaCh)
Initialize the NANDFLASH module.
int NANDFLASH_EccCorrect(uint32_t generatedEcc, uint32_t readEcc, uint8_t *data)
Check generated ECC against ECC read from device and correct data if possible.
NANDFLASH_Info_TypeDef * NANDFLASH_DeviceInfo(void)
Return a pointer to a NANDFLASH_Info_TypeDef structure, which contain vital nand flash device informa...
#define NAND_SPARE_ECC0_POS
NANDFLASH device information structure.
#define NAND256W3A_SPARESIZE
int NANDFLASH_ReadPage(uint32_t address, uint8_t *buffer)
Read a page from nand device. Ecc errors will be detected and corrected if possible. NANDFLASH_Info_TypeDef::ecc will be set to the ecc generated while reading the page data. NANDFLASH_Info_TypeDef::spare will be set to the content of the page spare area.
int NANDFLASH_EraseBlock(uint32_t address)
Erase a block in the nand flash.
#define _DMA_CTRL_CYCLE_CTRL_MASK
Direct memory access (DMA) API.
void DMA_ActivateAuto(unsigned int channel, bool primary, void *dst, const void *src, unsigned int nMinus1)
Activate DMA auto-request cycle (used for memory-memory transfers).
bool NANDFLASH_AddressValid(uint32_t address)
Check if an address is valid for the nand flash device.
void DMA_CfgDescr(unsigned int channel, bool primary, DMA_CfgDescr_TypeDef *cfg)
Configure DMA descriptor for auto-request, basic or ping-pong DMA cycles.