| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374 |
- #include "hard_flash_gd25q16.h"
- #include "board.h"
- #include "hpm_spi_drv.h"
- #include "hpm_clock_drv.h"
- #include "hpm_gpio_drv.h"
- #ifdef GD25Q16_FLASH
- /* 使用 SPI2 作为示例,你可以根据需要修改 */
- #define AT45DB_SPI_BASE HPM_SPI2
- /******************SPI时钟频率*******************/
- #define AT45DB_CLK_FRE 21000000
- /* GPIO 参数定义 - 根据实际硬件修改 */
- #define AT45DB_CS_GPIO_PTR HPM_GPIO0 /* GPIO 控制器基地址 */
- #define AT45DB_CS_PORT 1 /* GPIOB = 1 */
- #define AT45DB_CS_PIN 12 /* PIN12 */
- /* CS 控制宏 - 完全保留原名 */
- #define AT45db161_SPI_SELECT() gpio_write_pin(AT45DB_CS_GPIO_PTR, AT45DB_CS_PORT, AT45DB_CS_PIN, 0)
- #define AT45db161_SPI_DESELECT() gpio_write_pin(AT45DB_CS_GPIO_PTR, AT45DB_CS_PORT, AT45DB_CS_PIN, 1)
- void gd25q16_cs_high()
- {
- AT45db161_SPI_DESELECT();
- }
- void gd25q16_cs_low()
- {
- AT45db161_SPI_SELECT();
- }
- /* 静态变量 */
- static uint32_t spi_clk_freq;
- /**
- * @brief SPI 读写一个字节 - 保留原名
- */
- uint8_t SPI2_ReadWrite_Byte(uint8_t byte)
- {
- uint8_t rx_byte = 0;
- spi_control_config_t control_config;
-
- /* 配置传输控制 */
- spi_master_get_default_control_config(&control_config);
- control_config.common_config.trans_mode = spi_trans_write_read_together;
- control_config.master_config.cmd_enable = false;
- control_config.master_config.addr_enable = false;
-
- /* 执行传输 */
- spi_transfer(AT45DB_SPI_BASE,
- &control_config,
- NULL, NULL,
- &byte, 1,
- &rx_byte, 1);
-
- return rx_byte;
- }
- /**
- * @brief 写使能 - 保留为静态函数,不暴露给外部
- */
- static void GD25Q16_WriteEnable(void)
- {
- AT45db161_SPI_SELECT();
- SPI2_ReadWrite_Byte(GD25Q16_WRITE_ENABLE);
- AT45db161_SPI_DESELECT();
- }
- /**
- * @brief 扇区擦除 - 保留原名
- */
- static void GD25Q16_Erase_Sector(uint32_t addr)
- {
- while(AT45DB_IS_BUSY() == 0);
- GD25Q16_WriteEnable();
- while(AT45DB_IS_BUSY() == 0);
- AT45db161_SPI_SELECT();
- SPI2_ReadWrite_Byte(GD25Q16SECTOR_ERASE);
- SPI2_ReadWrite_Byte((uint8_t)(addr >> 16));
- SPI2_ReadWrite_Byte((uint8_t)(addr >> 8));
- SPI2_ReadWrite_Byte((uint8_t)(addr));
- AT45db161_SPI_DESELECT();
- while(AT45DB_IS_BUSY() == 0);
- }
- /**
- * @brief 初始化 SPI 接口 - 保留原名
- */
- void AT45db161_SPI_Configuration(void)
- {
- spi_timing_config_t timing_config = {0};
- spi_format_config_t format_config = {0};
-
- /* 1. 初始化 SPI 时钟和引脚 */
- spi_clk_freq = board_init_spi_clock(AT45DB_SPI_BASE);
- board_init_spi_pins(AT45DB_SPI_BASE);
-
- /* 2. 配置 CS 引脚为输出 */
- gpio_set_pin_output(AT45DB_CS_GPIO_PTR, AT45DB_CS_PORT, AT45DB_CS_PIN);
- AT45db161_SPI_DESELECT(); /* CS 默认高电平 */
-
- /* 3. 配置 SPI 时序(主模式)*/
- spi_master_get_default_timing_config(&timing_config);
- timing_config.master_config.clk_src_freq_in_hz = spi_clk_freq;
- timing_config.master_config.sclk_freq_in_hz = AT45DB_CLK_FRE;
- spi_master_timing_init(AT45DB_SPI_BASE, &timing_config);
-
- /* 4. 配置 SPI 格式 */
- spi_master_get_default_format_config(&format_config);
- format_config.common_config.data_len_in_bits = 8; /* 8位数据 */
- format_config.common_config.mode = spi_master_mode; /* 主机模式 */
- format_config.common_config.cpol = spi_sclk_low_idle; /* CPOL=0 */
- format_config.common_config.cpha = spi_sclk_sampling_odd_clk_edges; /* CPHA=0 */
- spi_format_init(AT45DB_SPI_BASE, &format_config);
- }
- /**
- * @brief 初始化 flash 接口 - 保留原名
- */
- void flash_at45db_init(void)
- {
- AT45db161_SPI_Configuration();
- }
- /**
- * @brief 查询是否准备好 - 保留原名
- */
- uint8_t AT45DB_IS_BUSY(void)
- {
- uint8_t Status_Register;
- AT45db161_SPI_SELECT();
- SPI2_ReadWrite_Byte(GD25Q16_READ_STATE_REGISTER);
- Status_Register = SPI2_ReadWrite_Byte(0x00);
- AT45db161_SPI_DESELECT();
-
- /* GD25Q16: bit0=0 表示空闲,bit0=1 表示忙 */
- /* 原代码返回1表示准备好,所以需要取反 */
- if ((Status_Register & 0x01) != 0x01)
- return 1; /* 准备好 */
- return 0; /* 忙 */
- }
- /**
- * @brief 检查芯片是否存在 - 保留原名
- */
- uint8_t AT45DB_Check(void)
- {
- uint8_t buf[3];
-
- AT45db161_SPI_SELECT();
- SPI2_ReadWrite_Byte(0x9F); /* 读JEDEC ID */
- buf[0] = SPI2_ReadWrite_Byte(0);
- buf[1] = SPI2_ReadWrite_Byte(0);
- buf[2] = SPI2_ReadWrite_Byte(0);
- AT45db161_SPI_DESELECT();
-
- /* GD25Q16 的 ID 是 0xC8, 0x40, 0x15 */
- if ((buf[0] == 0xC8) && (buf[1] == 0x40) && (buf[2] == 0x15))
- return 1;
- return 0;
- }
- /**
- * @brief 读一页数据 - 保留原名
- */
- void AT45DB_ReadPage(uint16_t Page_Add, uint8_t *pdata)
- {
- int i;
- if (Page_Add > 8192)
- return;
-
- while (AT45DB_IS_BUSY() == 0);
-
- uint32_t addr = Page_Add * 256;
-
- AT45db161_SPI_SELECT();
- SPI2_ReadWrite_Byte(GD25Q16_MM_PAGE_READ);
- SPI2_ReadWrite_Byte((int8_t)(addr >> 16));
- SPI2_ReadWrite_Byte((int8_t)(addr >> 8));
- SPI2_ReadWrite_Byte((int8_t)(addr));
- for (i = 0; i < 256; i++) {
- *pdata++ = SPI2_ReadWrite_Byte(0x00);
- }
- AT45db161_SPI_DESELECT();
- }
- /**
- * @brief 写一页数据 - 保留原名
- */
- void AT45DB_WritePage(uint16_t page, uint8_t *Data)
- {
- uint16_t i;
- uint32_t addr = page * 256;
-
- if (page >= 8192)
- return;
-
- while (AT45DB_IS_BUSY() == 0);
-
- GD25Q16_WriteEnable();
- while (AT45DB_IS_BUSY() == 0);
-
- AT45db161_SPI_SELECT();
- SPI2_ReadWrite_Byte(GD25Q16_WRITE);
- SPI2_ReadWrite_Byte((uint8_t)(addr >> 16));
- SPI2_ReadWrite_Byte((uint8_t)(addr >> 8));
- SPI2_ReadWrite_Byte((uint8_t)(addr));
-
- for (i = 0; i < 256; i++) {
- SPI2_ReadWrite_Byte(Data[i]);
- }
- AT45db161_SPI_DESELECT();
-
- while (AT45DB_IS_BUSY() == 0);
- }
- /**
- * @brief 在一页内写入部分数据 - 保留原名
- */
- void AT45DB_WriteBytes_OnOnePage(uint16_t page, uint8_t *Data, uint16_t len)
- {
- uint16_t i;
-
- if (page > 4095 || len > 256) return;
-
- while (AT45DB_IS_BUSY() == 0);
- AT45db161_SPI_SELECT();
- SPI2_ReadWrite_Byte(AT45DB_BUFFER_2_WRITE);
- SPI2_ReadWrite_Byte(0x00);
- SPI2_ReadWrite_Byte(0x00);
- SPI2_ReadWrite_Byte(0x00);
-
- for (i = 0; i < len; i++) {
- SPI2_ReadWrite_Byte(Data[i]);
- }
- AT45db161_SPI_DESELECT();
- while (AT45DB_IS_BUSY() == 0);
-
- if (page < 4096) {
- AT45db161_SPI_SELECT();
- SPI2_ReadWrite_Byte(GD25Q16_MM_PAGE_PROG_WITH_ERASE);
- SPI2_ReadWrite_Byte((uint8_t)(page >> 6));
- SPI2_ReadWrite_Byte((uint8_t)(page << 2));
- SPI2_ReadWrite_Byte(0x00);
- AT45db161_SPI_DESELECT();
- }
- }
- /**
- * @brief 从任意地址读取多个字节 - 保留原名
- */
- void AT45DB_Read_Bytes(uint32_t add, uint8_t *pdata, uint16_t len)
- {
- int i, j, k;
- uint8_t temp[256];
- uint16_t page, offset;
-
- if (add > 8192 * 256) return;
-
- page = add / 256;
- offset = add % 256;
- AT45DB_ReadPage(page++, temp);
- for (i = offset; (len != 0) && (i < 256); len--, i++) {
- *pdata++ = temp[i];
- }
- if ((i == 256) && (len != 0)) {
- if (len > 256) {
- for (k = 0; k < len / 256; k++) {
- AT45DB_ReadPage(page++, temp);
- for (j = 0; j < 256; j++) {
- *pdata++ = temp[j];
- }
- }
- len -= 256 * k;
- }
- if (len != 0) {
- AT45DB_ReadPage(page, temp);
- for (j = 0; j < len; j++) {
- *pdata++ = temp[j];
- }
- }
- }
- }
- /**
- * @brief 从任意地址写入多个字节 - 保留原名
- */
- void AT45DB_Write_Bytes(uint32_t add, uint8_t *pdata, uint16_t len)
- {
- uint8_t temp[256];
- uint16_t page, offset;
- uint16_t i, j, k;
-
- if (add > 8192 * 256) return;
-
- page = add / 256;
- offset = add % 256;
- AT45DB_ReadPage(page, temp);
- for (i = offset; (len != 0) && (i < 256); len--, i++) {
- temp[i] = *pdata++;
- }
-
- GD25Q16_Erase_Sector(add);
- AT45DB_WritePage(page++, temp);
- if ((i == 256) && (len != 0)) {
- if (len > 256) {
- for (k = 0; k < len / 256; k++) {
- for (j = 0; j < 256; j++) {
- temp[j] = *pdata++;
- }
- AT45DB_WritePage(page++, temp);
- }
- len -= 256 * k;
- }
- if (len != 0) {
- AT45DB_ReadPage(page, temp);
- for (j = 0; j < len; j++) {
- temp[j] = *pdata++;
- }
- AT45DB_WritePage(page, temp);
- }
- }
- }
- /**
- * @brief 写入浮点数 - 保留原名
- */
- void AT45DB_Write_float(uint32_t add, float wvalue)
- {
- f_bytes data;
- data.value = wvalue;
- AT45DB_Write_Bytes(add, &data.byte[0], 4);
- }
- /**
- * @brief 读取浮点数 - 保留原名
- */
- float AT45DB_Read_float(uint32_t add)
- {
- f_bytes data;
- data.value = 0;
- AT45DB_Read_Bytes(add, &data.byte[0], 4);
- return data.value;
- }
- /**
- * @brief 写入16位整数 - 保留原名
- */
- void AT45DB_Write_int16(uint32_t add, int16_t wvalue)
- {
- i_bytes data;
- data.value = wvalue;
- AT45DB_Write_Bytes(add, &data.byte[0], 2);
- }
- /**
- * @brief 读取16位整数 - 保留原名
- */
- int16_t AT45DB_Read_int16(uint32_t add)
- {
- i_bytes data;
- data.value = 0;
- AT45DB_Read_Bytes(add, &data.byte[0], 2);
- return data.value;
- }
- #endif /* GD25Q16_FLASH */
|