gd32f30x_exmc.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. /*!
  2. \file gd32f30x_exmc.c
  3. \brief EXMC driver
  4. */
  5. /*
  6. Copyright (C) 2017 GigaDevice
  7. 2017-02-10, V1.0.1, firmware for GD32F30x
  8. */
  9. #include "gd32f30x_exmc.h"
  10. /* EXMC bank0 register reset value */
  11. #define BANK0_SNCTL_REGION0_RESET ((uint32_t)0x000030DBU)
  12. #define BANK0_SNCTL_REGION1_2_3_RESET ((uint32_t)0x000030D2U)
  13. #define BANK0_SNTCFG_RESET ((uint32_t)0x0FFFFFFFU)
  14. #define BANK0_SNWTCFG_RESET ((uint32_t)0x0FFFFFFFU)
  15. /* EXMC bank1/2 register reset mask*/
  16. #define BANK1_2_NPCTL_RESET ((uint32_t)0x00000018U)
  17. #define BANK1_2_NPINTEN_RESET ((uint32_t)0x00000040U)
  18. #define BANK1_2_NPCTCFG_RESET ((uint32_t)0xFCFCFCFCU)
  19. #define BANK1_2_NPATCFG_RESET ((uint32_t)0xFCFCFCFCU)
  20. /* EXMC bank3 register reset mask*/
  21. #define BANK3_NPCTL_RESET ((uint32_t)0x00000018U)
  22. #define BANK3_NPINTEN_RESET ((uint32_t)0x00000040U)
  23. #define BANK3_NPCTCFG_RESET ((uint32_t)0xFCFCFCFCU)
  24. #define BANK3_NPATCFG_RESET ((uint32_t)0xFCFCFCFCU)
  25. #define BANK3_PIOTCFG3_RESET ((uint32_t)0xFCFCFCFCU)
  26. /* EXMC register bit offset */
  27. #define SNCTL_NRMUX_OFFSET ((uint32_t)1U)
  28. #define SNCTL_SBRSTEN_OFFSET ((uint32_t)8U)
  29. #define SNCTL_WRAPEN_OFFSET ((uint32_t)10U)
  30. #define SNCTL_WREN_OFFSET ((uint32_t)12U)
  31. #define SNCTL_NRWTEN_OFFSET ((uint32_t)13U)
  32. #define SNCTL_EXMODEN_OFFSET ((uint32_t)14U)
  33. #define SNCTL_ASYNCWAIT_OFFSET ((uint32_t)15U)
  34. #define SNTCFG_AHLD_OFFSET ((uint32_t)4U)
  35. #define SNTCFG_DSET_OFFSET ((uint32_t)8U)
  36. #define SNTCFG_BUSLAT_OFFSET ((uint32_t)16U)
  37. #define SNWTCFG_WAHLD_OFFSET ((uint32_t)4U)
  38. #define SNWTCFG_WDSET_OFFSET ((uint32_t)8U)
  39. #define SNWTCFG_WBUSLAT_OFFSET ((uint32_t)16U)
  40. #define NPCTL_NDWTEN_OFFSET ((uint32_t)1U)
  41. #define NPCTL_ECCEN_OFFSET ((uint32_t)6U)
  42. #define NPCTCFG_COMWAIT_OFFSET ((uint32_t)8U)
  43. #define NPCTCFG_COMHLD_OFFSET ((uint32_t)16U)
  44. #define NPCTCFG_COMHIZ_OFFSET ((uint32_t)24U)
  45. #define NPATCFG_ATTWAIT_OFFSET ((uint32_t)8U)
  46. #define NPATCFG_ATTHLD_OFFSET ((uint32_t)16U)
  47. #define NPATCFG_ATTHIZ_OFFSET ((uint32_t)24U)
  48. #define PIOTCFG_IOWAIT_OFFSET ((uint32_t)8U)
  49. #define PIOTCFG_IOHLD_OFFSET ((uint32_t)16U)
  50. #define PIOTCFG_IOHIZ_OFFSET ((uint32_t)24U)
  51. #define INTEN_INTS_OFFSET ((uint32_t)3U)
  52. /*!
  53. \brief deinitialize EXMC NOR/SRAM region
  54. \param[in] exmc_norsram_region: select the region of bank0
  55. \arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3)
  56. \param[out] none
  57. \retval none
  58. */
  59. void exmc_norsram_deinit(uint32_t exmc_norsram_region)
  60. {
  61. /* reset the registers */
  62. if(EXMC_BANK0_NORSRAM_REGION0 == exmc_norsram_region){
  63. EXMC_SNCTL(exmc_norsram_region) = BANK0_SNCTL_REGION0_RESET;
  64. }else{
  65. EXMC_SNCTL(exmc_norsram_region) = BANK0_SNCTL_REGION1_2_3_RESET;
  66. }
  67. EXMC_SNTCFG(exmc_norsram_region) = BANK0_SNTCFG_RESET;
  68. EXMC_SNWTCFG(exmc_norsram_region) = BANK0_SNWTCFG_RESET;
  69. }
  70. /*!
  71. \brief initialize EXMC NOR/SRAM region
  72. \param[in] exmc_norsram_parameter_struct: configure the EXMC NOR/SRAM parameter
  73. norsram_region: EXMC_BANK0_NORSRAM_REGIONx,x=0..3
  74. write_mode: EXMC_ASYN_WRITE,EXMC_SYN_WRITE
  75. extended_mode: ENABLE or DISABLE
  76. asyn_wait: ENABLE or DISABLE
  77. nwait_signal: ENABLE or DISABLE
  78. memory_write: ENABLE or DISABLE
  79. nwait_config: EXMC_NWAIT_CONFIG_BEFORE,EXMC_NWAIT_CONFIG_DURING
  80. wrap_burst_mode: ENABLE or DISABLE
  81. nwait_polarity: EXMC_NWAIT_POLARITY_LOW,EXMC_NWAIT_POLARITY_HIGH
  82. burst_mode: ENABLE or DISABLE
  83. databus_width: EXMC_NOR_DATABUS_WIDTH_8B,EXMC_NOR_DATABUS_WIDTH_16B
  84. memory_type: EXMC_MEMORY_TYPE_SRAM,EXMC_MEMORY_TYPE_PSRAM,EXMC_MEMORY_TYPE_NOR
  85. address_data_mux: ENABLE or DISABLE
  86. read_write_timing: struct exmc_norsram_timing_parameter_struct set the time
  87. write_timing: struct exmc_norsram_timing_parameter_struct set the time
  88. \param[out] none
  89. \retval none
  90. */
  91. void exmc_norsram_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct)
  92. {
  93. uint32_t snctl = 0x00000000U,sntcfg = 0x00000000U,snwtcfg = 0x00000000U;
  94. /* get the register value */
  95. snctl = EXMC_SNCTL(exmc_norsram_init_struct->norsram_region);
  96. /* clear relative bits */
  97. snctl &= ((uint32_t)~(EXMC_SNCTL_NRMUX | EXMC_SNCTL_NRTP | EXMC_SNCTL_NRW | EXMC_SNCTL_SBRSTEN |
  98. EXMC_SNCTL_NREN | EXMC_SNCTL_NRWTPOL | EXMC_SNCTL_WRAPEN | EXMC_SNCTL_NRWTCFG |
  99. EXMC_SNCTL_WREN | EXMC_SNCTL_NRWTEN | EXMC_SNCTL_EXMODEN | EXMC_SNCTL_ASYNCWAIT |
  100. EXMC_SNCTL_SYNCWR ));
  101. snctl |= (uint32_t)(exmc_norsram_init_struct->address_data_mux << SNCTL_NRMUX_OFFSET) |
  102. exmc_norsram_init_struct->memory_type |
  103. exmc_norsram_init_struct->databus_width |
  104. (exmc_norsram_init_struct->burst_mode << SNCTL_SBRSTEN_OFFSET) |
  105. exmc_norsram_init_struct->nwait_polarity |
  106. (exmc_norsram_init_struct->wrap_burst_mode << SNCTL_WRAPEN_OFFSET) |
  107. exmc_norsram_init_struct->nwait_config |
  108. (exmc_norsram_init_struct->memory_write << SNCTL_WREN_OFFSET) |
  109. (exmc_norsram_init_struct->nwait_signal << SNCTL_NRWTEN_OFFSET) |
  110. (exmc_norsram_init_struct->extended_mode << SNCTL_EXMODEN_OFFSET) |
  111. (exmc_norsram_init_struct->asyn_wait << SNCTL_ASYNCWAIT_OFFSET) |
  112. exmc_norsram_init_struct->write_mode;
  113. sntcfg = (uint32_t)((exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime - 1U ) & EXMC_SNTCFG_ASET )|
  114. (((exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime - 1U ) << SNTCFG_AHLD_OFFSET ) & EXMC_SNTCFG_AHLD ) |
  115. (((exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime - 1U ) << SNTCFG_DSET_OFFSET ) & EXMC_SNTCFG_DSET ) |
  116. (((exmc_norsram_init_struct->read_write_timing->bus_latency - 1U ) << SNTCFG_BUSLAT_OFFSET ) & EXMC_SNTCFG_BUSLAT )|
  117. exmc_norsram_init_struct->read_write_timing->syn_clk_division |
  118. exmc_norsram_init_struct->read_write_timing->syn_data_latency |
  119. exmc_norsram_init_struct->read_write_timing->asyn_access_mode;
  120. /* nor flash access enable */
  121. if(EXMC_MEMORY_TYPE_NOR == exmc_norsram_init_struct->memory_type){
  122. snctl |= (uint32_t)EXMC_SNCTL_NREN;
  123. }
  124. /* extended mode configure */
  125. if(ENABLE == exmc_norsram_init_struct->extended_mode){
  126. snwtcfg = (uint32_t)((exmc_norsram_init_struct->write_timing->asyn_address_setuptime - 1U) & EXMC_SNWTCFG_WASET ) |
  127. (((exmc_norsram_init_struct->write_timing->asyn_address_holdtime -1U ) << SNWTCFG_WAHLD_OFFSET ) & EXMC_SNWTCFG_WAHLD )|
  128. (((exmc_norsram_init_struct->write_timing->asyn_data_setuptime -1U ) << SNWTCFG_WDSET_OFFSET ) & EXMC_SNWTCFG_WDSET )|
  129. (((exmc_norsram_init_struct->write_timing->bus_latency - 1U ) << SNWTCFG_WBUSLAT_OFFSET ) & EXMC_SNWTCFG_WBUSLAT ) |
  130. exmc_norsram_init_struct->write_timing->asyn_access_mode;
  131. }else{
  132. snwtcfg = BANK0_SNWTCFG_RESET;
  133. }
  134. /* configure the registers */
  135. EXMC_SNCTL(exmc_norsram_init_struct->norsram_region) = snctl;
  136. EXMC_SNTCFG(exmc_norsram_init_struct->norsram_region) = sntcfg;
  137. EXMC_SNWTCFG(exmc_norsram_init_struct->norsram_region) = snwtcfg;
  138. }
  139. /*!
  140. \brief initialize the struct exmc_norsram_parameter_struct
  141. \param[in] none
  142. \param[out] exmc_norsram_init_struct: the initialized struct exmc_norsram_parameter_struct pointer
  143. \retval none
  144. */
  145. void exmc_norsram_parameter_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct)
  146. {
  147. /* configure the structure with default value */
  148. exmc_norsram_init_struct->norsram_region = EXMC_BANK0_NORSRAM_REGION0;
  149. exmc_norsram_init_struct->address_data_mux = ENABLE;
  150. exmc_norsram_init_struct->memory_type = EXMC_MEMORY_TYPE_SRAM;
  151. exmc_norsram_init_struct->databus_width = EXMC_NOR_DATABUS_WIDTH_8B;
  152. exmc_norsram_init_struct->burst_mode = DISABLE;
  153. exmc_norsram_init_struct->nwait_polarity = EXMC_NWAIT_POLARITY_LOW;
  154. exmc_norsram_init_struct->wrap_burst_mode = DISABLE;
  155. exmc_norsram_init_struct->nwait_config = EXMC_NWAIT_CONFIG_BEFORE;
  156. exmc_norsram_init_struct->memory_write = ENABLE;
  157. exmc_norsram_init_struct->nwait_signal = ENABLE;
  158. exmc_norsram_init_struct->extended_mode = DISABLE;
  159. exmc_norsram_init_struct->asyn_wait = DISABLE;
  160. exmc_norsram_init_struct->write_mode = EXMC_ASYN_WRITE;
  161. /* read/write timing configure */
  162. exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime = 0xFU;
  163. exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime = 0xFU;
  164. exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime = 0xFFU;
  165. exmc_norsram_init_struct->read_write_timing->bus_latency = 0xFU;
  166. exmc_norsram_init_struct->read_write_timing->syn_clk_division = EXMC_SYN_CLOCK_RATIO_16_CLK;
  167. exmc_norsram_init_struct->read_write_timing->syn_data_latency = EXMC_DATALAT_17_CLK;
  168. exmc_norsram_init_struct->read_write_timing->asyn_access_mode = EXMC_ACCESS_MODE_A;
  169. /* write timing configure, when extended mode is used */
  170. exmc_norsram_init_struct->write_timing->asyn_address_setuptime = 0xFU;
  171. exmc_norsram_init_struct->write_timing->asyn_address_holdtime = 0xFU;
  172. exmc_norsram_init_struct->write_timing->asyn_data_setuptime = 0xFFU;
  173. exmc_norsram_init_struct->write_timing->bus_latency = 0xFU;
  174. exmc_norsram_init_struct->write_timing->asyn_access_mode = EXMC_ACCESS_MODE_A;
  175. }
  176. /*!
  177. \brief CRAM page size configure
  178. \param[in] exmc_norsram_region: specifie the region of NOR/PSRAM bank
  179. \arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3)
  180. \param[in] page_size: CRAM page size
  181. \arg EXMC_CRAM_AUTO_SPLIT: the clock is generated only during synchronous access
  182. \arg EXMC_CRAM_PAGE_SIZE_128_BYTES: page size is 128 bytes
  183. \arg EXMC_CRAM_PAGE_SIZE_256_BYTES: page size is 256 bytes
  184. \arg EXMC_CRAM_PAGE_SIZE_512_BYTES: page size is 512 bytes
  185. \arg EXMC_CRAM_PAGE_SIZE_1024_BYTES: page size is 1024 bytes
  186. \param[out] none
  187. \retval none
  188. */
  189. void exmc_norsram_page_size_config(uint32_t exmc_norsram_region, uint32_t page_size)
  190. {
  191. /* reset the bits */
  192. EXMC_SNCTL(exmc_norsram_region) &= ~EXMC_SNCTL_CPS;
  193. /* set the CPS bits */
  194. EXMC_SNCTL(exmc_norsram_region) |= page_size;
  195. }
  196. /*!
  197. \brief enable EXMC NOR/PSRAM bank region
  198. \param[in] exmc_norsram_region: specifie the region of NOR/PSRAM bank
  199. \arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3)
  200. \param[out] none
  201. \retval none
  202. */
  203. void exmc_norsram_enable(uint32_t exmc_norsram_region)
  204. {
  205. EXMC_SNCTL(exmc_norsram_region) |= (uint32_t)EXMC_SNCTL_NRBKEN;
  206. }
  207. /*!
  208. \brief disable EXMC NOR/PSRAM bank region
  209. \param[in] exmc_norsram_region: specifie the region of NOR/PSRAM Bank
  210. \arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3)
  211. \param[out] none
  212. \retval none
  213. */
  214. void exmc_norsram_disable(uint32_t exmc_norsram_region)
  215. {
  216. EXMC_SNCTL(exmc_norsram_region) &= ~(uint32_t)EXMC_SNCTL_NRBKEN;
  217. }
  218. /*!
  219. \brief deinitialize EXMC NAND bank
  220. \param[in] exmc_nand_bank: select the bank of NAND
  221. \arg EXMC_BANKx_NAND(x=1..2)
  222. \param[out] none
  223. \retval none
  224. */
  225. void exmc_nand_deinit(uint32_t exmc_nand_bank)
  226. {
  227. /* EXMC_BANK1_NAND or EXMC_BANK2_NAND */
  228. EXMC_NPCTL(exmc_nand_bank) = BANK1_2_NPCTL_RESET;
  229. EXMC_NPINTEN(exmc_nand_bank) = BANK1_2_NPINTEN_RESET;
  230. EXMC_NPCTCFG(exmc_nand_bank) = BANK1_2_NPCTCFG_RESET;
  231. EXMC_NPATCFG(exmc_nand_bank) = BANK1_2_NPATCFG_RESET;
  232. }
  233. /*!
  234. \brief initialize EXMC NAND bank
  235. \param[in] exmc_nand_parameter_struct: configure the EXMC NAND parameter
  236. nand_bank: EXMC_BANK1_NAND,EXMC_BANK2_NAND
  237. ecc_size: EXMC_ECC_SIZE_xBYTES,x=256,512,1024,2048,4096
  238. atr_latency: EXMC_ALE_RE_DELAY_x_HCLK,x=1..16
  239. ctr_latency: EXMC_CLE_RE_DELAY_x_HCLK,x=1..16
  240. ecc_logic: ENABLE or DISABLE
  241. databus_width: EXMC_NAND_DATABUS_WIDTH_8B,EXMC_NAND_DATABUS_WIDTH_16B
  242. wait_feature: ENABLE or DISABLE
  243. common_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
  244. attribute_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
  245. \param[out] none
  246. \retval none
  247. */
  248. void exmc_nand_init(exmc_nand_parameter_struct* exmc_nand_init_struct)
  249. {
  250. uint32_t npctl = 0x00000000U, npctcfg = 0x00000000U, npatcfg = 0x00000000U;
  251. npctl = (uint32_t)(exmc_nand_init_struct->wait_feature << NPCTL_NDWTEN_OFFSET)|
  252. EXMC_NPCTL_NDTP |
  253. exmc_nand_init_struct->databus_width |
  254. (exmc_nand_init_struct->ecc_logic << NPCTL_ECCEN_OFFSET)|
  255. exmc_nand_init_struct->ecc_size |
  256. exmc_nand_init_struct->ctr_latency |
  257. exmc_nand_init_struct->atr_latency;
  258. npctcfg = (uint32_t)((exmc_nand_init_struct->common_space_timing->setuptime - 1U) & EXMC_NPCTCFG_COMSET ) |
  259. (((exmc_nand_init_struct->common_space_timing->waittime - 1U) << NPCTCFG_COMWAIT_OFFSET) & EXMC_NPCTCFG_COMWAIT ) |
  260. ((exmc_nand_init_struct->common_space_timing->holdtime << NPCTCFG_COMHLD_OFFSET) & EXMC_NPCTCFG_COMHLD ) |
  261. (((exmc_nand_init_struct->common_space_timing->databus_hiztime - 1U) << NPCTCFG_COMHIZ_OFFSET) & EXMC_NPCTCFG_COMHIZ );
  262. npatcfg = (uint32_t)((exmc_nand_init_struct->attribute_space_timing->setuptime - 1U) & EXMC_NPATCFG_ATTSET ) |
  263. (((exmc_nand_init_struct->attribute_space_timing->waittime - 1U) << NPATCFG_ATTWAIT_OFFSET) & EXMC_NPATCFG_ATTWAIT ) |
  264. ((exmc_nand_init_struct->attribute_space_timing->holdtime << NPATCFG_ATTHLD_OFFSET) & EXMC_NPATCFG_ATTHLD ) |
  265. (((exmc_nand_init_struct->attribute_space_timing->databus_hiztime -1U) << NPATCFG_ATTHIZ_OFFSET) & EXMC_NPATCFG_ATTHIZ );
  266. /* EXMC_BANK1_NAND or EXMC_BANK2_NAND initialize */
  267. EXMC_NPCTL(exmc_nand_init_struct->nand_bank) = npctl;
  268. EXMC_NPCTCFG(exmc_nand_init_struct->nand_bank) = npctcfg;
  269. EXMC_NPATCFG(exmc_nand_init_struct->nand_bank) = npatcfg;
  270. }
  271. /*!
  272. \brief initialize the struct exmc_norsram_parameter_struct
  273. \param[in] none
  274. \param[out] the initialized struct exmc_norsram_parameter_struct pointer
  275. \retval none
  276. */
  277. void exmc_nand_parameter_init(exmc_nand_parameter_struct* exmc_nand_init_struct)
  278. {
  279. /* configure the structure with default value */
  280. exmc_nand_init_struct->nand_bank = EXMC_BANK1_NAND;
  281. exmc_nand_init_struct->wait_feature = DISABLE;
  282. exmc_nand_init_struct->databus_width = EXMC_NAND_DATABUS_WIDTH_8B;
  283. exmc_nand_init_struct->ecc_logic = DISABLE;
  284. exmc_nand_init_struct->ecc_size = EXMC_ECC_SIZE_256BYTES;
  285. exmc_nand_init_struct->ctr_latency = 0x0U;
  286. exmc_nand_init_struct->atr_latency = 0x0U;
  287. exmc_nand_init_struct->common_space_timing->setuptime = 0xfcU;
  288. exmc_nand_init_struct->common_space_timing->waittime = 0xfcU;
  289. exmc_nand_init_struct->common_space_timing->holdtime = 0xfcU;
  290. exmc_nand_init_struct->common_space_timing->databus_hiztime = 0xfcU;
  291. exmc_nand_init_struct->attribute_space_timing->setuptime = 0xfcU;
  292. exmc_nand_init_struct->attribute_space_timing->waittime = 0xfcU;
  293. exmc_nand_init_struct->attribute_space_timing->holdtime = 0xfcU;
  294. exmc_nand_init_struct->attribute_space_timing->databus_hiztime = 0xfcU;
  295. }
  296. /*!
  297. \brief enable NAND bank
  298. \param[in] exmc_nand_bank: specifie the NAND bank
  299. \arg EXMC_BANKx_NAND(x=1,2)
  300. \param[out] none
  301. \retval none
  302. */
  303. void exmc_nand_enable(uint32_t exmc_nand_bank)
  304. {
  305. EXMC_NPCTL(exmc_nand_bank) |= EXMC_NPCTL_NDBKEN;
  306. }
  307. /*!
  308. \brief disable NAND bank
  309. \param[in] exmc_nand_bank: specifie the NAND bank
  310. \arg EXMC_BANKx_NAND(x=1,2)
  311. \param[out] none
  312. \retval none
  313. */
  314. void exmc_nand_disable(uint32_t exmc_nand_bank)
  315. {
  316. EXMC_NPCTL(exmc_nand_bank) &= (~EXMC_NPCTL_NDBKEN);
  317. }
  318. /*!
  319. \brief enable or disable the EXMC NAND ECC function
  320. \param[in] exmc_nand_bank: specifie the NAND bank
  321. \arg EXMC_BANKx_NAND(x=1,2)
  322. \param[in] newvalue: ENABLE or DISABLE
  323. \param[out] none
  324. \retval none
  325. */
  326. void exmc_nand_ecc_config(uint32_t exmc_nand_bank, ControlStatus newvalue)
  327. {
  328. if (ENABLE == newvalue){
  329. /* enable the selected NAND bank ECC function */
  330. EXMC_NPCTL(exmc_nand_bank) |= EXMC_NPCTL_ECCEN;
  331. }else{
  332. /* disable the selected NAND bank ECC function */
  333. EXMC_NPCTL(exmc_nand_bank) &= (~EXMC_NPCTL_ECCEN);
  334. }
  335. }
  336. /*!
  337. \brief get the EXMC ECC value
  338. \param[in] exmc_nand_bank: specifie the NAND bank
  339. \arg EXMC_BANKx_NAND(x=1,2)
  340. \param[out] none
  341. \retval the error correction code(ECC) value
  342. */
  343. uint32_t exmc_ecc_get(uint32_t exmc_nand_bank)
  344. {
  345. return (EXMC_NECC(exmc_nand_bank));
  346. }
  347. /*!
  348. \brief deinitialize EXMC PC card bank
  349. \param[in] none
  350. \param[out] none
  351. \retval none
  352. */
  353. void exmc_pccard_deinit(void)
  354. {
  355. /* EXMC_BANK3_PCCARD */
  356. EXMC_NPCTL3 = BANK3_NPCTL_RESET;
  357. EXMC_NPINTEN3 = BANK3_NPINTEN_RESET;
  358. EXMC_NPCTCFG3 = BANK3_NPCTCFG_RESET;
  359. EXMC_NPATCFG3 = BANK3_NPATCFG_RESET;
  360. EXMC_PIOTCFG3 = BANK3_PIOTCFG3_RESET;
  361. }
  362. /*!
  363. \brief initialize EXMC PC card bank
  364. \param[in] exmc_pccard_parameter_struct: configure the EXMC NAND parameter
  365. atr_latency: EXMC_ALE_RE_DELAY_x_HCLK,x=1..16
  366. ctr_latency: EXMC_CLE_RE_DELAY_x_HCLK,x=1..16
  367. wait_feature: ENABLE or DISABLE
  368. common_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
  369. attribute_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
  370. io_space_timing: exmc_nand_pccard_timing_parameter_struct set the time
  371. \param[out] none
  372. \retval none
  373. */
  374. void exmc_pccard_init(exmc_pccard_parameter_struct* exmc_pccard_init_struct)
  375. {
  376. /* configure the EXMC bank3 PC card control register */
  377. EXMC_NPCTL3 = (uint32_t)(exmc_pccard_init_struct->wait_feature << NPCTL_NDWTEN_OFFSET) |
  378. EXMC_NAND_DATABUS_WIDTH_16B |
  379. exmc_pccard_init_struct->ctr_latency |
  380. exmc_pccard_init_struct->atr_latency ;
  381. /* configure the EXMC bank3 PC card common space timing configuration register */
  382. EXMC_NPCTCFG3 = (uint32_t)((exmc_pccard_init_struct->common_space_timing->setuptime - 1U)& EXMC_NPCTCFG_COMSET ) |
  383. (((exmc_pccard_init_struct->common_space_timing->waittime - 1U) << NPCTCFG_COMWAIT_OFFSET) & EXMC_NPCTCFG_COMWAIT ) |
  384. ((exmc_pccard_init_struct->common_space_timing->holdtime << NPCTCFG_COMHLD_OFFSET) & EXMC_NPCTCFG_COMHLD ) |
  385. (((exmc_pccard_init_struct->common_space_timing->databus_hiztime - 1U) << NPCTCFG_COMHIZ_OFFSET) & EXMC_NPCTCFG_COMHIZ );
  386. /* configure the EXMC bank3 PC card attribute space timing configuration register */
  387. EXMC_NPATCFG3 = (uint32_t)((exmc_pccard_init_struct->attribute_space_timing->setuptime - 1U) & EXMC_NPATCFG_ATTSET ) |
  388. (((exmc_pccard_init_struct->attribute_space_timing->waittime - 1U) << NPATCFG_ATTWAIT_OFFSET) & EXMC_NPATCFG_ATTWAIT ) |
  389. ((exmc_pccard_init_struct->attribute_space_timing->holdtime << NPATCFG_ATTHLD_OFFSET) & EXMC_NPATCFG_ATTHLD )|
  390. (((exmc_pccard_init_struct->attribute_space_timing->databus_hiztime -1U) << NPATCFG_ATTHIZ_OFFSET) & EXMC_NPATCFG_ATTHIZ );
  391. /* configure the EXMC bank3 PC card io space timing configuration register */
  392. EXMC_PIOTCFG3 = (uint32_t)((exmc_pccard_init_struct->io_space_timing->setuptime - 1U) & EXMC_PIOTCFG3_IOSET ) |
  393. (((exmc_pccard_init_struct->io_space_timing->waittime - 1U) << PIOTCFG_IOWAIT_OFFSET) & EXMC_PIOTCFG3_IOWAIT ) |
  394. ((exmc_pccard_init_struct->io_space_timing->holdtime << PIOTCFG_IOHLD_OFFSET) & EXMC_PIOTCFG3_IOHLD )|
  395. ((exmc_pccard_init_struct->io_space_timing->databus_hiztime << PIOTCFG_IOHIZ_OFFSET) & EXMC_PIOTCFG3_IOHIZ );
  396. }
  397. /*!
  398. \brief initialize the struct exmc_pccard_parameter_struct
  399. \param[in] none
  400. \param[out] the initialized struct exmc_pccard_parameter_struct pointer
  401. \retval none
  402. */
  403. void exmc_pccard_parameter_init(exmc_pccard_parameter_struct* exmc_pccard_init_struct)
  404. {
  405. /* configure the structure with default value */
  406. exmc_pccard_init_struct->wait_feature = DISABLE;
  407. exmc_pccard_init_struct->ctr_latency = 0x0U;
  408. exmc_pccard_init_struct->atr_latency = 0x0U;
  409. exmc_pccard_init_struct->common_space_timing->setuptime = 0xFCU;
  410. exmc_pccard_init_struct->common_space_timing->waittime = 0xFCU;
  411. exmc_pccard_init_struct->common_space_timing->holdtime = 0xFCU;
  412. exmc_pccard_init_struct->common_space_timing->databus_hiztime = 0xFCU;
  413. exmc_pccard_init_struct->attribute_space_timing->setuptime = 0xFCU;
  414. exmc_pccard_init_struct->attribute_space_timing->waittime = 0xFCU;
  415. exmc_pccard_init_struct->attribute_space_timing->holdtime = 0xFCU;
  416. exmc_pccard_init_struct->attribute_space_timing->databus_hiztime = 0xFCU;
  417. exmc_pccard_init_struct->io_space_timing->setuptime = 0xFCU;
  418. exmc_pccard_init_struct->io_space_timing->waittime = 0xFCU;
  419. exmc_pccard_init_struct->io_space_timing->holdtime = 0xFCU;
  420. exmc_pccard_init_struct->io_space_timing->databus_hiztime = 0xFCU;
  421. }
  422. /*!
  423. \brief enable PC Card Bank
  424. \param[in] none
  425. \param[out] none
  426. \retval none
  427. */
  428. void exmc_pccard_enable(void)
  429. {
  430. EXMC_NPCTL3 |= EXMC_NPCTL_NDBKEN;
  431. }
  432. /*!
  433. \brief disable PC Card Bank
  434. \param[in] none
  435. \param[out] none
  436. \retval none
  437. */
  438. void exmc_pccard_disable(void)
  439. {
  440. EXMC_NPCTL3 &= (~EXMC_NPCTL_NDBKEN);
  441. }
  442. /*!
  443. \brief check EXMC flag is set or not
  444. \param[in] exmc_bank: specifies the NAND bank , PC card bank
  445. \arg EXMC_BANK1_NAND: the NAND bank1
  446. \arg EXMC_BANK2_NAND: the NAND bank2
  447. \arg EXMC_BANK3_PCCARD: the PC Card bank
  448. \param[in] flag: specify get which flag
  449. \arg EXMC_NAND_PCCARD_FLAG_RISE: interrupt rising edge status
  450. \arg EXMC_NAND_PCCARD_FLAG_LEVEL: interrupt high-level status
  451. \arg EXMC_NAND_PCCARD_FLAG_FALL: interrupt falling edge status
  452. \arg EXMC_NAND_PCCARD_FLAG_FIFOE: FIFO empty flag
  453. \param[out] none
  454. \retval FlagStatus: SET or RESET
  455. */
  456. FlagStatus exmc_flag_get(uint32_t exmc_bank,uint32_t flag)
  457. {
  458. uint32_t status = 0x00000000U;
  459. /* NAND bank1,bank2 or PC card bank3 */
  460. status = EXMC_NPINTEN(exmc_bank);
  461. if ((status & flag) != (uint32_t)flag ){
  462. /* flag is reset */
  463. return RESET;
  464. }else{
  465. /* flag is set */
  466. return SET;
  467. }
  468. }
  469. /*!
  470. \brief clear EXMC flag
  471. \param[in] exmc_bank: specifie the NAND bank , PCCARD bank
  472. \arg EXMC_BANK1_NAND: the NAND bank1
  473. \arg EXMC_BANK2_NAND: the NAND bank2
  474. \arg EXMC_BANK3_PCCARD: the PC card bank
  475. \param[in] flag: specify get which flag
  476. \arg EXMC_NAND_PCCARD_FLAG_RISE: interrupt rising edge status
  477. \arg EXMC_NAND_PCCARD_FLAG_LEVEL: interrupt high-level status
  478. \arg EXMC_NAND_PCCARD_FLAG_FALL: interrupt falling edge status
  479. \arg EXMC_NAND_PCCARD_FLAG_FIFOE: FIFO empty flag
  480. \param[out] none
  481. \retval none
  482. */
  483. void exmc_flag_clear(uint32_t exmc_bank,uint32_t flag)
  484. {
  485. /* NAND bank1,bank2 or PC card bank3 */
  486. EXMC_NPINTEN(exmc_bank) &= (~flag);
  487. }
  488. /*!
  489. \brief check EXMC interrupt flag is set or not
  490. \param[in] exmc_bank: specifies the NAND bank , PC card bank
  491. \arg EXMC_BANK1_NAND: the NAND bank1
  492. \arg EXMC_BANK2_NAND: the NAND bank2
  493. \arg EXMC_BANK3_PCCARD: the PC card bank
  494. \param[in] interrupt_source: specify get which interrupt flag
  495. \arg EXMC_NAND_PCCARD_INT_FLAG_RISE: interrupt source of rising edge
  496. \arg EXMC_NAND_PCCARD_INT_FLAG_LEVEL: interrupt source of high-level
  497. \arg EXMC_NAND_PCCARD_INT_FLAG_FALL: interrupt source of falling edge
  498. \param[out] none
  499. \retval FlagStatus: SET or RESET
  500. */
  501. FlagStatus exmc_interrupt_flag_get(uint32_t exmc_bank,uint32_t interrupt_source)
  502. {
  503. uint32_t status = 0x00000000U,interrupt_enable = 0x00000000U,interrupt_state = 0x00000000U;
  504. /* NAND bank1,bank2 or PC card bank3 */
  505. status = EXMC_NPINTEN(exmc_bank);
  506. interrupt_state = (status & (interrupt_source >> INTEN_INTS_OFFSET));
  507. interrupt_enable = (status & interrupt_source);
  508. if ((interrupt_enable) && (interrupt_state)){
  509. /* interrupt flag is set */
  510. return SET;
  511. }else{
  512. /* interrupt flag is reset */
  513. return RESET;
  514. }
  515. }
  516. /*!
  517. \brief clear EXMC interrupt flag
  518. \param[in] exmc_bank: specifies the NAND bank , PC card bank
  519. \arg EXMC_BANK1_NAND: the NAND bank1
  520. \arg EXMC_BANK2_NAND: the NAND bank2
  521. \arg EXMC_BANK3_PCCARD: the PC card bank
  522. \param[in] interrupt_source: specify get which interrupt flag
  523. \arg EXMC_NAND_PCCARD_INT_FLAG_RISE: interrupt source of rising edge
  524. \arg EXMC_NAND_PCCARD_INT_FLAG_LEVEL: interrupt source of high-level
  525. \arg EXMC_NAND_PCCARD_INT_FLAG_FALL: interrupt source of falling edge
  526. \param[out] none
  527. \retval none
  528. */
  529. void exmc_interrupt_flag_clear(uint32_t exmc_bank,uint32_t interrupt_source)
  530. {
  531. /* NAND bank1,bank2 or PC card bank3 */
  532. EXMC_NPINTEN(exmc_bank) &= ~(interrupt_source >> INTEN_INTS_OFFSET);
  533. }
  534. /*!
  535. \brief enable EXMC interrupt
  536. \param[in] exmc_bank: specifies the NAND bank,PC card bank
  537. \arg EXMC_BANK1_NAND: the NAND bank1
  538. \arg EXMC_BANK2_NAND: the NAND bank2
  539. \arg EXMC_BANK3_PCCARD: the PC card bank
  540. \param[in] interrupt_source: specify get which interrupt flag
  541. \arg EXMC_NAND_PCCARD_INT_RISE: interrupt source of rising edge
  542. \arg EXMC_NAND_PCCARD_INT_LEVEL: interrupt source of high-level
  543. \arg EXMC_NAND_PCCARD_INT_FALL: interrupt source of falling edge
  544. \param[out] none
  545. \retval none
  546. */
  547. void exmc_interrupt_enable(uint32_t exmc_bank,uint32_t interrupt_source)
  548. {
  549. /* NAND bank1,bank2 or PC card bank3 */
  550. EXMC_NPINTEN(exmc_bank) |= interrupt_source;
  551. }
  552. /*!
  553. \brief disable EXMC interrupt
  554. \param[in] exmc_bank: specifies the NAND bank , PC card bank
  555. \arg EXMC_BANK1_NAND: the NAND bank1
  556. \arg EXMC_BANK2_NAND: the NAND bank2
  557. \arg EXMC_BANK3_PCCARD: the PC card bank
  558. \param[in] interrupt_source: specify get which interrupt flag
  559. \arg EXMC_NAND_PCCARD_INT_RISE: interrupt source of rising edge
  560. \arg EXMC_NAND_PCCARD_INT_LEVEL: interrupt source of high-level
  561. \arg EXMC_NAND_PCCARD_INT_FALL: interrupt source of falling edge
  562. \param[out] none
  563. \retval none
  564. */
  565. void exmc_interrupt_disable(uint32_t exmc_bank,uint32_t interrupt_source)
  566. {
  567. /* NAND bank1,bank2 or PC card bank3 */
  568. EXMC_NPINTEN(exmc_bank) &= (~interrupt_source);
  569. }