exmc_nandflash.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. /*!
  2. \file exmc_nandflash.c
  3. \brief nandflash(GD9FU1G8F2AMG) driver
  4. \version 2017-02-10, V1.0.0, firmware for GD32F30x
  5. \version 2018-10-10, V1.1.0, firmware for GD32F30x
  6. \version 2018-12-25, V2.0.0, firmware for GD32F30x
  7. \version 2020-09-30, V2.1.0, firmware for GD32F30x
  8. */
  9. /*
  10. Copyright (c) 2020, GigaDevice Semiconductor Inc.
  11. Redistribution and use in source and binary forms, with or without modification,
  12. are permitted provided that the following conditions are met:
  13. 1. Redistributions of source code must retain the above copyright notice, this
  14. list of conditions and the following disclaimer.
  15. 2. Redistributions in binary form must reproduce the above copyright notice,
  16. this list of conditions and the following disclaimer in the documentation
  17. and/or other materials provided with the distribution.
  18. 3. Neither the name of the copyright holder nor the names of its contributors
  19. may be used to endorse or promote products derived from this software without
  20. specific prior written permission.
  21. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  22. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  23. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  24. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  25. INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  26. NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  27. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  28. WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  29. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  30. OF SUCH DAMAGE.
  31. */
  32. #include "gd32f30x.h"
  33. #include "exmc_nandflash.h"
  34. /* defines the physical address of nand flash, and it is determined by the hardware */
  35. #define BANK1_NAND_ADDR ((uint32_t)0x70000000)
  36. #define BANK_NAND_ADDR BANK1_NAND_ADDR
  37. /* define operating nand flash macro */
  38. #define NAND_CMD_AREA *(__IO uint8_t *)(BANK_NAND_ADDR | EXMC_CMD_AREA)
  39. #define NAND_ADDR_AREA *(__IO uint8_t *)(BANK_NAND_ADDR | EXMC_ADDR_AREA)
  40. #define NAND_DATA_AREA *(__IO uint8_t *)(BANK_NAND_ADDR | EXMC_DATA_AREA)
  41. /* the macro of calculate nand flash operating address */
  42. #define ROW_ADDRESS (address.page + (address.block + (address.zone * NAND_ZONE_SIZE)) * NAND_BLOCK_SIZE)
  43. /* page bit count per block */
  44. #define PAGE_BIT 6
  45. /* function prototypes */
  46. /* write a set of data to nand flash for the specified pages addresses */
  47. static uint8_t exmc_nand_writepage(uint8_t *pbuffer, nand_address_struct address, uint16_t bytecount);
  48. /* read a set of data from nand flash for the specified pages addresses */
  49. static uint8_t exmc_nand_readpage(uint8_t *pbuffer, nand_address_struct address, uint16_t bytecount);
  50. /* write the main area information for the specified pages addresses */
  51. static uint8_t exmc_nand_writedata(uint8_t *pbuffer, nand_address_struct physicaladdress, uint16_t bytecount);
  52. /* read the main area information for the specified pages addresses */
  53. static uint8_t exmc_nand_readdata(uint8_t *pbuffer, nand_address_struct phyaddress, uint16_t bytecount);
  54. /* erase data specified block */
  55. static uint8_t exmc_nand_eraseblock(uint32_t blocknum);
  56. /* reads the NAND memory status */
  57. static uint8_t exmc_nand_readstatus(void);
  58. /* get the NAND operation status */
  59. static uint8_t exmc_nand_getstatus(void);
  60. /*!
  61. \brief nand flash peripheral initialize
  62. \param[in] none
  63. \param[out] none
  64. \retval none
  65. */
  66. void exmc_nandflash_init(void)
  67. {
  68. exmc_nand_parameter_struct nand_init_struct;
  69. exmc_nand_pccard_timing_parameter_struct nand_timing_init_struct;
  70. /* enable EXMC clock*/
  71. rcu_periph_clock_enable(RCU_EXMC);
  72. rcu_periph_clock_enable(RCU_GPIOD);
  73. rcu_periph_clock_enable(RCU_GPIOE);
  74. rcu_periph_clock_enable(RCU_GPIOF);
  75. rcu_periph_clock_enable(RCU_GPIOG);
  76. /* configure GPIO EXMC_D[0-7] */
  77. gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_14 | GPIO_PIN_15);
  78. gpio_init(GPIOE, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10);
  79. /* configure GPIO ALE(EXMC_A16) and CLE(EXMC_A17) */
  80. gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_11 | GPIO_PIN_12);
  81. /* configure NOE(PD4) and NWE(PD5)*/
  82. gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4 | GPIO_PIN_5);
  83. /* configure NWAIT(PD6) */
  84. gpio_init(GPIOD, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
  85. /* configure NCE1(PD7) */
  86. gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
  87. /* EXMC configuration */
  88. nand_timing_init_struct.setuptime = 2;
  89. nand_timing_init_struct.waittime = 7;
  90. nand_timing_init_struct.holdtime = 4;
  91. nand_timing_init_struct.databus_hiztime = 4;
  92. nand_init_struct.nand_bank = EXMC_BANK1_NAND;
  93. nand_init_struct.ecc_size = EXMC_ECC_SIZE_2048BYTES;
  94. nand_init_struct.atr_latency = EXMC_ALE_RE_DELAY_1_HCLK;
  95. nand_init_struct.ctr_latency = EXMC_CLE_RE_DELAY_1_HCLK;
  96. nand_init_struct.ecc_logic = ENABLE;
  97. nand_init_struct.databus_width = EXMC_NAND_DATABUS_WIDTH_8B;
  98. nand_init_struct.wait_feature = ENABLE;
  99. nand_init_struct.common_space_timing = &nand_timing_init_struct;
  100. nand_init_struct.attribute_space_timing = &nand_timing_init_struct;
  101. exmc_nand_init(&nand_init_struct);
  102. /* enable EXMC NAND bank1 */
  103. exmc_nand_enable(EXMC_BANK1_NAND);
  104. }
  105. /*!
  106. \brief read NAND flash ID
  107. \param[in] nand_id: structure of nand flash ID
  108. \param[out] none
  109. \retval none
  110. */
  111. void nand_read_id(nand_id_struct* nand_id)
  112. {
  113. uint32_t data = 0;
  114. /* send command to the command area */
  115. NAND_CMD_AREA = NAND_CMD_READID;
  116. /* send address to the address area */
  117. NAND_ADDR_AREA = 0x00;
  118. /* read id from NAND flash */
  119. data = *(__IO uint32_t *)(BANK_NAND_ADDR | EXMC_DATA_AREA);
  120. nand_id->maker_id = ADDR_1ST_CYCLE (data);
  121. nand_id->device_id = ADDR_2ND_CYCLE (data);
  122. nand_id->third_id = ADDR_3RD_CYCLE (data);
  123. nand_id->fourth_id = ADDR_4TH_CYCLE (data);
  124. }
  125. /*!
  126. \brief write a set of data to nand flash for the specified pages addresses
  127. \param[in] pbuffer: pointer on the buffer containing data to be written
  128. \param[in] address: the address of the data to be written
  129. \param[in] bytecount: byte count to be written(bytecount + address.page_in_offset <= nand_page_total_size)
  130. \param[out] none
  131. \retval NAND_OK, NAND_FAIL
  132. */
  133. static uint8_t exmc_nand_writepage(uint8_t *pbuffer, nand_address_struct address, uint16_t bytecount)
  134. {
  135. uint16_t i;
  136. /* send 1st cycle page programming command to the command area */
  137. NAND_CMD_AREA = NAND_CMD_WRITE_1ST;
  138. /* send address to the address area, for GD9FU1G8F2AMG
  139. bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
  140. first byte: A7 A6 A5 A4 A3 A2 A1 A0 (bit7 - bit0 of page address)
  141. second byte: 0 0 0 0 A11 A10 A9 A8 (bit11 - bit8 of page address, high 4bit must be zero)
  142. third byte: A19 A18 A17 A16 A15 A14 A13 A12
  143. fourth byte: A27 A26 A25 A24 A23 A22 A21 A20
  144. */
  145. NAND_ADDR_AREA = address.page_in_offset;
  146. NAND_ADDR_AREA = address.page_in_offset >> 8;
  147. NAND_ADDR_AREA = ADDR_1ST_CYCLE(ROW_ADDRESS);
  148. NAND_ADDR_AREA = ADDR_2ND_CYCLE(ROW_ADDRESS);
  149. /* write data to data area */
  150. for(i = 0; i < bytecount; i++){
  151. NAND_DATA_AREA = pbuffer[i];
  152. }
  153. /* send 2nd cycle page programming command to the command area */
  154. NAND_CMD_AREA = NAND_CMD_WRITE_2ND;
  155. /* check operation stauts */
  156. if (NAND_READY == exmc_nand_getstatus()){
  157. return NAND_OK;
  158. }
  159. return NAND_FAIL;
  160. }
  161. /*!
  162. \brief read a set of data from nand flash for the specified pages addresses
  163. \param[in] pbuffer: pointer on the buffer filling data to be read
  164. \param[in] address: the address of the data to be read
  165. \param[in] bytecount: byte count to be read(bytecount + address.page_in_offset <= NAND_PAGE_TOTAL_SIZE)
  166. \param[out] none
  167. \retval NAND_OK, NAND_FAIL
  168. */
  169. static uint8_t exmc_nand_readpage(uint8_t *pbuffer, nand_address_struct address, uint16_t bytecount)
  170. {
  171. uint16_t i;
  172. /* send 1st cycle read command to the command area */
  173. NAND_CMD_AREA = NAND_CMD_READ1_1ST;
  174. /* send address to the address area, for GD9FU1G8F2AMG
  175. bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
  176. first byte: A7 A6 A5 A4 A3 A2 A1 A0 (bit7 - bit0 of page address)
  177. second byte: 0 0 0 0 A11 A10 A9 A8 (bit11 - bit8 of page address, high 4bit must be zero)
  178. third byte: A19 A18 A17 A16 A15 A14 A13 A12
  179. fourth byte: A27 A26 A25 A24 A23 A22 A21 A20
  180. */
  181. NAND_ADDR_AREA = address.page_in_offset;
  182. NAND_ADDR_AREA = address.page_in_offset >> 8;
  183. NAND_ADDR_AREA = ADDR_1ST_CYCLE(ROW_ADDRESS);
  184. NAND_ADDR_AREA = ADDR_2ND_CYCLE(ROW_ADDRESS);
  185. /* send 2nd cycle read command to the command area */
  186. NAND_CMD_AREA = NAND_CMD_READ1_2ND;
  187. /* read data to pbuffer */
  188. for(i = 0; i < bytecount; i++){
  189. pbuffer[i] = NAND_DATA_AREA;
  190. }
  191. /* check operation stauts */
  192. if (NAND_READY == exmc_nand_getstatus()){
  193. return NAND_OK;
  194. }
  195. return NAND_FAIL;
  196. }
  197. /*!
  198. \brief write the spare area information for the specified pages addresses
  199. \param[in] pbuffer: pointer on the buffer containing data to be written
  200. \param[in] address: the address of the data to be written
  201. \param[in] bytecount: byte count to be written(bytecount + (address.page_in_offset - NAND_PAGE_SIZE) <= NAND_SPARE_AREA_SIZE)
  202. \param[out] none
  203. \retval NAND_OK, NAND_FAIL
  204. */
  205. uint8_t exmc_nand_writespare(uint8_t *pbuffer, nand_address_struct address, uint16_t bytecount)
  206. {
  207. /* address.page_in_offset > NAND_PAGE_SIZE */
  208. if(address.page_in_offset <= NAND_PAGE_SIZE){
  209. return NAND_FAIL;
  210. }
  211. /* bytecount + address.page_in_offset < NAND_PAGE_TOTAL_SIZE */
  212. if (bytecount + address.page_in_offset >= NAND_PAGE_TOTAL_SIZE){
  213. return NAND_FAIL;
  214. }
  215. /* write spare area */
  216. return exmc_nand_writepage(pbuffer, address, bytecount);
  217. }
  218. /*!
  219. \brief read the spare area information for the specified pages addresses
  220. \param[in] pbuffer: pointer on the buffer containing data to be read
  221. \param[in] address: the address of the data to be read
  222. \param[in] bytecount: byte count to be read(bytecount + (address.page_in_offset - NAND_PAGE_SIZE) <= NAND_SPARE_AREA_SIZE)
  223. \param[out] none
  224. \retval NAND_OK, NAND_FAIL
  225. */
  226. uint8_t exmc_nand_readspare(uint8_t *pbuffer,nand_address_struct address, uint16_t bytecount)
  227. {
  228. /* address.page_in_offset > NAND_PAGE_SIZE */
  229. if(address.page_in_offset <= NAND_PAGE_SIZE){
  230. return NAND_FAIL;
  231. }
  232. /* bytecount + address.page_in_offset < NAND_PAGE_TOTAL_SIZE */
  233. if (bytecount + address.page_in_offset >= NAND_PAGE_TOTAL_SIZE){
  234. return NAND_FAIL;
  235. }
  236. /* read spare area */
  237. return exmc_nand_readpage(pbuffer, address, bytecount);
  238. }
  239. /*!
  240. \brief write the main area information for the specified pages addresses
  241. \param[in] pbuffer: pointer on the buffer containing data to be written
  242. \param[in] physicaladdress: the address of the data to be written
  243. \param[in] bytecount: byte count to be written
  244. \param[out] none
  245. \retval NAND_OK, NAND_FAIL
  246. */
  247. static uint8_t exmc_nand_writedata(uint8_t *pbuffer, nand_address_struct physicaladdress, uint16_t bytecount)
  248. {
  249. uint8_t *temp_pbuffer = pbuffer;
  250. /* erase block before write data based on the feature of nand flash */
  251. exmc_nand_eraseblock(physicaladdress.block);
  252. /* if the number of data bytes to be written plus the offset is greater than the page size,
  253. the automatic next page */
  254. while(bytecount + physicaladdress.page_in_offset > NAND_PAGE_SIZE){
  255. if(NAND_OK != exmc_nand_writepage(temp_pbuffer, physicaladdress, NAND_PAGE_SIZE - physicaladdress.page_in_offset)){
  256. return NAND_FAIL;
  257. }
  258. /* compute address of the next block */
  259. bytecount -= NAND_PAGE_SIZE - physicaladdress.page_in_offset;
  260. temp_pbuffer += NAND_PAGE_SIZE - physicaladdress.page_in_offset;
  261. physicaladdress.page++;
  262. physicaladdress.page_in_offset = 0;
  263. }
  264. /* write the last less than one block of data */
  265. if(bytecount > 0){
  266. if(exmc_nand_writepage(temp_pbuffer, physicaladdress,bytecount) != NAND_OK){
  267. return NAND_FAIL;
  268. }
  269. }
  270. return NAND_OK;
  271. }
  272. /*!
  273. \brief read the main area information for the specified pages addresses
  274. \param[in] pbuffer: pointer on the buffer containing data to be read
  275. \param[in] phyaddress: the address of the data to be read
  276. \param[in] bytecount: byte count to be read
  277. \param[out] none
  278. \retval NAND_OK, NAND_FAIL
  279. */
  280. static uint8_t exmc_nand_readdata(uint8_t *pbuffer, nand_address_struct phyaddress, uint16_t bytecount)
  281. {
  282. uint8_t *temp_pbuffer = pbuffer;
  283. /* if the number of data bytes to be read plus the offset is greater than the page size, the automatic next page */
  284. while(bytecount + phyaddress.page_in_offset > NAND_PAGE_SIZE){
  285. if(NAND_OK != exmc_nand_readpage(temp_pbuffer, phyaddress, NAND_PAGE_SIZE - phyaddress.page_in_offset)){
  286. return NAND_FAIL;
  287. }
  288. phyaddress.page++;
  289. temp_pbuffer += NAND_PAGE_SIZE - phyaddress.page_in_offset;
  290. bytecount -= NAND_PAGE_SIZE - phyaddress.page_in_offset;
  291. phyaddress.page_in_offset = 0;
  292. }
  293. if(bytecount>0){
  294. if(exmc_nand_readpage(temp_pbuffer, phyaddress, bytecount) != NAND_OK){
  295. return NAND_FAIL;
  296. }
  297. }
  298. return NAND_OK;
  299. }
  300. /*!
  301. \brief erase data specified block
  302. \param[in] blocknum: block number to be erased data
  303. \param[out] none
  304. \retval NAND memory status
  305. */
  306. static uint8_t exmc_nand_eraseblock(uint32_t blocknum)
  307. {
  308. /* send 1st cycle erase command to command area */
  309. NAND_CMD_AREA = NAND_CMD_ERASE_1ST;
  310. /* block number into a block number and the page number */
  311. blocknum <<= PAGE_BIT;
  312. NAND_ADDR_AREA = ADDR_1ST_CYCLE(blocknum);
  313. NAND_ADDR_AREA = ADDR_2ND_CYCLE(blocknum);
  314. /* send 2nd cycle erase command to command area */
  315. NAND_CMD_AREA = NAND_CMD_ERASE_2ND;
  316. return (exmc_nand_getstatus());
  317. }
  318. /*!
  319. \brief reset nand flash
  320. \param[in] none
  321. \param[out] none
  322. \retval NAND_OK, NAND_FAIL
  323. */
  324. uint8_t nand_reset(void)
  325. {
  326. NAND_CMD_AREA = NAND_CMD_RESET;
  327. /* check operation stauts */
  328. if (NAND_READY == exmc_nand_getstatus()){
  329. return NAND_OK;
  330. }
  331. return NAND_FAIL;
  332. }
  333. /*!
  334. \brief reads the NAND memory status
  335. \param[in] none
  336. \param[out] none
  337. \retval NAND memory status
  338. */
  339. static uint8_t exmc_nand_readstatus(void)
  340. {
  341. uint8_t data;
  342. uint8_t status = NAND_BUSY;
  343. /* send read status command to the command area */
  344. NAND_CMD_AREA = NAND_CMD_STATUS;
  345. data = NAND_DATA_AREA;
  346. if((data & NAND_ERROR) == NAND_ERROR){
  347. status = NAND_ERROR;
  348. }
  349. else if((data & NAND_READY) == NAND_READY){
  350. status = NAND_READY;
  351. }
  352. else{
  353. status = NAND_BUSY;
  354. }
  355. return (status);
  356. }
  357. /*!
  358. \brief get the NAND operation status
  359. \param[in] none
  360. \param[out] none
  361. \retval new status of the NAND operation
  362. */
  363. static uint8_t exmc_nand_getstatus(void)
  364. {
  365. uint32_t timeout = 0x10000;
  366. uint8_t status = NAND_READY;
  367. status = exmc_nand_readstatus();
  368. /* waiting for NAND operation over, it will exit after a timeout */
  369. while ((status != NAND_READY) && (timeout != 0x00)){
  370. status = exmc_nand_readstatus();
  371. timeout--;
  372. }
  373. if(timeout == 0x00){
  374. status = NAND_TIMEOUT_ERROR;
  375. }
  376. return (status);
  377. }
  378. /*!
  379. \brief write the main area information for the specified logic addresses
  380. \param[in] memaddr: the logic address of the data to be written
  381. \param[in] pwritebuf: pointer on the buffer containing data to be written
  382. \param[in] bytecount: byte count to be written
  383. \param[out] none
  384. \retval NAND_OK, NAND_FAIL
  385. */
  386. uint8_t nand_write(uint32_t memaddr, uint8_t *pwritebuf, uint16_t bytecount)
  387. {
  388. uint32_t temp_blockremainsize;
  389. nand_address_struct physicaladdress;
  390. uint32_t temp;
  391. temp = memaddr % (NAND_BLOCK_SIZE * NAND_PAGE_SIZE);
  392. /* compute physical zone number */
  393. physicaladdress.zone= memaddr / (NAND_BLOCK_SIZE * NAND_PAGE_SIZE * NAND_ZONE_SIZE);
  394. /* compute physical block number */
  395. physicaladdress.block = memaddr / (NAND_BLOCK_SIZE * NAND_PAGE_SIZE);
  396. /* compute physical page number */
  397. physicaladdress.page = temp / NAND_PAGE_SIZE;
  398. /* compute physical offset into page */
  399. physicaladdress.page_in_offset = temp % NAND_PAGE_SIZE;
  400. temp_blockremainsize = (NAND_BLOCK_SIZE * NAND_PAGE_SIZE)-(NAND_PAGE_SIZE * physicaladdress.page +
  401. physicaladdress.page_in_offset);
  402. /* if the number of data bytes to be written plus the offset is greater than the block size, the automatic next block. */
  403. while(bytecount > temp_blockremainsize){
  404. if(NAND_FAIL == exmc_nand_writedata(pwritebuf,physicaladdress,temp_blockremainsize)){
  405. return NAND_FAIL;
  406. }
  407. physicaladdress.block++;
  408. pwritebuf += temp_blockremainsize;
  409. bytecount -= temp_blockremainsize;
  410. physicaladdress.page = 0;
  411. physicaladdress.page_in_offset = 0;
  412. temp_blockremainsize = (NAND_BLOCK_SIZE * NAND_PAGE_SIZE);
  413. }
  414. if(bytecount > 0){
  415. if(NAND_FAIL == exmc_nand_writedata(pwritebuf, physicaladdress, bytecount)){
  416. return NAND_FAIL;
  417. }
  418. }
  419. return NAND_OK;
  420. }
  421. /*!
  422. \brief read the main area information for the specified logic addresses
  423. \param[in] memaddr: the logic address of the data to be read
  424. \param[in] preadbuf: pointer on the buffer containing data to be read
  425. \param[in] bytecount: byte count to be reas
  426. \param[out] none
  427. \retval NAND_OK, NAND_FAIL
  428. */
  429. uint8_t nand_read(uint32_t memaddr, uint8_t *preadbuf, uint16_t bytecount)
  430. {
  431. uint32_t temp_blockremainsize;
  432. nand_address_struct physicaladdress;
  433. uint32_t temp;
  434. temp = memaddr % (NAND_BLOCK_SIZE * NAND_PAGE_SIZE);
  435. /* compute physical zone number */
  436. physicaladdress.zone= memaddr / (NAND_BLOCK_SIZE * NAND_PAGE_SIZE * NAND_ZONE_SIZE);
  437. /* compute physical block number */
  438. physicaladdress.block = memaddr / (NAND_BLOCK_SIZE * NAND_PAGE_SIZE);
  439. /* compute physical page number */
  440. physicaladdress.page = temp / NAND_PAGE_SIZE;
  441. /* compute physical offset into page */
  442. physicaladdress.page_in_offset = temp % NAND_PAGE_SIZE;
  443. temp_blockremainsize=(NAND_BLOCK_SIZE * NAND_PAGE_SIZE) - (NAND_PAGE_SIZE * physicaladdress.page + physicaladdress.page_in_offset);
  444. /* if the number of data bytes to be read plus the offset is greater than the block size, the automatic next block */
  445. while(bytecount > temp_blockremainsize){
  446. if(NAND_FAIL == exmc_nand_readdata(preadbuf,physicaladdress,temp_blockremainsize)){
  447. return NAND_FAIL;
  448. }
  449. physicaladdress.block++;
  450. preadbuf += temp_blockremainsize;
  451. bytecount -= temp_blockremainsize;
  452. physicaladdress.page = 0;
  453. physicaladdress.page_in_offset = 0;
  454. temp_blockremainsize = (NAND_BLOCK_SIZE * NAND_PAGE_SIZE);
  455. }
  456. if(bytecount > 0){
  457. if(exmc_nand_readdata(preadbuf,physicaladdress, bytecount) == NAND_FAIL){
  458. return NAND_FAIL;
  459. }
  460. }
  461. return NAND_OK;
  462. }
  463. /*!
  464. \brief format nand flash
  465. \param[in] none
  466. \param[out] none
  467. \retval NAND_OK, NAND_FAIL
  468. */
  469. uint8_t nand_format(void)
  470. {
  471. uint16_t i;
  472. for (i = 0; i < NAND_BLOCK_COUNT; i++){
  473. if(NAND_READY != exmc_nand_eraseblock(i)){
  474. return NAND_FAIL;
  475. }
  476. }
  477. return NAND_OK;
  478. }
  479. /*!
  480. \brief fill the buffer with specified value
  481. \param[in] pbuffer: pointer on the buffer to fill
  482. \param[in] buffer_lenght: size of the buffer to fill
  483. \param[in] value: value to fill on the buffer
  484. \param[out] none
  485. \retval none
  486. */
  487. void fill_buffer_nand(uint8_t *pbuffer, uint16_t buffer_lenght, uint32_t value)
  488. {
  489. uint16_t index = 0;
  490. for (index = 0; index < buffer_lenght; index++){
  491. pbuffer[index] = value + index;
  492. }
  493. }