回答

收藏

F450读写GD25Q128

GD32 GD32 3615 人阅读 | 0 人回复 | 2017-06-02

本帖最后由 apleilx 于 2017-6-9 17:24 编辑

记录数据免不了要用到大容量的FLASH了,手上正好有GD25Q128的板子,连上写个驱动程序,现在可以读写擦除了。
450的DMA添加了不少功能,不过狗血限制太多,还没全搞明白,现在都是纯软件操作,程序留了DMA的接口,回头添加DMA传输。

freertos-bbs-gd25q.rar (3.15 MB, 下载次数: 26)


附件工程:
IDE : IAR ARM8.11.1
操作系统 : freeRTOS
创建测试任务 : \SOFTWARE\APP\strctr.c

gd25q部分程序清单:
gd25q_hal.h
  1. #ifndef _GD25Q_HAL_H_
  2. #define        _GD25Q_HAL_H_

  3. #include "stdint.h"
  4. #include "gd32f4xx.h"
  5. #include "pincfg.h"

  6. #ifdef _GD25Q_HAL_MODEL_
  7. #define GD_EXT
  8. #else
  9. #define GD_EXT extern
  10. #endif

  11. #define GDSPI                                     SPI3

  12. //WP# going low to protected the BP0~BP4 bits and SRP0~1 bits.
  13. #define GD25WpEn()                       
  14. #define GD25WpDis()                       
  15. //To re-start communication with chip, the HOLD# must be at high and then CS# must be at low
  16. #define GD25Cs(x)                                 (x?(SPI_F_CS = 1 ):(SPI_F_CS = 0))
  17. #define GD25Hold(x)                          

  18. GD_EXT uint32_t gd25qDmaEndSt;

  19. void gdSpiInit(void);
  20. uint8_t dgSpiRw(uint8_t dataW);
  21. void gdSpiDma(uint8_t NewState);
  22. void gdSpiDmaRw(uint8_t ModeRW, uint32_t  Len, uint8_t *Data);

  23. #undef GD_EXT

  24. #endif        /* _GD25Q_HAL_H_ */
复制代码
gd25q_hal.c
  1. /* ------------------------------------------------------------------------*
  2. *
  3. * ------------------------------------------------------------------------*/
  4. #define _GD25Q_HAL_MODEL_

  5. #include "gd25q_hal.h"
  6. #include "gd25q_cmd.h"

  7. /*****************************************************************************//*!
  8. * @brief   Dma for spi rx handle.
  9. *               
  10. * @param   none
  11. *
  12. * @return  none
  13. *
  14. * @ Pass/ Fail criteria: none
  15. *****************************************************************************/  
  16. void DMA1_Channel3_IRQHandler(){
  17.         dma_channel_disable(DMA1, DMA_CH3);        
  18.         dma_channel_disable(DMA1, DMA_CH4);         
  19.         
  20.         SPI_CTL1(GDSPI) &= ~ (SPI_CTL1_DMAREN | SPI_CTL1_DMATEN);
  21.         
  22.         dma_flag_clear(DMA1, DMA_CH3, DMA_INTC_FEEIFC);
  23.         dma_flag_clear(DMA1, DMA_CH4, DMA_INTC_FEEIFC);
  24.         //add code to tell os that data rw finished ----------------------------------------------
  25.         
  26.         //----------------------------------------------------------------------------------------
  27. }

  28. /*****************************************************************************//*!
  29. * @brief   Dma for spi tx handle.
  30. *               
  31. * @param   none
  32. *
  33. * @return  none
  34. *
  35. * @ Pass/ Fail criteria: none
  36. *****************************************************************************/  
  37. void DMA1_Channel4_IRQHandler(){

  38. }

  39. /*****************************************************************************//*!
  40. * @brief   hal init.
  41. *               
  42. * @param   none
  43. *
  44. * @return  none
  45. *
  46. * @ Pass/ Fail criteria: none
  47. *****************************************************************************/   
  48. void gdSpiInit()
  49. {
  50.     spi_parameter_struct SpiPar;
  51.     // Enable USART APB clock
  52.     rcu_periph_clock_enable(RCU_SPI3);
  53.     rcu_periph_reset_enable(RCU_SPI3RST);
  54.     rcu_periph_reset_disable(RCU_SPI3RST);  

  55.     // Configure USART Rx/Tx as alternate function push-pull
  56.     gpio_af_set(GPIOE, GPIO_AF_5,GPIO_PIN_2 | GPIO_PIN_5 | GPIO_PIN_6);
  57.     gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_2 | GPIO_PIN_5 | GPIO_PIN_6);
  58.     gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2 | GPIO_PIN_5 | GPIO_PIN_6);

  59.     GD25Cs(1);
  60.     //GD25Hold(1);
  61.     //GD25WpDis();

  62.     //config spi
  63.     SpiPar.device_mode = SPI_MASTER;
  64.     SpiPar.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
  65.     SpiPar.frame_size = SPI_FRAMESIZE_8BIT;
  66.     SpiPar.nss = SPI_NSS_SOFT;
  67.     SpiPar.endian = SPI_ENDIAN_MSB;
  68.     SpiPar.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
  69.     SpiPar.prescale =SPI_PSC_256;
  70.    
  71.     spi_init(GDSPI, &SpiPar);
  72.     spi_enable(GDSPI);
  73.    
  74.     NVIC_SetPriority(SPI3_IRQn, 0xFF);
  75.     NVIC_ClearPendingIRQ(SPI3_IRQn);
  76.     NVIC_DisableIRQ(SPI3_IRQn);
  77. }

  78. /*****************************************************************************//*!
  79. * @brief   DMA control.
  80. *               
  81. * @param   none
  82. *
  83. * @return  none
  84. *
  85. * @ Pass/ Fail criteria: none
  86. *****************************************************************************/
  87. void gdSpiDmaRw(uint8_t ModeRW, uint32_t  Len, uint8_t *Data)
  88. {
  89.   
  90. }

  91. /*****************************************************************************//*!
  92. * @brief   spi data read and write.
  93. *               
  94. * @param   none
  95. *
  96. * @return  none
  97. *
  98. * @ Pass/ Fail criteria: none
  99. *****************************************************************************/
  100. uint8_t dgSpiRw(uint8_t dataW)
  101. {
  102.     uint8_t dataR;
  103.    
  104.     while(SPI_STAT(GDSPI) & SPI_STAT_TRANS){}             //wait tx idle
  105.         
  106.     if(SPI_STAT(GDSPI) & SPI_STAT_RBNE)
  107.         dataR = SPI_DATA(GDSPI);
  108.    
  109.     SPI_DATA(GDSPI) = dataW;
  110.     dataW = 0;
  111.     while(!(SPI_STAT(GDSPI) & SPI_STAT_RBNE)){}            //wait tx idle
  112.     dataR = SPI_DATA(GDSPI);
  113.     return ( dataR );
  114. }
复制代码
gd25q_cmd.h
  1. #ifndef _GD25Q_CMD_H_
  2. #define        _GD25Q_CMD_H_

  3. #include "stdint.h"
  4. #include "gd25q_hal.h"

  5. // command list
  6. #define GD25CMD_Write_Enable                              0x06
  7. #define GD25CMD_Write_Disable                             0x04
  8. #define GD25CMD_SRWrite Enable                            0x50
  9. #define GD25CMD_Read_StReg1                               0x05
  10. #define GD25CMD_Read_StReg2                               0x35
  11. #define GD25CMD_Read_StReg3                               0x15
  12. #define GD25CMD_Write_StReg1                              0x01
  13. #define GD25CMD_Write_StReg2                              0x31
  14. #define GD25CMD_Write_StReg3                              0x11
  15. #define GD25CMD_Read_Data                                 0x03
  16. #define GD25CMD_Fast_Read                                 0x0B
  17. #define GD25CMD_Dual_Output                               0x3B
  18. #define GD25CMD_Dual_IO                                   0xBB
  19. #define GD25CMD_Quad_Output                               0x6B
  20. #define GD25CMD_Quad_IO                                   0xEB
  21. #define GD25CMD_Quad_IO_Word                              0xE7
  22. #define GD25CMD_Page_Program                              0x02
  23. #define GD25CMD_Quad_Page_Program                         0x32
  24. #define GD25CMD_Sector_Erase                              0x20
  25. #define GD25CMD_Block_Erase_32K                           0x52
  26. #define GD25CMD_Block_Erase_64K                           0xD8
  27. #define GD25CMD_Chip_Erase                                0x60
  28. #define GD25CMD_Enable_QPI                                0x38
  29. #define GD25CMD_Enable_Reset                              0x66
  30. #define GD25CMD_Reset                                     0x99
  31. #define GD25CMD_Set_Burst_with_Wrap                       0x77
  32. #define GD25CMD_Erase SecurityReg                         0x44
  33. #define GD25CMD_Program SecurityReg                       0x42
  34. #define GD25CMD_Read SecurityReg                          0x48
  35. #define GD25CMD_Individual_Block_Lock                     0x36
  36. #define GD25CMD_Individual_Block_Unlock                   0x39
  37. #define GD25CMD_Read_Block_Lock                           0x3D
  38. #define GD25CMD_Global_Block_Lock                         0x7E
  39. #define GD25CMD_Global_Block_Unlock                       0x98

  40. // flash information
  41. #define GD25Q128_PAGE_SIZE                                0x100UL          //256bytes
  42. #define GD25Q128_PAGE_MASK                                0xFFUL
  43. #define GD25Q128_SECTOR_SIZE                              0x1000UL         //4kbytes
  44. #define GD25Q128_SECTOR_MASK                              0xFFFUL
  45. #define GD25Q128_BLOCK_SIZE                               0x8000UL         //32kbytes
  46. #define GD25Q128_BLOCK_MASK                               0x7FFFUL
  47. #define GD25Q128_CHIP_SIZE                                0x1000000UL      //16mbytes
  48. #define GD25Q128_CHIP_MASK                                0xFFFFFFUL

  49. // statue define
  50. #define GD25Q_ST_BUSY_MASK                                0x01
  51. #define GD25Q_ST_WRITE_EN                                 0x02

  52. // mode
  53. #define GD25Q_READ                                        0x00
  54. #define GD25Q_WRITE                                       0x01

  55. //function
  56. uint32_t gd25qCmdStRead(void);
  57. uint8_t  gd25qBusy(void);


  58. void gd25qCmdWriteEn(void);
  59. void gd25qCmdWriteDis(void);
  60. void gd25qSectorErase(uint32_t addr);
  61. void gd25qBlockErase(uint32_t addr);
  62. void gd25qChipErase(void );

  63. void gd25qRead(uint32_t addr,uint32_t Len,uint8_t *Des);
  64. void gd25qWrite(uint32_t addr,uint32_t Len,uint8_t *Src);
  65. void gd25qDmaRead(uint32_t addr,uint32_t Len,uint8_t *Des);
  66. void gd25qDmaWrite(uint32_t addr,uint32_t Len,uint8_t *Src);

  67. #endif        /* _GD25Q_CMD_H_ */
复制代码
gd25q_cmd.c
  1. /* ------------------------------------------------------------------------*
  2. *
  3. * ------------------------------------------------------------------------*/
  4. #include "gd25q_cmd.h"
  5. #include "mytype.h"

  6. void gd25qWait(uint8_t Cnt)
  7. {
  8.     while(Cnt --){};
  9. }

  10. /*****************************************************************************//*!
  11. * @brief   read status.
  12. *               The Status Register may be read at any time,
  13. *               even while a Program, Erase or Write Status Register cycle is in progress.
  14. * @param   none
  15. *
  16. * @return  statues
  17. *
  18. * @ Pass/ Fail criteria: none
  19. *****************************************************************************/
  20. uint32_t gd25qCmdStRead(void)
  21. {
  22.     UINT32_VAL FlashSt;
  23.    
  24.     GD25Cs(0);
  25.     FlashSt.byte.MB = 0;
  26.     dgSpiRw( GD25CMD_Read_StReg1);
  27.     FlashSt.byte.LB = dgSpiRw( 0xFF);
  28.     GD25Cs(1);
  29.     gd25qWait(2);
  30.     GD25Cs(0);
  31.     dgSpiRw( GD25CMD_Read_StReg2);
  32.     FlashSt.byte.HB = dgSpiRw( 0xFF);
  33.     GD25Cs(1);
  34.     gd25qWait(2);
  35.     GD25Cs(0);
  36.     dgSpiRw( GD25CMD_Read_StReg3);
  37.     FlashSt.byte.UB = dgSpiRw( 0xFF);
  38.     GD25Cs(1);
  39.    
  40.     return FlashSt.Val;
  41. }

  42. /*****************************************************************************//*!
  43. * @brief   read busy statues.
  44. *               The Status Register may be read at any time,
  45. *               even while a Program, Erase or Write Status Register cycle is in progress.
  46. * @param   none
  47. *
  48. * @return  busy or not
  49. *
  50. * @ Pass/ Fail criteria: none
  51. *****************************************************************************/
  52. uint8_t  gd25qBusy(void)
  53. {
  54.     uint8_t FlashSt;
  55.    
  56.     GD25Cs(0);
  57.     dgSpiRw( GD25CMD_Read_StReg1);
  58.     FlashSt = dgSpiRw( 0xFF);
  59.     GD25Cs(1);
  60.    
  61.     return ((uint8_t)(FlashSt & GD25Q_ST_BUSY_MASK));
  62. }

  63. /*****************************************************************************//*!
  64. * @brief   write enable.
  65. *               
  66. * @param   none
  67. *
  68. * @return  none
  69. *
  70. * @ Pass/ Fail criteria: none
  71. *****************************************************************************/
  72. void gd25qCmdWriteEn(void)
  73. {
  74.     GD25Cs(0);

  75.     dgSpiRw( GD25CMD_Write_Enable);
  76.    
  77.     GD25Cs(1);
  78. }

  79. /*****************************************************************************//*!
  80. * @brief   write disable.
  81. *               
  82. * @param   none
  83. *
  84. * @return  none
  85. *
  86. * @ Pass/ Fail criteria: none
  87. *****************************************************************************/
  88. void gd25qCmdWriteDis(void)
  89. {
  90.     GD25Cs(0);

  91.     dgSpiRw( GD25CMD_Write_Disable);
  92.    
  93.     GD25Cs(1);
  94. }

  95. /*****************************************************************************//*!
  96. * @brief   Erase aector.       4k
  97. *               
  98. * @param   addr:      data address in chip
  99. *
  100. * @return  none
  101. *
  102. * @ Pass/ Fail criteria: none
  103. *****************************************************************************/
  104. void gd25qSectorErase(uint32_t addr)
  105. {
  106.     UINT32_VAL Par;
  107.    
  108.     //waiting for idle
  109.     while(gd25qBusy()){}
  110.         
  111.     gd25qCmdWriteEn();
  112.         
  113.     GD25Cs(0);
  114.     Par.Val = addr;   
  115.     dgSpiRw( GD25CMD_Sector_Erase);
  116.     dgSpiRw( Par.byte.UB);
  117.     dgSpiRw( Par.byte.HB);
  118.     dgSpiRw( Par.byte.LB);
  119.     GD25Cs(1);
  120. }

  121. /*****************************************************************************//*!
  122. * @brief   Erase block.      32k
  123. *               
  124. * @param   addr:      data address in chip
  125. *
  126. * @return  none
  127. *
  128. * @ Pass/ Fail criteria: none
  129. *****************************************************************************/
  130. void gd25qBlockErase(uint32_t addr)
  131. {
  132.     UINT32_VAL Par;
  133.    
  134.     //waiting for idle
  135.     while(gd25qBusy()){}
  136.         
  137.     gd25qCmdWriteEn();
  138.         
  139.     GD25Cs(0);
  140.     Par.Val = addr;   
  141.     dgSpiRw( GD25CMD_Block_Erase_32K);
  142.     dgSpiRw( Par.byte.UB);
  143.     dgSpiRw( Par.byte.HB);
  144.     dgSpiRw( Par.byte.LB);
  145.     GD25Cs(1);
  146. }

  147. /*****************************************************************************//*!
  148. * @brief   Erase chip.
  149. *               
  150. * @param   none
  151. *
  152. * @return  none
  153. *
  154. * @ Pass/ Fail criteria: none
  155. *****************************************************************************/
  156. void gd25qChipErase(void )
  157. {
  158.      while(gd25qBusy()){}
  159.         
  160.     gd25qCmdWriteEn();
  161.         
  162.     GD25Cs(0);  
  163.     dgSpiRw( GD25CMD_Chip_Erase);
  164.     GD25Cs(1);   
  165. }

  166. /*****************************************************************************//*!
  167. * @brief   read data.
  168. *               
  169. * @param   addr          address in chip
  170. *          len           length will be read
  171. *          des           destination
  172. *
  173. * @return  none
  174. *
  175. * @ Pass/ Fail criteria: none
  176. *****************************************************************************/
  177. void gd25qRead(uint32_t addr,uint32_t Len,uint8_t *Des)
  178. {
  179.     UINT32_VAL Par;
  180.    
  181.     //waiting for idle
  182.     while(gd25qBusy()){}
  183.     //
  184.     GD25Cs(0);
  185.     Par.Val = addr;   
  186.     dgSpiRw( GD25CMD_Read_Data);
  187.     dgSpiRw( Par.byte.UB);
  188.     dgSpiRw( Par.byte.HB);
  189.     dgSpiRw( Par.byte.LB);
  190.     while(Len--)
  191.     {
  192.         *Des++ = dgSpiRw( 0xFF );
  193.     }
  194.    
  195.     GD25Cs(1);
  196. }

  197. /*****************************************************************************//*!
  198. * @brief   write data ,must be in same page.
  199. *               
  200. * @param   addr          address in chip
  201. *          len           length will be read
  202. *          des           source
  203. *
  204. * @return  none
  205. *
  206. * @ Pass/ Fail criteria: none
  207. *****************************************************************************/
  208. void gd25qWrite(uint32_t addr,uint32_t Len,uint8_t *Src)
  209. {
  210.     UINT32_VAL Par;
  211.    
  212.     //waiting for idle
  213.     while(gd25qBusy()){}
  214.         
  215.     gd25qCmdWriteEn();
  216.         
  217.     GD25Cs(0);
  218.     Par.Val = addr;   
  219.     dgSpiRw( GD25CMD_Page_Program);
  220.     dgSpiRw( Par.byte.UB);
  221.     dgSpiRw( Par.byte.HB);
  222.     dgSpiRw( Par.byte.LB);
  223.     while(Len--)
  224.     {
  225.         dgSpiRw( *Src++ );
  226.     }  
  227.     GD25Cs(1);
  228. }

  229. /*****************************************************************************//*!
  230. * @brief   read data.
  231. *               
  232. * @param   addr          address in chip
  233. *          len           length will be read
  234. *          des           destination
  235. *
  236. * @return  none
  237. *
  238. * @ Pass/ Fail criteria: none
  239. *****************************************************************************/
  240. void gd25qDmaRead(uint32_t addr,uint32_t Len,uint8_t *Des)
  241. {
  242.     UINT32_VAL Par;
  243.    
  244.     //waiting for idle
  245.     while(gd25qBusy()){}
  246.     //
  247.     GD25Cs(0);
  248.     Par.Val = addr;   
  249.     dgSpiRw( GD25CMD_Read_Data);
  250.     dgSpiRw( Par.byte.UB);
  251.     dgSpiRw( Par.byte.HB);
  252.     dgSpiRw( Par.byte.LB);

  253.     gdSpiDmaRw(GD25Q_READ,  Len, Des);
  254.     GD25Cs(1);
  255. }

  256. /*****************************************************************************//*!
  257. * @brief   write data ,must be in same page.
  258. *               
  259. * @param   addr          address in chip
  260. *          len           length will be read
  261. *          des           source
  262. *
  263. * @return  none
  264. *
  265. * @ Pass/ Fail criteria: none
  266. *****************************************************************************/
  267. void gd25qDmaWrite(uint32_t addr,uint32_t Len,uint8_t *Src)
  268. {
  269.     UINT32_VAL Par;
  270.    
  271.     //waiting for idle
  272.     while(gd25qBusy()){}
  273.         
  274.     gd25qCmdWriteEn();
  275.         
  276.     GD25Cs(0);
  277.     Par.Val = addr;   
  278.     dgSpiRw( GD25CMD_Page_Program);
  279.     dgSpiRw( Par.byte.UB);
  280.     dgSpiRw( Par.byte.HB);
  281.     dgSpiRw( Par.byte.LB);
  282.         
  283.     gdSpiDmaRw(GD25Q_WRITE,  Len, Src);
  284.    
  285.     GD25Cs(1);
  286. }
复制代码
strctr.c
  1. #define _STR_MODULE_

  2. #include "osObjects.h"
  3. #include "strctr.h"
  4. #include "gd25q_cmd.h"

  5. uint8_t Gd25DataBuff[1024];

  6. /*****************************************************************************//*!
  7. *
  8. * @brief   led task.
  9. *     
  10. * @param   none
  11. *
  12. * @return  none
  13. *
  14. * @ Pass/ Fail criteria: none
  15. *****************************************************************************/

  16. void StrCtrTask(void *argument) {
  17.     uint16_t Cnt;
  18.   
  19.     gdSpiInit();
  20.     Cnt = 0;
  21.    
  22.     for (;;) {

  23.         vTaskDelay(250);
  24.         gd25qRead(Cnt, 1024, Gd25DataBuff);
  25.         Cnt++;
  26.         if(Gd25DataBuff[0]){
  27.            // Cnt = 256;
  28.             //while(Cnt--)
  29.             //  Gd25DataBuff[Cnt] = Cnt;
  30.             //gd25qWrite(0x00, 256, Gd25DataBuff);
  31.             //gd25qWrite(0x100, 256, Gd25DataBuff);
  32.             //gd25qWrite(0x200, 256, Gd25DataBuff);
  33.             //gd25qWrite(0x300, 256, Gd25DataBuff);
  34.             //gd25qWrite(0x400, 256, Gd25DataBuff);
  35.             //gd25qWrite(0x500, 256, Gd25DataBuff);
  36.         }
  37.     }
  38. }
复制代码
分享到:
回复

使用道具 举报

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

本版积分规则

关闭

站长推荐上一条 /3 下一条