at45db041.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. #include "at45db041.h"
  2. #include "periph.h"
  3. #include <memory.h>
  4. #include <stdio.h>
  5. /*Make the buffer visible for the external flash*/
  6. extern uint8_t SPI_REC_BUF[512];
  7. /*Information structure*/
  8. at45db_t AT45DB;
  9. /**
  10. * @brief Initialize the external flash, with basic parameters and checks its availability.
  11. * @retval None.
  12. */
  13. void at45db_init()
  14. {
  15. memset(&AT45DB, 0, sizeof(AT45DB));
  16. uint16_t res = -1;
  17. uint8_t status_register[2] = {0};
  18. /*Check if the external flash memory is accessible*/
  19. res = at45db_read_man_id();
  20. printf("device.man.id: 0x%02X\r\n", res);
  21. if (!res)
  22. {
  23. /*External flash memory is not accessible*/
  24. printf("Unable to communicate with external flash. Initiate wake up process!\r\n");
  25. /*Wake up process*/
  26. res = at45db_wake_up_from_deep_sleep(AT45DB);
  27. if (!res)
  28. {
  29. /*Device could be in ultra deep sleep*/
  30. res = at45db_wake_up_from_ultra_deep_sleep(AT45DB);
  31. if (!res)
  32. {
  33. printf("Cannot wake up the external flash from ultra deep sleep\r\n");
  34. }
  35. else if (res)
  36. {
  37. printf("External flash memory woke up from ultra deep sleep\r\n");
  38. }
  39. }
  40. else if (res)
  41. {
  42. printf("External flash memory wake up from power down mode\r\n");
  43. }
  44. }
  45. else if (res)
  46. {
  47. printf("Correct device ID, external flash memory is accessible\r\n");
  48. }
  49. HAL_Delay(100);
  50. /*Initializa information structure*/
  51. #ifdef BINARY_PAGE_SIZE
  52. AT45DB.block_size = 2048;
  53. AT45DB.blocks = 256;
  54. AT45DB.flash_mbit = 4;
  55. AT45DB.page_size = 256;
  56. #endif
  57. #ifdef DATAFLASH_PAGE_SIZE
  58. AT45DB.block_size = 2112;
  59. AT45DB.blocks = 256;
  60. AT45DB.flash_mbit = 4;
  61. AT45DB.page_size = 264;
  62. #endif
  63. }
  64. void at45db_disable_protection(void)
  65. {
  66. uint8_t cmd[4];
  67. // Магическая последовательность для отключения защиты
  68. cmd[0] = 0x3D;
  69. cmd[1] = 0x2A;
  70. cmd[2] = 0x7F;
  71. cmd[3] = 0x9A;
  72. at45db_wait_ready();
  73. FLASH_CS_ENABLE();
  74. HAL_SPI_Transmit(&hspi2, cmd, 4, HAL_MAX_DELAY);
  75. FLASH_CS_DISABLE();
  76. at45db_wait_ready();
  77. printf("Sector protection disabled command sent.\r\n");
  78. }
  79. /**
  80. * @brief Считывает один байт статус-регистра AT45DB041E.
  81. * @retval 1 байт статуса.
  82. *
  83. * Бит 7 (0x80) — RDY/BUSY: 1 = готов, 0 = занят
  84. * Бит 0 (0x01) — Page Size: 1 = binary (256 байт), 0 = standard (264 байта)
  85. */
  86. uint8_t at45db_get_status(void)
  87. {
  88. uint8_t cmd = STATUS_REGISTER;
  89. uint8_t status = 0;
  90. FLASH_CS_ENABLE();
  91. HAL_SPI_Transmit(&hspi2, &cmd, 1, HAL_MAX_DELAY);
  92. HAL_SPI_Receive(&hspi2, &status, 1, HAL_MAX_DELAY);
  93. FLASH_CS_DISABLE();
  94. return status;
  95. }
  96. /**
  97. * @brief Читает Manufacturer + Device ID.
  98. * @retval DEV_ID_OK или DEV_ID_ERROR.
  99. */
  100. dev_id_t at45db_read_man_id(void)
  101. {
  102. uint8_t opcode = MAN_ID_OPCD;
  103. uint8_t rec_buf[4] = {0};
  104. FLASH_CS_ENABLE();
  105. HAL_SPI_Transmit(&hspi2, &opcode, 1, HAL_MAX_DELAY);
  106. HAL_SPI_Receive(&hspi2, rec_buf, 4, HAL_MAX_DELAY);
  107. FLASH_CS_DISABLE();
  108. if (rec_buf[0] != 0x1F || rec_buf[1] != 0x24)
  109. return DEV_ID_ERROR;
  110. return DEV_ID_OK;
  111. }
  112. /**
  113. * @brief Проверяет текущий режим размера страницы.
  114. * @retval 256 если включён binary mode, 264 — если стандартный.
  115. */
  116. uint16_t at45db_get_page_size(void)
  117. {
  118. return (at45db_get_status() & 0x01) ? 256 : 264;
  119. }
  120. /**
  121. * @brief Проверяет, готов ли чип к новой операции.
  122. * @retval 1 — готов, 0 — занят.
  123. */
  124. int at45db_is_ready(void)
  125. {
  126. return (at45db_get_status() & 0x80) ? 1 : 0;
  127. }
  128. /**
  129. * @brief Wakes up external flash from deep sleep mode.
  130. * @param info : Structure information about the external flash operation.
  131. * @retval 1 for success, 0 on failure.
  132. */
  133. uint16_t at45db_wake_up_from_deep_sleep(at45db_t info)
  134. {
  135. uint16_t res = -1;
  136. uint8_t cmd = WAKE_UP_DEEP_SLEEP;
  137. FLASH_CS_ENABLE();
  138. HAL_SPI_Transmit(&hspi2, &cmd, 1, HAL_MAX_DELAY);
  139. FLASH_CS_DISABLE();
  140. // TODO: fix
  141. /*Return the MISO pin to its initial state*/
  142. // SET_BIT(GPIO_SPIx->MODER, (1U<<(SPIx_GPIO_MISO_PIN*2+1)));
  143. // CLEAR_BIT(GPIO_SPIx->MODER, (1U<<SPIx_GPIO_MISO_PIN*2));
  144. /*Read MAN-ID*/
  145. res = at45db_read_man_id();
  146. if (!res)
  147. {
  148. return 0;
  149. }
  150. info.state = _NORMAL_MODE;
  151. return 1;
  152. }
  153. /**
  154. * @brief Exit from ultra deep sleep.
  155. * @param info : Structure information about the external flash operation.
  156. * @retval 1 for success, 0 on failure.
  157. */
  158. uint16_t at45db_wake_up_from_ultra_deep_sleep(at45db_t info)
  159. {
  160. uint16_t res = -1;
  161. /*Select the device*/
  162. FLASH_CS_ENABLE();
  163. HAL_Delay(2);
  164. /*Release the device*/
  165. FLASH_CS_DISABLE();
  166. // TODO: fix
  167. /*Return the MISO pin to its initial state*/
  168. // SET_BIT(GPIO_SPIx->MODER, (1U<<(SPIx_GPIO_MISO_PIN*2+1)));
  169. // CLEAR_BIT(GPIO_SPIx->MODER, (1U<<SPIx_GPIO_MISO_PIN*2));
  170. /*Try to read MAD-ID*/
  171. res = at45db_read_man_id();
  172. if (!res)
  173. {
  174. /*Failure*/
  175. return 0;
  176. }
  177. /*Success*/
  178. info.state = _NORMAL_MODE;
  179. return 1;
  180. }
  181. void at45db_read(uint16_t page, uint8_t *data, uint16_t size)
  182. {
  183. uint8_t cmd[5];
  184. uint32_t addr = (uint32_t)page << 8;
  185. cmd[0] = 0x0B; // high-speed read
  186. cmd[1] = (addr >> 16) & 0xFF;
  187. cmd[2] = (addr >> 8) & 0xFF;
  188. cmd[3] = addr & 0xFF;
  189. cmd[4] = 0x00; // dummy
  190. FLASH_CS_ENABLE();
  191. HAL_SPI_Transmit(&hspi2, cmd, 5, HAL_MAX_DELAY);
  192. HAL_SPI_Receive(&hspi2, data, size, HAL_MAX_DELAY);
  193. FLASH_CS_DISABLE();
  194. }
  195. /**
  196. * @brief Enter flash into ultra deep sleep.
  197. * @param info : Structure information about the external flash operation.
  198. * @retval None.
  199. */
  200. void at45db_ultra_deep_sleep(at45db_t info)
  201. {
  202. uint8_t opcode = ULTRA_DEEP_SLEEP;
  203. /*Select the slave device*/
  204. FLASH_CS_ENABLE();
  205. /*Transmit the proper opcode*/
  206. HAL_SPI_Transmit(&hspi2, &opcode, 1, HAL_MAX_DELAY);
  207. /*Give some time to the system*/
  208. HAL_Delay(100);
  209. /*Release the device*/
  210. FLASH_CS_DISABLE();
  211. // TODO: fix
  212. /*Make the MISO pin analog, for power saving*/
  213. // SET_BIT(GPIO_SPIx->MODER, (1U<<(SPIx_GPIO_MISO_PIN*2+1)));
  214. // SET_BIT(GPIO_SPIx->MODER, (1U<<(SPIx_GPIO_MISO_PIN*2)));
  215. info.state = _U_DEEP_SLEEP;
  216. }
  217. void at45db_write_page(uint16_t page, uint8_t *data)
  218. {
  219. uint8_t cmd[4];
  220. uint32_t addr = (uint32_t)page << 8;
  221. cmd[0] = 0x84; // Buffer 1 Write
  222. cmd[1] = 0x00;
  223. cmd[2] = 0x00;
  224. cmd[3] = 0x00;
  225. FLASH_CS_ENABLE();
  226. HAL_SPI_Transmit(&hspi2, cmd, 4, HAL_MAX_DELAY);
  227. HAL_SPI_Transmit(&hspi2, data, 256, HAL_MAX_DELAY);
  228. FLASH_CS_DISABLE();
  229. cmd[0] = 0x83;
  230. cmd[1] = (addr >> 16) & 0xFF;
  231. cmd[2] = (addr >> 8) & 0xFF;
  232. cmd[3] = addr & 0xFF;
  233. FLASH_CS_ENABLE();
  234. HAL_SPI_Transmit(&hspi2, cmd, 4, HAL_MAX_DELAY);
  235. FLASH_CS_DISABLE();
  236. }
  237. void at45db_read_continuous(uint32_t addr, uint8_t *buffer, uint32_t size)
  238. {
  239. uint8_t cmd[8];
  240. /*Preparing the command*/
  241. cmd[0] = 0xE8; //Opcode
  242. cmd[1] = (addr >> 16) & 0xFF; // Address byte 1
  243. cmd[2] = (addr >> 8) & 0xFF; // Address byte 2
  244. cmd[3] = addr & 0xFF; // Address byte 3
  245. cmd[4] = 0x00; // Dummy byte 1
  246. cmd[5] = 0x00; // Dummy byte 2
  247. cmd[6] = 0x00; // Dummy byte 3
  248. cmd[7] = 0x00; // Dummy byte 4
  249. /*Select the external flash memory*/
  250. FLASH_CS_ENABLE();
  251. /*Send the proper commands to load data to the internal buffer 1*/
  252. HAL_SPI_Transmit(&hspi2, cmd, sizeof(cmd), HAL_MAX_DELAY);
  253. /*Receive the data*/
  254. HAL_SPI_Receive(&hspi2, buffer, size, HAL_MAX_DELAY);
  255. /*Deselect the external flash memory*/
  256. FLASH_CS_DISABLE();
  257. }
  258. /**
  259. * @brief Configure page size. Careful you only have 10000 times to do that.
  260. * @param mode : Set 1 for DataFlash (264 bytes), 2 for Binary (256 bytes).
  261. * @retval None.
  262. */
  263. void at45db_page_size_conf(uint16_t mode)
  264. {
  265. uint8_t cmd[4] = {0};
  266. cmd[0] = 0x3D;
  267. cmd[1] = 0x2A;
  268. cmd[2] = 0x80;
  269. /*Check user input*/
  270. if (mode == 1)
  271. {
  272. /*Data flash page size*/
  273. cmd[3] = 0xA7;
  274. FLASH_CS_ENABLE();
  275. HAL_SPI_Transmit(&hspi2, cmd, sizeof(cmd), HAL_MAX_DELAY);
  276. FLASH_CS_DISABLE();
  277. }
  278. else if (mode == 2)
  279. {
  280. /*Binary page size*/
  281. cmd[3] = 0xA6;
  282. FLASH_CS_ENABLE();
  283. HAL_SPI_Transmit(&hspi2, cmd, sizeof(cmd), HAL_MAX_DELAY);
  284. FLASH_CS_DISABLE();
  285. }
  286. }
  287. /**
  288. * @brief Perform chip erase. This command erase the entire main memory.
  289. * @retval None.
  290. */
  291. void at45db_chip_erase(void)
  292. {
  293. uint8_t cmd[4] = {0};
  294. int res = -1;
  295. cmd[0] = CHIP_ERASE_1;
  296. cmd[1] = CHIP_ERASE_2;
  297. cmd[2] = CHIP_ERASE_3;
  298. cmd[3] = CHIP_ERASE_4;
  299. FLASH_CS_ENABLE();
  300. HAL_SPI_Transmit(&hspi2, cmd, 4, HAL_MAX_DELAY);
  301. FLASH_CS_DISABLE();
  302. /*Check for fault operation*/
  303. res = at45db_fault_check();
  304. if (res == 1) {
  305. printf("There was a fault in erase operation...\n\r");
  306. }
  307. else if (res == 0) {
  308. printf("Successful, erase operation...\n\r");
  309. }
  310. }
  311. /**
  312. * @brief Checks if a fault erased after an erase or program operation.
  313. * @retval 1 if an error is detected, 0 otherwise.
  314. */
  315. uint16_t at45db_fault_check(void)
  316. {
  317. uint8_t status_register[2];
  318. uint8_t opcode = STATUS_REGISTER;
  319. FLASH_CS_ENABLE();
  320. HAL_SPI_Transmit(&hspi2, &opcode, 1, HAL_MAX_DELAY);
  321. HAL_SPI_Receive(&hspi2, status_register, 2, HAL_MAX_DELAY);
  322. FLASH_CS_DISABLE();
  323. /*Check the 5th bit of the second byte EPE bit*/
  324. if ((status_register[1] & EPE_BIT)) {
  325. /*Error detected*/
  326. return 1;
  327. }
  328. /*Success, in erasing external flash memory*/
  329. return 0;
  330. }
  331. /**
  332. * @brief This function erases a sector inside the external memory.
  333. * @param sector_num : This is the number of the sector you need to erase.
  334. * @retval None.
  335. */
  336. void at45db_sector_erase(uint8_t sector_num)
  337. {
  338. uint8_t opcode = SECTOR_ERASE;
  339. uint8_t address_byte[3];
  340. address_byte[0] = ((sector_num) << 3) & 0xF8;
  341. address_byte[1] = 0x00;
  342. address_byte[2] = 0x00;
  343. FLASH_CS_ENABLE();
  344. HAL_SPI_Transmit(&hspi2, &opcode, 1, HAL_MAX_DELAY);
  345. HAL_SPI_Transmit(&hspi2, address_byte, 3, HAL_MAX_DELAY);
  346. FLASH_CS_DISABLE();
  347. }
  348. /**
  349. * @brief Erases a specific page inside the main memory.
  350. * @reval None.
  351. */
  352. void at45db_page_erase(uint16_t page)
  353. {
  354. uint8_t cmd[4];
  355. uint8_t opcode = 0x81; // PAGE_ERASE_CMD
  356. // Для Binary Mode (256 байт) сдвиг должен быть 8
  357. // Для Standard Mode (264 байта) сдвиг должен быть 9
  358. // Используем ваш макрос PAGE_SHIFT
  359. uint32_t addr = (uint32_t)page << PAGE_SHIFT;
  360. FLASH_CS_ENABLE();
  361. HAL_SPI_Transmit(&hspi2, &opcode, 1, HAL_MAX_DELAY);
  362. cmd[0] = (addr >> 16) & 0xFF;
  363. cmd[1] = (addr >> 8) & 0xFF;
  364. cmd[2] = addr & 0xFF;
  365. HAL_SPI_Transmit(&hspi2, cmd, 3, HAL_MAX_DELAY);
  366. FLASH_CS_DISABLE();
  367. }
  368. /**
  369. * @brief Enter flash into deep sleep mode.
  370. * @param info : Structure information about the external flash operation.
  371. * @retval None.
  372. */
  373. void at45db_deep_sleep(at45db_t *info)
  374. {
  375. uint8_t opcode = DEEP_SLEEP;
  376. /*Select the device*/
  377. FLASH_CS_ENABLE();
  378. /*Transmit the command the external FLASH memory*/
  379. HAL_SPI_Transmit(&hspi2, &opcode, 1, HAL_MAX_DELAY);
  380. /*Give some time to process*/
  381. HAL_Delay(100);
  382. /*Release the slave device*/
  383. FLASH_CS_DISABLE();
  384. /*Give some time to the system*/
  385. HAL_Delay(2);
  386. //TODO: fix
  387. /*Make the MISO pin analog, for power saving*/
  388. // SET_BIT(GPIO_SPIx->MODER, (1U<<(SPIx_GPIO_MISO_PIN*2+1)));
  389. // SET_BIT(GPIO_SPIx->MODER, (1U<<(SPIx_GPIO_MISO_PIN*2)));
  390. }
  391. void at45db_wait_ready(void)
  392. {
  393. while (!(at45db_get_status() & 0x80)) {
  394. HAL_Delay(1);
  395. }
  396. }