- /**************************************************************************//**
- * [url=home.php?mod=space&uid=288409]@file[/url] main.c
- * [url=home.php?mod=space&uid=895143]@version[/url] V2.0
- * $Revision: 11 $
- * $Date: 15/03/04 9:47a $
- * [url=home.php?mod=space&uid=247401]@brief[/url] Access the SPI Flash through a SPI interface.
- *
- * @note
- * Copyright (C) 2015 Nuvoton Technology Corp. All rights reserved.
- *
- ******************************************************************************/
- #include <stdio.h>
- #include "NUC505Series.h"
- #define TEST_NUMBER 1 /* page numbers */
- #define TEST_LENGTH 256 /* length */
- #define SPI_FLASH_PORT SPI0
- uint8_t SrcArray[TEST_LENGTH];
- uint8_t DestArray[TEST_LENGTH];
- /* Function prototype declaration */
- void SYS_Init(void);
- void UART0_Init(void);
- void SPI0_Init(void);
- uint16_t SpiFlash_ReadMidDid(void)
- {
- uint8_t u8RxData[6], u8IDCnt = 0;
- // /CS: active
- SPI_SET_SS_LOW(SPI_FLASH_PORT);
- // send Command: 0x90, Read Manufacturer/Device ID
- SPI_WRITE_TX(SPI_FLASH_PORT, 0x90);
- // send 24-bit '0', dummy
- SPI_WRITE_TX(SPI_FLASH_PORT, 0x00);
- SPI_WRITE_TX(SPI_FLASH_PORT, 0x00);
- SPI_WRITE_TX(SPI_FLASH_PORT, 0x00);
- // receive 16-bit
- SPI_WRITE_TX(SPI_FLASH_PORT, 0x00);
- SPI_WRITE_TX(SPI_FLASH_PORT, 0x00);
- // wait tx finish
- while(SPI_IS_BUSY(SPI_FLASH_PORT));
- // /CS: de-active
- SPI_SET_SS_HIGH(SPI_FLASH_PORT);
- while(!SPI_GET_RX_FIFO_EMPTY_FLAG(SPI_FLASH_PORT))
- u8RxData[u8IDCnt ++] = SPI_READ_RX(SPI_FLASH_PORT);
- return ( (u8RxData[4]<<8) | u8RxData[5] );
- }
- void SpiFlash_ChipErase(void)
- {
- // /CS: active
- SPI_SET_SS_LOW(SPI_FLASH_PORT);
- // send Command: 0x06, Write enable
- SPI_WRITE_TX(SPI_FLASH_PORT, 0x06);
- // wait tx finish
- while(SPI_IS_BUSY(SPI_FLASH_PORT));
- // /CS: de-active
- SPI_SET_SS_HIGH(SPI_FLASH_PORT);
- //////////////////////////////////////////
- // /CS: active
- SPI_SET_SS_LOW(SPI_FLASH_PORT);
- // send Command: 0xC7, Chip Erase
- SPI_WRITE_TX(SPI_FLASH_PORT, 0xC7);
- // wait tx finish
- while(SPI_IS_BUSY(SPI_FLASH_PORT));
- // /CS: de-active
- SPI_SET_SS_HIGH(SPI_FLASH_PORT);
- SPI_ClearRxFIFO(SPI0);
- }
- uint8_t SpiFlash_ReadStatusReg(void)
- {
- // /CS: active
- SPI_SET_SS_LOW(SPI_FLASH_PORT);
- // send Command: 0x05, Read status register
- SPI_WRITE_TX(SPI_FLASH_PORT, 0x05);
- // read status
- SPI_WRITE_TX(SPI_FLASH_PORT, 0x00);
- // wait tx finish
- while(SPI_IS_BUSY(SPI_FLASH_PORT));
- // /CS: de-active
- SPI_SET_SS_HIGH(SPI_FLASH_PORT);
- // skip first rx data
- SPI_READ_RX(SPI_FLASH_PORT);
- return (SPI_READ_RX(SPI_FLASH_PORT) & 0xff);
- }
- void SpiFlash_WriteStatusReg(uint8_t u8Value)
- {
- // /CS: active
- SPI_SET_SS_LOW(SPI_FLASH_PORT);
- // send Command: 0x06, Write enable
- SPI_WRITE_TX(SPI_FLASH_PORT, 0x06);
- // wait tx finish
- while(SPI_IS_BUSY(SPI_FLASH_PORT));
- // /CS: de-active
- SPI_SET_SS_HIGH(SPI_FLASH_PORT);
- ///////////////////////////////////////
- // /CS: active
- SPI_SET_SS_LOW(SPI_FLASH_PORT);
- // send Command: 0x01, Write status register
- SPI_WRITE_TX(SPI_FLASH_PORT, 0x01);
- // write status
- SPI_WRITE_TX(SPI_FLASH_PORT, u8Value);
- // wait tx finish
- while(SPI_IS_BUSY(SPI_FLASH_PORT));
- // /CS: de-active
- SPI_SET_SS_HIGH(SPI_FLASH_PORT);
- }
- void SpiFlash_WaitReady(void)
- {
- uint8_t ReturnValue;
- do {
- ReturnValue = SpiFlash_ReadStatusReg();
- ReturnValue = ReturnValue & 1;
- } while(ReturnValue!=0); // check the BUSY bit
- }
- void SpiFlash_NormalPageProgram(uint32_t StartAddress, uint8_t *u8DataBuffer)
- {
- uint32_t i = 0;
- // /CS: active
- SPI_SET_SS_LOW(SPI_FLASH_PORT);
- // send Command: 0x06, Write enable
- SPI_WRITE_TX(SPI_FLASH_PORT, 0x06);
- // wait tx finish
- while(SPI_IS_BUSY(SPI_FLASH_PORT));
- // /CS: de-active
- SPI_SET_SS_HIGH(SPI_FLASH_PORT);
- // /CS: active
- SPI_SET_SS_LOW(SPI_FLASH_PORT);
- // send Command: 0x02, Page program
- SPI_WRITE_TX(SPI_FLASH_PORT, 0x02);
- // send 24-bit start address
- SPI_WRITE_TX(SPI_FLASH_PORT, (StartAddress>>16) & 0xFF);
- SPI_WRITE_TX(SPI_FLASH_PORT, (StartAddress>>8) & 0xFF);
- SPI_WRITE_TX(SPI_FLASH_PORT, StartAddress & 0xFF);
- // write data
- while(1) {
- if(!SPI_GET_TX_FIFO_FULL_FLAG(SPI_FLASH_PORT)) {
- SPI_WRITE_TX(SPI_FLASH_PORT, u8DataBuffer[i++]);
- if(i >= 255) break;
- }
- }
- // wait tx finish
- while(SPI_IS_BUSY(SPI_FLASH_PORT));
- // /CS: de-active
- SPI_SET_SS_HIGH(SPI_FLASH_PORT);
- SPI_ClearRxFIFO(SPI_FLASH_PORT);
- }
- void SpiFlash_NormalRead(uint32_t StartAddress, uint8_t *u8DataBuffer)
- {
- uint32_t i;
- // /CS: active
- SPI_SET_SS_LOW(SPI_FLASH_PORT);
- // send Command: 0x03, Read data
- SPI_WRITE_TX(SPI_FLASH_PORT, 0x03);
- // send 24-bit start address
- SPI_WRITE_TX(SPI_FLASH_PORT, (StartAddress>>16) & 0xFF);
- SPI_WRITE_TX(SPI_FLASH_PORT, (StartAddress>>8) & 0xFF);
- SPI_WRITE_TX(SPI_FLASH_PORT, StartAddress & 0xFF);
- while(SPI_IS_BUSY(SPI_FLASH_PORT));
- // clear RX buffer
- SPI_ClearRxFIFO(SPI_FLASH_PORT);
- // read data
- for(i=0; i<256; i++) {
- SPI_WRITE_TX(SPI_FLASH_PORT, 0x00);
- while(SPI_IS_BUSY(SPI_FLASH_PORT));
- u8DataBuffer[i] = SPI_READ_RX(SPI_FLASH_PORT);
- }
- // wait tx finish
- while(SPI_IS_BUSY(SPI_FLASH_PORT));
- // /CS: de-active
- SPI_SET_SS_HIGH(SPI_FLASH_PORT);
- }
- /* Main */
- int main(void)
- {
- uint32_t u32ByteCount, u32FlashAddress, u32PageNumber;
- uint32_t nError = 0;
- uint16_t u16ID;
- /* Init System, IP clock and multi-function I/O */
- SYS_Init();
- /* Init UART0 to 115200-8n1 for print message */
- UART0_Init();
- /* Init SPI0, IP clock and multi-function I/O */
- SPI0_Init();
-
- /* Configure SPI_FLASH_PORT as a master, MSB first, 8-bit transaction, SPI Mode-0 timing, clock is 2MHz */
- SPI_Open(SPI_FLASH_PORT, SPI_MASTER, SPI_MODE_0, 8, 2000000);
- /* Enable the automatic hardware slave select function. Select the SS0 pin and configure as low-active. */
- SPI_EnableAutoSS(SPI_FLASH_PORT, SPI_SS, SPI_SS_ACTIVE_LOW);
- SPI_ENABLE(SPI_FLASH_PORT);
- printf("\n+------------------------------------------------------------------------+\n");
- printf("| NUC505 SPI Sample with SPI Flash |\n");
- printf("+------------------------------------------------------------------------+\n");
- /* Wait ready */
- SpiFlash_WaitReady();
- /// if((u16ID = SpiFlash_ReadMidDid()) != 0x1C14) {
- if((u16ID = SpiFlash_ReadMidDid()) != 0xEF14) {
- printf("Wrong ID, 0x%x\n", u16ID);
- return -1;
- } else
- printf("Flash found: Winbond 25Q16OVSEG ...\n");
- printf("Erase chip ...");
- /* Erase SPI flash */
- SpiFlash_ChipErase();
- /* Wait ready */
- SpiFlash_WaitReady();
- printf("[OK]\n");
- /* init source data buffer */
- for(u32ByteCount=0; u32ByteCount<TEST_LENGTH; u32ByteCount++) {
- SrcArray[u32ByteCount] = u32ByteCount;
- }
- printf("Start to normal write data to Flash ...");
- /* Program SPI flash */
- u32FlashAddress = 0;
- for(u32PageNumber=0; u32PageNumber<TEST_NUMBER; u32PageNumber++) {
- /* page program */
- SpiFlash_NormalPageProgram(u32FlashAddress, SrcArray);
- SpiFlash_WaitReady();
- u32FlashAddress += 0x100;
- }
- printf("[OK]\n");
- /* clear destination data buffer */
- for(u32ByteCount=0; u32ByteCount<TEST_LENGTH; u32ByteCount++) {
- DestArray[u32ByteCount] = 0;
- }
- printf("Normal Read & Compare ...");
- /* Read SPI flash */
- u32FlashAddress = 0;
- for(u32PageNumber=0; u32PageNumber<TEST_NUMBER; u32PageNumber++) {
- /* page read */
- SpiFlash_NormalRead(u32FlashAddress, DestArray);
- u32FlashAddress += 0x100;
- for(u32ByteCount=0; u32ByteCount<TEST_LENGTH; u32ByteCount++) {
- if(DestArray[u32ByteCount] != SrcArray[u32ByteCount])
- nError ++;
- }
- }
- if(nError == 0)
- printf("[OK]\n");
- else
- printf("[FAIL]\n");
- while(1);
- }
- void SYS_Init(void)
- {
- /*---------------------------------------------------------------------------------------------------------*/
- /* Init System Clock */
- /*---------------------------------------------------------------------------------------------------------*/
- /* Unlock protected registers */
- //SYS_UnlockReg();
-
- /* Enable XTAL */
- CLK->PWRCTL |= CLK_PWRCTL_HXTEN_Msk;
- CLK_SetCoreClock(FREQ_96MHZ);
-
- /* PCLK divider */
- CLK_SetModuleClock(PCLK_MODULE, NULL, 1);
-
- /* Lock protected registers */
- //SYS_LockReg();
-
- }
- void UART0_Init(void)
- {
- /* Enable UART0 Module clock */
- CLK_EnableModuleClock(UART0_MODULE);
- /* UART0 module clock from EXT */
- CLK_SetModuleClock(UART0_MODULE, CLK_UART0_SRC_EXT, 0);
- /* Reset IP */
- SYS_ResetModule(UART0_RST);
- /* Configure UART0 and set UART0 Baud-rate */
- UART_Open(UART0, 115200);
- /*---------------------------------------------------------------------------------------------------------*/
- /* Init I/O Multi-function */
- /*---------------------------------------------------------------------------------------------------------*/
- /* Configure multi-function pins for UART0 RXD and TXD */
- SYS->GPB_MFPL = (SYS->GPB_MFPL & (~SYS_GPB_MFPL_PB0MFP_Msk) ) | SYS_GPB_MFPL_PB0MFP_UART0_TXD;
- SYS->GPB_MFPL = (SYS->GPB_MFPL & (~SYS_GPB_MFPL_PB1MFP_Msk) ) | SYS_GPB_MFPL_PB1MFP_UART0_RXD;
-
- }
- void SPI0_Init(void)
- {
- /* Enable SPI0 Module clock */
- CLK_EnableModuleClock(SPI0_MODULE);
- /* SPI0 module clock from EXT */
- CLK_SetModuleClock(SPI0_MODULE, CLK_SPI0_SRC_PLL, 0);
- /* Reset IP */
- SYS_ResetModule(SPI0_RST);
- /*---------------------------------------------------------------------------------------------------------*/
- /* Init I/O Multi-function */
- /*---------------------------------------------------------------------------------------------------------*/
- /* Configure multi-function pins for SPI0 */
- SYS->GPB_MFPL = (SYS->GPB_MFPL & (~SYS_GPB_MFPL_PB2MFP_Msk) ) | SYS_GPB_MFPL_PB2MFP_SPI0_SS;
- SYS->GPB_MFPL = (SYS->GPB_MFPL & (~SYS_GPB_MFPL_PB3MFP_Msk) ) | SYS_GPB_MFPL_PB3MFP_SPI0_CLK;
- SYS->GPB_MFPL = (SYS->GPB_MFPL & (~SYS_GPB_MFPL_PB4MFP_Msk) ) | SYS_GPB_MFPL_PB4MFP_SPI0_MOSI;
- SYS->GPB_MFPL = (SYS->GPB_MFPL & (~SYS_GPB_MFPL_PB5MFP_Msk) ) | SYS_GPB_MFPL_PB5MFP_SPI0_MISO;
-
- }
- /*** (C) COPYRIGHT 2015 Nuvoton Technology Corp. ***/
这个是吧