spiflash.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. /*
  2. * This file is part of the MicroPython project, http://micropython.org/
  3. *
  4. * The MIT License (MIT)
  5. *
  6. * Copyright (c) 2016-2018 Damien P. George
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included in
  16. * all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. */
  26. #include <stdio.h>
  27. #include <string.h>
  28. #include "py/mperrno.h"
  29. #include "py/mphal.h"
  30. #include "drivers/memory/spiflash.h"
  31. #define QSPI_QE_MASK (0x02)
  32. #define USE_WR_DELAY (1)
  33. #define CMD_WRSR (0x01)
  34. #define CMD_WRITE (0x02)
  35. #define CMD_READ (0x03)
  36. #define CMD_RDSR (0x05)
  37. #define CMD_WREN (0x06)
  38. #define CMD_SEC_ERASE (0x20)
  39. #define CMD_RDCR (0x35)
  40. #define CMD_RD_DEVID (0x9f)
  41. #define CMD_CHIP_ERASE (0xc7)
  42. #define CMD_C4READ (0xeb)
  43. #define WAIT_SR_TIMEOUT (1000000)
  44. #define PAGE_SIZE (256) // maximum bytes we can write in one SPI transfer
  45. #define SECTOR_SIZE MP_SPIFLASH_ERASE_BLOCK_SIZE
  46. STATIC void mp_spiflash_acquire_bus(mp_spiflash_t *self) {
  47. const mp_spiflash_config_t *c = self->config;
  48. if (c->bus_kind == MP_SPIFLASH_BUS_QSPI) {
  49. c->bus.u_qspi.proto->ioctl(c->bus.u_qspi.data, MP_QSPI_IOCTL_BUS_ACQUIRE);
  50. }
  51. }
  52. STATIC void mp_spiflash_release_bus(mp_spiflash_t *self) {
  53. const mp_spiflash_config_t *c = self->config;
  54. if (c->bus_kind == MP_SPIFLASH_BUS_QSPI) {
  55. c->bus.u_qspi.proto->ioctl(c->bus.u_qspi.data, MP_QSPI_IOCTL_BUS_RELEASE);
  56. }
  57. }
  58. STATIC void mp_spiflash_write_cmd_data(mp_spiflash_t *self, uint8_t cmd, size_t len, uint32_t data) {
  59. const mp_spiflash_config_t *c = self->config;
  60. if (c->bus_kind == MP_SPIFLASH_BUS_SPI) {
  61. // Note: len/data are unused for standard SPI
  62. mp_hal_pin_write(c->bus.u_spi.cs, 0);
  63. c->bus.u_spi.proto->transfer(c->bus.u_spi.data, 1, &cmd, NULL);
  64. mp_hal_pin_write(c->bus.u_spi.cs, 1);
  65. } else {
  66. c->bus.u_qspi.proto->write_cmd_data(c->bus.u_qspi.data, cmd, len, data);
  67. }
  68. }
  69. STATIC void mp_spiflash_write_cmd_addr_data(mp_spiflash_t *self, uint8_t cmd, uint32_t addr, size_t len, const uint8_t *src) {
  70. const mp_spiflash_config_t *c = self->config;
  71. if (c->bus_kind == MP_SPIFLASH_BUS_SPI) {
  72. uint8_t buf[4] = {cmd, addr >> 16, addr >> 8, addr};
  73. mp_hal_pin_write(c->bus.u_spi.cs, 0);
  74. c->bus.u_spi.proto->transfer(c->bus.u_spi.data, 4, buf, NULL);
  75. if (len) {
  76. c->bus.u_spi.proto->transfer(c->bus.u_spi.data, len, src, NULL);
  77. }
  78. mp_hal_pin_write(c->bus.u_spi.cs, 1);
  79. } else {
  80. c->bus.u_qspi.proto->write_cmd_addr_data(c->bus.u_qspi.data, cmd, addr, len, src);
  81. }
  82. }
  83. STATIC uint32_t mp_spiflash_read_cmd(mp_spiflash_t *self, uint8_t cmd, size_t len) {
  84. const mp_spiflash_config_t *c = self->config;
  85. if (c->bus_kind == MP_SPIFLASH_BUS_SPI) {
  86. uint32_t buf;
  87. mp_hal_pin_write(c->bus.u_spi.cs, 0);
  88. c->bus.u_spi.proto->transfer(c->bus.u_spi.data, 1, &cmd, NULL);
  89. c->bus.u_spi.proto->transfer(c->bus.u_spi.data, len, (void*)&buf, (void*)&buf);
  90. mp_hal_pin_write(c->bus.u_spi.cs, 1);
  91. return buf;
  92. } else {
  93. return c->bus.u_qspi.proto->read_cmd(c->bus.u_qspi.data, cmd, len);
  94. }
  95. }
  96. STATIC void mp_spiflash_read_data(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) {
  97. const mp_spiflash_config_t *c = self->config;
  98. if (c->bus_kind == MP_SPIFLASH_BUS_SPI) {
  99. uint8_t buf[4] = {CMD_READ, addr >> 16, addr >> 8, addr};
  100. mp_hal_pin_write(c->bus.u_spi.cs, 0);
  101. c->bus.u_spi.proto->transfer(c->bus.u_spi.data, 4, buf, NULL);
  102. c->bus.u_spi.proto->transfer(c->bus.u_spi.data, len, dest, dest);
  103. mp_hal_pin_write(c->bus.u_spi.cs, 1);
  104. } else {
  105. c->bus.u_qspi.proto->read_cmd_qaddr_qdata(c->bus.u_qspi.data, CMD_C4READ, addr, len, dest);
  106. }
  107. }
  108. STATIC void mp_spiflash_write_cmd(mp_spiflash_t *self, uint8_t cmd) {
  109. mp_spiflash_write_cmd_data(self, cmd, 0, 0);
  110. }
  111. STATIC void mp_spiflash_write_cmd_addr(mp_spiflash_t *self, uint8_t cmd, uint32_t addr) {
  112. mp_spiflash_write_cmd_addr_data(self, cmd, addr, 0, NULL);
  113. }
  114. STATIC int mp_spiflash_wait_sr(mp_spiflash_t *self, uint8_t mask, uint8_t val, uint32_t timeout) {
  115. uint8_t sr;
  116. for (; timeout; --timeout) {
  117. sr = mp_spiflash_read_cmd(self, CMD_RDSR, 1);
  118. if ((sr & mask) == val) {
  119. break;
  120. }
  121. }
  122. if ((sr & mask) == val) {
  123. return 0; // success
  124. } else if (timeout == 0) {
  125. return -MP_ETIMEDOUT;
  126. } else {
  127. return -MP_EIO;
  128. }
  129. }
  130. STATIC int mp_spiflash_wait_wel1(mp_spiflash_t *self) {
  131. return mp_spiflash_wait_sr(self, 2, 2, WAIT_SR_TIMEOUT);
  132. }
  133. STATIC int mp_spiflash_wait_wip0(mp_spiflash_t *self) {
  134. return mp_spiflash_wait_sr(self, 1, 0, WAIT_SR_TIMEOUT);
  135. }
  136. void mp_spiflash_init(mp_spiflash_t *self) {
  137. self->flags = 0;
  138. if (self->config->bus_kind == MP_SPIFLASH_BUS_SPI) {
  139. mp_hal_pin_write(self->config->bus.u_spi.cs, 1);
  140. mp_hal_pin_output(self->config->bus.u_spi.cs);
  141. self->config->bus.u_spi.proto->ioctl(self->config->bus.u_spi.data, MP_SPI_IOCTL_INIT);
  142. } else {
  143. self->config->bus.u_qspi.proto->ioctl(self->config->bus.u_qspi.data, MP_QSPI_IOCTL_INIT);
  144. }
  145. mp_spiflash_acquire_bus(self);
  146. #if defined(CHECK_DEVID)
  147. // Validate device id
  148. uint32_t devid = mp_spiflash_read_cmd(self, CMD_RD_DEVID, 3);
  149. if (devid != CHECK_DEVID) {
  150. return 0;
  151. }
  152. #endif
  153. if (self->config->bus_kind == MP_SPIFLASH_BUS_QSPI) {
  154. // Set QE bit
  155. uint32_t data = (mp_spiflash_read_cmd(self, CMD_RDSR, 1) & 0xff)
  156. | (mp_spiflash_read_cmd(self, CMD_RDCR, 1) & 0xff) << 8;
  157. if (!(data & (QSPI_QE_MASK << 8))) {
  158. data |= QSPI_QE_MASK << 8;
  159. mp_spiflash_write_cmd(self, CMD_WREN);
  160. mp_spiflash_write_cmd_data(self, CMD_WRSR, 2, data);
  161. mp_spiflash_wait_wip0(self);
  162. }
  163. }
  164. mp_spiflash_release_bus(self);
  165. }
  166. STATIC int mp_spiflash_erase_block_internal(mp_spiflash_t *self, uint32_t addr) {
  167. // enable writes
  168. mp_spiflash_write_cmd(self, CMD_WREN);
  169. // wait WEL=1
  170. int ret = mp_spiflash_wait_wel1(self);
  171. if (ret != 0) {
  172. return ret;
  173. }
  174. // erase the sector
  175. mp_spiflash_write_cmd_addr(self, CMD_SEC_ERASE, addr);
  176. // wait WIP=0
  177. return mp_spiflash_wait_wip0(self);
  178. }
  179. STATIC int mp_spiflash_write_page(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src) {
  180. // enable writes
  181. mp_spiflash_write_cmd(self, CMD_WREN);
  182. // wait WEL=1
  183. int ret = mp_spiflash_wait_wel1(self);
  184. if (ret != 0) {
  185. return ret;
  186. }
  187. // write the page
  188. mp_spiflash_write_cmd_addr_data(self, CMD_WRITE, addr, len, src);
  189. // wait WIP=0
  190. return mp_spiflash_wait_wip0(self);
  191. }
  192. /******************************************************************************/
  193. // Interface functions that go direct to the SPI flash device
  194. int mp_spiflash_erase_block(mp_spiflash_t *self, uint32_t addr) {
  195. mp_spiflash_acquire_bus(self);
  196. int ret = mp_spiflash_erase_block_internal(self, addr);
  197. mp_spiflash_release_bus(self);
  198. return ret;
  199. }
  200. void mp_spiflash_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) {
  201. if (len == 0) {
  202. return;
  203. }
  204. mp_spiflash_acquire_bus(self);
  205. mp_spiflash_read_data(self, addr, len, dest);
  206. mp_spiflash_release_bus(self);
  207. }
  208. int mp_spiflash_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src) {
  209. mp_spiflash_acquire_bus(self);
  210. int ret = 0;
  211. uint32_t offset = addr & (PAGE_SIZE - 1);
  212. while (len) {
  213. size_t rest = PAGE_SIZE - offset;
  214. if (rest > len) {
  215. rest = len;
  216. }
  217. ret = mp_spiflash_write_page(self, addr, rest, src);
  218. if (ret != 0) {
  219. break;
  220. }
  221. len -= rest;
  222. addr += rest;
  223. src += rest;
  224. offset = 0;
  225. }
  226. mp_spiflash_release_bus(self);
  227. return ret;
  228. }
  229. /******************************************************************************/
  230. // Interface functions that use the cache
  231. void mp_spiflash_cached_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) {
  232. if (len == 0) {
  233. return;
  234. }
  235. mp_spiflash_acquire_bus(self);
  236. mp_spiflash_cache_t *cache = self->config->cache;
  237. if (cache->user == self && cache->block != 0xffffffff) {
  238. uint32_t bis = addr / SECTOR_SIZE;
  239. uint32_t bie = (addr + len - 1) / SECTOR_SIZE;
  240. if (bis <= cache->block && cache->block <= bie) {
  241. // Read straddles current buffer
  242. size_t rest = 0;
  243. if (bis < cache->block) {
  244. // Read direct from flash for first part
  245. rest = cache->block * SECTOR_SIZE - addr;
  246. mp_spiflash_read_data(self, addr, rest, dest);
  247. len -= rest;
  248. dest += rest;
  249. addr += rest;
  250. }
  251. uint32_t offset = addr & (SECTOR_SIZE - 1);
  252. rest = SECTOR_SIZE - offset;
  253. if (rest > len) {
  254. rest = len;
  255. }
  256. memcpy(dest, &cache->buf[offset], rest);
  257. len -= rest;
  258. if (len == 0) {
  259. mp_spiflash_release_bus(self);
  260. return;
  261. }
  262. dest += rest;
  263. addr += rest;
  264. }
  265. }
  266. // Read rest direct from flash
  267. mp_spiflash_read_data(self, addr, len, dest);
  268. mp_spiflash_release_bus(self);
  269. }
  270. STATIC void mp_spiflash_cache_flush_internal(mp_spiflash_t *self) {
  271. #if USE_WR_DELAY
  272. if (!(self->flags & 1)) {
  273. return;
  274. }
  275. self->flags &= ~1;
  276. mp_spiflash_cache_t *cache = self->config->cache;
  277. // Erase sector
  278. int ret = mp_spiflash_erase_block_internal(self, cache->block * SECTOR_SIZE);
  279. if (ret != 0) {
  280. return;
  281. }
  282. // Write
  283. for (int i = 0; i < 16; i += 1) {
  284. uint32_t addr = cache->block * SECTOR_SIZE + i * PAGE_SIZE;
  285. int ret = mp_spiflash_write_page(self, addr, PAGE_SIZE, cache->buf + i * PAGE_SIZE);
  286. if (ret != 0) {
  287. return;
  288. }
  289. }
  290. #endif
  291. }
  292. void mp_spiflash_cache_flush(mp_spiflash_t *self) {
  293. mp_spiflash_acquire_bus(self);
  294. mp_spiflash_cache_flush_internal(self);
  295. mp_spiflash_release_bus(self);
  296. }
  297. STATIC int mp_spiflash_cached_write_part(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src) {
  298. // Align to 4096 sector
  299. uint32_t offset = addr & 0xfff;
  300. uint32_t sec = addr >> 12;
  301. addr = sec << 12;
  302. // Restriction for now, so we don't need to erase multiple pages
  303. if (offset + len > SECTOR_SIZE) {
  304. printf("mp_spiflash_cached_write_part: len is too large\n");
  305. return -MP_EIO;
  306. }
  307. mp_spiflash_cache_t *cache = self->config->cache;
  308. // Acquire the sector buffer
  309. if (cache->user != self) {
  310. if (cache->user != NULL) {
  311. mp_spiflash_cache_flush(cache->user);
  312. }
  313. cache->user = self;
  314. cache->block = 0xffffffff;
  315. }
  316. if (cache->block != sec) {
  317. // Read sector
  318. #if USE_WR_DELAY
  319. if (cache->block != 0xffffffff) {
  320. mp_spiflash_cache_flush_internal(self);
  321. }
  322. #endif
  323. mp_spiflash_read_data(self, addr, SECTOR_SIZE, cache->buf);
  324. }
  325. #if USE_WR_DELAY
  326. cache->block = sec;
  327. // Just copy to buffer
  328. memcpy(cache->buf + offset, src, len);
  329. // And mark dirty
  330. self->flags |= 1;
  331. #else
  332. uint32_t dirty = 0;
  333. for (size_t i = 0; i < len; ++i) {
  334. if (cache->buf[offset + i] != src[i]) {
  335. if (cache->buf[offset + i] != 0xff) {
  336. // Erase sector
  337. int ret = mp_spiflash_erase_block_internal(self, addr);
  338. if (ret != 0) {
  339. return ret;
  340. }
  341. dirty = 0xffff;
  342. break;
  343. } else {
  344. dirty |= (1 << ((offset + i) >> 8));
  345. }
  346. }
  347. }
  348. cache->block = sec;
  349. // Copy new block into buffer
  350. memcpy(cache->buf + offset, src, len);
  351. // Write sector in pages of 256 bytes
  352. for (size_t i = 0; i < 16; ++i) {
  353. if (dirty & (1 << i)) {
  354. int ret = mp_spiflash_write_page(self, addr + i * PAGE_SIZE, PAGE_SIZE, cache->buf + i * PAGE_SIZE);
  355. if (ret != 0) {
  356. return ret;
  357. }
  358. }
  359. }
  360. #endif
  361. return 0; // success
  362. }
  363. int mp_spiflash_cached_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src) {
  364. uint32_t bis = addr / SECTOR_SIZE;
  365. uint32_t bie = (addr + len - 1) / SECTOR_SIZE;
  366. mp_spiflash_acquire_bus(self);
  367. mp_spiflash_cache_t *cache = self->config->cache;
  368. if (cache->user == self && bis <= cache->block && bie >= cache->block) {
  369. // Write straddles current buffer
  370. uint32_t pre;
  371. uint32_t offset;
  372. if (cache->block * SECTOR_SIZE >= addr) {
  373. pre = cache->block * SECTOR_SIZE - addr;
  374. offset = 0;
  375. } else {
  376. pre = 0;
  377. offset = addr - cache->block * SECTOR_SIZE;
  378. }
  379. // Write buffered part first
  380. uint32_t len_in_buf = len - pre;
  381. len = 0;
  382. if (len_in_buf > SECTOR_SIZE - offset) {
  383. len = len_in_buf - (SECTOR_SIZE - offset);
  384. len_in_buf = SECTOR_SIZE - offset;
  385. }
  386. memcpy(&cache->buf[offset], &src[pre], len_in_buf);
  387. self->flags |= 1; // Mark dirty
  388. // Write part before buffer sector
  389. while (pre) {
  390. int rest = pre & (SECTOR_SIZE - 1);
  391. if (rest == 0) {
  392. rest = SECTOR_SIZE;
  393. }
  394. int ret = mp_spiflash_cached_write_part(self, addr, rest, src);
  395. if (ret != 0) {
  396. mp_spiflash_release_bus(self);
  397. return ret;
  398. }
  399. src += rest;
  400. addr += rest;
  401. pre -= rest;
  402. }
  403. src += len_in_buf;
  404. addr += len_in_buf;
  405. // Fall through to write remaining part
  406. }
  407. uint32_t offset = addr & (SECTOR_SIZE - 1);
  408. while (len) {
  409. int rest = SECTOR_SIZE - offset;
  410. if (rest > len) {
  411. rest = len;
  412. }
  413. int ret = mp_spiflash_cached_write_part(self, addr, rest, src);
  414. if (ret != 0) {
  415. mp_spiflash_release_bus(self);
  416. return ret;
  417. }
  418. len -= rest;
  419. addr += rest;
  420. src += rest;
  421. offset = 0;
  422. }
  423. mp_spiflash_release_bus(self);
  424. return 0;
  425. }