dma.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /**************************************************************************************************
  2. Phyplus Microelectronics Limited confidential and proprietary.
  3. All rights reserved.
  4. IMPORTANT: All rights of this software belong to Phyplus Microelectronics
  5. Limited ("Phyplus"). Your use of this Software is limited to those
  6. specific rights granted under the terms of the business contract, the
  7. confidential agreement, the non-disclosure agreement and any other forms
  8. of agreements as a customer or a partner of Phyplus. You may not use this
  9. Software unless you agree to abide by the terms of these agreements.
  10. You acknowledge that the Software may not be modified, copied,
  11. distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy
  12. (BLE) integrated circuit, either as a product or is integrated into your
  13. products. Other than for the aforementioned purposes, you may not use,
  14. reproduce, copy, prepare derivative works of, modify, distribute, perform,
  15. display or sell this Software and/or its documentation for any purposes.
  16. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  17. PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  18. INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
  19. NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
  20. PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT,
  21. NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
  22. LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
  23. INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
  24. OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
  25. OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
  26. (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
  27. **************************************************************************************************/
  28. #include <string.h>
  29. #include "ap_cp.h"
  30. #include "clock.h"
  31. #include "pwrmgr.h"
  32. #include "error.h"
  33. #include "log.h"
  34. #include "dma.h"
  35. typedef struct{
  36. bool init_flg;
  37. }dma_ctx_t;
  38. const static AP_DMACH_TypeDef* spDMACh[8] = {
  39. AP_DMACH0, // GPDMA Channel 0
  40. AP_DMACH1, // GPDMA Channel 1
  41. AP_DMACH2, // GPDMA Channel 2
  42. AP_DMACH3, // GPDMA Channel 3
  43. AP_DMACH4, // GPDMA Channel 4
  44. AP_DMACH5, // GPDMA Channel 5
  45. AP_DMACH6, // GPDMA Channel 6
  46. AP_DMACH7, // GPDMA Channel 7
  47. };
  48. dma_ctx_t s_dma_ctx = {
  49. .init_flg = FALSE,
  50. };
  51. /**
  52. * @brief Optimized Peripheral Source and Destination burst size
  53. */
  54. const uint8_t DMA_LUTPerBurst[] = {
  55. DMA_BSIZE_1, // Memory
  56. DMA_BSIZE_32, // SD Card
  57. DMA_BSIZE_4, // SSP0 Tx
  58. DMA_BSIZE_4, // SSP0 Rx
  59. DMA_BSIZE_4, // SSP1 Tx
  60. DMA_BSIZE_4, // SSP1 Rx
  61. DMA_BSIZE_4, // SSP2 Tx
  62. DMA_BSIZE_4, // SSP2 Rx
  63. DMA_BSIZE_4, // ADC
  64. DMA_BSIZE_1, // DAC
  65. DMA_BSIZE_1, // UART0 Tx
  66. DMA_BSIZE_1, // UART0 Rx
  67. DMA_BSIZE_1, // UART1 Tx
  68. DMA_BSIZE_1, // UART1 Rx
  69. DMA_BSIZE_1, // UART2 Tx
  70. DMA_BSIZE_1, // UART2 Rx
  71. DMA_BSIZE_1, // MAT0.0
  72. DMA_BSIZE_1, // MAT0.1
  73. DMA_BSIZE_1, // MAT1.0
  74. DMA_BSIZE_1, // MAT1.1
  75. DMA_BSIZE_1, // MAT2.0
  76. DMA_BSIZE_1, // MAT2.1
  77. DMA_BSIZE_32, // I2S channel 0
  78. DMA_BSIZE_32, // I2S channel 1
  79. 0, // Reserved
  80. 0, // Reserved
  81. DMA_BSIZE_1, // UART3 Tx
  82. DMA_BSIZE_1, // UART3 Rx
  83. DMA_BSIZE_1, // UART4 Tx
  84. DMA_BSIZE_1, // UART4 Rx
  85. DMA_BSIZE_1, // MAT3.0
  86. DMA_BSIZE_1, // MAT3.1
  87. };
  88. /**
  89. * @brief Optimized Peripheral Source and Destination transfer width
  90. */
  91. const uint8_t DMA_LUTPerWid[] = {
  92. DMA_WIDTH_WORD, // memory
  93. DMA_WIDTH_WORD, // SD Card
  94. DMA_WIDTH_BYTE, // SSP0 Tx
  95. DMA_WIDTH_BYTE, // SSP0 Rx
  96. DMA_WIDTH_BYTE, // SSP1 Tx
  97. DMA_WIDTH_BYTE, // SSP1 Rx
  98. DMA_WIDTH_BYTE, // SSP2 Tx
  99. DMA_WIDTH_BYTE, // SSP2 Rx
  100. DMA_WIDTH_WORD, // ADC
  101. DMA_WIDTH_BYTE, // DAC
  102. DMA_WIDTH_BYTE, // UART0 Tx
  103. DMA_WIDTH_BYTE, // UART0 Rx
  104. DMA_WIDTH_BYTE, // UART1 Tx
  105. DMA_WIDTH_BYTE, // UART1 Rx
  106. DMA_WIDTH_BYTE, // UART2 Tx
  107. DMA_WIDTH_BYTE, // UART2 Rx
  108. DMA_WIDTH_WORD, // MAT0.0
  109. DMA_WIDTH_WORD, // MAT0.1
  110. DMA_WIDTH_WORD, // MAT1.0
  111. DMA_WIDTH_WORD, // MAT1.1
  112. DMA_WIDTH_WORD, // MAT2.0
  113. DMA_WIDTH_WORD, // MAT2.1
  114. DMA_WIDTH_WORD, // I2S channel 0
  115. DMA_WIDTH_WORD, // I2S channel 1
  116. 0, // Reserved
  117. 0, // Reserved
  118. DMA_WIDTH_BYTE, // UART3 Tx
  119. DMA_WIDTH_BYTE, // UART3 Rx
  120. DMA_WIDTH_BYTE, // UART4 Tx
  121. DMA_WIDTH_BYTE, // UART4 Rx
  122. DMA_WIDTH_WORD, // MAT3.0
  123. DMA_WIDTH_WORD, // MAT3.1
  124. };
  125. int dma_config_channel(dma_ch_t ch, dma_ch_cfg_t* cfg)
  126. {
  127. AP_DMACH_TypeDef *pdma;
  128. uint32_t cctrl = 0;
  129. uint32_t transf_type = DMA_TRANSFERTYPE_M2M;
  130. uint32_t src_bsize = DMA_BSIZE_1;
  131. uint32_t dst_bsize = DMA_BSIZE_1;
  132. uint32_t src_wide = DMA_WIDTH_WORD;
  133. uint32_t dst_wide = DMA_WIDTH_WORD;
  134. if(!s_dma_ctx.init_flg)
  135. return PPlus_ERR_NOT_REGISTED;
  136. clk_gate_enable(MOD_DMA);
  137. if (AP_DMA->EnbldChns & (DMA_DMACEnbldChns_Ch(ch))) {
  138. // This channel is enabled, return ERROR, need to release this channel first
  139. return PPlus_ERR_BUSY;
  140. }
  141. // Get Channel
  142. pdma = (AP_DMACH_TypeDef *) spDMACh[ch];
  143. // Reset the Interrupt status
  144. AP_DMA->IntTCClear = DMA_DMACIntTCClear_Ch(ch);
  145. AP_DMA->IntErrClr = DMA_DMACIntErrClr_Ch(ch);
  146. // Clear DMA configure
  147. pdma->CControl = 0x00;
  148. pdma->CConfig = 0x00;
  149. /* Assign Linker List Item value */
  150. pdma->CLLI = cfg->lli;
  151. if(cfg->src_conn && cfg->dst_conn){
  152. transf_type = DMA_TRANSFERTYPE_P2P;
  153. src_bsize = DMA_LUTPerBurst[cfg->src_conn];
  154. dst_bsize = DMA_LUTPerBurst[cfg->dst_conn];
  155. src_wide = DMA_LUTPerWid[cfg->src_conn];
  156. dst_wide = DMA_LUTPerWid[cfg->dst_conn];
  157. }
  158. else if(cfg->src_conn){
  159. transf_type = DMA_TRANSFERTYPE_P2M;
  160. src_bsize = DMA_LUTPerBurst[cfg->src_conn];
  161. src_wide = DMA_LUTPerWid[cfg->src_conn];
  162. }
  163. else if(cfg->dst_conn){
  164. transf_type = DMA_TRANSFERTYPE_M2P;
  165. dst_bsize = DMA_LUTPerBurst[cfg->dst_conn];
  166. dst_wide = DMA_LUTPerWid[cfg->dst_conn];
  167. }
  168. pdma->CSrcAddr = cfg->src_addr;
  169. pdma->CDestAddr = cfg->dst_addr;
  170. //pdma->CControl = 0x8c480005;//DMA_DMACCxControl_TransferSize(cfg->transf_size)|
  171. cctrl = DMA_DMACCxControl_TransferSize(cfg->transf_size)| \
  172. DMA_DMACCxControl_SBSize(src_bsize)| \
  173. DMA_DMACCxControl_DBSize(dst_bsize)| \
  174. DMA_DMACCxControl_SWidth(src_wide)| \
  175. DMA_DMACCxControl_DWidth(dst_wide);
  176. if(cfg->di)
  177. cctrl |= DMA_DMACCxControl_DI;
  178. if(cfg->si)
  179. cctrl |= DMA_DMACCxControl_SI;
  180. if(cfg->enable_int)
  181. cctrl |= DMA_DMACCxControl_I;
  182. pdma->CControl = cctrl;
  183. /* Enable DMA channels, little endian */
  184. AP_DMA->Config = DMA_DMACConfig_E;
  185. while (!(AP_DMA->Config & DMA_DMACConfig_E));
  186. // Configure DMA Channel, enable Error Counter and Terminate counter
  187. //pdma->CConfig = DMA_DMACCxConfig_IE | DMA_DMACCxConfig_ITC|DMA_DMACCxConfig_TransferType(transf_type)
  188. pdma->CConfig = DMA_DMACCxConfig_TransferType(transf_type)| \
  189. DMA_DMACCxConfig_SrcPeripheral(cfg->src_conn)| \
  190. DMA_DMACCxConfig_DestPeripheral(cfg->dst_conn);
  191. if(cfg->enable_int)
  192. pdma->CConfig |= DMA_DMACCxConfig_IE | DMA_DMACCxConfig_ITC;
  193. return PPlus_SUCCESS;
  194. }
  195. int dma_start_channel(dma_ch_t ch, bool enable)
  196. {
  197. AP_DMACH_TypeDef *pDMAch;
  198. if(!s_dma_ctx.init_flg)
  199. return PPlus_ERR_NOT_REGISTED;
  200. // Get Channel pointer
  201. pDMAch = (AP_DMACH_TypeDef *) spDMACh[ch];
  202. if(enable){
  203. pDMAch->CConfig |= DMA_DMACCxConfig_E;
  204. } else {
  205. pDMAch->CConfig &= ~DMA_DMACCxConfig_E;
  206. }
  207. return PPlus_SUCCESS;
  208. }
  209. int dma_wait_channel_complete(dma_ch_t ch)
  210. {
  211. if(!s_dma_ctx.init_flg)
  212. return PPlus_ERR_NOT_REGISTED;
  213. return PPlus_SUCCESS;
  214. }
  215. int dma_init(void)
  216. {
  217. s_dma_ctx.init_flg = TRUE;
  218. return PPlus_SUCCESS;
  219. }