hard_flash_gd25q16.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. #include "hard_flash_gd25q16.h"
  2. #include "board.h"
  3. #include "hpm_spi_drv.h"
  4. #include "hpm_clock_drv.h"
  5. #include "hpm_gpio_drv.h"
  6. #ifdef GD25Q16_FLASH
  7. /* 使用 SPI2 作为示例,你可以根据需要修改 */
  8. #define AT45DB_SPI_BASE HPM_SPI2
  9. /******************SPI时钟频率*******************/
  10. #define AT45DB_CLK_FRE 21000000
  11. /* GPIO 参数定义 - 根据实际硬件修改 */
  12. #define AT45DB_CS_GPIO_PTR HPM_GPIO0 /* GPIO 控制器基地址 */
  13. #define AT45DB_CS_PORT 1 /* GPIOB = 1 */
  14. #define AT45DB_CS_PIN 12 /* PIN12 */
  15. /* CS 控制宏 - 完全保留原名 */
  16. #define AT45db161_SPI_SELECT() gpio_write_pin(AT45DB_CS_GPIO_PTR, AT45DB_CS_PORT, AT45DB_CS_PIN, 0)
  17. #define AT45db161_SPI_DESELECT() gpio_write_pin(AT45DB_CS_GPIO_PTR, AT45DB_CS_PORT, AT45DB_CS_PIN, 1)
  18. void gd25q16_cs_high()
  19. {
  20. AT45db161_SPI_DESELECT();
  21. }
  22. void gd25q16_cs_low()
  23. {
  24. AT45db161_SPI_SELECT();
  25. }
  26. /* 静态变量 */
  27. static uint32_t spi_clk_freq;
  28. /**
  29. * @brief SPI 读写一个字节 - 保留原名
  30. */
  31. uint8_t SPI2_ReadWrite_Byte(uint8_t byte)
  32. {
  33. uint8_t rx_byte = 0;
  34. spi_control_config_t control_config;
  35. /* 配置传输控制 */
  36. spi_master_get_default_control_config(&control_config);
  37. control_config.common_config.trans_mode = spi_trans_write_read_together;
  38. control_config.master_config.cmd_enable = false;
  39. control_config.master_config.addr_enable = false;
  40. /* 执行传输 */
  41. spi_transfer(AT45DB_SPI_BASE,
  42. &control_config,
  43. NULL, NULL,
  44. &byte, 1,
  45. &rx_byte, 1);
  46. return rx_byte;
  47. }
  48. /**
  49. * @brief 写使能 - 保留为静态函数,不暴露给外部
  50. */
  51. static void GD25Q16_WriteEnable(void)
  52. {
  53. AT45db161_SPI_SELECT();
  54. SPI2_ReadWrite_Byte(GD25Q16_WRITE_ENABLE);
  55. AT45db161_SPI_DESELECT();
  56. }
  57. /**
  58. * @brief 扇区擦除 - 保留原名
  59. */
  60. static void GD25Q16_Erase_Sector(uint32_t addr)
  61. {
  62. while(AT45DB_IS_BUSY() == 0);
  63. GD25Q16_WriteEnable();
  64. while(AT45DB_IS_BUSY() == 0);
  65. AT45db161_SPI_SELECT();
  66. SPI2_ReadWrite_Byte(GD25Q16SECTOR_ERASE);
  67. SPI2_ReadWrite_Byte((uint8_t)(addr >> 16));
  68. SPI2_ReadWrite_Byte((uint8_t)(addr >> 8));
  69. SPI2_ReadWrite_Byte((uint8_t)(addr));
  70. AT45db161_SPI_DESELECT();
  71. while(AT45DB_IS_BUSY() == 0);
  72. }
  73. /**
  74. * @brief 初始化 SPI 接口 - 保留原名
  75. */
  76. void AT45db161_SPI_Configuration(void)
  77. {
  78. spi_timing_config_t timing_config = {0};
  79. spi_format_config_t format_config = {0};
  80. /* 1. 初始化 SPI 时钟和引脚 */
  81. spi_clk_freq = board_init_spi_clock(AT45DB_SPI_BASE);
  82. board_init_spi_pins(AT45DB_SPI_BASE);
  83. /* 2. 配置 CS 引脚为输出 */
  84. gpio_set_pin_output(AT45DB_CS_GPIO_PTR, AT45DB_CS_PORT, AT45DB_CS_PIN);
  85. AT45db161_SPI_DESELECT(); /* CS 默认高电平 */
  86. /* 3. 配置 SPI 时序(主模式)*/
  87. spi_master_get_default_timing_config(&timing_config);
  88. timing_config.master_config.clk_src_freq_in_hz = spi_clk_freq;
  89. timing_config.master_config.sclk_freq_in_hz = AT45DB_CLK_FRE;
  90. spi_master_timing_init(AT45DB_SPI_BASE, &timing_config);
  91. /* 4. 配置 SPI 格式 */
  92. spi_master_get_default_format_config(&format_config);
  93. format_config.common_config.data_len_in_bits = 8; /* 8位数据 */
  94. format_config.common_config.mode = spi_master_mode; /* 主机模式 */
  95. format_config.common_config.cpol = spi_sclk_low_idle; /* CPOL=0 */
  96. format_config.common_config.cpha = spi_sclk_sampling_odd_clk_edges; /* CPHA=0 */
  97. spi_format_init(AT45DB_SPI_BASE, &format_config);
  98. }
  99. /**
  100. * @brief 初始化 flash 接口 - 保留原名
  101. */
  102. void flash_at45db_init(void)
  103. {
  104. AT45db161_SPI_Configuration();
  105. }
  106. /**
  107. * @brief 查询是否准备好 - 保留原名
  108. */
  109. uint8_t AT45DB_IS_BUSY(void)
  110. {
  111. uint8_t Status_Register;
  112. AT45db161_SPI_SELECT();
  113. SPI2_ReadWrite_Byte(GD25Q16_READ_STATE_REGISTER);
  114. Status_Register = SPI2_ReadWrite_Byte(0x00);
  115. AT45db161_SPI_DESELECT();
  116. /* GD25Q16: bit0=0 表示空闲,bit0=1 表示忙 */
  117. /* 原代码返回1表示准备好,所以需要取反 */
  118. if ((Status_Register & 0x01) != 0x01)
  119. return 1; /* 准备好 */
  120. return 0; /* 忙 */
  121. }
  122. /**
  123. * @brief 检查芯片是否存在 - 保留原名
  124. */
  125. uint8_t AT45DB_Check(void)
  126. {
  127. uint8_t buf[3];
  128. AT45db161_SPI_SELECT();
  129. SPI2_ReadWrite_Byte(0x9F); /* 读JEDEC ID */
  130. buf[0] = SPI2_ReadWrite_Byte(0);
  131. buf[1] = SPI2_ReadWrite_Byte(0);
  132. buf[2] = SPI2_ReadWrite_Byte(0);
  133. AT45db161_SPI_DESELECT();
  134. /* GD25Q16 的 ID 是 0xC8, 0x40, 0x15 */
  135. if ((buf[0] == 0xC8) && (buf[1] == 0x40) && (buf[2] == 0x15))
  136. return 1;
  137. return 0;
  138. }
  139. /**
  140. * @brief 读一页数据 - 保留原名
  141. */
  142. void AT45DB_ReadPage(uint16_t Page_Add, uint8_t *pdata)
  143. {
  144. int i;
  145. if (Page_Add > 8192)
  146. return;
  147. while (AT45DB_IS_BUSY() == 0);
  148. uint32_t addr = Page_Add * 256;
  149. AT45db161_SPI_SELECT();
  150. SPI2_ReadWrite_Byte(GD25Q16_MM_PAGE_READ);
  151. SPI2_ReadWrite_Byte((int8_t)(addr >> 16));
  152. SPI2_ReadWrite_Byte((int8_t)(addr >> 8));
  153. SPI2_ReadWrite_Byte((int8_t)(addr));
  154. for (i = 0; i < 256; i++) {
  155. *pdata++ = SPI2_ReadWrite_Byte(0x00);
  156. }
  157. AT45db161_SPI_DESELECT();
  158. }
  159. /**
  160. * @brief 写一页数据 - 保留原名
  161. */
  162. void AT45DB_WritePage(uint16_t page, uint8_t *Data)
  163. {
  164. uint16_t i;
  165. uint32_t addr = page * 256;
  166. if (page >= 8192)
  167. return;
  168. while (AT45DB_IS_BUSY() == 0);
  169. GD25Q16_WriteEnable();
  170. while (AT45DB_IS_BUSY() == 0);
  171. AT45db161_SPI_SELECT();
  172. SPI2_ReadWrite_Byte(GD25Q16_WRITE);
  173. SPI2_ReadWrite_Byte((uint8_t)(addr >> 16));
  174. SPI2_ReadWrite_Byte((uint8_t)(addr >> 8));
  175. SPI2_ReadWrite_Byte((uint8_t)(addr));
  176. for (i = 0; i < 256; i++) {
  177. SPI2_ReadWrite_Byte(Data[i]);
  178. }
  179. AT45db161_SPI_DESELECT();
  180. while (AT45DB_IS_BUSY() == 0);
  181. }
  182. /**
  183. * @brief 在一页内写入部分数据 - 保留原名
  184. */
  185. void AT45DB_WriteBytes_OnOnePage(uint16_t page, uint8_t *Data, uint16_t len)
  186. {
  187. uint16_t i;
  188. if (page > 4095 || len > 256) return;
  189. while (AT45DB_IS_BUSY() == 0);
  190. AT45db161_SPI_SELECT();
  191. SPI2_ReadWrite_Byte(AT45DB_BUFFER_2_WRITE);
  192. SPI2_ReadWrite_Byte(0x00);
  193. SPI2_ReadWrite_Byte(0x00);
  194. SPI2_ReadWrite_Byte(0x00);
  195. for (i = 0; i < len; i++) {
  196. SPI2_ReadWrite_Byte(Data[i]);
  197. }
  198. AT45db161_SPI_DESELECT();
  199. while (AT45DB_IS_BUSY() == 0);
  200. if (page < 4096) {
  201. AT45db161_SPI_SELECT();
  202. SPI2_ReadWrite_Byte(GD25Q16_MM_PAGE_PROG_WITH_ERASE);
  203. SPI2_ReadWrite_Byte((uint8_t)(page >> 6));
  204. SPI2_ReadWrite_Byte((uint8_t)(page << 2));
  205. SPI2_ReadWrite_Byte(0x00);
  206. AT45db161_SPI_DESELECT();
  207. }
  208. }
  209. /**
  210. * @brief 从任意地址读取多个字节 - 保留原名
  211. */
  212. void AT45DB_Read_Bytes(uint32_t add, uint8_t *pdata, uint16_t len)
  213. {
  214. int i, j, k;
  215. uint8_t temp[256];
  216. uint16_t page, offset;
  217. if (add > 8192 * 256) return;
  218. page = add / 256;
  219. offset = add % 256;
  220. AT45DB_ReadPage(page++, temp);
  221. for (i = offset; (len != 0) && (i < 256); len--, i++) {
  222. *pdata++ = temp[i];
  223. }
  224. if ((i == 256) && (len != 0)) {
  225. if (len > 256) {
  226. for (k = 0; k < len / 256; k++) {
  227. AT45DB_ReadPage(page++, temp);
  228. for (j = 0; j < 256; j++) {
  229. *pdata++ = temp[j];
  230. }
  231. }
  232. len -= 256 * k;
  233. }
  234. if (len != 0) {
  235. AT45DB_ReadPage(page, temp);
  236. for (j = 0; j < len; j++) {
  237. *pdata++ = temp[j];
  238. }
  239. }
  240. }
  241. }
  242. /**
  243. * @brief 从任意地址写入多个字节 - 保留原名
  244. */
  245. void AT45DB_Write_Bytes(uint32_t add, uint8_t *pdata, uint16_t len)
  246. {
  247. uint8_t temp[256];
  248. uint16_t page, offset;
  249. uint16_t i, j, k;
  250. if (add > 8192 * 256) return;
  251. page = add / 256;
  252. offset = add % 256;
  253. AT45DB_ReadPage(page, temp);
  254. for (i = offset; (len != 0) && (i < 256); len--, i++) {
  255. temp[i] = *pdata++;
  256. }
  257. GD25Q16_Erase_Sector(add);
  258. AT45DB_WritePage(page++, temp);
  259. if ((i == 256) && (len != 0)) {
  260. if (len > 256) {
  261. for (k = 0; k < len / 256; k++) {
  262. for (j = 0; j < 256; j++) {
  263. temp[j] = *pdata++;
  264. }
  265. AT45DB_WritePage(page++, temp);
  266. }
  267. len -= 256 * k;
  268. }
  269. if (len != 0) {
  270. AT45DB_ReadPage(page, temp);
  271. for (j = 0; j < len; j++) {
  272. temp[j] = *pdata++;
  273. }
  274. AT45DB_WritePage(page, temp);
  275. }
  276. }
  277. }
  278. /**
  279. * @brief 写入浮点数 - 保留原名
  280. */
  281. void AT45DB_Write_float(uint32_t add, float wvalue)
  282. {
  283. f_bytes data;
  284. data.value = wvalue;
  285. AT45DB_Write_Bytes(add, &data.byte[0], 4);
  286. }
  287. /**
  288. * @brief 读取浮点数 - 保留原名
  289. */
  290. float AT45DB_Read_float(uint32_t add)
  291. {
  292. f_bytes data;
  293. data.value = 0;
  294. AT45DB_Read_Bytes(add, &data.byte[0], 4);
  295. return data.value;
  296. }
  297. /**
  298. * @brief 写入16位整数 - 保留原名
  299. */
  300. void AT45DB_Write_int16(uint32_t add, int16_t wvalue)
  301. {
  302. i_bytes data;
  303. data.value = wvalue;
  304. AT45DB_Write_Bytes(add, &data.byte[0], 2);
  305. }
  306. /**
  307. * @brief 读取16位整数 - 保留原名
  308. */
  309. int16_t AT45DB_Read_int16(uint32_t add)
  310. {
  311. i_bytes data;
  312. data.value = 0;
  313. AT45DB_Read_Bytes(add, &data.byte[0], 2);
  314. return data.value;
  315. }
  316. #endif /* GD25Q16_FLASH */