|
|
本帖最后由 apleilx 于 2017-6-9 17:24 编辑
记录数据免不了要用到大容量的FLASH了,手上正好有GD25Q128的板子,连上写个驱动程序,现在可以读写擦除了。
450的DMA添加了不少功能,不过狗血限制太多,还没全搞明白,现在都是纯软件操作,程序留了DMA的接口,回头添加DMA传输。
附件工程:
IDE : IAR ARM8.11.1
操作系统 : freeRTOS
创建测试任务 : \SOFTWARE\APP\strctr.c
gd25q部分程序清单:
gd25q_hal.h- #ifndef _GD25Q_HAL_H_
- #define _GD25Q_HAL_H_
- #include "stdint.h"
- #include "gd32f4xx.h"
- #include "pincfg.h"
- #ifdef _GD25Q_HAL_MODEL_
- #define GD_EXT
- #else
- #define GD_EXT extern
- #endif
- #define GDSPI SPI3
- //WP# going low to protected the BP0~BP4 bits and SRP0~1 bits.
- #define GD25WpEn()
- #define GD25WpDis()
- //To re-start communication with chip, the HOLD# must be at high and then CS# must be at low
- #define GD25Cs(x) (x?(SPI_F_CS = 1 ):(SPI_F_CS = 0))
- #define GD25Hold(x)
- GD_EXT uint32_t gd25qDmaEndSt;
- void gdSpiInit(void);
- uint8_t dgSpiRw(uint8_t dataW);
- void gdSpiDma(uint8_t NewState);
- void gdSpiDmaRw(uint8_t ModeRW, uint32_t Len, uint8_t *Data);
- #undef GD_EXT
- #endif /* _GD25Q_HAL_H_ */
复制代码 gd25q_hal.c- /* ------------------------------------------------------------------------*
- *
- * ------------------------------------------------------------------------*/
- #define _GD25Q_HAL_MODEL_
-
- #include "gd25q_hal.h"
- #include "gd25q_cmd.h"
- /*****************************************************************************//*!
- * @brief Dma for spi rx handle.
- *
- * @param none
- *
- * @return none
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- void DMA1_Channel3_IRQHandler(){
- dma_channel_disable(DMA1, DMA_CH3);
- dma_channel_disable(DMA1, DMA_CH4);
-
- SPI_CTL1(GDSPI) &= ~ (SPI_CTL1_DMAREN | SPI_CTL1_DMATEN);
-
- dma_flag_clear(DMA1, DMA_CH3, DMA_INTC_FEEIFC);
- dma_flag_clear(DMA1, DMA_CH4, DMA_INTC_FEEIFC);
- //add code to tell os that data rw finished ----------------------------------------------
-
- //----------------------------------------------------------------------------------------
- }
- /*****************************************************************************//*!
- * @brief Dma for spi tx handle.
- *
- * @param none
- *
- * @return none
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- void DMA1_Channel4_IRQHandler(){
- }
- /*****************************************************************************//*!
- * @brief hal init.
- *
- * @param none
- *
- * @return none
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- void gdSpiInit()
- {
- spi_parameter_struct SpiPar;
- // Enable USART APB clock
- rcu_periph_clock_enable(RCU_SPI3);
- rcu_periph_reset_enable(RCU_SPI3RST);
- rcu_periph_reset_disable(RCU_SPI3RST);
- // Configure USART Rx/Tx as alternate function push-pull
- gpio_af_set(GPIOE, GPIO_AF_5,GPIO_PIN_2 | GPIO_PIN_5 | GPIO_PIN_6);
- gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_2 | GPIO_PIN_5 | GPIO_PIN_6);
- gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2 | GPIO_PIN_5 | GPIO_PIN_6);
- GD25Cs(1);
- //GD25Hold(1);
- //GD25WpDis();
- //config spi
- SpiPar.device_mode = SPI_MASTER;
- SpiPar.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
- SpiPar.frame_size = SPI_FRAMESIZE_8BIT;
- SpiPar.nss = SPI_NSS_SOFT;
- SpiPar.endian = SPI_ENDIAN_MSB;
- SpiPar.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
- SpiPar.prescale =SPI_PSC_256;
-
- spi_init(GDSPI, &SpiPar);
- spi_enable(GDSPI);
-
- NVIC_SetPriority(SPI3_IRQn, 0xFF);
- NVIC_ClearPendingIRQ(SPI3_IRQn);
- NVIC_DisableIRQ(SPI3_IRQn);
- }
- /*****************************************************************************//*!
- * @brief DMA control.
- *
- * @param none
- *
- * @return none
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- void gdSpiDmaRw(uint8_t ModeRW, uint32_t Len, uint8_t *Data)
- {
-
- }
- /*****************************************************************************//*!
- * @brief spi data read and write.
- *
- * @param none
- *
- * @return none
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- uint8_t dgSpiRw(uint8_t dataW)
- {
- uint8_t dataR;
-
- while(SPI_STAT(GDSPI) & SPI_STAT_TRANS){} //wait tx idle
-
- if(SPI_STAT(GDSPI) & SPI_STAT_RBNE)
- dataR = SPI_DATA(GDSPI);
-
- SPI_DATA(GDSPI) = dataW;
- dataW = 0;
- while(!(SPI_STAT(GDSPI) & SPI_STAT_RBNE)){} //wait tx idle
- dataR = SPI_DATA(GDSPI);
- return ( dataR );
- }
复制代码 gd25q_cmd.h- #ifndef _GD25Q_CMD_H_
- #define _GD25Q_CMD_H_
- #include "stdint.h"
- #include "gd25q_hal.h"
- // command list
- #define GD25CMD_Write_Enable 0x06
- #define GD25CMD_Write_Disable 0x04
- #define GD25CMD_SRWrite Enable 0x50
- #define GD25CMD_Read_StReg1 0x05
- #define GD25CMD_Read_StReg2 0x35
- #define GD25CMD_Read_StReg3 0x15
- #define GD25CMD_Write_StReg1 0x01
- #define GD25CMD_Write_StReg2 0x31
- #define GD25CMD_Write_StReg3 0x11
- #define GD25CMD_Read_Data 0x03
- #define GD25CMD_Fast_Read 0x0B
- #define GD25CMD_Dual_Output 0x3B
- #define GD25CMD_Dual_IO 0xBB
- #define GD25CMD_Quad_Output 0x6B
- #define GD25CMD_Quad_IO 0xEB
- #define GD25CMD_Quad_IO_Word 0xE7
- #define GD25CMD_Page_Program 0x02
- #define GD25CMD_Quad_Page_Program 0x32
- #define GD25CMD_Sector_Erase 0x20
- #define GD25CMD_Block_Erase_32K 0x52
- #define GD25CMD_Block_Erase_64K 0xD8
- #define GD25CMD_Chip_Erase 0x60
- #define GD25CMD_Enable_QPI 0x38
- #define GD25CMD_Enable_Reset 0x66
- #define GD25CMD_Reset 0x99
- #define GD25CMD_Set_Burst_with_Wrap 0x77
- #define GD25CMD_Erase SecurityReg 0x44
- #define GD25CMD_Program SecurityReg 0x42
- #define GD25CMD_Read SecurityReg 0x48
- #define GD25CMD_Individual_Block_Lock 0x36
- #define GD25CMD_Individual_Block_Unlock 0x39
- #define GD25CMD_Read_Block_Lock 0x3D
- #define GD25CMD_Global_Block_Lock 0x7E
- #define GD25CMD_Global_Block_Unlock 0x98
- // flash information
- #define GD25Q128_PAGE_SIZE 0x100UL //256bytes
- #define GD25Q128_PAGE_MASK 0xFFUL
- #define GD25Q128_SECTOR_SIZE 0x1000UL //4kbytes
- #define GD25Q128_SECTOR_MASK 0xFFFUL
- #define GD25Q128_BLOCK_SIZE 0x8000UL //32kbytes
- #define GD25Q128_BLOCK_MASK 0x7FFFUL
- #define GD25Q128_CHIP_SIZE 0x1000000UL //16mbytes
- #define GD25Q128_CHIP_MASK 0xFFFFFFUL
- // statue define
- #define GD25Q_ST_BUSY_MASK 0x01
- #define GD25Q_ST_WRITE_EN 0x02
- // mode
- #define GD25Q_READ 0x00
- #define GD25Q_WRITE 0x01
- //function
- uint32_t gd25qCmdStRead(void);
- uint8_t gd25qBusy(void);
- void gd25qCmdWriteEn(void);
- void gd25qCmdWriteDis(void);
- void gd25qSectorErase(uint32_t addr);
- void gd25qBlockErase(uint32_t addr);
- void gd25qChipErase(void );
- void gd25qRead(uint32_t addr,uint32_t Len,uint8_t *Des);
- void gd25qWrite(uint32_t addr,uint32_t Len,uint8_t *Src);
- void gd25qDmaRead(uint32_t addr,uint32_t Len,uint8_t *Des);
- void gd25qDmaWrite(uint32_t addr,uint32_t Len,uint8_t *Src);
- #endif /* _GD25Q_CMD_H_ */
复制代码 gd25q_cmd.c- /* ------------------------------------------------------------------------*
- *
- * ------------------------------------------------------------------------*/
- #include "gd25q_cmd.h"
- #include "mytype.h"
- void gd25qWait(uint8_t Cnt)
- {
- while(Cnt --){};
- }
- /*****************************************************************************//*!
- * @brief read status.
- * The Status Register may be read at any time,
- * even while a Program, Erase or Write Status Register cycle is in progress.
- * @param none
- *
- * @return statues
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- uint32_t gd25qCmdStRead(void)
- {
- UINT32_VAL FlashSt;
-
- GD25Cs(0);
- FlashSt.byte.MB = 0;
- dgSpiRw( GD25CMD_Read_StReg1);
- FlashSt.byte.LB = dgSpiRw( 0xFF);
- GD25Cs(1);
- gd25qWait(2);
- GD25Cs(0);
- dgSpiRw( GD25CMD_Read_StReg2);
- FlashSt.byte.HB = dgSpiRw( 0xFF);
- GD25Cs(1);
- gd25qWait(2);
- GD25Cs(0);
- dgSpiRw( GD25CMD_Read_StReg3);
- FlashSt.byte.UB = dgSpiRw( 0xFF);
- GD25Cs(1);
-
- return FlashSt.Val;
- }
- /*****************************************************************************//*!
- * @brief read busy statues.
- * The Status Register may be read at any time,
- * even while a Program, Erase or Write Status Register cycle is in progress.
- * @param none
- *
- * @return busy or not
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- uint8_t gd25qBusy(void)
- {
- uint8_t FlashSt;
-
- GD25Cs(0);
- dgSpiRw( GD25CMD_Read_StReg1);
- FlashSt = dgSpiRw( 0xFF);
- GD25Cs(1);
-
- return ((uint8_t)(FlashSt & GD25Q_ST_BUSY_MASK));
- }
- /*****************************************************************************//*!
- * @brief write enable.
- *
- * @param none
- *
- * @return none
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- void gd25qCmdWriteEn(void)
- {
- GD25Cs(0);
- dgSpiRw( GD25CMD_Write_Enable);
-
- GD25Cs(1);
- }
- /*****************************************************************************//*!
- * @brief write disable.
- *
- * @param none
- *
- * @return none
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- void gd25qCmdWriteDis(void)
- {
- GD25Cs(0);
- dgSpiRw( GD25CMD_Write_Disable);
-
- GD25Cs(1);
- }
- /*****************************************************************************//*!
- * @brief Erase aector. 4k
- *
- * @param addr: data address in chip
- *
- * @return none
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- void gd25qSectorErase(uint32_t addr)
- {
- UINT32_VAL Par;
-
- //waiting for idle
- while(gd25qBusy()){}
-
- gd25qCmdWriteEn();
-
- GD25Cs(0);
- Par.Val = addr;
- dgSpiRw( GD25CMD_Sector_Erase);
- dgSpiRw( Par.byte.UB);
- dgSpiRw( Par.byte.HB);
- dgSpiRw( Par.byte.LB);
- GD25Cs(1);
- }
- /*****************************************************************************//*!
- * @brief Erase block. 32k
- *
- * @param addr: data address in chip
- *
- * @return none
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- void gd25qBlockErase(uint32_t addr)
- {
- UINT32_VAL Par;
-
- //waiting for idle
- while(gd25qBusy()){}
-
- gd25qCmdWriteEn();
-
- GD25Cs(0);
- Par.Val = addr;
- dgSpiRw( GD25CMD_Block_Erase_32K);
- dgSpiRw( Par.byte.UB);
- dgSpiRw( Par.byte.HB);
- dgSpiRw( Par.byte.LB);
- GD25Cs(1);
- }
- /*****************************************************************************//*!
- * @brief Erase chip.
- *
- * @param none
- *
- * @return none
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- void gd25qChipErase(void )
- {
- while(gd25qBusy()){}
-
- gd25qCmdWriteEn();
-
- GD25Cs(0);
- dgSpiRw( GD25CMD_Chip_Erase);
- GD25Cs(1);
- }
- /*****************************************************************************//*!
- * @brief read data.
- *
- * @param addr address in chip
- * len length will be read
- * des destination
- *
- * @return none
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- void gd25qRead(uint32_t addr,uint32_t Len,uint8_t *Des)
- {
- UINT32_VAL Par;
-
- //waiting for idle
- while(gd25qBusy()){}
- //
- GD25Cs(0);
- Par.Val = addr;
- dgSpiRw( GD25CMD_Read_Data);
- dgSpiRw( Par.byte.UB);
- dgSpiRw( Par.byte.HB);
- dgSpiRw( Par.byte.LB);
- while(Len--)
- {
- *Des++ = dgSpiRw( 0xFF );
- }
-
- GD25Cs(1);
- }
- /*****************************************************************************//*!
- * @brief write data ,must be in same page.
- *
- * @param addr address in chip
- * len length will be read
- * des source
- *
- * @return none
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- void gd25qWrite(uint32_t addr,uint32_t Len,uint8_t *Src)
- {
- UINT32_VAL Par;
-
- //waiting for idle
- while(gd25qBusy()){}
-
- gd25qCmdWriteEn();
-
- GD25Cs(0);
- Par.Val = addr;
- dgSpiRw( GD25CMD_Page_Program);
- dgSpiRw( Par.byte.UB);
- dgSpiRw( Par.byte.HB);
- dgSpiRw( Par.byte.LB);
- while(Len--)
- {
- dgSpiRw( *Src++ );
- }
- GD25Cs(1);
- }
- /*****************************************************************************//*!
- * @brief read data.
- *
- * @param addr address in chip
- * len length will be read
- * des destination
- *
- * @return none
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- void gd25qDmaRead(uint32_t addr,uint32_t Len,uint8_t *Des)
- {
- UINT32_VAL Par;
-
- //waiting for idle
- while(gd25qBusy()){}
- //
- GD25Cs(0);
- Par.Val = addr;
- dgSpiRw( GD25CMD_Read_Data);
- dgSpiRw( Par.byte.UB);
- dgSpiRw( Par.byte.HB);
- dgSpiRw( Par.byte.LB);
- gdSpiDmaRw(GD25Q_READ, Len, Des);
- GD25Cs(1);
- }
- /*****************************************************************************//*!
- * @brief write data ,must be in same page.
- *
- * @param addr address in chip
- * len length will be read
- * des source
- *
- * @return none
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- void gd25qDmaWrite(uint32_t addr,uint32_t Len,uint8_t *Src)
- {
- UINT32_VAL Par;
-
- //waiting for idle
- while(gd25qBusy()){}
-
- gd25qCmdWriteEn();
-
- GD25Cs(0);
- Par.Val = addr;
- dgSpiRw( GD25CMD_Page_Program);
- dgSpiRw( Par.byte.UB);
- dgSpiRw( Par.byte.HB);
- dgSpiRw( Par.byte.LB);
-
- gdSpiDmaRw(GD25Q_WRITE, Len, Src);
-
- GD25Cs(1);
- }
复制代码 strctr.c- #define _STR_MODULE_
- #include "osObjects.h"
- #include "strctr.h"
- #include "gd25q_cmd.h"
- uint8_t Gd25DataBuff[1024];
- /*****************************************************************************//*!
- *
- * @brief led task.
- *
- * @param none
- *
- * @return none
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- void StrCtrTask(void *argument) {
- uint16_t Cnt;
-
- gdSpiInit();
- Cnt = 0;
-
- for (;;) {
- vTaskDelay(250);
- gd25qRead(Cnt, 1024, Gd25DataBuff);
- Cnt++;
- if(Gd25DataBuff[0]){
- // Cnt = 256;
- //while(Cnt--)
- // Gd25DataBuff[Cnt] = Cnt;
- //gd25qWrite(0x00, 256, Gd25DataBuff);
- //gd25qWrite(0x100, 256, Gd25DataBuff);
- //gd25qWrite(0x200, 256, Gd25DataBuff);
- //gd25qWrite(0x300, 256, Gd25DataBuff);
- //gd25qWrite(0x400, 256, Gd25DataBuff);
- //gd25qWrite(0x500, 256, Gd25DataBuff);
- }
- }
- }
复制代码 |
|