core_dma.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. /*
  2. * Copyright (c) 2022 OpenLuat & AirM2M
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  5. * this software and associated documentation files (the "Software"), to deal in
  6. * the Software without restriction, including without limitation the rights to
  7. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  8. * the Software, and to permit persons to whom the Software is furnished to do so,
  9. * subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in all
  12. * copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  16. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  17. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  18. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  20. */
  21. #include "user.h"
  22. //#define __MUTLI_BLOCKS__
  23. typedef struct
  24. {
  25. const DMA_TypeDef *RegBase;
  26. const uint32_t Index;
  27. CBFuncEx_t CB;
  28. void *pData;
  29. #ifdef __MUTLI_BLOCKS__
  30. LLI *Linklist;
  31. #endif
  32. uint8_t TxDir;
  33. }DMAChannal_struct;
  34. /************ operation definition for DMA DMA_CTL_H REGISTER ************/
  35. #define DMA_CTL_BLOCK_TS_Pos (0)
  36. #define DMA_CTL_BLOCK_TS_Mask (0x0fffU<<DMA_CTL_BLOCK_TS_Pos)
  37. /************ operation definition for DMA DMA_CTL_L REGISTER ************/
  38. #define DMA_CTL_TT_FC_Pos (20)
  39. #define DMA_CTL_TT_FC_Mask (0x07U<<DMA_CTL_TT_FC_Pos)
  40. #define DMA_CTL_TT_FC_Memory_to_Memory_Set (0x00U<<DMA_CTL_TT_FC_Pos)
  41. #define DMA_CTL_TT_FC_Memory_to_Peripheral_Set (0x01U<<DMA_CTL_TT_FC_Pos)
  42. #define DMA_CTL_TT_FC_Peripheral_to_Memory_Set (0x02U<<DMA_CTL_TT_FC_Pos)
  43. #define DMA_CTL_TT_FC_Peripheral_to_Memory_P_Set (0x04U<<DMA_CTL_TT_FC_Pos)
  44. #define DMA_CTL_TT_FC_Memory_to_Peripheral_P_Set (0x06U<<DMA_CTL_TT_FC_Pos)
  45. #define DMA_CTL_SRC_MSIZE_Pos (14)
  46. #define DMA_CTL_SRC_MSIZE_Mask (0x07U<<DMA_CTL_SRC_MSIZE_Pos)
  47. #define DMA_CTL_DEST_MSIZE_Pos (11)
  48. #define DMA_CTL_DEST_MSIZE_Mask (0x07U<<DMA_CTL_DEST_MSIZE_Pos)
  49. #define DMA_CTL_SINC_Pos (9)
  50. #define DMA_CTL_SINC_Mask (0x03U<<DMA_CTL_SINC_Pos)
  51. #define DMA_CTL_DINC_Pos (7)
  52. #define DMA_CTL_DINC_Mask (0x03U<<DMA_CTL_DINC_Pos)
  53. #define DMA_CTL_SRC_TR_WIDTH_Pos (4)
  54. #define DMA_CTL_SRC_TR_WIDTH_Mask (0x07U<<DMA_CTL_SRC_TR_WIDTH_Pos)
  55. #define DMA_CTL_DST_TR_WIDTH_Pos (1)
  56. #define DMA_CTL_DST_TR_WIDTH_Mask (0x07U<<DMA_CTL_DST_TR_WIDTH_Pos)
  57. #define DMA_CTL_INT_EN_Set ((uint32_t)0x01)
  58. /************ operation definition for DMA DMA_CFG_L REGISTER ************/
  59. #define DMA_CFG_HS_SEL_SRC_Pos (11)
  60. #define DMA_CFG_HS_SEL_SRC_Mask (0x01U<<DMA_CFG_HS_SEL_SRC_Pos)//0 HARD 1 SOFT
  61. #define DMA_CFG_HS_SEL_DST_Pos (10)
  62. #define DMA_CFG_HS_SEL_DST_Mask (0x01U<<DMA_CFG_HS_SEL_DST_Pos)
  63. /************ operation definition for DMA DMA_CFG_H REGISTER ************/
  64. #define DMA_CFG_DEST_PER_Pos (11)
  65. #define DMA_CFG_DEST_PER_Mask (0x07U<<DMA_CFG_DEST_PER_Pos)//need write current channel num
  66. #define DMA_CFG_SRC_PER_Pos (7)
  67. #define DMA_CFG_SRC_PER_Mask (0x07U<<DMA_CFG_SRC_PER_Pos)//need write current channel num
  68. /************ operation definition for DMA DMA_LLP_L REGISTER ************/
  69. #define DMAC_LLP_NEXT_LLI_MSK (0x3)
  70. static DMAChannal_struct hwDMAChannal[DMA_STREAM_QTY] = {
  71. {
  72. DMA_Channel_0,
  73. 1 << 0,
  74. },
  75. {
  76. DMA_Channel_1,
  77. 1 << 1,
  78. },
  79. {
  80. DMA_Channel_2,
  81. 1 << 2,
  82. },
  83. {
  84. DMA_Channel_3,
  85. 1 << 3,
  86. },
  87. {
  88. DMA_Channel_4,
  89. 1 << 4,
  90. },
  91. {
  92. DMA_Channel_5,
  93. 1 << 5,
  94. },
  95. {
  96. DMA_Channel_6,
  97. 1 << 6,
  98. },
  99. {
  100. DMA_Channel_7,
  101. 1 << 7,
  102. },
  103. };
  104. static uint8_t DMALock[(DMA_STREAM_QTY - 1)/8 + 1];
  105. static int32_t DMA_DummyCB(void *pData, void *pParam)
  106. {
  107. return 0;
  108. }
  109. void *DMA_TakeStream(uint8_t Stream)
  110. {
  111. if (BSP_TestBit(DMALock, Stream))
  112. {
  113. return NULL;
  114. }
  115. BSP_SetBit(DMALock, Stream, 1);
  116. return &hwDMAChannal[Stream];
  117. }
  118. int DMA_CheckStreamLock(uint8_t Stream)
  119. {
  120. return BSP_TestBit(DMALock, Stream);
  121. }
  122. void DMA_ReleaseStream(uint8_t Stream)
  123. {
  124. BSP_SetBit(DMALock, Stream, 0);
  125. }
  126. uint8_t DMA_CheckStreamBusy(uint8_t Stream)
  127. {
  128. DMA_TypeDef *hwDMA = hwDMAChannal[Stream].RegBase;
  129. uint32_t BaseIndex = hwDMAChannal[Stream].Index;
  130. if (DMA->ChEnReg_L & BaseIndex)
  131. {
  132. return 1;
  133. }
  134. return 0;
  135. }
  136. void DMA_BaseConfig(void *Config)
  137. {
  138. DMA_InitTypeDef *DMA_InitStruct = (DMA_InitTypeDef *)Config;
  139. memset(DMA_InitStruct, 0, sizeof(DMA_InitTypeDef));
  140. DMA_InitStruct->DMA_PeripheralBurstSize = DMA_BurstSize_1;
  141. DMA_InitStruct->DMA_PeripheralDataSize = DMA_DataSize_Byte;
  142. DMA_InitStruct->DMA_PeripheralInc = DMA_Inc_Nochange;
  143. DMA_InitStruct->DMA_MemoryBurstSize = DMA_BurstSize_1;
  144. DMA_InitStruct->DMA_MemoryDataSize = DMA_DataSize_Byte;
  145. DMA_InitStruct->DMA_MemoryInc = DMA_Inc_Increment;
  146. }
  147. int DMA_ConfigStream(uint8_t Stream, void *Config)
  148. {
  149. DMA_TypeDef *hwDMA = hwDMAChannal[Stream].RegBase;
  150. uint32_t tmpChannelxBit = hwDMAChannal[Stream].Index;
  151. DMA_InitTypeDef *DMA_InitStruct = (DMA_InitTypeDef *)Config;
  152. if (DMA->ChEnReg_L & tmpChannelxBit)
  153. {
  154. return -1;
  155. }
  156. DMA->ClearTfr_L = tmpChannelxBit;
  157. DMA->ClearBlock_L = tmpChannelxBit;
  158. DMA->ClearSrcTran_L = tmpChannelxBit;
  159. DMA->ClearDstTran_L = tmpChannelxBit;
  160. DMA->ClearErr_L = tmpChannelxBit;
  161. if((DMA->RawBlock_L & tmpChannelxBit) | (DMA->RawDstTran_L & tmpChannelxBit) | (DMA->RawErr_L & tmpChannelxBit) \
  162. | (DMA->RawSrcTran_L & tmpChannelxBit) | (DMA->RawTfr_L & tmpChannelxBit) | (DMA->StatusBlock_L & tmpChannelxBit) \
  163. | (DMA->StatusDstTran_L & tmpChannelxBit) | (DMA->StatusErr_L & tmpChannelxBit) | (DMA->StatusSrcTran_L & tmpChannelxBit) \
  164. | (DMA->StatusTfr_L & tmpChannelxBit) )
  165. {
  166. return -1;
  167. }
  168. switch(DMA_InitStruct->DMA_Peripheral)
  169. {
  170. case SYSCTRL_PHER_CTRL_DMA_CHx_IF_LCD:
  171. case SYSCTRL_PHER_CTRL_DMA_CHx_IF_UART0_TX:
  172. case SYSCTRL_PHER_CTRL_DMA_CHx_IF_UART1_TX:
  173. case SYSCTRL_PHER_CTRL_DMA_CHx_IF_DAC:
  174. case SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI0_TX:
  175. case SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI1_TX:
  176. case SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI2_TX:
  177. case SYSCTRL_PHER_CTRL_DMA_CHx_IF_UART2_TX:
  178. case SYSCTRL_PHER_CTRL_DMA_CHx_IF_UART3_TX:
  179. case SYSCTRL_PHER_CTRL_DMA_CHx_IF_I2C_TX:
  180. case SYSCTRL_PHER_CTRL_DMA_CHx_IF_QSPI_TX:
  181. case SYSCTRL_PHER_CTRL_DMA_CHx_IF_HSPI_TX:
  182. hwDMA->SAR_L = DMA_InitStruct->DMA_MemoryBaseAddr;
  183. hwDMA->DAR_L = DMA_InitStruct->DMA_PeripheralBaseAddr;
  184. hwDMA->CTL_L = DMA_CTL_TT_FC_Memory_to_Peripheral_Set|
  185. (DMA_InitStruct->DMA_MemoryBurstSize << DMA_CTL_SRC_MSIZE_Pos)|
  186. (DMA_InitStruct->DMA_PeripheralBurstSize << DMA_CTL_DEST_MSIZE_Pos)|
  187. (DMA_InitStruct->DMA_MemoryInc << DMA_CTL_SINC_Pos)|
  188. (DMA_InitStruct->DMA_PeripheralInc << DMA_CTL_DINC_Pos)|
  189. (DMA_InitStruct->DMA_MemoryDataSize << DMA_CTL_SRC_TR_WIDTH_Pos)|
  190. (DMA_InitStruct->DMA_PeripheralDataSize << DMA_CTL_DST_TR_WIDTH_Pos);
  191. hwDMAChannal[Stream].TxDir = 1;
  192. // hwDMA->CFG_L = (1 << 18);
  193. hwDMA->CFG_L = 0;
  194. break;
  195. default:
  196. hwDMA->SAR_L = DMA_InitStruct->DMA_PeripheralBaseAddr;
  197. hwDMA->DAR_L = DMA_InitStruct->DMA_MemoryBaseAddr;
  198. hwDMA->CTL_L = DMA_CTL_TT_FC_Peripheral_to_Memory_Set|
  199. (DMA_InitStruct->DMA_PeripheralBurstSize << DMA_CTL_SRC_MSIZE_Pos)|
  200. (DMA_InitStruct->DMA_MemoryBurstSize << DMA_CTL_DEST_MSIZE_Pos)|
  201. (DMA_InitStruct->DMA_PeripheralInc << DMA_CTL_SINC_Pos)|
  202. (DMA_InitStruct->DMA_MemoryInc << DMA_CTL_DINC_Pos)|
  203. (DMA_InitStruct->DMA_PeripheralDataSize << DMA_CTL_SRC_TR_WIDTH_Pos)|
  204. (DMA_InitStruct->DMA_MemoryDataSize << DMA_CTL_DST_TR_WIDTH_Pos);
  205. hwDMAChannal[Stream].TxDir = 0;
  206. hwDMA->CFG_L = 0;
  207. break;
  208. }
  209. hwDMA->CFG_L |= DMA_InitStruct->DMA_Priority;
  210. hwDMA->CFG_H |= (Stream << DMA_CFG_DEST_PER_Pos) | (Stream << DMA_CFG_SRC_PER_Pos);
  211. if (Stream <= DMA1_STREAM_3)
  212. {
  213. tmpChannelxBit = (Stream - DMA1_STREAM_0) * 8;
  214. SYSCTRL->DMA_CHAN = (SYSCTRL->DMA_CHAN & ~(0x0000003f << tmpChannelxBit)) | (DMA_InitStruct->DMA_Peripheral << tmpChannelxBit);
  215. }
  216. else
  217. {
  218. tmpChannelxBit = (Stream - DMA1_STREAM_4) * 8;
  219. SYSCTRL->DMA_CHAN1 = (SYSCTRL->DMA_CHAN1 & ~(0x0000003f << tmpChannelxBit)) | (DMA_InitStruct->DMA_Peripheral << tmpChannelxBit);
  220. }
  221. return 0;
  222. }
  223. int DMA_StartStream(uint8_t Stream, const void *Data, uint32_t Len, CBFuncEx_t CB, void *pUserData, uint8_t NeedIrq)
  224. {
  225. uint32_t tmpChannelxBit = hwDMAChannal[Stream].Index;
  226. if (DMA->ChEnReg_L & tmpChannelxBit)
  227. {
  228. return -1;
  229. }
  230. DMA_ForceStartStream(Stream, Data, Len, CB, pUserData, NeedIrq);
  231. return 0;
  232. }
  233. void DMA_ForceStartStream(uint8_t Stream, const void *Data, uint32_t Len, CBFuncEx_t CB, void *pUserData, uint8_t NeedIrq)
  234. {
  235. uint32_t Blocks = 0, i;
  236. DMA_TypeDef *hwDMA = hwDMAChannal[Stream].RegBase;
  237. volatile uint32_t tmpChannelxBit = hwDMAChannal[Stream].Index;
  238. DMA->ChEnReg_L = (tmpChannelxBit << 8);
  239. while(DMA->ChEnReg_L & tmpChannelxBit) {;}
  240. #ifdef __MUTLI_BLOCKS__
  241. if (hwDMAChannal[Stream].Linklist)
  242. {
  243. free(hwDMAChannal[Stream].Linklist);
  244. hwDMAChannal[Stream].Linklist = NULL;
  245. }
  246. #endif
  247. if (hwDMAChannal[Stream].TxDir)
  248. {
  249. hwDMA->SAR_L = (uint32_t)Data;
  250. }
  251. else
  252. {
  253. hwDMA->DAR_L = (uint32_t)Data;
  254. }
  255. tmpChannelxBit = (tmpChannelxBit << 8) + tmpChannelxBit;
  256. if (NeedIrq)
  257. {
  258. hwDMA->CTL_L |= DMA_CTL_INT_EN_Set;
  259. }
  260. else
  261. {
  262. hwDMA->CTL_L &= ~DMA_CTL_INT_EN_Set;
  263. }
  264. hwDMAChannal[Stream].pData = pUserData;
  265. if (CB)
  266. {
  267. hwDMAChannal[Stream].CB = CB;
  268. }
  269. else
  270. {
  271. hwDMAChannal[Stream].CB = DMA_DummyCB;
  272. }
  273. hwDMA->CTL_L &= ~(BIT(28)|BIT(27));
  274. hwDMA->CTL_H &= ~DMA_CTL_BLOCK_TS_Mask;
  275. hwDMA->LLP_L = 0;
  276. #ifdef __MUTLI_BLOCKS__
  277. if (Len > 4000)
  278. {
  279. Blocks = (Len / 4000) + 1;
  280. hwDMAChannal[Stream].Linklist = zalloc(Blocks * sizeof(LLI));
  281. hwDMA->CTL_L |= (BIT(28)|BIT(27));
  282. for(i = 0; i < (Blocks - 1); i++)
  283. {
  284. hwDMAChannal[Stream].Linklist[i].CTL_L = hwDMA->CTL_L;
  285. hwDMAChannal[Stream].Linklist[i].SAR = hwDMAChannal[Stream].TxDir?((uint32_t)Data + i * 4000):hwDMA->SAR_L;
  286. hwDMAChannal[Stream].Linklist[i].DAR = hwDMAChannal[Stream].TxDir?hwDMA->DAR_L:((uint32_t)Data + i * 4000);
  287. hwDMAChannal[Stream].Linklist[i].LLP = &hwDMAChannal[Stream].Linklist[i + 1];
  288. hwDMAChannal[Stream].Linklist[i].CTL_H = 4000;
  289. }
  290. hwDMAChannal[Stream].Linklist[Blocks - 1].CTL_L = hwDMA->CTL_L;
  291. hwDMAChannal[Stream].Linklist[Blocks - 1].SAR = hwDMAChannal[Stream].TxDir?((uint32_t)Data + (Blocks - 1) * 4000):hwDMA->SAR_L;
  292. hwDMAChannal[Stream].Linklist[Blocks - 1].DAR = hwDMAChannal[Stream].TxDir?hwDMA->DAR_L:((uint32_t)Data + (Blocks - 1) * 4000);
  293. hwDMAChannal[Stream].Linklist[Blocks - 1].LLP = 0;
  294. hwDMAChannal[Stream].Linklist[Blocks - 1].CTL_H = Len - (Blocks - 1) * 4000;
  295. hwDMA->LLP_L = &hwDMAChannal[Stream].Linklist[0];
  296. }
  297. else
  298. #endif
  299. {
  300. hwDMA->CTL_H |= Len;
  301. DMA->ChEnReg_L = tmpChannelxBit;
  302. }
  303. }
  304. void DMA_ForceStartStreamMultiBlocks(uint8_t Stream)
  305. {
  306. DMA_TypeDef *hwDMA = hwDMAChannal[Stream].RegBase;
  307. volatile uint32_t tmpChannelxBit = hwDMAChannal[Stream].Index;
  308. tmpChannelxBit = (tmpChannelxBit << 8) + tmpChannelxBit;
  309. DMA->ChEnReg_L = tmpChannelxBit;
  310. }
  311. void DMA_ClearStreamFlag(uint8_t Stream)
  312. {
  313. DMA_TypeDef *hwDMA = hwDMAChannal[Stream].RegBase;
  314. uint32_t tmpChannelxBit = hwDMAChannal[Stream].Index;
  315. DMA->ClearTfr_L = tmpChannelxBit;
  316. DMA->ClearBlock_L = tmpChannelxBit;
  317. DMA->ClearSrcTran_L = tmpChannelxBit;
  318. DMA->ClearDstTran_L = tmpChannelxBit;
  319. DMA->ClearErr_L = tmpChannelxBit;
  320. }
  321. void DMA_StopStream(uint8_t Stream)
  322. {
  323. if (Stream >= DMA_STREAM_QTY) return;
  324. DMA_TypeDef *hwDMA = hwDMAChannal[Stream].RegBase;
  325. uint32_t tmpChannelxBit = hwDMAChannal[Stream].Index;
  326. DMA->ChEnReg_L = (tmpChannelxBit << 8);
  327. DMA->ClearTfr_L = tmpChannelxBit;
  328. DMA->ClearBlock_L = tmpChannelxBit;
  329. DMA->ClearSrcTran_L = tmpChannelxBit;
  330. DMA->ClearDstTran_L = tmpChannelxBit;
  331. DMA->ClearErr_L = tmpChannelxBit;
  332. #ifdef __MUTLI_BLOCKS__
  333. if (hwDMAChannal[Stream].Linklist)
  334. {
  335. free(hwDMAChannal[Stream].Linklist);
  336. hwDMAChannal[Stream].Linklist = NULL;
  337. }
  338. #endif
  339. }
  340. uint32_t DMA_GetRemainingDataLength(uint8_t Stream)
  341. {
  342. return 0;
  343. }
  344. uint32_t DMA_GetDataLength(uint8_t Stream, uint32_t FirstAddress)
  345. {
  346. DMA_TypeDef *hwDMA = hwDMAChannal[Stream].RegBase;
  347. return (hwDMA->CTL_H);
  348. }
  349. static void DMA_IrqHandle(int32_t IrqLine, void *pData)
  350. {
  351. uint32_t i;
  352. // DBG("%x", DMA->StatusTfr_L);
  353. if (DMA->StatusInt_L & (1 << 0))
  354. {
  355. for(i = 0; i < DMA_STREAM_QTY; i++)
  356. {
  357. if (DMA->StatusTfr_L & (1 << i))
  358. {
  359. DMA->ClearTfr_L = (1 << i);
  360. hwDMAChannal[i].CB(hwDMAChannal[i].pData, 0);
  361. }
  362. }
  363. }
  364. if (DMA->StatusInt_L & (1 << 4))
  365. {
  366. for(i = 0; i < DMA_STREAM_QTY; i++)
  367. {
  368. if (DMA->StatusErr_L & (1 << i))
  369. {
  370. DMA->ClearErr_L = (1 << i);
  371. hwDMAChannal[i].CB(hwDMAChannal[i].pData, 0xffffffff);
  372. }
  373. }
  374. }
  375. DMA->ClearBlock_L = 0x000000ff;
  376. DMA->ClearSrcTran_L = 0x000000ff;
  377. DMA->ClearDstTran_L = 0x000000ff;
  378. }
  379. void DMA_GlobalInit(void)
  380. {
  381. ISR_SetHandler(DMA_IRQn, DMA_IrqHandle, NULL);
  382. #ifdef __BUILD_OS__
  383. ISR_SetPriority(DMA_IRQn, IRQ_MAX_PRIORITY + 2);
  384. #else
  385. ISR_SetPriority(DMA_IRQn, 3);
  386. #endif
  387. DMA->DmaCfgReg_L = 1;
  388. DMA->ChEnReg_L = 0x0000ff00;
  389. ISR_OnOff(DMA_IRQn, 1);
  390. DMA->MaskTfr_L = 0x0000ffff;
  391. DMA->MaskErr_L = 0x0000ffff;
  392. }
  393. void DMA_PrintReg(uint8_t Stream)
  394. {
  395. DMA_TypeDef *hwDMA = hwDMAChannal[Stream].RegBase;
  396. DBG("%d, %d, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x", Stream, hwDMAChannal[Stream].TxDir, hwDMA->SAR_L, hwDMA->DAR_L, hwDMA->CTL_H, hwDMA->CTL_L, hwDMA->CFG_L);
  397. }
  398. void DMA_PrintGlobalReg(void)
  399. {
  400. DBG("global 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x", SYSCTRL->DMA_CHAN, SYSCTRL->DMA_CHAN1, DMA->StatusTfr_L,
  401. DMA->StatusErr_L, DMA->ChEnReg_L, DMA->DmaCfgReg_L);
  402. }