- /**
 
-  * [url=home.php?mod=space&uid=288409]@file[/url]        main.c
 
-  *
 
-  * [url=home.php?mod=space&uid=247401]@brief[/url]       Main program body
 
-  *
 
-  * [url=home.php?mod=space&uid=895143]@version[/url]     V1.0.0
 
-  *
 
-  * [url=home.php?mod=space&uid=212281]@date[/url]        2024-12-01
 
-  *
 
-  * @attention
 
-  *
 
-  *  Copyright (C) 2024-2025 Geehy Semiconductor
 
-  *
 
-  *  You may not use this file except in compliance with the
 
-  *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
 
-  *
 
-  *  The program is only for reference, which is distributed in the hope
 
-  *  that it will be useful and instructional for customers to develop
 
-  *  their software. Unless required by applicable law or agreed to in
 
-  *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
 
-  *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
 
-  *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
 
-  *  and limitations under the License.
 
-  */
 
 
- /* Includes ***************************************************************/
 
- #include "main.h"
 
- #include "bsp_w25q16.h"
 
 
- /* Private includes *******************************************************/
 
- #include <stdio.h>
 
 
- /* Private macro **********************************************************/
 
- /* printf function configs to USART */
 
- #define DEBUG_USART  USART1
 
- #define DATA_BUF_SIZE       128
 
 
- typedef enum {FALSE, TRUE} BOOL;
 
- W25Q16_INFO_T w25q16Info;
 
- uint16_t txDataBufSPI1[DATA_BUF_SIZE] = {0};
 
- uint16_t rxDataBufSPI1[DATA_BUF_SIZE] = {0};
 
 
- /** SPI TX Buffer*/
 
- const uint16_t SPI_Data_TX[DATA_BUF_SIZE] =
 
- {
 
-     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0X07,
 
-     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0X07,
 
-     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0X07,
 
-     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0X07,
 
-     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0X07,
 
-     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0X07,
 
-     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0X07,
 
-     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0X07,
 
- };
 
 
- /* Private function prototypes ********************************************/
 
- void USART_Init(void);
 
- void Delay(uint32_t count);
 
- void W25Q16_SPI_Test(void);
 
- void Print_Buffer(uint16_t* pBuffer, uint16_t BufferLength);
 
- uint8_t BufferCompare(uint16_t* buf1, uint16_t* buf2, uint8_t size);
 
 
- /* External variables *****************************************************/
 
 
- /* External functions *****************************************************/
 
 
- /*!
 
-  * @brief   Main program
 
-  *
 
-  * @param   None
 
-  *
 
-  * @retval  None
 
-  */
 
- int main(void)
 
- {
 
-                 USART_Init();        
 
 
-     W25Q16_SPI_Init();
 
-         
 
-     /* Get Flash Device ID */
 
-                 w25q16Info.deviceID = W25Q16_ReadFlashDeviceID();
 
-                 printf("Device ID:0x%X\r\n",w25q16Info.deviceID);
 
-         
 
-                 /* Get Flash ID */
 
-                 w25q16Info.flashID = W25Q16_ReadFlashID();
 
-                 printf("Flash  ID:0x%X\r\n",w25q16Info.flashID);
 
 
-                 W25Q16_SPI_Test();
 
-     /* Infinite loop */
 
-     while (1)
 
-     {
 
 
-     }
 
- }
 
 
- /*!
 
-  * @brief       USART INIT
 
-  *
 
-  * @param       None
 
-  *
 
-  * @retval      None
 
-  *
 
-  * @note
 
-  */
 
- void USART_Init(void)
 
- {
 
-     USART_Config_T USART_ConfigStruct;
 
-     GPIO_Config_T GPIO_ConfigStruct;
 
 
-     // 使能 USART1 和 GPIO 端口时钟
 
-     RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_USART1 | RCM_APB2_PERIPH_GPIOA);
 
 
-     // 配置 TX 引脚为复用推挽输出
 
-     GPIO_ConfigStruct.pin = GPIO_PIN_9;
 
-     GPIO_ConfigStruct.mode = GPIO_MODE_AF_PP;
 
-     GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
 
-     GPIO_Config(GPIOA, &GPIO_ConfigStruct);
 
 
-     // 配置 RX 引脚为浮空输入
 
-     GPIO_ConfigStruct.pin = GPIO_PIN_10;
 
-     GPIO_ConfigStruct.mode = GPIO_MODE_IN_FLOATING;
 
-     GPIO_Config(GPIOA, &GPIO_ConfigStruct);
 
 
-     // USART 配置
 
-     USART_ConfigStructInit(&USART_ConfigStruct);
 
-     USART_ConfigStruct.baudRate = 115200;
 
-     USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;
 
-     USART_ConfigStruct.mode = USART_MODE_TX_RX;  // 同时启用发送和接收模式
 
-     USART_ConfigStruct.parity = USART_PARITY_NONE;
 
-     USART_ConfigStruct.stopBits = USART_STOP_BIT_1;
 
-     USART_ConfigStruct.wordLength = USART_WORD_LEN_8B;
 
 
-     USART_Config(USART1, &USART_ConfigStruct);
 
 
-     // 使能 USART1
 
-     USART_Enable(USART1);        
 
- }
 
 
- /*!
 
-  * @brief       Using SPI operate W25Q16 flash
 
-  *
 
-  * @param       None
 
-  *
 
-  * @retval      None
 
-  *
 
-  * @note
 
-  */
 
- void W25Q16_SPI_Test(void)
 
- {
 
-     uint16_t i = 0;
 
-     
 
-     /* initialization  Buffer*/
 
-     for (i = 0; i < DATA_BUF_SIZE; i++)
 
-     {
 
-         txDataBufSPI1[i] = SPI_Data_TX[i] + 0x1010;
 
-         rxDataBufSPI1[i] = 0;
 
-     }
 
 
-     printf("SPI write Data to flash \r\n");
 
 
-     /* Erase SPI FLASH Sector */
 
-     W25Q16_EraseSector(W25Q16_FLASH_WRITE_ADDR);
 
 
-     /* Write data to flash */
 
-     W25Q16_WriteBuffer((uint8_t*)txDataBufSPI1, W25Q16_FLASH_WRITE_ADDR, DATA_BUF_SIZE * 2);
 
-     printf("\r\nWrite data: \r\n");
 
-     Print_Buffer(txDataBufSPI1, DATA_BUF_SIZE);
 
 
-     /* Read data from flash */
 
-     W25Q16_ReadBuffer((uint8_t*)rxDataBufSPI1, W25Q16_FLASH_READ_ADDR, DATA_BUF_SIZE * 2);
 
-     printf("\r\nRead data: \r\n");
 
-     Print_Buffer(rxDataBufSPI1, DATA_BUF_SIZE);
 
 
-     /* Compare receive Buffer */
 
-     /* Data is ok then turn on LED2 */
 
-     if (BufferCompare(txDataBufSPI1, rxDataBufSPI1, DATA_BUF_SIZE) == TRUE)
 
-     {
 
-         printf("\r\nSPI Flash test OK! LED2 on\n\r");
 
-     }
 
-     else
 
-     {
 
-         printf("\r\nSPI Flash test fail! LED3 on\n\r");
 
-     }
 
- }
 
- /*!
 
-  * @brief       Compares two buffers
 
-  *
 
-  * @param       buf1:    First buffer to be compared
 
-  *
 
-  * @param       buf1:    Second buffer to be compared
 
-  *
 
-  * @param       size:    Buffer size
 
-  *
 
-  * @retval      Return TRUE if buf1 = buf2. If not then return FALSE
 
-  */
 
- uint8_t BufferCompare(uint16_t* buf1, uint16_t* buf2, uint8_t size)
 
- {
 
-     uint8_t i;
 
 
-     for (i = 0; i < size; i++)
 
-     {
 
-         if (buf1[i] != buf2[i])
 
-         {
 
-             return FALSE;
 
-         }
 
-     }
 
 
-     return TRUE;
 
- }
 
 
- /*!
 
-  * @brief       Print Buffer Data
 
-  *
 
-  * @param       pBuffer:buffer
 
-  *
 
-  * @param       length : length of the Buffer
 
-  *
 
-  * @retval      None
 
-  */
 
- void Print_Buffer(uint16_t* pBuffer, uint16_t BufferLength)
 
- {
 
-     uint16_t i;
 
 
-     for (i=0; i  < BufferLength; i++)
 
-     {
 
-         printf("0x%04X  ", pBuffer[i]);
 
 
-         if ((i+1)%8 == 0)
 
-         {
 
-             printf("\r\n");
 
-         }
 
-     }
 
- }
 
- /*!
 
-  * @brief     Delay
 
-  *
 
-  * @param     count:  delay count
 
-  *
 
-  * @retval    None
 
-  */
 
- void Delay(uint32_t count)
 
- {
 
-     uint16_t i = 0;
 
 
-     while (count--)
 
-     {
 
-         i = 7995;
 
-         while (i--);
 
-     }
 
- }
 
 
- #if defined (__CC_ARM) || defined (__ICCARM__) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
 
 
- /*!
 
- * @brief       Redirect C Library function printf to serial port.
 
- *              After Redirection, you can use printf function.
 
- *
 
- * @param       ch:  The characters that need to be send.
 
- *
 
- * @param       *f:  pointer to a FILE that can recording all information
 
- *              needed to control a stream
 
- *
 
- * @retval      The characters that need to be send.
 
- *
 
- * @note
 
- */
 
- int fputc(int ch, FILE* f)
 
- {
 
-     /* send a byte of data to the serial port */
 
-     USART_TxData(DEBUG_USART, (uint8_t)ch);
 
 
-     /* wait for the data to be send */
 
-     while (USART_ReadStatusFlag(DEBUG_USART, USART_FLAG_TXBE) == RESET);
 
 
-     return (ch);
 
- }
 
 
- #elif defined (__GNUC__)
 
 
- /*!
 
- * @brief       Redirect C Library function printf to serial port.
 
- *              After Redirection, you can use printf function.
 
- *
 
- * @param       ch:  The characters that need to be send.
 
- *
 
- * @retval      The characters that need to be send.
 
- *
 
- * @note
 
- */
 
- int __io_putchar(int ch)
 
- {
 
-     /* send a byte of data to the serial port */
 
-     USART_TxData(DEBUG_USART, ch);
 
 
-     /* wait for the data to be send */
 
-     while (USART_ReadStatusFlag(DEBUG_USART, USART_FLAG_TXBE) == RESET);
 
 
-     return ch;
 
- }
 
 
- /*!
 
- * @brief       Redirect C Library function printf to serial port.
 
- *              After Redirection, you can use printf function.
 
- *
 
- * @param       file:  Meaningless in this function.
 
- *
 
- * @param       *ptr:  Buffer pointer for data to be sent.
 
- *
 
- * @param       len:  Length of data to be sent.
 
- *
 
- * @retval      The characters that need to be send.
 
- *
 
- * @note
 
- */
 
- int _write(int file, char* ptr, int len)
 
- {
 
-         UNUSED(file);
 
 
-     int i;
 
-     for (i = 0; i < len; i++)
 
-     {
 
-         __io_putchar(*ptr++);
 
-     }
 
 
-     return len;
 
- }
 
 
- #else
 
- #warning Not supported compiler type
 
- #endif
 
- /*!
 
-  * @file        bsp_sdio.c
 
-  *
 
-  * @brief       SDIO board support package body
 
-  *
 
-  * @version     V1.0.0
 
-  *
 
-  * @date        2022-09-30
 
-  *
 
-  * @attention
 
-  *
 
-  *  Copyright (C) 2022 Geehy Semiconductor
 
-  *
 
-  *  You may not use this file except in compliance with the
 
-  *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
 
-  *
 
-  *  The program is only for reference, which is distributed in the hope
 
-  *  that it will be useful and instructional for customers to develop
 
-  *  their software. Unless required by applicable law or agreed to in
 
-  *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
 
-  *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
 
-  *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
 
-  *  and limitations under the License.
 
-  */
 
 
- /* Includes */
 
- #include "bsp_w25q16.h"
 
 
- /** @addtogroup Board
 
-   @{
 
- */
 
 
- /** @addtogroup Board_APM32E103_EVAL
 
-   @{
 
- */
 
 
- /** @defgroup APM32E103_EVAL_Fuctions
 
-   @{
 
-   */
 
 
- /*!
 
-  * @brief       W25Q16 SPI Initialization
 
-  *
 
-  * @param       None
 
-  *
 
-  * @retval      None
 
-  */
 
- void W25Q16_SPI_Init(void)
 
- {
 
-     GPIO_Config_T gpioConfig;
 
-     SPI_Config_T spiConfig;
 
 
-     /* Enable related Clock */
 
-     RCM_EnableAPB2PeriphClock(FLASH_SPI_BUS_CLK | FLASH_SPI_GPIO_CLK | FLASH_SPI_CS_GPIO_CLK |RCM_APB2_PERIPH_AFIO);
 
-     
 
-     GPIO_ConfigPinRemap(GPIO_REMAP_SWJ_JTAGDISABLE);
 
 
-     /* Configure FLASH_SPI pins: SCK */
 
-     gpioConfig.pin =  FLASH_SPI_SCK_PIN ;
 
-     gpioConfig.mode = GPIO_MODE_AF_PP;
 
-     gpioConfig.speed = GPIO_SPEED_50MHz;
 
-     GPIO_Config(FLASH_SPI_GPIO_PORT, &gpioConfig);
 
 
-     /* Configure FLASH_SPI pins: MOSI */
 
-     gpioConfig.pin = FLASH_SPI_MOSI_PIN;
 
-     GPIO_Config(FLASH_SPI_GPIO_PORT, &gpioConfig);
 
 
-     /* Configure FLASH_SPI pins: MISO */
 
-     gpioConfig.pin = FLASH_SPI_MISO_PIN;
 
-     gpioConfig.mode = GPIO_MODE_IN_FLOATING;
 
-     GPIO_Config(FLASH_SPI_GPIO_PORT, &gpioConfig);
 
 
-     /* Configure FLASH_SPI_CS_PIN pin: sFLASH Card CS pin */
 
-     gpioConfig.pin = FLASH_SPI_CS_PIN;
 
-     gpioConfig.mode = GPIO_MODE_OUT_PP;
 
-     GPIO_Config(FLASH_SPI_CS_GPIO_PORT, &gpioConfig);
 
 
-     /* Deselect the FLASH: Chip Select high */
 
-     FLASH_SPI_CS_SET();
 
 
-     /* SPI configuration */
 
-     spiConfig.direction = SPI_DIRECTION_2LINES_FULLDUPLEX;
 
-     spiConfig.mode = SPI_MODE_MASTER;
 
-     spiConfig.length = SPI_DATA_LENGTH_8B;
 
-     spiConfig.polarity = SPI_CLKPOL_HIGH;
 
-     spiConfig.phase = SPI_CLKPHA_2EDGE;
 
-     spiConfig.nss = SPI_NSS_SOFT;
 
-     spiConfig.baudrateDiv = SPI_BAUDRATE_DIV_4;
 
-     spiConfig.firstBit = SPI_FIRSTBIT_MSB;
 
-     spiConfig.crcPolynomial =0;
 
-     SPI_Config(FLASH_SPI_BUS, &spiConfig);
 
 
-     /* Enable SPI  */
 
-     SPI_Enable(FLASH_SPI_BUS);
 
- }
 
 
- /*!
 
-  * @brief       Erase Falsh Sector
 
-  *
 
-  * @param       SectorAddr:Sector Addr
 
-  *
 
-  * @retval      None
 
-  */
 
- void W25Q16_EraseSector(uint32_t SectorAddr)
 
- {
 
-     /* Flash Write Enable  */
 
-     W25Q16_EnableFlashWrite();
 
-     W25Q16_WaitFlashWriteEnd();
 
 
-     /* Select the FLASH */
 
-     FLASH_SPI_CS_CLR();
 
 
-     /* send cmd */
 
-     W25Q16_SendByte(W25Q16_SECTOR_ERASE);
 
 
-     /* send Sector Addr */
 
-     W25Q16_SendByte((SectorAddr & 0xFF0000) >> 16);
 
-     W25Q16_SendByte((SectorAddr & 0xFF00) >> 8);
 
-     W25Q16_SendByte(SectorAddr & 0xFF);
 
 
-     /* Deselect the FLASH */
 
-     FLASH_SPI_CS_SET();
 
 
-     /* wait Falsh Erase end */
 
-     W25Q16_WaitFlashWriteEnd();
 
- }
 
-  /**
 
-   * @brief  擦除FLASH扇区,整片擦除
 
-   * @param  无
 
-   * @retval 无
 
-   */
 
- void SPI_FLASH_BulkErase(void)
 
- {
 
-   /* 发送FLASH写使能命令 */
 
-   W25Q16_EnableFlashWrite();
 
 
-   /* 整块 Erase */
 
-   /* 选择FLASH: CS低电平 */
 
-   FLASH_SPI_CS_CLR();
 
-   /* 发送整块擦除指令*/
 
-   W25Q16_SendByte(W25Q16_CHIP_ERASE);
 
-   /* 停止信号 FLASH: CS 高电平 */
 
-   FLASH_SPI_CS_SET();
 
 
-   /* 等待擦除完毕*/
 
-   W25Q16_WaitFlashWriteEnd();
 
- }
 
- /*!
 
-  * @brief       Flash Write Page
 
-  *
 
-  * @param       pBuffer: pointer to the Write buffer
 
-  *
 
-  * @param       WriteAddr: Write the flash Address
 
-  *
 
-  * @param       NumToWrite: the number of byte to write
 
-  *
 
-  * @retval      None
 
-  */
 
- void W25Q16_WritePage(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumToWrite)
 
- {
 
-     /* Enable Flash Write */
 
-     W25Q16_EnableFlashWrite();
 
 
-     /* Select the FLASH */
 
-     FLASH_SPI_CS_CLR();
 
 
-     /* W25Q16 Page Program */
 
-     W25Q16_SendByte(W25Q16_PAGE_PROGRAM);
 
-     W25Q16_SendByte((WriteAddr & 0xFF0000) >> 16);
 
-     W25Q16_SendByte((WriteAddr & 0xFF00) >> 8);
 
-     W25Q16_SendByte(WriteAddr & 0xFF);
 
 
-     if (NumToWrite > W25Q16_FLASH_PAGE_SIZE)
 
-     {
 
-         NumToWrite = W25Q16_FLASH_PAGE_SIZE;
 
-     }
 
 
-     /* Write data to flash*/
 
-                 while (NumToWrite--)
 
-                 {
 
-                         /* 发送当前要写入的字节数据 */
 
-                         W25Q16_SendByte(*pBuffer);
 
-                         /* 指向下一字节数据 */
 
-                         pBuffer++;
 
-                 }
 
-     /* Deselect the FLASH */
 
-     FLASH_SPI_CS_SET();
 
 
-     /* Wait Write End*/
 
-     W25Q16_WaitFlashWriteEnd();
 
- }
 
 
- /*!
 
-  * @brief       Flash Write Buffer
 
-  *
 
-  * @param       pBuffer: pointer to the Write buffer
 
-  *
 
-  * @param       WriteAddr: Write the flash Address
 
-  *
 
-  * @param       NumToWrite: the number of byte to write
 
-  *
 
-  * @retval      None
 
-  */
 
- void W25Q16_WriteBuffer(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumToWrite)
 
- {
 
-     uint8_t i = 0;
 
-     uint8_t PageNumber = 0;
 
-     uint8_t RemainNumber = 0;
 
-     uint8_t PageRemainNumber = 0;
 
 
-     /* complete Page need to write */
 
-     PageNumber =  NumToWrite / W25Q16_FLASH_PAGE_SIZE;
 
 
-     /* Remain byte */
 
-     RemainNumber = NumToWrite % W25Q16_FLASH_PAGE_SIZE;
 
 
-     /* if WriteAddr align */
 
-     if ((WriteAddr % W25Q16_FLASH_PAGE_SIZE) == 0)
 
-     {
 
-         /* NumToWrite < W25Q16_FLASH_PAGE_SIZE */
 
-         if (PageNumber == 0)
 
-         {
 
-             W25Q16_WritePage(pBuffer, WriteAddr, NumToWrite);
 
-         }
 
-         else
 
-         {
 
-             /* write complete Page */
 
-             for (i = 0; i < PageNumber; i++)
 
-             {
 
-                 W25Q16_WritePage(pBuffer, WriteAddr, W25Q16_FLASH_PAGE_SIZE);
 
-                 WriteAddr +=  W25Q16_FLASH_PAGE_SIZE;
 
-                 pBuffer += W25Q16_FLASH_PAGE_SIZE;
 
-             }
 
 
-             /* write remain data */
 
-             if (RemainNumber > 0)
 
-             {
 
-                 W25Q16_WritePage(pBuffer, WriteAddr, RemainNumber);
 
-             }
 
-         }
 
-     }
 
-     else
 
-     {
 
-         /* Write Address Page Remain Number */
 
-         PageRemainNumber = W25Q16_FLASH_PAGE_SIZE - (WriteAddr % W25Q16_FLASH_PAGE_SIZE);
 
 
-         /* NumToWrite < W25Q16_FLASH_PAGE_SIZE */
 
-         if (PageNumber == 0)
 
-         {
 
-             if (RemainNumber > PageRemainNumber)
 
-             {
 
-                 /* write all over the current page */
 
-                 W25Q16_WritePage(pBuffer, WriteAddr, PageRemainNumber);
 
-                 WriteAddr +=  PageRemainNumber;
 
-                 pBuffer += PageRemainNumber;
 
 
-                 RemainNumber = RemainNumber - PageRemainNumber;;
 
 
-                 /* write remain data */
 
-                 W25Q16_WritePage(pBuffer, WriteAddr, RemainNumber);
 
-             }
 
-             else
 
-             {
 
-                 W25Q16_WritePage(pBuffer, WriteAddr, RemainNumber);
 
-             }
 
-         }
 
-         else
 
-         {
 
-             /* write all over the current page */
 
-             W25Q16_WritePage(pBuffer, WriteAddr, PageRemainNumber);
 
-             WriteAddr +=  PageRemainNumber;
 
-             pBuffer += PageRemainNumber;
 
 
-             NumToWrite -= PageRemainNumber;
 
-             PageNumber =  NumToWrite / W25Q16_FLASH_PAGE_SIZE;
 
-             RemainNumber = NumToWrite % W25Q16_FLASH_PAGE_SIZE;
 
 
-             /* write complete Page */
 
-             for (i = 0; i < PageNumber; i++)
 
-             {
 
-                 W25Q16_WritePage(pBuffer, WriteAddr, W25Q16_FLASH_PAGE_SIZE);
 
-                 WriteAddr +=  W25Q16_FLASH_PAGE_SIZE;
 
-                 pBuffer += W25Q16_FLASH_PAGE_SIZE;
 
-             }
 
 
-             /* write remain data */
 
-             if (RemainNumber > 0)
 
-             {
 
-                 W25Q16_WritePage(pBuffer, WriteAddr, RemainNumber);
 
-             }
 
-         }
 
-     }
 
- }
 
 
- /*!
 
-  * @brief       Flash Read Buffer
 
-  *
 
-  * @param       pBuffer: pointer to the read buffer
 
-  *
 
-  * @param       ReadAddr: read the flash Address
 
-  *
 
-  * @param       NumToWrite: the number of byte to read
 
-  *
 
-  * @retval      None
 
-  */
 
- void W25Q16_ReadBuffer(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumToRead)
 
- {
 
-     uint16_t i = 0;
 
 
-     /* Select the FLASH */
 
-     FLASH_SPI_CS_CLR();
 
 
-     /* send read cmd */
 
-     W25Q16_SendByte(W25Q16_READ_DATA);
 
-     W25Q16_SendByte((ReadAddr & 0xFF0000) >> 16);
 
-     W25Q16_SendByte((ReadAddr& 0xFF00) >> 8);
 
-     W25Q16_SendByte(ReadAddr & 0xFF);
 
 
-     /* read data to flash*/
 
-     for (i = 0; i < NumToRead; i++)
 
-     {
 
-         *pBuffer = W25Q16_SendByte(W25Q16_DUMMY_BYTE);
 
-         pBuffer++;
 
-     }
 
 
-     /* Deselect the FLASH */
 
-     FLASH_SPI_CS_SET();
 
- }
 
 
 
- /*!
 
-  * @brief       Flash Read ID
 
-  *
 
-  * @param       None
 
-  *
 
-  * @retval      None
 
-  */
 
- uint32_t W25Q16_ReadFlashID(void)
 
- {
 
-     uint32_t TempBuffer[3] = {0};
 
-     uint32_t FlashID = 0;
 
 
-     /* Select the FLASH */
 
-     FLASH_SPI_CS_CLR();
 
 
-     /* send read ID cmd */
 
-     W25Q16_SendByte(W25Q16_JEDEC_DEVICE_ID);
 
-     TempBuffer[0] = W25Q16_SendByte(W25Q16_DUMMY_BYTE);
 
-     TempBuffer[1] = W25Q16_SendByte(W25Q16_DUMMY_BYTE);
 
-     TempBuffer[2] = W25Q16_SendByte(W25Q16_DUMMY_BYTE);
 
 
-     /* Deselect the FLASH */
 
-     FLASH_SPI_CS_SET();
 
 
-     FlashID = (TempBuffer[0] << 16) | (TempBuffer[1] << 8) | TempBuffer[2];
 
 
-     return FlashID;
 
- }
 
 
- /*!
 
-  * @brief       Read Flash DeviceID
 
-  *
 
-  * @param       None
 
-  *
 
-  * @retval      None
 
-  */
 
- uint32_t W25Q16_ReadFlashDeviceID(void)
 
- {
 
-     uint32_t DeviceID = 0;
 
 
-     /* Select the FLASH */
 
-     FLASH_SPI_CS_CLR();
 
 
-     /* Send W25Q16 DeviceID cmd */
 
-     W25Q16_SendByte(W25Q16_DEVICE_ID);
 
-     W25Q16_SendByte(W25Q16_DUMMY_BYTE);
 
-     W25Q16_SendByte(W25Q16_DUMMY_BYTE);
 
-     W25Q16_SendByte(W25Q16_DUMMY_BYTE);
 
 
-     /* Read DeviceID from the FLASH */
 
-     DeviceID = W25Q16_SendByte(W25Q16_DUMMY_BYTE);
 
 
-     /* Deselect the FLASH */
 
-     FLASH_SPI_CS_SET();
 
 
-     return DeviceID;
 
- }
 
 
- /*!
 
-  * @brief       SPI read Byte from flash
 
-  *
 
-  * @param       None
 
-  *
 
-  * @retval      None
 
-  */
 
- uint8_t W25Q16_ReadByte(void)
 
- {
 
-     uint8_t temp = 0;
 
 
-     temp = W25Q16_SendByte(W25Q16_DUMMY_BYTE);
 
 
-     return temp;
 
- }
 
 
- /*!
 
-  * @brief       SPI Send Byte to flash
 
-  *
 
-  * @param       None
 
-  *
 
-  * @retval      None
 
-  */
 
- uint8_t W25Q16_SendByte(uint8_t data)
 
- {
 
-     /* SPI master send data */
 
-     while (SPI_I2S_ReadStatusFlag(FLASH_SPI_BUS, SPI_FLAG_TXBE) == RESET);
 
 
-     SPI_I2S_TxData(FLASH_SPI_BUS, data);
 
 
-     /* SPI slave receive data */
 
-     while (SPI_I2S_ReadStatusFlag(FLASH_SPI_BUS, SPI_FLAG_RXBNE) == RESET);
 
 
-     return SPI_I2S_RxData(FLASH_SPI_BUS);
 
- }
 
 
- /*!
 
-  * @brief       Enable Flash Write
 
-  *
 
-  * @param       None
 
-  *
 
-  * @retval      None
 
-  */
 
- void W25Q16_EnableFlashWrite(void)
 
- {
 
-     FLASH_SPI_CS_CLR();
 
 
-     /* send W25Q16 Write Enable cmd */
 
-     W25Q16_SendByte(W25Q16_WRITE_ENABLE);
 
 
-     FLASH_SPI_CS_SET();
 
- }
 
 
- /*!
 
-  * @brief       Wait Flash Write End
 
-  *
 
-  * @param       None
 
-  *
 
-  * @retval      None
 
-  */
 
- void W25Q16_WaitFlashWriteEnd(void)
 
- {
 
-     uint8_t RegStatus = 0;
 
 
-     FLASH_SPI_CS_CLR();
 
 
-     /* send Read W25Q16 Status cmd */
 
-     W25Q16_SendByte(W25Q16_READ_STATUS_REG);
 
 
-     do
 
-     {
 
-         /* Read W25Q16 Status Reg */
 
-         RegStatus = W25Q16_SendByte(W25Q16_DUMMY_BYTE);
 
-     }
 
-     while ((RegStatus & W25Q16_WIP_FLAG) != 0);
 
 
-     FLASH_SPI_CS_SET();
 
- }
 
 
- /*!
 
-  * @brief       Flash Into PowerDown
 
-  *
 
-  * @param       None
 
-  *
 
-  * @retval      None
 
-  */
 
- void W25Q16_IntoPowerDown(void)
 
- {
 
-     FLASH_SPI_CS_CLR();
 
 
-     /* send PowerDown cmd*/
 
-     W25Q16_SendByte(W25Q16_POWER_DOWN);
 
 
-     FLASH_SPI_CS_SET();
 
- }
 
 
- /**@} end of group APM32E103_EVAL_Functions */
 
- /**@} end of group Board_APM32E103_EVAL */
 
- /**@} end of group Board */
 
- /* Define to prevent recursive inclusion */
 
- #ifndef __BSP_SPI_FLASH_H
 
- #define __BSP_SPI_FLASH_H
 
 
- /* Includes */
 
- #include "main.h"
 
 
- /* W25Q16 */
 
- #define W25Q16_FLASH_ID                   0xEF4015
 
- #define W25Q16_FLASH_PAGE_SIZE            256
 
 
- #define W25Q16_FLASH_WRITE_ADDR           0x00000
 
- #define W25Q16_FLASH_READ_ADDR            W25Q16_FLASH_WRITE_ADDR
 
 
- /* W25Q16 CMD */
 
- #define W25Q16_WRITE_ENABLE               0x06
 
- #define W25Q16_WRITE_DISABLE              0x04
 
- #define W25Q16_READ_STATUS_REG            0x05
 
- #define W25Q16_WRITE_STATUS_REG           0x01
 
- #define W25Q16_READ_DATA                  0x03
 
- #define W25Q16_FAST_READ_DATA             0x0B
 
- #define W25Q16_FAST_RAED_DUAL             0x3B
 
- #define W25Q16_PAGE_PROGRAM               0x02
 
- #define W25Q16_BLOCK_ERASE                0xD8
 
- #define W25Q16_SECTOR_ERASE               0x20
 
- #define W25Q16_CHIP_ERASE                 0xC7
 
- #define W25Q16_POWER_DOWN                 0xB9
 
- #define W25Q16_RELEASE_POWER_DOWN         0xAB
 
- #define W25Q16_DEVICE_ID                  0xAB
 
- #define W25Q16_MANUFACT_DEVICE_ID         0x90
 
- #define W25Q16_JEDEC_DEVICE_ID            0x9F
 
- #define W25Q16_WIP_FLAG                   0x01
 
- #define W25Q16_DUMMY_BYTE                 0xFF
 
 
- /* FLASH CS */
 
- #define FLASH_SPI_BUS                     SPI1
 
- #define FLASH_SPI_BUS_CLK                 RCM_APB2_PERIPH_SPI1
 
 
- #define FLASH_SPI_MOSI_PIN                GPIO_PIN_7
 
- #define FLASH_SPI_MISO_PIN                GPIO_PIN_6
 
- #define FLASH_SPI_SCK_PIN                 GPIO_PIN_5
 
- #define FLASH_SPI_GPIO_CLK                RCM_APB2_PERIPH_GPIOA
 
- #define FLASH_SPI_GPIO_PORT               GPIOA
 
 
- #define FLASH_SPI_CS_PIN                  GPIO_PIN_4
 
- #define FLASH_SPI_CS_GPIO_CLK             RCM_APB2_PERIPH_GPIOA
 
- #define FLASH_SPI_CS_GPIO_PORT            GPIOA
 
-                                         
 
- //#define FLASH_SPI_MOSI_SOURCE             GPIO_PIN_SOURCE_15
 
- //#define FLASH_SPI_MISO_SOURCE             GPIO_PIN_SOURCE_14
 
- //#define FLASH_SPI_SCK_SOURCE              GPIO_PIN_SOURCE_13
 
- //#define FLASH_SPI_CS_SOURCE               GPIO_PIN_SOURCE_12
 
- //#define FLASH_SPI_GPIO_AF                 GPIO_AF_PIN1
 
-                                         
 
- #define FLASH_SPI_MOSI_CLR()              GPIO_ResetBit(FLASH_SPI_GPIO_PORT, FLASH_SPI_MOSI_PIN)
 
- #define FLASH_SPI_MOSI_SET()              GPIO_SetBit(FLASH_SPI_GPIO_PORT, FLASH_SPI_MOSI_PIN)
 
-                                         
 
- #define FLASH_SPI_MISO_CLR()              GPIO_ResetBit(FLASH_SPI_GPIO_PORT, FLASH_SPI_MISO_PIN)
 
- #define FLASH_SPI_MISO_SET()              GPIO_SetBit(FLASH_SPI_GPIO_PORT, FLASH_SPI_MISO_PIN)
 
-                                         
 
- #define FLASH_SPI_SCK_CLR()               GPIO_ResetBit(FLASH_SPI_GPIO_PORT, FLASH_SPI_SCK_PIN)
 
- #define FLASH_SPI_SCK_SET()               GPIO_SetBit(FLASH_SPI_GPIO_PORT, FLASH_SPI_SCK_PIN)
 
-                                         
 
- #define FLASH_SPI_CS_CLR()                GPIO_ResetBit(FLASH_SPI_CS_GPIO_PORT, FLASH_SPI_CS_PIN)
 
- #define FLASH_SPI_CS_SET()                GPIO_SetBit(FLASH_SPI_CS_GPIO_PORT, FLASH_SPI_CS_PIN)
 
 
- /**@} end of group APM32E103_EVAL_Macros*/
 
 
- /** @defgroup APM32E103_EVAL_Structures Structures
 
-   @{
 
-   */
 
 
- typedef struct {
 
-     uint32_t deviceID;
 
-     uint32_t flashID;
 
- } W25Q16_INFO_T;
 
 
- /**@} end of group APM32E103_EVAL_Structures*/
 
 
- /** @defgroup APM32E103_EVAL_Functions Functions
 
-   @{
 
-   */
 
 
- void W25Q16_IntoPowerDown(void);
 
- uint8_t W25Q16_SendByte(uint8_t byte);
 
- uint8_t W25Q16_ReadByte(void);
 
- void W25Q16_SPI_Init(void);
 
- void W25Q16_WritePage(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumToWrite);
 
- void W25Q16_WriteBuffer(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumToWrite);
 
- void W25Q16_ReadBuffer(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumToRead);
 
- uint32_t W25Q16_ReadFlashID(void);
 
- uint32_t W25Q16_ReadFlashDeviceID(void);
 
- void W25Q16_EnableFlashWrite(void);
 
- void W25Q16_WaitFlashWriteEnd(void);
 
- void W25Q16_EraseSector(uint32_t SectorAddr);
 
- void SPI_FLASH_BulkErase(void);
 
- #endif /* __BSP_SPI_FLASH_H */