nu_pdma.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. /**************************************************************************//**
  2. * @file pdma.c
  3. * @brief PDMA driver source file
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. * @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
  7. *****************************************************************************/
  8. #include "nuc980.h"
  9. #include "nu_pdma.h"
  10. /** @addtogroup Standard_Driver Standard Driver
  11. @{
  12. */
  13. /** @addtogroup PDMA_Driver PDMA Driver
  14. @{
  15. */
  16. /** @addtogroup PDMA_EXPORTED_FUNCTIONS PDMA Exported Functions
  17. @{
  18. */
  19. /**
  20. * @brief PDMA Open
  21. *
  22. * @param[in] pdma The pointer of the specified PDMA module
  23. *
  24. * @param[in] u32Mask Channel enable bits.
  25. *
  26. * @return None
  27. *
  28. * @details This function enable the PDMA channels.
  29. */
  30. void PDMA_Open(PDMA_T *pdma, uint32_t u32Mask)
  31. {
  32. uint32_t i;
  33. for (i = 0UL; i < PDMA_CH_MAX; i++)
  34. {
  35. if ((1 << i) & u32Mask)
  36. {
  37. pdma->DSCT[i].CTL = 0UL;
  38. }
  39. }
  40. pdma->CHCTL |= u32Mask;
  41. }
  42. /**
  43. * @brief PDMA Close
  44. *
  45. * @param[in] pdma The pointer of the specified PDMA module
  46. *
  47. * @return None
  48. *
  49. * @details This function disable all PDMA channels.
  50. */
  51. void PDMA_Close(PDMA_T *pdma)
  52. {
  53. pdma->CHCTL = 0UL;
  54. }
  55. /**
  56. * @brief Set PDMA Transfer Count
  57. *
  58. * @param[in] pdma The pointer of the specified PDMA module
  59. * @param[in] u32Ch The selected channel
  60. * @param[in] u32Width Data width. Valid values are
  61. * - \ref PDMA_WIDTH_8
  62. * - \ref PDMA_WIDTH_16
  63. * - \ref PDMA_WIDTH_32
  64. * @param[in] u32TransCount Transfer count
  65. *
  66. * @return None
  67. *
  68. * @details This function set the selected channel data width and transfer count.
  69. */
  70. void PDMA_SetTransferCnt(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Width, uint32_t u32TransCount)
  71. {
  72. pdma->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_TXCNT_Msk | PDMA_DSCT_CTL_TXWIDTH_Msk);
  73. pdma->DSCT[u32Ch].CTL |= (u32Width | ((u32TransCount - 1UL) << PDMA_DSCT_CTL_TXCNT_Pos));
  74. }
  75. /**
  76. * @brief Set PDMA Stride Mode
  77. *
  78. * @param[in] pdma The pointer of the specified PDMA module
  79. * @param[in] u32Ch The selected channel
  80. * @param[in] u32DestLen Destination stride count
  81. * @param[in] u32SrcLen Source stride count
  82. * @param[in] u32TransCount Transfer count
  83. *
  84. * @return None
  85. *
  86. * @details This function set the selected stride mode.
  87. */
  88. void PDMA_SetStride(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32DestLen, uint32_t u32SrcLen, uint32_t u32TransCount)
  89. {
  90. pdma->DSCT[u32Ch].CTL |= PDMA_DSCT_CTL_STRIDEEN_Msk;
  91. pdma->STRIDE[u32Ch].ASOCR = (u32DestLen << 16) | u32SrcLen;
  92. pdma->STRIDE[u32Ch].STCR = u32TransCount;
  93. }
  94. /**
  95. * @brief Set PDMA Transfer Address
  96. *
  97. * @param[in] pdma The pointer of the specified PDMA module
  98. * @param[in] u32Ch The selected channel
  99. * @param[in] u32SrcAddr Source address
  100. * @param[in] u32SrcCtrl Source control attribute. Valid values are
  101. * - \ref PDMA_SAR_INC
  102. * - \ref PDMA_SAR_FIX
  103. * @param[in] u32DstAddr destination address
  104. * @param[in] u32DstCtrl destination control attribute. Valid values are
  105. * - \ref PDMA_DAR_INC
  106. * - \ref PDMA_DAR_FIX
  107. *
  108. * @return None
  109. *
  110. * @details This function set the selected channel source/destination address and attribute.
  111. */
  112. void PDMA_SetTransferAddr(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32SrcAddr, uint32_t u32SrcCtrl, uint32_t u32DstAddr, uint32_t u32DstCtrl)
  113. {
  114. pdma->DSCT[u32Ch].SA = u32SrcAddr;
  115. pdma->DSCT[u32Ch].DA = u32DstAddr;
  116. pdma->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_SAINC_Msk | PDMA_DSCT_CTL_DAINC_Msk);
  117. pdma->DSCT[u32Ch].CTL |= (u32SrcCtrl | u32DstCtrl);
  118. }
  119. /**
  120. * @brief Set PDMA Transfer Mode
  121. *
  122. * @param[in] pdma The pointer of the specified PDMA module
  123. * @param[in] u32Ch The selected channel
  124. * @param[in] u32Peripheral The selected peripheral. Valid values are
  125. * - \ref PDMA_MEM
  126. * - \ref PDMA_UART0_TX
  127. * - \ref PDMA_UART0_RX
  128. * - \ref PDMA_UART1_TX
  129. * - \ref PDMA_UART1_RX
  130. * - \ref PDMA_UART2_TX
  131. * - \ref PDMA_UART2_RX
  132. * - \ref PDMA_UART3_TX
  133. * - \ref PDMA_UART3_RX
  134. * - \ref PDMA_UART4_TX
  135. * - \ref PDMA_UART4_RX
  136. * - \ref PDMA_UART5_TX
  137. * - \ref PDMA_UART5_RX
  138. * - \ref PDMA_UART6_TX
  139. * - \ref PDMA_UART6_RX
  140. * - \ref PDMA_UART7_TX
  141. * - \ref PDMA_UART7_RX
  142. * - \ref PDMA_QSPI0_TX
  143. * - \ref PDMA_QSPI0_RX
  144. * - \ref PDMA_SPI0_TX
  145. * - \ref PDMA_SPI0_RX
  146. * - \ref PDMA_SPI1_TX
  147. * - \ref PDMA_SPI1_RX
  148. * - \ref PDMA_UART8_TX
  149. * - \ref PDMA_UART8_RX
  150. * - \ref PDMA_UART9_TX
  151. * - \ref PDMA_UART9_RX
  152. * - \ref PDMA_I2C0_TX
  153. * - \ref PDMA_I2C0_RX
  154. * - \ref PDMA_I2C1_TX
  155. * - \ref PDMA_I2C1_RX
  156. * - \ref PDMA_I2C2_TX
  157. * - \ref PDMA_I2C2_RX
  158. * - \ref PDMA_I2C3_TX
  159. * - \ref PDMA_I2C3_RX
  160. * - \ref PDMA_TIMER0
  161. * - \ref PDMA_TIMER1
  162. * - \ref PDMA_TIMER2
  163. * - \ref PDMA_TIMER3
  164. * - \ref PDMA_TIMER4
  165. * - \ref PDMA_TIMER5
  166. * @param[in] u32ScatterEn Scatter-gather mode enable
  167. * @param[in] u32DescAddr Scatter-gather descriptor address
  168. *
  169. * @return None
  170. *
  171. * @details This function set the selected channel transfer mode. Include peripheral setting.
  172. */
  173. void PDMA_SetTransferMode(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Peripheral, uint32_t u32ScatterEn, uint32_t u32DescAddr)
  174. {
  175. if (u32Ch < PDMA_CH_MAX)
  176. {
  177. __IO uint32_t *pau32REQSEL = (__IO uint32_t *)&pdma->REQSEL0_3;
  178. uint32_t u32REQSEL_Pos, u32REQSEL_Msk;
  179. u32REQSEL_Pos = (u32Ch % 4) * 8 ;
  180. u32REQSEL_Msk = PDMA_REQSEL0_3_REQSRC0_Msk << u32REQSEL_Pos;
  181. pau32REQSEL[u32Ch / 4] = (pau32REQSEL[u32Ch / 4] & ~u32REQSEL_Msk) | (u32Peripheral << u32REQSEL_Pos);
  182. if (u32ScatterEn)
  183. {
  184. pdma->DSCT[u32Ch].CTL = (pdma->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_SCATTER;
  185. pdma->DSCT[u32Ch].NEXT = u32DescAddr - (pdma->SCATBA);
  186. }
  187. else
  188. {
  189. pdma->DSCT[u32Ch].CTL = (pdma->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_BASIC;
  190. }
  191. }
  192. else {}
  193. }
  194. /**
  195. * @brief Set PDMA Burst Type and Size
  196. *
  197. * @param[in] pdma The pointer of the specified PDMA module
  198. * @param[in] u32Ch The selected channel
  199. * @param[in] u32BurstType Burst mode or single mode. Valid values are
  200. * - \ref PDMA_REQ_SINGLE
  201. * - \ref PDMA_REQ_BURST
  202. * @param[in] u32BurstSize Set the size of burst mode. Valid values are
  203. * - \ref PDMA_BURST_128
  204. * - \ref PDMA_BURST_64
  205. * - \ref PDMA_BURST_32
  206. * - \ref PDMA_BURST_16
  207. * - \ref PDMA_BURST_8
  208. * - \ref PDMA_BURST_4
  209. * - \ref PDMA_BURST_2
  210. * - \ref PDMA_BURST_1
  211. *
  212. * @return None
  213. *
  214. * @details This function set the selected channel burst type and size.
  215. */
  216. void PDMA_SetBurstType(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32BurstType, uint32_t u32BurstSize)
  217. {
  218. pdma->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_TXTYPE_Msk | PDMA_DSCT_CTL_BURSIZE_Msk);
  219. pdma->DSCT[u32Ch].CTL |= (u32BurstType | u32BurstSize);
  220. }
  221. /**
  222. * @brief Enable timeout function
  223. *
  224. * @param[in] pdma The pointer of the specified PDMA module
  225. *
  226. * @param[in] u32Mask Channel enable bits.
  227. *
  228. * @return None
  229. *
  230. * @details This function enable timeout function of the selected channel(s).
  231. */
  232. void PDMA_EnableTimeout(PDMA_T *pdma, uint32_t u32Mask)
  233. {
  234. pdma->TOUTEN |= u32Mask;
  235. }
  236. /**
  237. * @brief Disable timeout function
  238. *
  239. * @param[in] pdma The pointer of the specified PDMA module
  240. *
  241. * @param[in] u32Mask Channel enable bits.
  242. *
  243. * @return None
  244. *
  245. * @details This function disable timeout function of the selected channel(s).
  246. */
  247. void PDMA_DisableTimeout(PDMA_T *pdma, uint32_t u32Mask)
  248. {
  249. pdma->TOUTEN &= ~u32Mask;
  250. }
  251. /**
  252. * @brief Set PDMA Timeout Count
  253. *
  254. * @param[in] pdma The pointer of the specified PDMA module
  255. * @param[in] u32Ch The selected channel,
  256. * @param[in] u32OnOff Enable/disable time out function
  257. * @param[in] u32TimeOutCnt Timeout count
  258. *
  259. * @return None
  260. *
  261. * @details This function set the timeout count.
  262. */
  263. void PDMA_SetTimeOut(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32OnOff, uint32_t u32TimeOutCnt)
  264. {
  265. if (u32Ch < PDMA_CH_MAX)
  266. {
  267. __IO uint32_t *pau32TOC = (__IO uint32_t *)&pdma->TOC0_1;
  268. uint32_t u32TOC_Pos, u32TOC_Msk;
  269. u32TOC_Pos = (u32Ch % 2) * 16 ;
  270. u32TOC_Msk = PDMA_TOC0_1_TOC0_Msk << u32TOC_Pos;
  271. pau32TOC[u32Ch / 2] = (pau32TOC[u32Ch / 2] & ~u32TOC_Msk) | (u32TimeOutCnt << u32TOC_Pos);
  272. if (u32OnOff)
  273. pdma->TOUTEN |= (1 << u32Ch);
  274. else
  275. pdma->TOUTEN &= ~(1 << u32Ch);
  276. }
  277. else {}
  278. }
  279. /**
  280. * @brief Trigger PDMA
  281. *
  282. * @param[in] pdma The pointer of the specified PDMA module
  283. * @param[in] u32Ch The selected channel
  284. *
  285. * @return None
  286. *
  287. * @details This function trigger the selected channel.
  288. */
  289. void PDMA_Trigger(PDMA_T *pdma, uint32_t u32Ch)
  290. {
  291. __IO uint32_t *pau32REQSEL = (__IO uint32_t *)&pdma->REQSEL0_3;
  292. uint32_t u32REQSEL_Pos, u32REQSEL_Msk, u32ChReq;
  293. u32REQSEL_Pos = (u32Ch % 4) * 8 ;
  294. u32REQSEL_Msk = PDMA_REQSEL0_3_REQSRC0_Msk << u32REQSEL_Pos;
  295. u32ChReq = (pau32REQSEL[u32Ch / 4] & u32REQSEL_Msk) >> u32REQSEL_Pos;
  296. if (u32ChReq == PDMA_MEM)
  297. {
  298. pdma->SWREQ = (1ul << u32Ch);
  299. }
  300. else {}
  301. }
  302. /**
  303. * @brief Enable Interrupt
  304. *
  305. * @param[in] pdma The pointer of the specified PDMA module
  306. * @param[in] u32Ch The selected channel
  307. * @param[in] u32Mask The Interrupt Type. Valid values are
  308. * - \ref PDMA_INT_TRANS_DONE
  309. * - \ref PDMA_INT_TEMPTY
  310. * - \ref PDMA_INT_TIMEOUT
  311. *
  312. * @return None
  313. *
  314. * @details This function enable the selected channel interrupt.
  315. */
  316. void PDMA_EnableInt(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Mask)
  317. {
  318. switch (u32Mask)
  319. {
  320. case PDMA_INT_TRANS_DONE:
  321. pdma->INTEN |= (1ul << u32Ch);
  322. break;
  323. case PDMA_INT_TEMPTY:
  324. pdma->DSCT[u32Ch].CTL &= ~PDMA_DSCT_CTL_TBINTDIS_Msk;
  325. break;
  326. case PDMA_INT_TIMEOUT:
  327. pdma->TOUTIEN |= (1ul << u32Ch);
  328. break;
  329. default:
  330. break;
  331. }
  332. }
  333. /**
  334. * @brief Disable Interrupt
  335. *
  336. * @param[in] pdma The pointer of the specified PDMA module
  337. * @param[in] u32Ch The selected channel
  338. * @param[in] u32Mask The Interrupt Type. Valid values are
  339. * - \ref PDMA_INT_TRANS_DONE
  340. * - \ref PDMA_INT_TEMPTY
  341. * - \ref PDMA_INT_TIMEOUT
  342. *
  343. * @return None
  344. *
  345. * @details This function disable the selected channel interrupt.
  346. */
  347. void PDMA_DisableInt(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Mask)
  348. {
  349. switch (u32Mask)
  350. {
  351. case PDMA_INT_TRANS_DONE:
  352. pdma->INTEN &= ~(1ul << u32Ch);
  353. break;
  354. case PDMA_INT_TEMPTY:
  355. pdma->DSCT[u32Ch].CTL |= PDMA_DSCT_CTL_TBINTDIS_Msk;
  356. break;
  357. case PDMA_INT_TIMEOUT:
  358. pdma->TOUTIEN &= ~(1ul << u32Ch);
  359. break;
  360. default:
  361. break;
  362. }
  363. }
  364. /*@}*/ /* end of group PDMA_EXPORTED_FUNCTIONS */
  365. /*@}*/ /* end of group PDMA_Driver */
  366. /*@}*/ /* end of group Standard_Driver */