dma.c
上传用户:jankzhpno
上传日期:2022-08-03
资源大小:4763k
文件大小:6k
源码类别:

Windows CE

开发平台:

Visual C++

  1. #include "def.h"
  2. #include "option.h"
  3. #include "2440addr.h"
  4. #include "2440lib.h"
  5. #include "2440slib.h" 
  6. #include "dma.h"
  7. #define DMA_CHECK_ATTR 1
  8. typedef struct{ //can't use __packed???
  9.     volatile U32 DISRC;     //0x0
  10.     volatile U32 DISRCC;    //0x4
  11.     volatile U32 DIDST;     //0x8
  12.     volatile U32 DIDSTC;    //0xc
  13.     volatile U32 DCON;     //0x10
  14.     volatile U32 DSTAT;     //0x14
  15.     volatile U32 DCSRC;     //0x18
  16.     volatile U32 DCDST;     //0x1c
  17.     volatile U32 DMASKTRIG; //0x20
  18. }DMAReg;
  19. static struct{
  20. U16 used;
  21. U16 DevID;
  22. DMAReg *pDMA;
  23. }
  24. DMAChannel[MAX_DMA_CHANNEL];
  25. /********************************************************/
  26. //attr高16位为设备ID,低16位的高8位为DMA传送源,目的属性(AHP/APB,INCREASE/FIX)
  27. //低8位为请求源,返回值失败为REQUEST_DMA_FAIL,成功高16位为设备ID,低8位为申请到的通道
  28. U32 RequestDMASW(U32 attr, U32 mode)
  29. {
  30. U16 channel;
  31. U32 ret;
  32. attr &= ~0xff;
  33. mode &= ~HW_TRIG;
  34. for(channel=0; channel<(MAX_DMA_CHANNEL*0x10); channel+=0x10)
  35. {
  36. ret = RequestDMA(attr|channel, mode);
  37. if(ret!=REQUEST_DMA_FAIL)
  38. break;
  39. }
  40. return ret;
  41. }
  42. U32 RequestDMA(U32 attr, U32 mode)
  43. {
  44. U16 DevID, ReqSrc, ch;
  45. U32 ret=REQUEST_DMA_FAIL, r;
  46. DevID   = attr>>16;
  47. ReqSrc  = attr&0xff;
  48. if(((ReqSrc>>4)>=MAX_DMA_CHANNEL)||((ReqSrc&0xf)>4))
  49. return ret;
  50. EnterCritical(&r);
  51. if(DMAChannel[ReqSrc>>4].used!=DMA_IS_FREE)
  52. {
  53. U8 src = ReqSrc;
  54. if(src==REQ_IISDI)
  55. {
  56. if(DMAChannel[2].used!=DMA_IS_FREE)
  57. goto RequestDmaExit;
  58. else
  59. ReqSrc = 0x21;
  60. }
  61. else if(src==REQ_SDI)
  62. {
  63. if(DMAChannel[2].used!=DMA_IS_FREE)
  64. {
  65. if(DMAChannel[3].used!=DMA_IS_FREE)
  66. goto RequestDmaExit;
  67. else
  68. ReqSrc = 0x31;
  69. }
  70. else
  71. ReqSrc = 0x22;
  72. }
  73. else if(src==REQ_SPI)
  74. {
  75. if(DMAChannel[3].used!=DMA_IS_FREE)
  76. goto RequestDmaExit;
  77. else
  78. ReqSrc = 0x32;
  79. }
  80. else if(src==REQ_TIMER)
  81. {
  82. if(DMAChannel[2].used!=DMA_IS_FREE)
  83. {
  84. if(DMAChannel[3].used!=DMA_IS_FREE)
  85. goto RequestDmaExit;
  86. else
  87. ReqSrc = 0x33;
  88. }
  89. else
  90. ReqSrc = 0x23;
  91. }
  92. else
  93. goto RequestDmaExit;
  94. }
  95. ch = ReqSrc>>4;
  96. if(mode&HW_TRIG)
  97. DMAChannel[ch].used  = DMA_IS_HWTRIG;
  98. else
  99. DMAChannel[ch].used  = DMA_IS_SWTRIG;
  100. DMAChannel[ch].DevID = DevID;
  101. DMAChannel[ch].pDMA  = (DMAReg *)(0x4b000000+(ch)*0x40);
  102. DMAChannel[ch].pDMA->DMASKTRIG = 1<<2; //stop dma
  103. DMAChannel[ch].pDMA->DISRCC = (attr>>8)&3;
  104. DMAChannel[ch].pDMA->DIDSTC = (attr>>12)&3;
  105. mode &= ~0x07000000;
  106. mode |= (ReqSrc&0x7)<<24;
  107. DMAChannel[ch].pDMA->DCON = mode;
  108. // DbgOut("Request DMA %x successn", ReqSrc);
  109. ret = (DevID<<16)|ReqSrc;
  110. RequestDmaExit:
  111. ExitCritical(&r);
  112. return ret;
  113. }
  114. U16 ReleaseDMA(U32 attr)
  115. {
  116. U16 DevID, ReqSrc, ch;
  117. DevID  = attr>>16;
  118. ReqSrc = attr&0xf;
  119. ch     = (attr&0xf0)>>4;
  120. #if DMA_CHECK_ATTR
  121. if((ch>=MAX_DMA_CHANNEL)||(ReqSrc>4))
  122. return 1;
  123. if((DMAChannel[ch].used==DMA_IS_FREE)||(DMAChannel[ch].DevID!=DevID))
  124. return 1;
  125. #endif
  126. DMAChannel[ch].pDMA->DMASKTRIG = 0;//4; //stop dma and channel off 
  127. DMAChannel[ch].used = DMA_IS_FREE;
  128. return 0;
  129. }
  130. U16 StartDMA(U32 attr)
  131. {
  132. U16 DevID, ReqSrc, ch;
  133. DevID  = attr>>16;
  134. ReqSrc = attr&0xf;
  135. ch     = (attr&0xf0)>>4;
  136. #if DMA_CHECK_ATTR
  137. if((ch>=MAX_DMA_CHANNEL)||(ReqSrc>4))
  138. return 1;
  139. if((DMAChannel[ch].used==DMA_IS_FREE)||(DMAChannel[ch].DevID!=DevID))
  140. return 1;
  141. #endif
  142. if(DMAChannel[ch].used==DMA_IS_HWTRIG)
  143. DMAChannel[ch].pDMA->DMASKTRIG = 2; //channel on
  144. if(DMAChannel[ch].used==DMA_IS_SWTRIG)
  145. DMAChannel[ch].pDMA->DMASKTRIG = 3; //sw_trig
  146. return 0;
  147. }
  148. U16 StopDMA(U32 attr)
  149. {
  150. U16 DevID, ReqSrc, ch;
  151. DevID  = attr>>16;
  152. ReqSrc = attr&0xf;
  153. ch     = (attr&0xf0)>>4;
  154. #if DMA_CHECK_ATTR
  155. if((ch>=MAX_DMA_CHANNEL)||(ReqSrc>4))
  156. return 1;
  157. if((DMAChannel[ch].used==DMA_IS_FREE)||(DMAChannel[ch].DevID!=DevID))
  158. return 1;
  159. #endif
  160. DMAChannel[ch].pDMA->DMASKTRIG = 1<<2; //channel off
  161. return 0;
  162. }
  163. U16 SetDMARun(U32 attr, U32 src_addr, U32 dst_addr, U32 len)
  164. {
  165. U16 DevID, ReqSrc, ch;
  166. DevID  = attr>>16;
  167. ReqSrc = attr&0xf;
  168. ch     = (attr&0xf0)>>4;
  169. #if DMA_CHECK_ATTR
  170. if((ch>=MAX_DMA_CHANNEL)||(ReqSrc>4))
  171. return 1;
  172. if((DMAChannel[ch].used==DMA_IS_FREE)||(DMAChannel[ch].DevID!=DevID))
  173. return 1;
  174. #endif
  175. DMAChannel[ch].pDMA->DISRC = src_addr;
  176. DMAChannel[ch].pDMA->DIDST = dst_addr;
  177. DMAChannel[ch].pDMA->DCON &= ~0xfffff;
  178. DMAChannel[ch].pDMA->DCON |= len&0xfffff;
  179. if(attr&DMA_START)
  180. {
  181. if(DMAChannel[ch].used==DMA_IS_HWTRIG)
  182. DMAChannel[ch].pDMA->DMASKTRIG = 2; //channel on
  183. if(DMAChannel[ch].used==DMA_IS_SWTRIG)
  184. DMAChannel[ch].pDMA->DMASKTRIG = 3; //sw_trig
  185. }
  186. return 0;
  187. }
  188. U32 QueryDMAStat(U32 attr)
  189. {
  190. U16 DevID, ReqSrc, ch;
  191. DevID  = attr>>16;
  192. ReqSrc = attr&0xf;
  193. ch     = (attr&0xf0)>>4;
  194. #if DMA_CHECK_ATTR
  195. if((ch>=MAX_DMA_CHANNEL)||(ReqSrc>4))
  196. return -1;
  197. if((DMAChannel[ch].used==DMA_IS_FREE)||(DMAChannel[ch].DevID!=DevID))
  198. return -1;
  199. #endif
  200. return DMAChannel[ch].pDMA->DSTAT; //STAT[21:20], CURR_TC[19:0] 
  201. }
  202. U32 QueryDMASrc(U32 attr)
  203. {
  204. U16 DevID, ReqSrc, ch;
  205. DevID  = attr>>16;
  206. ReqSrc = attr&0xf;
  207. ch     = (attr&0xf0)>>4;
  208. #if DMA_CHECK_ATTR
  209. if((ch>=MAX_DMA_CHANNEL)||(ReqSrc>4))
  210. return -1;
  211. if((DMAChannel[ch].used==DMA_IS_FREE)||(DMAChannel[ch].DevID!=DevID))
  212. return -1;
  213. #endif
  214. return DMAChannel[ch].pDMA->DCSRC;
  215. }
  216. U32 QueryDMADst(U32 attr)
  217. {
  218. U16 DevID, ReqSrc, ch;
  219. DevID  = attr>>16;
  220. ReqSrc = attr&0xf;
  221. ch     = (attr&0xf0)>>4;
  222. #if DMA_CHECK_ATTR
  223. if((ch>=MAX_DMA_CHANNEL)||(ReqSrc>4))
  224. return -1;
  225. if((DMAChannel[ch].used==DMA_IS_FREE)||(DMAChannel[ch].DevID!=DevID))
  226. return -1;
  227. #endif
  228. return DMAChannel[ch].pDMA->DCDST;
  229. }