关于SPI 外部FLASH读写,不知道哪里的问题,望指教

[复制链接]
1997|1
 楼主| devilxiaowei 发表于 2018-5-30 13:37 | 显示全部楼层 |阅读模式
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "Platform.h"
  4. #include "i94100.h"
  5. #include "gpio.h"

  6. #define PLL_CLOCK           72000000

  7. #define TEST_NUMBER 1   /* page numbers */
  8. #define TEST_LENGTH 256 /* length */

  9. #define SPI_FLASH_PORT  SPI1

  10. uint8_t SrcArray[TEST_LENGTH];
  11. uint8_t DestArray[TEST_LENGTH];

  12. uint16_t SpiFlash_ReadMidDid(void)
  13. {
  14.     uint8_t u8RxData[6], u8IDCnt = 0;

  15.     // /CS: active
  16.     SPI_SET_SS_LOW(SPI_FLASH_PORT);

  17.     // send Command: 0x90, Read Manufacturer/Device ID
  18.     SPI_WRITE_TX(SPI_FLASH_PORT, 0x90);

  19.     // send 24-bit '0', dummy
  20.     SPI_WRITE_TX(SPI_FLASH_PORT, 0x00);
  21.     SPI_WRITE_TX(SPI_FLASH_PORT, 0x00);
  22.     SPI_WRITE_TX(SPI_FLASH_PORT, 0x00);

  23.     // receive 16-bit
  24.     SPI_WRITE_TX(SPI_FLASH_PORT, 0x00);
  25.     SPI_WRITE_TX(SPI_FLASH_PORT, 0x00);

  26.     // wait tx finish
  27.     while(SPI_IS_BUSY(SPI_FLASH_PORT));

  28.     // /CS: de-active
  29.     SPI_SET_SS_HIGH(SPI_FLASH_PORT);

  30.                 //printf("SPI_GET_RX_FIFO_EMPTY_FLAG(%p)=%ld\n",SPI_FLASH_PORT,SPI_GET_RX_FIFO_FULL_FLAG(SPI_FLASH_PORT));
  31.     while(!SPI_GET_RX_FIFO_EMPTY_FLAG(SPI_FLASH_PORT))
  32.                 {
  33.         u8RxData[u8IDCnt] = SPI_READ_RX(SPI_FLASH_PORT);
  34.                     printf(" u8RxData[%d]=%d\n",u8IDCnt,u8RxData[u8IDCnt]);
  35.                           u8IDCnt ++;
  36.         }
  37.                
  38.     return ( (u8RxData[4]<<8) | u8RxData[5] );
  39. }

  40. void SpiFlash_ChipErase(void)
  41. {
  42.     // /CS: active
  43.     SPI_SET_SS_LOW(SPI_FLASH_PORT);

  44.     // send Command: 0x06, Write enable
  45.     SPI_WRITE_TX(SPI_FLASH_PORT, 0x06);

  46.     // wait tx finish
  47.     while(SPI_IS_BUSY(SPI_FLASH_PORT));

  48.     // /CS: de-active
  49.     SPI_SET_SS_HIGH(SPI_FLASH_PORT);

  50.     //////////////////////////////////////////

  51.     // /CS: active
  52.     SPI_SET_SS_LOW(SPI_FLASH_PORT);

  53.     // send Command: 0xC7, Chip Erase
  54.     SPI_WRITE_TX(SPI_FLASH_PORT, 0xC7);

  55.     // wait tx finish
  56.     while(SPI_IS_BUSY(SPI_FLASH_PORT));

  57.     // /CS: de-active
  58.     SPI_SET_SS_HIGH(SPI_FLASH_PORT);

  59.     SPI_ClearRxFIFO(SPI_FLASH_PORT);
  60. }

  61. uint8_t SpiFlash_ReadStatusReg(void)
  62. {
  63.     // /CS: active
  64.     SPI_SET_SS_LOW(SPI_FLASH_PORT);

  65.     // send Command: 0x05, Read status register
  66.     SPI_WRITE_TX(SPI_FLASH_PORT, 0x05);

  67.     // read status
  68.     SPI_WRITE_TX(SPI_FLASH_PORT, 0x00);

  69.     // wait tx finish
  70.     while(SPI_IS_BUSY(SPI_FLASH_PORT));

  71.     // /CS: de-active
  72.     SPI_SET_SS_HIGH(SPI_FLASH_PORT);

  73.     // skip first rx data
  74.     SPI_READ_RX(SPI_FLASH_PORT);

  75.     return (SPI_READ_RX(SPI_FLASH_PORT) & 0xff);
  76. }

  77. void SpiFlash_WriteStatusReg(uint8_t u8Value)
  78. {
  79.     // /CS: active
  80.     SPI_SET_SS_LOW(SPI_FLASH_PORT);

  81.     // send Command: 0x06, Write enable
  82.     SPI_WRITE_TX(SPI_FLASH_PORT, 0x06);

  83.     // wait tx finish
  84.     while(SPI_IS_BUSY(SPI_FLASH_PORT));

  85.     // /CS: de-active
  86.     SPI_SET_SS_HIGH(SPI_FLASH_PORT);

  87.     ///////////////////////////////////////

  88.     // /CS: active
  89.     SPI_SET_SS_LOW(SPI_FLASH_PORT);

  90.     // send Command: 0x01, Write status register
  91.     SPI_WRITE_TX(SPI_FLASH_PORT, 0x01);

  92.     // write status
  93.     SPI_WRITE_TX(SPI_FLASH_PORT, u8Value);

  94.     // wait tx finish
  95.     while(SPI_IS_BUSY(SPI_FLASH_PORT));

  96.     // /CS: de-active
  97.     SPI_SET_SS_HIGH(SPI_FLASH_PORT);
  98. }

  99. void SpiFlash_WaitReady(void)
  100. {
  101.     uint8_t ReturnValue;

  102.     do {
  103.         ReturnValue = SpiFlash_ReadStatusReg();
  104.                           printf("ReturnValue = %d\n",ReturnValue);
  105.         ReturnValue = ReturnValue & 1;
  106.     } while(ReturnValue!=0); // check the BUSY bit
  107. }

  108. void SpiFlash_NormalPageProgram(uint32_t StartAddress, uint8_t *u8DataBuffer)
  109. {
  110.     uint32_t i = 0;

  111.     // /CS: active
  112.     SPI_SET_SS_LOW(SPI_FLASH_PORT);

  113.     // send Command: 0x06, Write enable
  114.     SPI_WRITE_TX(SPI_FLASH_PORT, 0x06);

  115.     // wait tx finish
  116.     while(SPI_IS_BUSY(SPI_FLASH_PORT));

  117.     // /CS: de-active
  118.     SPI_SET_SS_HIGH(SPI_FLASH_PORT);


  119.     // /CS: active
  120.     SPI_SET_SS_LOW(SPI_FLASH_PORT);

  121.     // send Command: 0x02, Page program
  122.     SPI_WRITE_TX(SPI_FLASH_PORT, 0x02);

  123.     // send 24-bit start address
  124.     SPI_WRITE_TX(SPI_FLASH_PORT, (StartAddress>>16) & 0xFF);
  125.     SPI_WRITE_TX(SPI_FLASH_PORT, (StartAddress>>8)  & 0xFF);
  126.     SPI_WRITE_TX(SPI_FLASH_PORT, StartAddress       & 0xFF);

  127.     // write data
  128.     while(1) {
  129.         if(!SPI_GET_TX_FIFO_FULL_FLAG(SPI_FLASH_PORT)) {
  130.             SPI_WRITE_TX(SPI_FLASH_PORT, u8DataBuffer[i++]);
  131.             if(i >= 255) break;
  132.         }
  133.     }

  134.     // wait tx finish
  135.     while(SPI_IS_BUSY(SPI_FLASH_PORT));

  136.     // /CS: de-active
  137.     SPI_SET_SS_HIGH(SPI_FLASH_PORT);

  138.     SPI_ClearRxFIFO(SPI_FLASH_PORT);
  139. }

  140. void SpiFlash_NormalRead(uint32_t StartAddress, uint8_t *u8DataBuffer)
  141. {
  142.     uint32_t i;

  143.     // /CS: active
  144.     SPI_SET_SS_LOW(SPI_FLASH_PORT);

  145.     // send Command: 0x03, Read data
  146.     SPI_WRITE_TX(SPI_FLASH_PORT, 0x03);

  147.     // send 24-bit start address
  148.     SPI_WRITE_TX(SPI_FLASH_PORT, (StartAddress>>16) & 0xFF);
  149.     SPI_WRITE_TX(SPI_FLASH_PORT, (StartAddress>>8)  & 0xFF);
  150.     SPI_WRITE_TX(SPI_FLASH_PORT, StartAddress       & 0xFF);

  151.     while(SPI_IS_BUSY(SPI_FLASH_PORT));
  152.     // clear RX buffer
  153.     SPI_ClearRxFIFO(SPI_FLASH_PORT);

  154.     // read data
  155.     for(i=0; i<256; i++) {
  156.         SPI_WRITE_TX(SPI_FLASH_PORT, 0x00);
  157.         while(SPI_IS_BUSY(SPI_FLASH_PORT));
  158.         u8DataBuffer[i] = SPI_READ_RX(SPI_FLASH_PORT);
  159.     }

  160.     // wait tx finish
  161.     while(SPI_IS_BUSY(SPI_FLASH_PORT));

  162.     // /CS: de-active
  163.     SPI_SET_SS_HIGH(SPI_FLASH_PORT);
  164. }

  165. void SYS_Init(void)
  166. {
  167.     /*---------------------------------------------------------------------------------------------------------*/
  168.     /* Init System Clock                                                                                       */
  169.     /*---------------------------------------------------------------------------------------------------------*/


  170.        
  171.          /* Enable HXT clock (external XTAL 12MHz) */
  172.     CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);
  173.           /* Wait for HXT clock ready */
  174.     CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);
  175.           /* Configure PLL */
  176.     CLK_EnablePLL(CLK_PLLCTL_PLLSRC_HXT, FREQ_72MHZ);
  177.                 //CLK_SetPCLKDivider(CLK_PCLKDIV_PCLK0DIV4);
  178.     //CLK_SetPCLKDivider(CLK_PCLKDIV_PCLK1DIV4);
  179.     /* Switch HCLK clock source to PLL */
  180.     CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_PLL, CLK_CLKDIV0_HCLK(1));
  181.     /* Set both PCLK0 and PCLK1 as HCLK/2 */
  182.    // CLK->PCLKDIV = CLK_PCLKDIV_PCLK0DIV2 | CLK_PCLKDIV_PCLK1DIV2;

  183.                 /* Select UART module clock source as HXT and UART module clock divider as 1 */
  184.     CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HXT, CLK_CLKDIV0_UART0(1));

  185.     /* Select PCLK0 as the clock source of SPI0 */
  186.     CLK_SetModuleClock(SPI1_MODULE, CLK_CLKSEL2_SPI1SEL_PCLK1, MODULE_NoMsk);

  187.     /* Enable UART peripheral clock */
  188.     CLK_EnableModuleClock(UART0_MODULE);

  189.     /* Enable SPI0 peripheral clock */
  190.     CLK_EnableModuleClock(SPI1_MODULE);

  191.        




  192.                 /* Update System Core Clock */
  193.     /* User can use SystemCoreClockUpdate() to calculate SystemCoreClock and CyclesPerUs automatically. */
  194.     //SystemCoreClockUpdate();
  195.                
  196.     /*---------------------------------------------------------------------------------------------------------*/
  197.     /* Init I/O Multi-function                                                                                 */
  198.     /*---------------------------------------------------------------------------------------------------------*/
  199.     /* Set PD multi-function pins for UART0 RXD(PD.2) and TXD(PD.3) */
  200.     //SYS->GPD_MFPL &= ~(SYS_GPD_MFPL_PD2MFP_Msk | SYS_GPD_MFPL_PD3MFP_Msk);
  201.     //SYS->GPD_MFPL |= (SYS_GPD_MFPL_PD2MFP_UART0_RXD | SYS_GPD_MFPL_PD3MFP_UART0_TXD);
  202.                 SYS->GPB_MFPH  = (SYS->GPB_MFPH & (~SYS_GPB_MFPH_PB8MFP_Msk) ) | SYS_GPB_MFPH_PB8MFP_UART0_TXD;       
  203.                 SYS->GPB_MFPH  = (SYS->GPB_MFPH & (~SYS_GPB_MFPH_PB9MFP_Msk) ) | SYS_GPB_MFPH_PB9MFP_UART0_RXD;       

  204.     /* Setup SPI0 multi-function pins */
  205.    // SYS->GPA_MFPL |= SYS_GPA_MFPL_PA0MFP_SPI0_MOSI | SYS_GPA_MFPL_PA1MFP_SPI0_MISO | SYS_GPA_MFPL_PA2MFP_SPI0_CLK | SYS_GPA_MFPL_PA3MFP_SPI0_SS;
  206.                 //SYS->GPA_MFPL = (SYS->GPA_MFPL & ~(SYS_GPA_MFPL_PA3MFP_Msk | SYS_GPA_MFPL_PA4MFP_Msk | SYS_GPA_MFPL_PA5MFP_Msk | SYS_GPA_MFPL_PA6MFP_Msk)) |
  207.           //(SYS_GPA_MFPL_PA5MFP_SPI0_CLK | SYS_GPA_MFPL_PA4MFP_SPI0_MISO0 | SYS_GPA_MFPL_PA6MFP_SPI0_SS0 | SYS_GPA_MFPL_PA3MFP_SPI0_MOSI0);
  208.                         SYS->GPC_MFPL = (SYS->GPC_MFPL & ~(SYS_GPC_MFPL_PC2MFP_Msk | SYS_GPC_MFPL_PC1MFP_Msk | SYS_GPC_MFPL_PC3MFP_Msk | SYS_GPC_MFPL_PC0MFP_Msk)) |
  209.           (SYS_GPC_MFPL_PC2MFP_SPI1_CLK | SYS_GPC_MFPL_PC1MFP_SPI1_MISO0 | SYS_GPC_MFPL_PC3MFP_SPI1_SS0 | SYS_GPC_MFPL_PC0MFP_SPI1_MOSI0);
  210.     /* Enable SPI0 clock pin (PA2) schmitt trigger */
  211.     //PA->SMTEN |= GPIO_SMTEN_SMTEN4_Msk;

  212.     /* Update System Core Clock */
  213.     /* User can use SystemCoreClockUpdate() to calculate SystemCoreClock and CyclesPerUs automatically. */
  214.     SystemCoreClockUpdate();
  215. }

  216. /* Main */
  217. int main(void)
  218. {
  219.     uint32_t u32ByteCount, u32FlashAddress, u32PageNumber;
  220.     uint32_t nError = 0;
  221.     uint16_t u16ID,i;

  222.     /* Unlock protected registers */
  223.     SYS_UnlockReg();

  224.     /* Init System, IP clock and multi-function I/O. */
  225.     SYS_Init();
  226.        
  227.         /* Lock protected registers */
  228.     SYS_LockReg();

  229.         /* Reset UART0 module */
  230.     SYS_ResetModule(UART0_RST);
  231.        
  232.     /* Init UART to 115200-8n1 for print message */
  233.     UART_Open(UART0, 115200);
  234.           
  235.     SYS_ResetModule(SPI1_RST);       
  236.        
  237.     /* Configure SPI_FLASH_PORT as a master, MSB first, 8-bit transaction, SPI Mode-0 timing, clock is 20MHz */
  238.     SPI_Open(SPI_FLASH_PORT, SPI_MASTER, SPI_MODE_0, 8, 2000000);

  239.     /* Disable auto SS function, control SS signal manually. */
  240.     //SPI_DisableAutoSS(SPI_FLASH_PORT);
  241.                 //SPI_EnableAutoSS(SPI_FLASH_PORT, SPI_SS0, SPI_SS_ACTIVE_LOW);
  242.                 SPI_ENABLE(SPI_FLASH_PORT);
  243.                 GPIO_SetMode(PD, BIT15, GPIO_MODE_OUTPUT);
  244.                
  245.                 //SpiFlash_WaitReady();
  246. PD15=0;
  247. //printf("SpiFlash_ReadMidDid=%x\n",SpiFlash_ReadMidDid());
  248.                
  249.                
  250. PD15=1;
  251.     //while(1)__NOP;
  252.     if((u16ID = SpiFlash_ReadMidDid()) != 0xEF14) {
  253.         printf("Wrong ID, 0x%x\n", u16ID);
  254.     } else
  255.         printf("Flash found: W25X16 ...\n");
  256. PD15=1;
  257.                
  258.     printf("Erase chip ...");

  259.     /* Erase SPI flash */
  260.     SpiFlash_ChipErase();

  261.     /* Wait ready */
  262.     SpiFlash_WaitReady();

  263.     printf("[OK]\n");

  264.     /* init source data buffer */
  265.     for(u32ByteCount=0; u32ByteCount<TEST_LENGTH; u32ByteCount++) {
  266.         SrcArray[u32ByteCount] = u32ByteCount;
  267.                           //printf("SrcArrat[%d]=%d\n",u32ByteCount,SrcArray[u32ByteCount]);
  268.     }

  269.     printf("Start to normal write data to Flash ...");
  270.     /* Program SPI flash */
  271.     u32FlashAddress = 0;
  272.     for(u32PageNumber=0; u32PageNumber<TEST_NUMBER; u32PageNumber++) {
  273.         /* page program */
  274.         SpiFlash_NormalPageProgram(u32FlashAddress, SrcArray);
  275.         SpiFlash_WaitReady();
  276.         u32FlashAddress += 0x100;
  277.     }

  278.     printf("[OK]\n");

  279.     /* clear destination data buffer */
  280.     for(u32ByteCount=0; u32ByteCount<TEST_LENGTH; u32ByteCount++) {
  281.         DestArray[u32ByteCount] = 0;
  282.     }

  283.     printf("Normal Read & Compare ...");

  284.     /* Read SPI flash */
  285.     u32FlashAddress = 0;
  286.     for(u32PageNumber=0; u32PageNumber<TEST_NUMBER; u32PageNumber++) {
  287.         /* page read */
  288.         SpiFlash_NormalRead(u32FlashAddress, DestArray);
  289.         u32FlashAddress += 0x100;

  290.         for(u32ByteCount=0; u32ByteCount<TEST_LENGTH; u32ByteCount++) {
  291.                                         printf("DestArray[%d]=%d\n",u32ByteCount,DestArray[u32ByteCount]);
  292.             if(DestArray[u32ByteCount] != SrcArray[u32ByteCount])
  293.                 nError ++;
  294.         }
  295.     }

  296.     if(nError == 0)
  297.         printf("[OK]\n");
  298.     else
  299.         printf("[FAIL]\n");

  300.     while(1);
  301. }

我感觉没有写进flash里面,但是找不出原因
tyw 发表于 2018-5-30 13:54 | 显示全部楼层
先做工艺试验,写一字节,再读出来,成功了再复杂化. 你弄这么一大坨东东,估计不会有人这么有耐心看的拉,哈哈






本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

5

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部