exmc_nandflash.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080
  1. /*!
  2. \file exmc_nandflash.c
  3. \brief nandflash(hynix HY27UF081G2A) driver
  4. \version 2023-06-30, V2.1.6, firmware for GD32F30x
  5. */
  6. /*
  7. Copyright (c) 2021, GigaDevice Semiconductor Inc.
  8. Redistribution and use in source and binary forms, with or without modification,
  9. are permitted provided that the following conditions are met:
  10. 1. Redistributions of source code must retain the above copyright notice, this
  11. list of conditions and the following disclaimer.
  12. 2. Redistributions in binary form must reproduce the above copyright notice,
  13. this list of conditions and the following disclaimer in the documentation
  14. and/or other materials provided with the distribution.
  15. 3. Neither the name of the copyright holder nor the names of its contributors
  16. may be used to endorse or promote products derived from this software without
  17. specific prior written permission.
  18. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  19. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  21. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  22. INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  23. NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  24. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  25. WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  26. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  27. OF SUCH DAMAGE.
  28. */
  29. #include "gd32f30x.h"
  30. #include "exmc_nandflash.h"
  31. /* define the physical address of nand flash, and it is determined by the hardware */
  32. #define BANK1_NAND_ADDR ((uint32_t)0x70000000)
  33. #define BANK_NAND_ADDR BANK1_NAND_ADDR
  34. /* define operating nand flash macro */
  35. #define NAND_CMD_AREA *(__IO uint8_t *)(BANK_NAND_ADDR | EXMC_CMD_AREA)
  36. #define NAND_ADDR_AREA *(__IO uint8_t *)(BANK_NAND_ADDR | EXMC_ADDR_AREA)
  37. #define NAND_DATA_AREA *(__IO uint8_t *)(BANK_NAND_ADDR | EXMC_DATA_AREA)
  38. /* the macro of calculate nand flash operating address */
  39. #define ROW_ADDRESS (addr.page + (addr.block + (addr.zone * NAND_ZONE_SIZE)) * NAND_BLOCK_SIZE)
  40. /* define NWATI operation */
  41. #define NWAIT_OPERA_FUNC() while(gpio_input_bit_get(GPIOD, GPIO_PIN_6) == 0)
  42. /* static variable definition */
  43. static uint16_t cur_zone = 0;
  44. static uint16_t LUT_tab[NAND_BLOCK_COUNT];
  45. static uint8_t temp_buf[NAND_PAGE_TOTAL_SIZE];
  46. /* local function prototypes ('static') */
  47. static uint8_t exmc_nand_page_copyback(uint32_t src_pageno, uint32_t dest_pageno);
  48. static uint8_t exmc_nand_page_copyback_ex(uint32_t src_pageno, uint32_t dest_pageno, uint8_t *pbuf, uint16_t offset, uint16_t size);
  49. static uint8_t exmc_nand_write_page(uint8_t *pbuf, nand_address_struct addr, uint16_t bytecnt);
  50. static uint8_t exmc_nand_read_page(uint8_t *pbuf, nand_address_struct addr, uint16_t bytecnt);
  51. static uint8_t exmc_nand_write_spare(uint8_t *pbuf, nand_address_struct addr, uint16_t bytecnt);
  52. static uint8_t exmc_nand_read_spare(uint8_t *pbuf, nand_address_struct addr, uint16_t bytecnt);
  53. static uint8_t exmc_nand_write_data(uint8_t *pbuf, nand_address_struct addr, uint16_t bytecnt);
  54. static uint8_t exmc_nand_read_data(uint8_t *pbuf, nand_address_struct addr, uint16_t bytecnt);
  55. static uint8_t exmc_nand_erase_block(uint32_t blocknum);
  56. static uint8_t exmc_nand_read_status(void);
  57. static uint8_t exmc_nand_get_status(void);
  58. static uint8_t nand_write_new_block(nand_address_struct addr, nand_address_struct logaddr, uint8_t *pwritebuf, uint16_t size);
  59. static uint8_t nand_write_block(nand_address_struct logaddr, uint8_t *pwritebuf, uint16_t size);
  60. static uint8_t nand_read_block(nand_address_struct logaddr, uint8_t *preadbuf, uint16_t size);
  61. static uint8_t nand_build_LUT(uint16_t zone);
  62. static uint16_t nand_find_free_block(uint8_t odd_even);
  63. static uint8_t nand_judge_buf_ok(uint8_t *pbuf, uint32_t len, uint8_t value);
  64. static uint8_t nand_isbad_block(uint32_t blocknum);
  65. static uint8_t nand_mark_used_block(uint32_t blocknum);
  66. static void nand_mark_bad_block(uint32_t blocknum);
  67. static uint8_t nand_mark_logic_block(uint32_t blocknum, uint16_t logblock);
  68. /*!
  69. \brief initialize nand flash peripheral
  70. \param[in] none
  71. \param[out] none
  72. \retval NAND_OK, NAND_FAIL
  73. */
  74. uint8_t exmc_nandflash_init(uint32_t nand_bank)
  75. {
  76. exmc_nand_parameter_struct nand_init_struct;
  77. exmc_nand_pccard_timing_parameter_struct nand_timing_init_struct;
  78. /* enable EXMC clock*/
  79. rcu_periph_clock_enable(RCU_EXMC);
  80. rcu_periph_clock_enable(RCU_GPIOD);
  81. rcu_periph_clock_enable(RCU_GPIOE);
  82. /* common GPIO configuration */
  83. /* D2(PD0),D3(PD1),D0(PD14) and D1(PD15) pins configuration */
  84. gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_14 | GPIO_PIN_15);
  85. /* D4(PE7),D5(PE8),D6(PE9) and D7(PE10) pins configuration */
  86. gpio_init(GPIOE, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10);
  87. /* CLE(PD11)and ALE(PD12) pins configuration */
  88. gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_11 | GPIO_PIN_12);
  89. /* NOE(PD4) and NWE(PD5) pins configuration*/
  90. gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4 | GPIO_PIN_5);
  91. /* NWAIT(PD6) pin configuration */
  92. gpio_init(GPIOD, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
  93. /* NCE1(PD7) pin configuration */
  94. gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7); /* EXMC configuration */
  95. nand_timing_init_struct.setuptime = 1U;
  96. nand_timing_init_struct.waittime = 3U;
  97. nand_timing_init_struct.holdtime = 2U;
  98. nand_timing_init_struct.databus_hiztime = 2U;
  99. nand_init_struct.nand_bank = EXMC_BANK1_NAND;
  100. nand_init_struct.ecc_size = EXMC_ECC_SIZE_2048BYTES;
  101. nand_init_struct.atr_latency = EXMC_ALE_RE_DELAY_1_HCLK;
  102. nand_init_struct.ctr_latency = EXMC_CLE_RE_DELAY_1_HCLK;
  103. nand_init_struct.ecc_logic = ENABLE;
  104. nand_init_struct.databus_width = EXMC_NAND_DATABUS_WIDTH_8B;
  105. nand_init_struct.wait_feature = ENABLE;
  106. nand_init_struct.common_space_timing = &nand_timing_init_struct;
  107. nand_init_struct.attribute_space_timing = &nand_timing_init_struct;
  108. exmc_nand_init(&nand_init_struct);
  109. /* enable EXMC NAND bank1 */
  110. exmc_nand_enable(EXMC_BANK1_NAND);
  111. /* build LUT(Look up table) */
  112. return nand_build_LUT(0);
  113. }
  114. /*!
  115. \brief read NAND flash ID
  116. \param[in] nand_id: structure of nand flash ID
  117. \param[out] none
  118. \retval none
  119. */
  120. void nand_read_id(nand_id_struct *nand_id)
  121. {
  122. uint32_t data = 0;
  123. /* send command to the command area */
  124. NAND_CMD_AREA = NAND_CMD_READID;
  125. /* send address to the address area */
  126. NAND_ADDR_AREA = 0x00;
  127. /* sequence to read ID from NAND flash */
  128. data = *(__IO uint32_t *)(BANK_NAND_ADDR | EXMC_DATA_AREA);
  129. nand_id->maker_id = ADDR_1ST_CYCLE(data);
  130. nand_id->device_id = ADDR_2ND_CYCLE(data);
  131. nand_id->third_id = ADDR_3RD_CYCLE(data);
  132. nand_id->fourth_id = ADDR_4TH_CYCLE(data);
  133. }
  134. /*!
  135. \brief write data to nand flash
  136. \param[in] mem_addr: logic page number to be written
  137. \param[in] pwritebuf: pointer to write data buffer
  138. \param[in] size: data count
  139. \param[out] none
  140. \retval NAND_OK, NAND_FAIL
  141. */
  142. uint8_t nand_write(uint32_t mem_addr, uint8_t *pwritebuf, uint16_t size)
  143. {
  144. uint32_t temp;
  145. uint32_t block_remain_size;
  146. nand_address_struct logaddr;
  147. temp = mem_addr % (NAND_BLOCK_SIZE * NAND_PAGE_SIZE);
  148. logaddr.zone = mem_addr / (NAND_BLOCK_SIZE * NAND_PAGE_SIZE * NAND_ZONE_SIZE);
  149. logaddr.block = mem_addr / (NAND_BLOCK_SIZE * NAND_PAGE_SIZE);
  150. logaddr.page = temp / NAND_PAGE_SIZE;
  151. logaddr.page_in_offset = temp % NAND_PAGE_SIZE;
  152. block_remain_size = (NAND_BLOCK_SIZE * NAND_PAGE_SIZE) - \
  153. (NAND_PAGE_SIZE * logaddr.page + logaddr.page_in_offset);
  154. while(size > block_remain_size) {
  155. if(NAND_FAIL == nand_write_block(logaddr, pwritebuf, block_remain_size)) {
  156. return NAND_FAIL;
  157. }
  158. logaddr.block++;
  159. pwritebuf += block_remain_size;
  160. size -= block_remain_size;
  161. logaddr.page = 0;
  162. logaddr.page_in_offset = 0;
  163. block_remain_size = (NAND_BLOCK_SIZE * NAND_PAGE_SIZE);
  164. }
  165. if(size > 0) {
  166. if(NAND_FAIL == nand_write_block(logaddr, pwritebuf, size)) {
  167. return NAND_FAIL;
  168. }
  169. }
  170. return NAND_OK;
  171. }
  172. /*!
  173. \brief read data from nand flash
  174. \param[in] mem_addr: logic page number to be read
  175. \param[in] preadbuf: pointer to the data buffer to be read
  176. \param[in] size: data count
  177. \param[out] none
  178. \retval NAND_OK, NAND_FAIL
  179. */
  180. uint8_t nand_read(uint32_t mem_addr, uint8_t *preadbuf, uint16_t size)
  181. {
  182. uint32_t temp;
  183. uint32_t block_remain_size;
  184. nand_address_struct logaddr;
  185. temp = mem_addr % (NAND_BLOCK_SIZE * NAND_PAGE_SIZE);
  186. logaddr.zone = mem_addr / (NAND_BLOCK_SIZE * NAND_PAGE_SIZE * NAND_ZONE_SIZE);
  187. logaddr.block = mem_addr / (NAND_BLOCK_SIZE * NAND_PAGE_SIZE);
  188. logaddr.page = temp / NAND_PAGE_SIZE;
  189. logaddr.page_in_offset = temp % NAND_PAGE_SIZE;
  190. block_remain_size = (NAND_BLOCK_SIZE * NAND_PAGE_SIZE) - \
  191. (NAND_PAGE_SIZE * logaddr.page + logaddr.page_in_offset);
  192. while(size > block_remain_size) {
  193. if(NAND_FAIL == nand_read_block(logaddr, preadbuf, block_remain_size)) {
  194. return NAND_FAIL;
  195. }
  196. logaddr.block++;
  197. preadbuf += block_remain_size;
  198. size -= block_remain_size;
  199. logaddr.page = 0;
  200. logaddr.page_in_offset = 0;
  201. block_remain_size = (NAND_BLOCK_SIZE * NAND_PAGE_SIZE);
  202. }
  203. if(size > 0) {
  204. if(NAND_FAIL == nand_read_block(logaddr, preadbuf, size)) {
  205. return NAND_FAIL;
  206. }
  207. }
  208. return NAND_OK;
  209. }
  210. /*!
  211. \brief scan and test specific block
  212. \param[in] blocknum: block number
  213. \param[out] none
  214. \retval NAND_OK, NAND_FAIL
  215. */
  216. uint8_t nand_scan_block(uint32_t blocknum)
  217. {
  218. uint32_t i, k;
  219. nand_address_struct addr;
  220. addr.zone = cur_zone;
  221. addr.block = blocknum;
  222. addr.page = 0;
  223. addr.page_in_offset = NAND_PAGE_SIZE;
  224. memset(temp_buf, 0x00, NAND_PAGE_TOTAL_SIZE);
  225. for(i = 0; i < BAD_BALOK_TEST_CYCLE; i++) {
  226. if(NAND_READY != exmc_nand_erase_block(blocknum)) {
  227. nand_mark_bad_block(blocknum);
  228. return NAND_FAIL;
  229. }
  230. addr.page = 0;
  231. for(k = 0; k < NAND_BLOCK_SIZE; k++) {
  232. exmc_nand_read_page(temp_buf, addr, NAND_PAGE_TOTAL_SIZE);
  233. if(NAND_OK != nand_judge_buf_ok(temp_buf, NAND_PAGE_TOTAL_SIZE, 0xFF)) {
  234. nand_mark_bad_block(blocknum);
  235. return NAND_FAIL;
  236. }
  237. addr.page++;
  238. }
  239. addr.page = 0;
  240. for(k = 0; k < NAND_BLOCK_SIZE; k++) {
  241. memset(temp_buf, 0x00, NAND_PAGE_TOTAL_SIZE);
  242. if(NAND_OK != exmc_nand_write_page(temp_buf, addr, NAND_PAGE_TOTAL_SIZE)) {
  243. nand_mark_bad_block(blocknum);
  244. return NAND_FAIL;
  245. }
  246. exmc_nand_read_page(temp_buf, addr, NAND_PAGE_TOTAL_SIZE);
  247. if(NAND_OK != nand_judge_buf_ok(temp_buf, NAND_PAGE_TOTAL_SIZE, 0x00)) {
  248. nand_mark_bad_block(blocknum);
  249. return NAND_FAIL;
  250. }
  251. addr.page++;
  252. }
  253. }
  254. if(NAND_READY != exmc_nand_erase_block(blocknum)) {
  255. nand_mark_bad_block(blocknum);
  256. return NAND_FAIL;
  257. }
  258. addr.page = 0;
  259. for(k = 0; k < NAND_BLOCK_SIZE; k++) {
  260. exmc_nand_read_page(temp_buf, addr, NAND_PAGE_TOTAL_SIZE);
  261. if(NAND_OK != nand_judge_buf_ok(temp_buf, NAND_PAGE_TOTAL_SIZE, 0xFF)) {
  262. nand_mark_bad_block(blocknum);
  263. return NAND_FAIL;
  264. }
  265. addr.page++;
  266. }
  267. return NAND_OK;
  268. }
  269. /*!
  270. \brief check block is free block
  271. \param[in] blocknum: block number
  272. \param[out] none
  273. \retval NAND_OK, NAND_FAIL
  274. */
  275. uint8_t nand_judge_free_block(uint32_t blocknum)
  276. {
  277. uint8_t flag;
  278. nand_address_struct addr;
  279. addr.zone = cur_zone;
  280. addr.block = blocknum;
  281. addr.page = 0;
  282. addr.page_in_offset = NAND_PAGE_SIZE + USED_OFFSET;
  283. if(nand_isbad_block(blocknum)) {
  284. return 0;
  285. }
  286. exmc_nand_read_page(&flag, addr, 1);
  287. if(0xFF == flag) {
  288. return 1;
  289. }
  290. return 0;
  291. }
  292. /*!
  293. \brief copy data from a page to another page
  294. \param[in] src_pageno: source page number
  295. \param[in] dest_pageno: destination page number
  296. \param[out] none
  297. \retval NAND_OK, NAND_FAIL
  298. */
  299. static uint8_t exmc_nand_page_copyback(uint32_t src_pageno, uint32_t dest_pageno)
  300. {
  301. NAND_CMD_AREA = NAND_CMD_COPYBACK_A;
  302. NAND_ADDR_AREA = 0;
  303. NAND_ADDR_AREA = 0;
  304. NAND_ADDR_AREA = src_pageno;
  305. NAND_ADDR_AREA = (src_pageno & 0xFF00) >> 8;
  306. NAND_CMD_AREA = NAND_CMD_COPYBACK_B;
  307. /* must wait, or read data wrong */
  308. NWAIT_OPERA_FUNC();
  309. NAND_CMD_AREA = NAND_CMD_COPYBACK_C;
  310. NAND_ADDR_AREA = 0;
  311. NAND_ADDR_AREA = 0;
  312. NAND_ADDR_AREA = dest_pageno;
  313. NAND_ADDR_AREA = (dest_pageno & 0xFF00) >> 8;
  314. NAND_CMD_AREA = NAND_CMD_COPYBACK_D;
  315. /* check operation status */
  316. if(NAND_READY == exmc_nand_get_status()) {
  317. return NAND_OK;
  318. }
  319. return NAND_FAIL;
  320. }
  321. /*!
  322. \brief copy data from a page to another page and update some data in target page
  323. \param[in] src_pageno: source page number
  324. \param[in] dest_pageno: destination page number
  325. \param[in] pbuf: data buffer
  326. \param[in] offset: offset in the page, data buffer will write data from it
  327. \param[in] size: data buffer size
  328. \param[out] none
  329. \retval NAND_OK, NAND_FAIL
  330. */
  331. static uint8_t exmc_nand_page_copyback_ex(uint32_t src_pageno, uint32_t dest_pageno, uint8_t *pbuf, uint16_t offset, uint16_t size)
  332. {
  333. uint16_t i;
  334. NAND_CMD_AREA = NAND_CMD_COPYBACK_A;
  335. NAND_ADDR_AREA = 0;
  336. NAND_ADDR_AREA = 0;
  337. NAND_ADDR_AREA = src_pageno;
  338. NAND_ADDR_AREA = (src_pageno & 0xFF00U) >> 8U;
  339. NAND_CMD_AREA = NAND_CMD_COPYBACK_B;
  340. /* must wait, or read data wrong */
  341. NWAIT_OPERA_FUNC();
  342. NAND_CMD_AREA = NAND_CMD_COPYBACK_C;
  343. NAND_ADDR_AREA = 0;
  344. NAND_ADDR_AREA = 0;
  345. NAND_ADDR_AREA = dest_pageno;
  346. NAND_ADDR_AREA = (dest_pageno & 0xFF00U) >> 8U;
  347. /* need no data, need no wait */
  348. NAND_CMD_AREA = NAND_CMD_COPYBACK_C;
  349. NAND_ADDR_AREA = offset;
  350. NAND_ADDR_AREA = offset >> 8U;
  351. /* send data */
  352. for(i = 0; i < size; i++) {
  353. NAND_DATA_AREA = pbuf[i];
  354. }
  355. NAND_CMD_AREA = NAND_CMD_COPYBACK_D;
  356. /* check operation status */
  357. if(NAND_READY == exmc_nand_get_status()) {
  358. return NAND_OK;
  359. }
  360. return NAND_FAIL;
  361. }
  362. /*!
  363. \brief write data to page
  364. \param[in] pbuf: pointer on the buffer containing data to be written
  365. \param[in] addr: the address of the data to be written
  366. \param[in] bytecnt: byte count to be written
  367. \param[out] none
  368. \retval NAND_OK, NAND_FAIL
  369. */
  370. static uint8_t exmc_nand_write_page(uint8_t *pbuf, nand_address_struct addr, uint16_t bytecnt)
  371. {
  372. uint16_t i;
  373. /* send write page command */
  374. NAND_CMD_AREA = NAND_CMD_WRITE_1ST;
  375. NAND_ADDR_AREA = addr.page_in_offset;
  376. NAND_ADDR_AREA = addr.page_in_offset >> 8U;
  377. NAND_ADDR_AREA = ADDR_1ST_CYCLE(ROW_ADDRESS);
  378. NAND_ADDR_AREA = ADDR_2ND_CYCLE(ROW_ADDRESS);
  379. /* write data */
  380. for(i = 0; i < bytecnt; i++) {
  381. NAND_DATA_AREA = pbuf[i];
  382. }
  383. NAND_CMD_AREA = NAND_CMD_WRITE_2ND;
  384. /* check operation status */
  385. if(NAND_READY == exmc_nand_get_status()) {
  386. return NAND_OK;
  387. }
  388. return NAND_FAIL;
  389. }
  390. /*!
  391. \brief read data from page
  392. \param[in] pbuf: pointer on the buffer filling data to be read
  393. \param[in] addr: the address of the data to be read
  394. \param[in] bytecnt: byte count to be read
  395. \param[out] none
  396. \retval NAND_OK, NAND_FAIL
  397. */
  398. static uint8_t exmc_nand_read_page(uint8_t *pbuf, nand_address_struct addr, uint16_t bytecnt)
  399. {
  400. uint16_t i;
  401. /* send read page command */
  402. NAND_CMD_AREA = NAND_CMD_READ1_1ST;
  403. NAND_ADDR_AREA = addr.page_in_offset;
  404. NAND_ADDR_AREA = addr.page_in_offset >> 8;
  405. NAND_ADDR_AREA = ADDR_1ST_CYCLE(ROW_ADDRESS);
  406. NAND_ADDR_AREA = ADDR_2ND_CYCLE(ROW_ADDRESS);
  407. NAND_CMD_AREA = NAND_CMD_READ1_2ND;
  408. /* must wait, or read data wrong */
  409. NWAIT_OPERA_FUNC();
  410. /* read data to buffer */
  411. for(i = 0; i < bytecnt; i++) {
  412. pbuf[i] = NAND_DATA_AREA;
  413. }
  414. return NAND_OK;
  415. }
  416. /*!
  417. \brief write the spare area of one page data
  418. \param[in] pbuf: pointer on the buffer containing data to be written
  419. \param[in] addr: the address of the data to be written
  420. \param[in] bytecnt: byte count to be written
  421. \param[out] none
  422. \retval NAND_OK, NAND_FAIL
  423. */
  424. static uint8_t exmc_nand_write_spare(uint8_t *pbuf, nand_address_struct addr, uint16_t bytecnt)
  425. {
  426. if(addr.page_in_offset < NAND_PAGE_SIZE) {
  427. return NAND_FAIL;
  428. }
  429. if(bytecnt + addr.page_in_offset > NAND_PAGE_TOTAL_SIZE) {
  430. return NAND_FAIL;
  431. }
  432. return exmc_nand_write_page(pbuf, addr, bytecnt);
  433. }
  434. /*!
  435. \brief read data from the spare area of 1 page
  436. \param[in] pbuf: pointer on the buffer filling data to be read
  437. \param[in] addr: the address of the data to be read
  438. \param[in] bytecnt: count of spare area to be read
  439. \param[out] none
  440. \retval NAND_OK, NAND_FAIL
  441. */
  442. static uint8_t exmc_nand_read_spare(uint8_t *pbuf, nand_address_struct addr, uint16_t bytecnt)
  443. {
  444. if(addr.page_in_offset < NAND_PAGE_SIZE) {
  445. return NAND_FAIL;
  446. }
  447. if(bytecnt + addr.page_in_offset > NAND_PAGE_TOTAL_SIZE) {
  448. return NAND_FAIL;
  449. }
  450. return exmc_nand_read_page(pbuf, addr, bytecnt);
  451. }
  452. /*!
  453. \brief write data to the page main data area
  454. \param[in] pbuf: pointer on the buffer containing data to be written
  455. \param[in] addr: physical address data to be written
  456. \param[in] bytecnt: byte count to be written
  457. \param[out] none
  458. \retval NAND_OK, NAND_FAIL
  459. */
  460. static uint8_t exmc_nand_write_data(uint8_t *pbuf, nand_address_struct addr, uint16_t bytecnt)
  461. {
  462. uint8_t *temppbuf = pbuf;
  463. while(bytecnt + addr.page_in_offset > NAND_PAGE_SIZE) {
  464. if(NAND_OK != exmc_nand_write_page(temppbuf,
  465. addr,
  466. NAND_PAGE_SIZE - addr.page_in_offset)) {
  467. return NAND_FAIL;
  468. }
  469. bytecnt -= NAND_PAGE_SIZE - addr.page_in_offset;
  470. temppbuf += NAND_PAGE_SIZE - addr.page_in_offset;
  471. addr.page++;
  472. addr.page_in_offset = 0;
  473. }
  474. if(bytecnt > 0) {
  475. if(NAND_OK != exmc_nand_write_page(temppbuf, addr, bytecnt)) {
  476. return NAND_FAIL;
  477. }
  478. }
  479. return NAND_OK;
  480. }
  481. /*!
  482. \brief read data from the page main data area
  483. \param[in] pbuf: pointer on the buffer filling data to be read
  484. \param[in] addr: the physical address of the data to be read
  485. \param[in] bytecnt: byte count to be read
  486. \param[out] none
  487. \retval NAND_OK, NAND_FAIL
  488. */
  489. static uint8_t exmc_nand_read_data(uint8_t *pbuf, nand_address_struct addr, uint16_t bytecnt)
  490. {
  491. uint8_t *temppbuf = pbuf;
  492. while(bytecnt + addr.page_in_offset > NAND_PAGE_SIZE) {
  493. if(NAND_OK != exmc_nand_read_page(temppbuf, addr, NAND_PAGE_SIZE - addr.page_in_offset)) {
  494. return NAND_FAIL;
  495. }
  496. addr.page++;
  497. temppbuf += NAND_PAGE_SIZE - addr.page_in_offset;
  498. bytecnt -= NAND_PAGE_SIZE - addr.page_in_offset;
  499. addr.page_in_offset = 0;
  500. }
  501. if(bytecnt > 0) {
  502. if(NAND_OK != exmc_nand_read_page(temppbuf, addr, bytecnt)) {
  503. return NAND_FAIL;
  504. }
  505. }
  506. return NAND_OK;
  507. }
  508. /*!
  509. \brief erase complete block of NAND flash
  510. \param[in] blocknum: block number to be erased
  511. \param[out] none
  512. \retval NAND_TIMEOUT_ERROR, NAND_READY
  513. */
  514. static uint8_t exmc_nand_erase_block(uint32_t blocknum)
  515. {
  516. /* send erase command */
  517. NAND_CMD_AREA = NAND_CMD_ERASE_1ST;
  518. blocknum <<= 6;
  519. NAND_ADDR_AREA = blocknum;
  520. NAND_ADDR_AREA = blocknum >> 8;
  521. NAND_CMD_AREA = NAND_CMD_ERASE_2ND;
  522. return (exmc_nand_get_status());
  523. }
  524. /*!
  525. \brief read the NAND flash status
  526. \param[in] none
  527. \param[out] none
  528. \retval NAND_BUSY, NAND_READY, NAND_ERROR
  529. */
  530. static uint8_t exmc_nand_read_status(void)
  531. {
  532. uint8_t data;
  533. uint8_t status = NAND_BUSY;
  534. /* read operation status */
  535. NAND_CMD_AREA = NAND_CMD_STATUS;
  536. data = *(__IO uint8_t *)(BANK_NAND_ADDR);
  537. if(NAND_ERROR == (data & NAND_ERROR)) {
  538. status = NAND_ERROR;
  539. } else if(NAND_READY == (data & NAND_READY)) {
  540. status = NAND_READY;
  541. } else {
  542. status = NAND_BUSY;
  543. }
  544. return (status);
  545. }
  546. /*!
  547. \brief get NAND flash operation status
  548. \param[in] none
  549. \param[out] none
  550. \retval NAND_TIMEOUT_ERROR, NAND_READY
  551. */
  552. static uint8_t exmc_nand_get_status(void)
  553. {
  554. uint32_t timeout = 0x10000;
  555. uint8_t status = NAND_READY;
  556. status = exmc_nand_read_status();
  557. /* wait for operation is over, exit when time out */
  558. while((NAND_READY != status) && (0x00U != timeout)) {
  559. status = exmc_nand_read_status();
  560. timeout--;
  561. }
  562. if(0x00 == timeout) {
  563. status = NAND_TIMEOUT_ERROR;
  564. }
  565. return status;
  566. }
  567. /*!
  568. \brief copy data from old block to new block and write new data to the new block
  569. \param[in] addr: physical address data to be written
  570. \param[in] logaddr: logic address data to be written
  571. \param[in] pwritebuf: pointer to write data buffer
  572. \param[in] size: data count
  573. \param[out] none
  574. \retval NAND_OK, NAND_FAIL
  575. */
  576. static uint8_t nand_write_new_block(nand_address_struct addr, nand_address_struct logaddr, uint8_t *pwritebuf, uint16_t size)
  577. {
  578. uint16_t n, i, offset;
  579. uint16_t newblock;
  580. for(n = 0; n < 5; n++) {
  581. if(addr.block & 0x0001) {
  582. newblock = nand_find_free_block(BLOCK_EVEN);
  583. } else {
  584. newblock = nand_find_free_block(BLOCK_ODD);
  585. }
  586. if(newblock >= NAND_BLOCK_COUNT) {
  587. return NAND_FAIL;
  588. }
  589. for(i = 0; i < NAND_BLOCK_SIZE; i++) {
  590. if(i == addr.page) {
  591. offset = addr.page_in_offset;
  592. while(offset + size > NAND_PAGE_SIZE) {
  593. if(exmc_nand_page_copyback_ex(addr.block * NAND_BLOCK_SIZE + i,
  594. newblock * NAND_BLOCK_SIZE + i,
  595. pwritebuf, offset,
  596. NAND_PAGE_SIZE - offset) == NAND_FAIL) {
  597. nand_mark_bad_block(newblock);
  598. nand_build_LUT(addr.zone);
  599. break;
  600. }
  601. pwritebuf += NAND_PAGE_SIZE - offset;
  602. size -= NAND_PAGE_SIZE - offset;
  603. offset = 0;
  604. i++;
  605. }
  606. if(size > 0) {
  607. if(exmc_nand_page_copyback_ex(addr.block * NAND_BLOCK_SIZE + i,
  608. newblock * NAND_BLOCK_SIZE + i,
  609. pwritebuf, offset, size) == NAND_FAIL) {
  610. nand_mark_bad_block(newblock);
  611. nand_build_LUT(addr.zone);
  612. break;
  613. }
  614. }
  615. } else {
  616. if(exmc_nand_page_copyback(addr.block * NAND_BLOCK_SIZE + i,
  617. newblock * NAND_BLOCK_SIZE + i) == NAND_FAIL) {
  618. nand_mark_bad_block(newblock);
  619. nand_build_LUT(addr.zone);
  620. break;
  621. }
  622. }
  623. }
  624. if(i == NAND_BLOCK_SIZE) {
  625. if(NAND_FAIL == nand_mark_used_block(newblock)) {
  626. nand_mark_bad_block(newblock);
  627. nand_build_LUT(addr.zone);
  628. continue;
  629. } else {
  630. nand_mark_logic_block(newblock, logaddr.block);
  631. }
  632. if(NAND_READY != exmc_nand_erase_block(addr.block)) {
  633. nand_mark_bad_block(addr.block);
  634. nand_build_LUT(addr.zone);
  635. continue;
  636. }
  637. nand_build_LUT(addr.zone);
  638. break;
  639. }
  640. }
  641. return NAND_OK;
  642. }
  643. /*!
  644. \brief write data to block
  645. \param[in] logaddr: logic address to be written
  646. \param[in] pwritebuf: pointer to write data buffer
  647. \param[in] size: data count
  648. \param[out] none
  649. \retval NAND_OK, NAND_FAIL
  650. */
  651. static uint8_t nand_write_block(nand_address_struct logaddr, uint8_t *pwritebuf, uint16_t size)
  652. {
  653. uint16_t PBN;
  654. nand_address_struct addr;
  655. if(cur_zone != logaddr.zone) {
  656. nand_build_LUT(logaddr.zone);
  657. }
  658. PBN = LUT_tab[logaddr.block];
  659. if(0xFFFFU == PBN) {
  660. return NAND_FAIL;
  661. }
  662. addr.zone = logaddr.zone;
  663. addr.block = PBN & 0x03FF;
  664. addr.page = logaddr.page;
  665. addr.page_in_offset = logaddr.page_in_offset;
  666. if(PBN & USED_BLOCK) {
  667. return nand_write_new_block(addr, logaddr, (uint8_t *)pwritebuf, size);
  668. } else {
  669. if(NAND_FAIL == exmc_nand_write_data((uint8_t *)pwritebuf, addr, size)) {
  670. return NAND_FAIL;
  671. }
  672. if(NAND_FAIL == nand_mark_used_block(addr.block)) {
  673. return NAND_FAIL;
  674. } else {
  675. if(NAND_FAIL == nand_mark_logic_block(addr.block, logaddr.block)) {
  676. return NAND_FAIL;
  677. }
  678. }
  679. return NAND_OK;
  680. }
  681. }
  682. /*!
  683. \brief read data from block
  684. \param[in] logaddr: logic address to be read
  685. \param[in] preadbuf: pointer to the data buffer to be read
  686. \param[in] size: data count
  687. \param[out] none
  688. \retval NAND_OK, NAND_FAIL
  689. */
  690. static uint8_t nand_read_block(nand_address_struct logaddr, uint8_t *preadbuf, uint16_t size)
  691. {
  692. uint16_t PBN;
  693. nand_address_struct addr;
  694. if(cur_zone != logaddr.zone) {
  695. nand_build_LUT(logaddr.zone);
  696. }
  697. PBN = LUT_tab[logaddr.block];
  698. addr.block = PBN & 0x03FF;
  699. if(addr.block >= NAND_BLOCK_COUNT) {
  700. return NAND_FAIL;
  701. }
  702. addr.zone = logaddr.zone;
  703. addr.page = logaddr.page;
  704. addr.page_in_offset = logaddr.page_in_offset;
  705. if(NAND_FAIL == exmc_nand_read_data((uint8_t *)preadbuf, addr, size)) {
  706. return NAND_FAIL;
  707. }
  708. return NAND_OK;
  709. }
  710. /*!
  711. \brief build NAND flash look up table
  712. \param[in] zone: bulid zone
  713. \param[out] none
  714. \retval NAND_OK, NAND_FAIL
  715. */
  716. static uint8_t nand_build_LUT(uint16_t zone)
  717. {
  718. uint16_t logic_blockID;
  719. uint16_t bad_block, cur_block, free_block;
  720. uint8_t spare_area[NAND_SPARE_AREA_SIZE];
  721. nand_address_struct addr;
  722. cur_zone = zone;
  723. addr.zone = cur_zone;
  724. addr.block = 0x00;
  725. addr.page = 0x00;
  726. addr.page_in_offset = NAND_PAGE_SIZE;
  727. /* 1st step : init */
  728. for(cur_block = 0; cur_block < NAND_ZONE_SIZE; cur_block++) {
  729. LUT_tab[cur_block] = FREE_BLOCK;
  730. }
  731. /* init Pointers */
  732. bad_block = NAND_ZONE_SIZE - 1;
  733. cur_block = 0;
  734. /* 2nd step : locate used and bad blocks */
  735. while(cur_block < NAND_ZONE_SIZE) {
  736. addr.block = cur_block;
  737. exmc_nand_read_spare(spare_area, addr, NAND_SPARE_AREA_SIZE);
  738. if(spare_area[BI_OFFSET] != 0xFF) {
  739. LUT_tab[bad_block--] |= cur_block | (uint16_t)BAD_BLOCK;
  740. LUT_tab[cur_block] &= (uint16_t)~FREE_BLOCK;
  741. if(bad_block <= MAX_LOG_BLOCKS_PER_ZONE + EXCHANGE_BLOCKS_NUM) {
  742. return NAND_FAIL;
  743. }
  744. } else if(spare_area[USED_OFFSET] == 0xFE) {
  745. logic_blockID = (spare_area[LBN0_OFFSET] + (spare_area[LBN1_OFFSET] * 256)) & 0x03FF;
  746. LUT_tab[logic_blockID] |= cur_block | VALID_BLOCK | USED_BLOCK;
  747. LUT_tab[cur_block] &= (uint16_t)(~FREE_BLOCK);
  748. }
  749. cur_block++;
  750. }
  751. /* 3rd step : locate free blocks by scanning the LUT already built partially */
  752. free_block = 0;
  753. for(cur_block = 0; cur_block < NAND_ZONE_SIZE; cur_block++) {
  754. if(cur_block == 81) {
  755. }
  756. if(!(LUT_tab[cur_block] & USED_BLOCK)) {
  757. do {
  758. if(LUT_tab[free_block] & FREE_BLOCK) {
  759. LUT_tab [cur_block] |= free_block;
  760. LUT_tab [free_block] &= ~FREE_BLOCK;
  761. break;
  762. }
  763. free_block++;
  764. } while(free_block < NAND_ZONE_SIZE);
  765. }
  766. }
  767. return NAND_OK;
  768. }
  769. /*!
  770. \brief find free exchange block, according the block number(odd number select 1001, even number select 1000)
  771. \param[in] odd_even: block number is odd or even
  772. \param[out] none
  773. \retval NAND_OK, NAND_FAIL
  774. */
  775. static uint16_t nand_find_free_block(uint8_t odd_even)
  776. {
  777. if(BLOCK_ODD == odd_even) {
  778. return LUT_tab[MAX_LOG_BLOCKS_PER_ZONE] & 0x03FF;
  779. } else if(BLOCK_EVEN == odd_even) {
  780. return LUT_tab[MAX_LOG_BLOCKS_PER_ZONE + 1] & 0x03FF;
  781. }
  782. return 0xFFFF;
  783. }
  784. /*!
  785. \brief check NAND data is right
  786. \param[in] pbuf: input buffer
  787. \param[in] len: buffer length
  788. \param[in] value: right value in buffer
  789. \param[out] none
  790. \retval NAND_OK, NAND_FAIL
  791. */
  792. static uint8_t nand_judge_buf_ok(uint8_t *pbuf, uint32_t len, uint8_t value)
  793. {
  794. uint32_t i;
  795. for(i = 0; i < len; i++) {
  796. if(pbuf[i] != value) {
  797. return NAND_FAIL;
  798. }
  799. }
  800. return NAND_OK;
  801. }
  802. /*!
  803. \brief check block is bad block
  804. \param[in] blocknum: physical block number
  805. \param[out] none
  806. \retval NAND_OK, NAND_FAIL
  807. */
  808. static uint8_t nand_isbad_block(uint32_t blocknum)
  809. {
  810. uint8_t flag;
  811. nand_address_struct addr;
  812. addr.zone = cur_zone;
  813. addr.block = blocknum;
  814. addr.page = 0;
  815. addr.page_in_offset = NAND_PAGE_SIZE + BI_OFFSET;
  816. exmc_nand_read_spare(&flag, addr, 1);
  817. if(0xFFU != flag) {
  818. return NAND_FAIL;
  819. }
  820. return NAND_OK;
  821. }
  822. /*!
  823. \brief mark used block
  824. \param[in] blocknum: physical block number
  825. \param[out] none
  826. \retval NAND_OK, NAND_FAIL
  827. */
  828. static uint8_t nand_mark_used_block(uint32_t blocknum)
  829. {
  830. uint8_t flag;
  831. nand_address_struct addr;
  832. addr.zone = cur_zone;
  833. addr.block = blocknum;
  834. addr.page = 0;
  835. addr.page_in_offset = NAND_PAGE_SIZE + USED_OFFSET;
  836. flag = NAND_USED_BLOCK_FLAG;
  837. if(NAND_FAIL == exmc_nand_write_spare(&flag, addr, 1)) {
  838. return NAND_FAIL;
  839. }
  840. return NAND_OK;
  841. }
  842. /*!
  843. \brief mark bad block
  844. \param[in] blocknum: block number
  845. \param[out] none
  846. \retval none
  847. */
  848. static void nand_mark_bad_block(uint32_t blocknum)
  849. {
  850. uint8_t flag;
  851. nand_address_struct addr;
  852. addr.zone = cur_zone;
  853. addr.block = blocknum;
  854. addr.page = 0;
  855. addr.page_in_offset = NAND_PAGE_SIZE + BI_OFFSET;
  856. flag = NAND_BAD_BLOCK_FLAG;
  857. if(NAND_FAIL == exmc_nand_write_spare(&flag, addr, 1)) {
  858. addr.page = 1;
  859. exmc_nand_write_spare(&flag, addr, 1);
  860. }
  861. }
  862. /*!
  863. \brief mark logic block to specific block
  864. \param[in] blocknum: physical block number
  865. \param[in] logblock: logic block number
  866. \param[out] none
  867. \retval none
  868. */
  869. static uint8_t nand_mark_logic_block(uint32_t blocknum, uint16_t logblock)
  870. {
  871. nand_address_struct addr;
  872. addr.zone = cur_zone;
  873. addr.block = blocknum;
  874. addr.page = 0;
  875. addr.page_in_offset = NAND_PAGE_SIZE + LBN0_OFFSET;
  876. if(NAND_FAIL == exmc_nand_write_spare((uint8_t *)&logblock, addr, 2)) {
  877. return NAND_FAIL;
  878. }
  879. return NAND_OK;
  880. }