纠结,前段时间把厂家的驱动弄上去,结果2440 无法启动,后来搞虚拟串口去了,现在重新回来继续搞。
发现代码很庞大,还是先看懂大概再说吧。经过一番查看,这个模块有一个外部中断,还有一个DMA中断也用到了,我很纠结,这两个中断到底是如何处理协调的呢?
在代码里面我看见了
代码
1
2
3 ///
4 /// dma_init: Initialize the DMA
5 /// Input:
6 /// pHC - Hard context
7 /// Output:
8 /// None
9 /// Return:
10 /// 0 - success
11 /// -1 - fail
12 static int dma_init(PSSP_HARDWARE_CONTEXT pHC)
13 {
14 int result=0;
15 int resultdma=5;
16 DMA_ADAPTER_OBJECT Adapter;
17 PHYSICAL_ADDRESS PA;
18 DWORD inIoSpace=0; ///I/O Space
19
20
21 #if (USE_DMA == 1)
22 //PHYSICAL_ADDRESS DCSRAddr[] = { {DMA_DCSR(DMA_CH_READ), 0},
23 // {DMA_DCSR(DMA_CH_RW), 0}};
24
25 PHYSICAL_ADDRESS DCSRAddr[] = { {0x4B000054, 0},
26 {0x0, 0}};
27
28
29 #endif
30
31 pHC->pIntRegs->INTMSK&= ~(0x1<<18);//DMA1 service available
32
33 //DMA init
34
35
36
37 ///Allocate the DMA buffers
38 Adapter.ObjectSize = sizeof(DMA_ADAPTER_OBJECT);
39 Adapter.InterfaceType = Internal;
40 Adapter.BusNumber = 0;
41
42 ///Allocate I/O buffers
43 pHC->iodata = (PBYTE) HalAllocateCommonBuffer(&Adapter, PXA_SSP_IODATA_SIZE, &PA, FALSE);
44 if (pHC->iodata) {
45 pHC->phys_addr = (PBYTE)PA.LowPart;
46 }
47
48 pHC->iorw = (PBYTE) HalAllocateCommonBuffer(&Adapter, PXA_SSP_IODATA_SIZE, &PA, FALSE);
49 if (pHC->iorw) {
50 pHC->phys_addr_rw = (PBYTE)PA.LowPart;
51 }
52
53 #if (USE_DMA == 1)
54 /*
55 pHC->DMAParam[RDDMA_PARAM].pDMARegs = pHC->pDMARegs;
56 pHC->DMAParam[RDDMA_PARAM].channel = DMA_CH_READ;
57 if(!(pHC->DMAParam[RDDMA_PARAM].dmaWaitObj = CreateEvent( NULL, FALSE, FALSE,NULL))) {
58 GSPIMSG(ERRMSG, (TEXT("Init rddmaWaitObj, CreateEvent FAILED")));
59 result = -1;
60 goto errFuncRet;
61 }
62 */
63 pHC->DMAParam[RWDMA_PARAM].pDMARegs = pHC->pDMARegs;
64 pHC->DMAParam[RWDMA_PARAM].channel = DMA_CH_RW;
65 if(!(pHC->DMAParam[RWDMA_PARAM].dmaWaitObj = CreateEvent( NULL, FALSE, FALSE,NULL))) {
66 GSPIMSG(ERRMSG, (TEXT("Init wtdmaWaitObj, CreateEvent FAILED")));
67 result = -1;
68 goto errFuncRet;
69 }
70
71 //pHC->pDMARegs->drcmr[DMA_CHMAP_SSP_RX] = pHC->DMAParam[RDDMA_PARAM].channel | DRCMR_MAPVAL;
72 //pHC->pDMARegs->drcmr[DMA_CHMAP_SSP_TX] = pHC->DMAParam[WTDMA_PARAM].channel | DRCMR_MAPVAL;
73
74 #endif
75
76
77 ///==============================================================
78 /// Request the DMA IRQ
79 #if (USE_DMA == 1) && (USE_DMAIRQ == 1)
80 pHC->hBusAcceHND = CreateBusAccessHandle( pg_szActiveKey );
81 {
82 int i;
83 for (i=0 ; i<MAXDMA_PARAM ; i++) {
84 pHC->DMAIntrInfo[i].irq = IRQ_DMA1;
85 pHC->DMAIntrInfo[i].pIstFunc = (MYISTFUNC) dma_ist;
86 pHC->DMAIntrInfo[i].param = (LPVOID)&pHC->DMAParam[i];
87 pHC->DMAIntrInfo[i].IntrMask = (0x01 << 20);//need to check
88
89 if (!BusTransBusAddrToStatic(pHC->hBusAcceHND, Internal, 0, DCSRAddr[i], sizeof(DWORD), &inIoSpace, &pHC->DMAIntrInfo[i].IntrRgPhysAddr)) {
90 GSPIMSG(ERRMSG, (TEXT("installISR: Failed TransBusAddrToStatic - (read)\r\n")));
91 }
92 RETAILMSG(1, (TEXT("installISR: PhysAddr: %xh\r\n"), pHC->DMAIntrInfo[i].IntrRgPhysAddr));
93 ///Initialize the interrupt, IST
94 resultdma = setupInterrupt(&pHC->DMAIntrInfo[i]);
95 GSPIMSG(1, (TEXT("resultdma setupInterrupt== [%d]...\n"), resultdma));
96 ///Load the ISR
97 resultdma=installISR(&pHC->DMAIntrInfo[i]);
98 GSPIMSG(1, (TEXT("resultdma installISR == [%d]...\n"), resultdma));
99 }
100 }
101 #endif ///USE_DMAIRQ
102
103
104 return result;
105 errFuncRet:
106
107 return result;
108 }
109
110
111 int installISR(MYINTRINFO* pMyIntrInfo)
112 {
113 GIISR_INFO Info;
114
115 // install the DMA ISR handler
116 pMyIntrInfo->hGIIsr = LoadIntChainHandler(
117 TEXT("giisr.dll"),
118 TEXT("ISRHandler"),
119 (BYTE)pMyIntrInfo->irq);
120
121 if (!(pMyIntrInfo->hGIIsr)) {
122 RETAILMSG(1, (TEXT("xxxxxxxx>Can not load giisr.dll\n")));
123 goto errFuncRet;
124 } else {
125 RETAILMSG(1, (TEXT("*********> loading agiisr.dll ok\n")));
126 }
127
128 Info.SysIntr = pMyIntrInfo->dwSysIntr;
129 Info.CheckPort = TRUE;
130 Info.PortIsIO = FALSE;
131 Info.UseMaskReg = FALSE;
132 Info.PortAddr = (DWORD)pMyIntrInfo->IntrRgPhysAddr;
133 Info.PortSize = sizeof(DWORD);
134 Info.Mask = pMyIntrInfo->IntrMask;
135 Info.MaskAddr = 0;
136
137
138 if (!KernelLibIoControl(pMyIntrInfo->hGIIsr, IOCTL_GIISR_INFO,
139 &Info, sizeof(Info),
140 NULL, 0, NULL))
141 {
142 goto errFuncRet;
143 }
144
145 return 0;
146 errFuncRet:
147 return -1;
148 }
149