DSP program for the Surfboard hardware (PCB to be open sourced) http://www.avbotz.com/ourauv/electrical/signal-processing/

Dependencies:   MODDMA SimpleIOMacros mbed-dsp mbed

Committer:
avbotz
Date:
Fri Aug 02 02:25:12 2013 +0000
Revision:
1:f69ec4c889ff
Parent:
0:2381a319fc35
Initial commit. Not working. MODDMA makes DMA setup slow, and the mbed SPI peripheral corrupts data sometimes. I will write my own SPI and DMA classes and see how it goes.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
avbotz 0:2381a319fc35 1 #include "MODDMA_cache.h"
avbotz 0:2381a319fc35 2
avbotz 0:2381a319fc35 3 // Exists so the IRQ handler can access MODDMA object.
avbotz 0:2381a319fc35 4 MODDMA_Cache* moddma_p;
avbotz 0:2381a319fc35 5
avbotz 0:2381a319fc35 6 // Setup the DMA controller and then cache some values. they will be used in Reset().
avbotz 0:2381a319fc35 7 // does not work; these values do not change. we aren't caching the right ones.
avbotz 0:2381a319fc35 8
avbotz 0:2381a319fc35 9 MODDMA_Cache::MODDMA_Cache()
avbotz 0:2381a319fc35 10 {
avbotz 0:2381a319fc35 11 moddma_p = this;
avbotz 0:2381a319fc35 12 init();
avbotz 0:2381a319fc35 13 }
avbotz 0:2381a319fc35 14
avbotz 0:2381a319fc35 15 // A copy of Kirkham's setup function. This caches most values as they are set.
avbotz 0:2381a319fc35 16 uint32_t MODDMA_Cache::Setup(MODDMA_Config* config)
avbotz 0:2381a319fc35 17 {
avbotz 0:2381a319fc35 18 LPC_GPDMACH_TypeDef *pChannel = (LPC_GPDMACH_TypeDef *)Channel_p( config->channelNum() );
avbotz 0:2381a319fc35 19
avbotz 0:2381a319fc35 20 setups[config->channelNum() & 0x7] = config;
avbotz 0:2381a319fc35 21
avbotz 0:2381a319fc35 22 // Reset the Interrupt status
avbotz 0:2381a319fc35 23 LPC_GPDMA->DMACIntTCClear = DMACIntTCClear = IntTCClear_Ch( config->channelNum() );
avbotz 0:2381a319fc35 24 LPC_GPDMA->DMACIntErrClr = DMACIntErrClr = IntErrClr_Ch ( config->channelNum() );
avbotz 0:2381a319fc35 25
avbotz 0:2381a319fc35 26 // Clear DMA configure
avbotz 0:2381a319fc35 27 pChannel->DMACCControl = 0x00;
avbotz 0:2381a319fc35 28 pChannel->DMACCConfig = 0x00;
avbotz 0:2381a319fc35 29
avbotz 0:2381a319fc35 30 // Assign Linker List Item value
avbotz 0:2381a319fc35 31 pChannel->DMACCLLI = DMACCLLI = config->dmaLLI();
avbotz 0:2381a319fc35 32
avbotz 0:2381a319fc35 33 // Set value to Channel Control Registers
avbotz 0:2381a319fc35 34 switch (config->transferType()) {
avbotz 0:2381a319fc35 35
avbotz 0:2381a319fc35 36 // Memory to memory
avbotz 0:2381a319fc35 37 case m2m:
avbotz 0:2381a319fc35 38 // Assign physical source and destination address
avbotz 0:2381a319fc35 39 pChannel->DMACCSrcAddr = config->srcMemAddr();
avbotz 0:2381a319fc35 40 pChannel->DMACCDestAddr = config->dstMemAddr();
avbotz 0:2381a319fc35 41 pChannel->DMACCControl
avbotz 0:2381a319fc35 42 = CxControl_TransferSize(config->transferSize())
avbotz 0:2381a319fc35 43 | CxControl_SBSize(_32)
avbotz 0:2381a319fc35 44 | CxControl_DBSize(_32)
avbotz 0:2381a319fc35 45 | CxControl_SWidth(config->transferWidth())
avbotz 0:2381a319fc35 46 | CxControl_DWidth(config->transferWidth())
avbotz 0:2381a319fc35 47 | CxControl_SI()
avbotz 0:2381a319fc35 48 | CxControl_DI()
avbotz 0:2381a319fc35 49 | CxControl_I();
avbotz 0:2381a319fc35 50 break;
avbotz 0:2381a319fc35 51
avbotz 0:2381a319fc35 52 // Memory to peripheral
avbotz 0:2381a319fc35 53 case m2p:
avbotz 0:2381a319fc35 54 // Assign physical source
avbotz 0:2381a319fc35 55 pChannel->DMACCSrcAddr = DMACCSrcAddr = config->srcMemAddr();
avbotz 0:2381a319fc35 56 // Assign peripheral destination address
avbotz 0:2381a319fc35 57 pChannel->DMACCDestAddr = DMACCDestAddr = (uint32_t)LUTPerAddr(config->dstConn());
avbotz 0:2381a319fc35 58 pChannel->DMACCControl = DMACCControl
avbotz 0:2381a319fc35 59 = CxControl_TransferSize((uint32_t)config->transferSize())
avbotz 0:2381a319fc35 60 | CxControl_SBSize((uint32_t)LUTPerBurst(config->dstConn()))
avbotz 0:2381a319fc35 61 | CxControl_DBSize((uint32_t)LUTPerBurst(config->dstConn()))
avbotz 0:2381a319fc35 62 | CxControl_SWidth((uint32_t)LUTPerWid(config->dstConn()))
avbotz 0:2381a319fc35 63 | CxControl_DWidth((uint32_t)LUTPerWid(config->dstConn()))
avbotz 0:2381a319fc35 64 | CxControl_SI()
avbotz 0:2381a319fc35 65 | CxControl_I();
avbotz 0:2381a319fc35 66 break;
avbotz 0:2381a319fc35 67
avbotz 0:2381a319fc35 68 // Peripheral to memory
avbotz 0:2381a319fc35 69 case p2m:
avbotz 0:2381a319fc35 70 // Assign peripheral source address
avbotz 0:2381a319fc35 71 pChannel->DMACCSrcAddr = DMACCSrcAddr = (uint32_t)LUTPerAddr(config->srcConn());
avbotz 0:2381a319fc35 72 // Assign memory destination address
avbotz 0:2381a319fc35 73 pChannel->DMACCDestAddr = DMACCDestAddr = config->dstMemAddr();
avbotz 0:2381a319fc35 74 pChannel->DMACCControl = DMACCControl
avbotz 0:2381a319fc35 75 = CxControl_TransferSize((uint32_t)config->transferSize())
avbotz 0:2381a319fc35 76 | CxControl_SBSize((uint32_t)LUTPerBurst(config->srcConn()))
avbotz 0:2381a319fc35 77 | CxControl_DBSize((uint32_t)LUTPerBurst(config->srcConn()))
avbotz 0:2381a319fc35 78 | CxControl_SWidth((uint32_t)LUTPerWid(config->srcConn()))
avbotz 0:2381a319fc35 79 | CxControl_DWidth((uint32_t)LUTPerWid(config->srcConn()))
avbotz 0:2381a319fc35 80 | CxControl_DI()
avbotz 0:2381a319fc35 81 | CxControl_I();
avbotz 0:2381a319fc35 82 break;
avbotz 0:2381a319fc35 83
avbotz 0:2381a319fc35 84 // Peripheral to peripheral
avbotz 0:2381a319fc35 85 case p2p:
avbotz 0:2381a319fc35 86 // Assign peripheral source address
avbotz 0:2381a319fc35 87 pChannel->DMACCSrcAddr = (uint32_t)LUTPerAddr(config->srcConn());
avbotz 0:2381a319fc35 88 // Assign peripheral destination address
avbotz 0:2381a319fc35 89 pChannel->DMACCDestAddr = (uint32_t)LUTPerAddr(config->dstConn());
avbotz 0:2381a319fc35 90 pChannel->DMACCControl
avbotz 0:2381a319fc35 91 = CxControl_TransferSize((uint32_t)config->transferSize())
avbotz 0:2381a319fc35 92 | CxControl_SBSize((uint32_t)LUTPerBurst(config->srcConn()))
avbotz 0:2381a319fc35 93 | CxControl_DBSize((uint32_t)LUTPerBurst(config->dstConn()))
avbotz 0:2381a319fc35 94 | CxControl_SWidth((uint32_t)LUTPerWid(config->srcConn()))
avbotz 0:2381a319fc35 95 | CxControl_DWidth((uint32_t)LUTPerWid(config->dstConn()))
avbotz 0:2381a319fc35 96 | CxControl_I();
avbotz 0:2381a319fc35 97 break;
avbotz 0:2381a319fc35 98
avbotz 0:2381a319fc35 99 // GPIO to memory
avbotz 0:2381a319fc35 100 case g2m:
avbotz 0:2381a319fc35 101 // Assign GPIO source address
avbotz 0:2381a319fc35 102 pChannel->DMACCSrcAddr = config->srcMemAddr();
avbotz 0:2381a319fc35 103 // Assign memory destination address
avbotz 0:2381a319fc35 104 pChannel->DMACCDestAddr = config->dstMemAddr();
avbotz 0:2381a319fc35 105 pChannel->DMACCControl
avbotz 0:2381a319fc35 106 = CxControl_TransferSize((uint32_t)config->transferSize())
avbotz 0:2381a319fc35 107 | CxControl_SBSize((uint32_t)LUTPerBurst(config->srcConn()))
avbotz 0:2381a319fc35 108 | CxControl_DBSize((uint32_t)LUTPerBurst(config->srcConn()))
avbotz 0:2381a319fc35 109 | CxControl_SWidth((uint32_t)LUTPerWid(config->srcConn()))
avbotz 0:2381a319fc35 110 | CxControl_DWidth((uint32_t)LUTPerWid(config->srcConn()))
avbotz 0:2381a319fc35 111 | CxControl_DI()
avbotz 0:2381a319fc35 112 | CxControl_I();
avbotz 0:2381a319fc35 113 break;
avbotz 0:2381a319fc35 114
avbotz 0:2381a319fc35 115 // Memory to GPIO
avbotz 0:2381a319fc35 116 case m2g:
avbotz 0:2381a319fc35 117 // Assign physical source
avbotz 0:2381a319fc35 118 pChannel->DMACCSrcAddr = config->srcMemAddr();
avbotz 0:2381a319fc35 119 // Assign peripheral destination address
avbotz 0:2381a319fc35 120 pChannel->DMACCDestAddr = config->dstMemAddr();
avbotz 0:2381a319fc35 121 pChannel->DMACCControl
avbotz 0:2381a319fc35 122 = CxControl_TransferSize((uint32_t)config->transferSize())
avbotz 0:2381a319fc35 123 | CxControl_SBSize((uint32_t)LUTPerBurst(config->dstConn()))
avbotz 0:2381a319fc35 124 | CxControl_DBSize((uint32_t)LUTPerBurst(config->dstConn()))
avbotz 0:2381a319fc35 125 | CxControl_SWidth((uint32_t)LUTPerWid(config->dstConn()))
avbotz 0:2381a319fc35 126 | CxControl_DWidth((uint32_t)LUTPerWid(config->dstConn()))
avbotz 0:2381a319fc35 127 | CxControl_SI()
avbotz 0:2381a319fc35 128 | CxControl_I();
avbotz 0:2381a319fc35 129 break;
avbotz 0:2381a319fc35 130
avbotz 0:2381a319fc35 131 // Do not support any more transfer type, return ERROR
avbotz 0:2381a319fc35 132 default:
avbotz 0:2381a319fc35 133 return 0;
avbotz 0:2381a319fc35 134 }
avbotz 0:2381a319fc35 135
avbotz 0:2381a319fc35 136 // Re-Configure DMA Request Select for source peripheral
avbotz 0:2381a319fc35 137 if (config->srcConn() > 15) {
avbotz 0:2381a319fc35 138 DMAREQSEL = LPC_SC->DMAREQSEL |= (1 << (config->srcConn() - 16));
avbotz 0:2381a319fc35 139 }
avbotz 0:2381a319fc35 140 else {
avbotz 0:2381a319fc35 141 DMAREQSEL = LPC_SC->DMAREQSEL &= ~(1 << (config->srcConn() - 8));
avbotz 0:2381a319fc35 142 }
avbotz 0:2381a319fc35 143
avbotz 0:2381a319fc35 144 // Re-Configure DMA Request Select for destination peripheral
avbotz 0:2381a319fc35 145 if (config->dstConn() > 15) {
avbotz 0:2381a319fc35 146 DMAREQSEL = LPC_SC->DMAREQSEL |= (1 << (config->dstConn() - 16));
avbotz 0:2381a319fc35 147 }
avbotz 0:2381a319fc35 148 else {
avbotz 0:2381a319fc35 149 DMAREQSEL = LPC_SC->DMAREQSEL &= ~(1 << (config->dstConn() - 8));
avbotz 0:2381a319fc35 150 }
avbotz 0:2381a319fc35 151
avbotz 0:2381a319fc35 152 // Enable DMA channels, little endian
avbotz 0:2381a319fc35 153 LPC_GPDMA->DMACConfig = _E;
avbotz 0:2381a319fc35 154 while (!(LPC_GPDMA->DMACConfig & _E));
avbotz 0:2381a319fc35 155
avbotz 0:2381a319fc35 156 // Calculate absolute value for Connection number
avbotz 0:2381a319fc35 157 uint32_t tmp1 = config->srcConn(); tmp1 = ((tmp1 > 15) ? (tmp1 - 8) : tmp1);
avbotz 0:2381a319fc35 158 uint32_t tmp2 = config->dstConn(); tmp2 = ((tmp2 > 15) ? (tmp2 - 8) : tmp2);
avbotz 0:2381a319fc35 159
avbotz 0:2381a319fc35 160 if (config->dmacSync()) {
avbotz 0:2381a319fc35 161 uint32_t tmp3 = config->dmacSync(); tmp3 = ((tmp3 > 15) ? (tmp3 - 8) : tmp3);
avbotz 0:2381a319fc35 162 LPC_GPDMA->DMACSync |= DMACSync = Sync_Src( tmp3 );
avbotz 0:2381a319fc35 163 }
avbotz 0:2381a319fc35 164
avbotz 0:2381a319fc35 165 uint32_t tfer_type = (uint32_t)config->transferType();
avbotz 0:2381a319fc35 166 if (tfer_type == g2m || tfer_type == m2g) {
avbotz 0:2381a319fc35 167 tfer_type -= 2; // Adjust psuedo transferType to a real transferType.
avbotz 0:2381a319fc35 168 }
avbotz 0:2381a319fc35 169
avbotz 0:2381a319fc35 170 // Configure DMA Channel, enable Error Counter and Terminate counter
avbotz 0:2381a319fc35 171 pChannel->DMACCConfig = DMACCConfig
avbotz 0:2381a319fc35 172 = CxConfig_IE()
avbotz 0:2381a319fc35 173 | CxConfig_ITC()
avbotz 0:2381a319fc35 174 | CxConfig_TransferType(tfer_type)
avbotz 0:2381a319fc35 175 | CxConfig_SrcPeripheral(tmp1)
avbotz 0:2381a319fc35 176 | CxConfig_DestPeripheral(tmp2);
avbotz 0:2381a319fc35 177
avbotz 0:2381a319fc35 178 return pChannel->DMACCControl;
avbotz 0:2381a319fc35 179 }
avbotz 0:2381a319fc35 180 /*
avbotz 0:2381a319fc35 181 uint32_t MODDMA_Cache::Setup(MODDMA_Config* config)
avbotz 0:2381a319fc35 182 {
avbotz 0:2381a319fc35 183 moddma_p = this;
avbotz 0:2381a319fc35 184
avbotz 0:2381a319fc35 185 //uint32_t ret = ((MODDMA*)this)->Setup(config);
avbotz 0:2381a319fc35 186 uint32_t ret = MODDMA::Setup(config);
avbotz 0:2381a319fc35 187 LPC_GPDMACH_TypeDef *pChannel = (LPC_GPDMACH_TypeDef*)Channel_p(config->channelNum());
avbotz 0:2381a319fc35 188
avbotz 0:2381a319fc35 189 DMACCSrcAddr = pChannel->DMACCSrcAddr;
avbotz 0:2381a319fc35 190 DMACCDestAddr = pChannel->DMACCDestAddr;
avbotz 0:2381a319fc35 191 DMACCLLI = pChannel->DMACCLLI;
avbotz 0:2381a319fc35 192 //DMACCControl = pChannel->DMACCControl;
avbotz 0:2381a319fc35 193
avbotz 0:2381a319fc35 194 switch (config->transferType())
avbotz 0:2381a319fc35 195 {
avbotz 0:2381a319fc35 196 case p2m:
avbotz 0:2381a319fc35 197 DMACCControl
avbotz 0:2381a319fc35 198 = CxControl_TransferSize((uint32_t)config->transferSize())
avbotz 0:2381a319fc35 199 | CxControl_SBSize((uint32_t)LUTPerBurst(config->srcConn()))
avbotz 0:2381a319fc35 200 | CxControl_DBSize((uint32_t)LUTPerBurst(config->srcConn()))
avbotz 0:2381a319fc35 201 | CxControl_SWidth((uint32_t)LUTPerWid(config->srcConn()))
avbotz 0:2381a319fc35 202 | CxControl_DWidth((uint32_t)LUTPerWid(config->srcConn()))
avbotz 0:2381a319fc35 203 | CxControl_DI()
avbotz 0:2381a319fc35 204 | CxControl_I();
avbotz 0:2381a319fc35 205 break;
avbotz 0:2381a319fc35 206
avbotz 0:2381a319fc35 207 case m2p:
avbotz 0:2381a319fc35 208 DMACCControl
avbotz 0:2381a319fc35 209 = CxControl_TransferSize((uint32_t)config->transferSize())
avbotz 0:2381a319fc35 210 | CxControl_SBSize((uint32_t)LUTPerBurst(config->dstConn()))
avbotz 0:2381a319fc35 211 | CxControl_DBSize((uint32_t)LUTPerBurst(config->dstConn()))
avbotz 0:2381a319fc35 212 | CxControl_SWidth((uint32_t)LUTPerWid(config->dstConn()))
avbotz 0:2381a319fc35 213 | CxControl_DWidth((uint32_t)LUTPerWid(config->dstConn()))
avbotz 0:2381a319fc35 214 | CxControl_SI()
avbotz 0:2381a319fc35 215 | CxControl_I();
avbotz 0:2381a319fc35 216 break;
avbotz 0:2381a319fc35 217
avbotz 0:2381a319fc35 218 default:
avbotz 0:2381a319fc35 219 return 5000; // oh no, your mbed blew up!
avbotz 0:2381a319fc35 220 }
avbotz 0:2381a319fc35 221
avbotz 0:2381a319fc35 222 uint32_t tmp1 = config->srcConn(); tmp1 = ((tmp1 > 15) ? (tmp1 - 8) : tmp1);
avbotz 0:2381a319fc35 223 uint32_t tmp2 = config->dstConn(); tmp2 = ((tmp2 > 15) ? (tmp2 - 8) : tmp2);
avbotz 0:2381a319fc35 224
avbotz 0:2381a319fc35 225 if (config->dmacSync()) {
avbotz 0:2381a319fc35 226 uint32_t tmp3 = config->dmacSync(); tmp3 = ((tmp3 > 15) ? (tmp3 - 8) : tmp3);
avbotz 0:2381a319fc35 227 LPC_GPDMA->DMACSync |= Sync_Src( tmp3 );
avbotz 0:2381a319fc35 228 }
avbotz 0:2381a319fc35 229
avbotz 0:2381a319fc35 230 uint32_t tfer_type = (uint32_t)config->transferType();
avbotz 0:2381a319fc35 231 if (tfer_type == g2m || tfer_type == m2g) {
avbotz 0:2381a319fc35 232 tfer_type -= 2; // Adjust psuedo transferType to a real transferType.
avbotz 0:2381a319fc35 233 }
avbotz 0:2381a319fc35 234
avbotz 0:2381a319fc35 235 // Configure DMA Channel, enable Error Counter and Terminate counter
avbotz 0:2381a319fc35 236 DMACCConfig = CxConfig_IE()
avbotz 0:2381a319fc35 237 | CxConfig_ITC()
avbotz 0:2381a319fc35 238 | CxConfig_TransferType(tfer_type)
avbotz 0:2381a319fc35 239 | CxConfig_SrcPeripheral(tmp1)
avbotz 0:2381a319fc35 240 | CxConfig_DestPeripheral(tmp2);
avbotz 0:2381a319fc35 241
avbotz 0:2381a319fc35 242 DMACSync = LPC_GPDMA->DMACSync;
avbotz 0:2381a319fc35 243
avbotz 0:2381a319fc35 244 return ret;
avbotz 0:2381a319fc35 245 }*/
avbotz 0:2381a319fc35 246
avbotz 0:2381a319fc35 247 // This is modified from MODDMA::Setup(). Values that don't change between DMA operations will be cached to make it faster.
avbotz 0:2381a319fc35 248 // Everything commented or deleted here wasn't necessary to restart DMA.
avbotz 0:2381a319fc35 249 /*void MODDMA_Cache::Reset(MODDMA_Config* config)
avbotz 0:2381a319fc35 250 {
avbotz 0:2381a319fc35 251 LPC_GPDMACH_TypeDef *pChannel = (LPC_GPDMACH_TypeDef*)Channel_p(config->channelNum());
avbotz 0:2381a319fc35 252
avbotz 0:2381a319fc35 253 //LPC_GPDMA->DMACIntTCClear = IntTCClear_Ch( config->channelNum() );
avbotz 0:2381a319fc35 254 //LPC_GPDMA->DMACIntErrClr = IntErrClr_Ch ( config->channelNum() );
avbotz 0:2381a319fc35 255
avbotz 0:2381a319fc35 256 //pChannel->DMACCLLI = DMACCLLI;
avbotz 0:2381a319fc35 257 pChannel->DMACCConfig = DMACCConfig;//
avbotz 0:2381a319fc35 258
avbotz 0:2381a319fc35 259 //LPC_GPDMA->DMACSync = DMACSync;
avbotz 0:2381a319fc35 260
avbotz 0:2381a319fc35 261
avbotz 0:2381a319fc35 262 //setups[config->channelNum() & 0x7] = config;
avbotz 0:2381a319fc35 263
avbotz 0:2381a319fc35 264 // Reset the Interrupt status
avbotz 0:2381a319fc35 265 LPC_GPDMA->DMACIntTCClear = IntTCClear_Ch( config->channelNum() );//
avbotz 0:2381a319fc35 266 LPC_GPDMA->DMACIntErrClr = IntErrClr_Ch ( config->channelNum() );
avbotz 0:2381a319fc35 267
avbotz 0:2381a319fc35 268 // BIGASS SWITCH WENT HERE
avbotz 0:2381a319fc35 269 pChannel->DMACCControl = DMACCControl;
avbotz 0:2381a319fc35 270
avbotz 0:2381a319fc35 271 if (config->transferType() == p2m)
avbotz 0:2381a319fc35 272 {
avbotz 0:2381a319fc35 273 pChannel->DMACCSrcAddr = DMACCSrcAddr;
avbotz 0:2381a319fc35 274 pChannel->DMACCDestAddr = config->dstMemAddr();//
avbotz 0:2381a319fc35 275 }
avbotz 0:2381a319fc35 276
avbotz 0:2381a319fc35 277 // Enable DMA channels, little endian
avbotz 0:2381a319fc35 278 pChannel->DMACCConfig |= _E;
avbotz 0:2381a319fc35 279 return;
avbotz 0:2381a319fc35 280 }
avbotz 0:2381a319fc35 281 */
avbotz 0:2381a319fc35 282
avbotz 0:2381a319fc35 283 /*
avbotz 0:2381a319fc35 284 void MODDMA_Cache::Reset(MODDMA_Config* config)
avbotz 0:2381a319fc35 285 {
avbotz 0:2381a319fc35 286 LPC_GPDMACH_TypeDef *pChannel = (LPC_GPDMACH_TypeDef*)Channel_p(config->channelNum());
avbotz 0:2381a319fc35 287
avbotz 0:2381a319fc35 288 LPC_GPDMA->DMACIntTCClear = IntTCClear_Ch( config->channelNum() );
avbotz 0:2381a319fc35 289 LPC_GPDMA->DMACIntErrClr = IntErrClr_Ch ( config->channelNum() );
avbotz 0:2381a319fc35 290
avbotz 0:2381a319fc35 291 pChannel->DMACCLLI = DMACCLLI;
avbotz 0:2381a319fc35 292 pChannel->DMACCConfig = DMACCConfig;//
avbotz 0:2381a319fc35 293
avbotz 0:2381a319fc35 294 LPC_GPDMA->DMACSync = DMACSync;
avbotz 0:2381a319fc35 295
avbotz 0:2381a319fc35 296
avbotz 0:2381a319fc35 297 setups[config->channelNum() & 0x7] = config;
avbotz 0:2381a319fc35 298
avbotz 0:2381a319fc35 299 // Reset the Interrupt status
avbotz 0:2381a319fc35 300 LPC_GPDMA->DMACIntTCClear = IntTCClear_Ch( config->channelNum() );//
avbotz 0:2381a319fc35 301 LPC_GPDMA->DMACIntErrClr = IntErrClr_Ch ( config->channelNum() );
avbotz 0:2381a319fc35 302
avbotz 0:2381a319fc35 303 // BIGASS SWITCH WENT HERE
avbotz 0:2381a319fc35 304 pChannel->DMACCControl = DMACCControl;
avbotz 0:2381a319fc35 305
avbotz 0:2381a319fc35 306 if (config->transferType() == p2m)
avbotz 0:2381a319fc35 307 {
avbotz 0:2381a319fc35 308 pChannel->DMACCSrcAddr = DMACCSrcAddr;
avbotz 0:2381a319fc35 309 pChannel->DMACCDestAddr = config->dstMemAddr();//
avbotz 0:2381a319fc35 310 }
avbotz 0:2381a319fc35 311
avbotz 0:2381a319fc35 312 // Enable DMA channels, little endian
avbotz 0:2381a319fc35 313 //pChannel->DMACCConfig |= _E;
avbotz 0:2381a319fc35 314 LPC_GPDMA->DMACConfig = _E;
avbotz 0:2381a319fc35 315 return;
avbotz 0:2381a319fc35 316 }*/
avbotz 0:2381a319fc35 317 /*
avbotz 0:2381a319fc35 318 These notes based on the LPC17xx family datasheet:
avbotz 0:2381a319fc35 319
avbotz 0:2381a319fc35 320 DMACIntTCClear
avbotz 0:2381a319fc35 321 Interrupt terminal count clear
avbotz 0:2381a319fc35 322 clear interrupt request
avbotz 0:2381a319fc35 323 from <http://dreamrunner.org/wiki/public_html/Embedded%20System/kernel/DMA.html>
avbotz 0:2381a319fc35 324 "When the value in the current count register goes from 0 to -1, a terminal count (TC) signal is generated, which signifies the completion of the DMA transfer sequence."
avbotz 0:2381a319fc35 325 "DMA controllers require reprogramming when a DMA channel reaches TC."
avbotz 0:2381a319fc35 326
avbotz 0:2381a319fc35 327 DMACIntErrClr
avbotz 0:2381a319fc35 328 Write 1 to request that some error flags be cleared
avbotz 0:2381a319fc35 329
avbotz 0:2381a319fc35 330 DMACCControl*
avbotz 0:2381a319fc35 331 contain tons of information: transfer size, burst size, transfer width, etc
avbotz 0:2381a319fc35 332 Updated by DMA controller when the linked list is followed. So may not change in our application?
avbotz 0:2381a319fc35 333
avbotz 0:2381a319fc35 334 DMACCConfig
avbotz 0:2381a319fc35 335 Contains Enable, src type, dest type, transfer type, error mask (to find/mask out the error bit), terminal count irq mask, active (whether there is data), and halt (to stop transfer)
avbotz 0:2381a319fc35 336
avbotz 0:2381a319fc35 337 DMACCLLI
avbotz 0:2381a319fc35 338 address of next linked list item. If zero, this is the last item in the list and the transfer is complete after this list item is done.
avbotz 0:2381a319fc35 339
avbotz 0:2381a319fc35 340 DMACCSrcAddr*
avbotz 0:2381a319fc35 341 User sets the starting address. DMA updates w/ current read address as it goes.
avbotz 0:2381a319fc35 342
avbotz 0:2381a319fc35 343 DMACCDestAddr*
avbotz 0:2381a319fc35 344 same idea as SrcAddr, but for the data destination
avbotz 0:2381a319fc35 345
avbotz 0:2381a319fc35 346 DMAREQSEL
avbotz 0:2381a319fc35 347 Datasheet calls it "DMAReqSel" for some reason.
avbotz 0:2381a319fc35 348 I'm not too clear on what this is.
avbotz 0:2381a319fc35 349 Lets you pick whether you want UART or Timer DMA for DMA inputs 8-15.
avbotz 0:2381a319fc35 350
avbotz 0:2381a319fc35 351 *Changes very quickly while the transfer in progress, so don't bother reading at that time
avbotz 0:2381a319fc35 352 */
avbotz 0:2381a319fc35 353 void MODDMA_Cache::Reset(MODDMA_Config *config)
avbotz 0:2381a319fc35 354 {
avbotz 0:2381a319fc35 355 /*Setup(config);
avbotz 0:2381a319fc35 356 return;*/
avbotz 0:2381a319fc35 357 LPC_GPDMACH_TypeDef *pChannel = (LPC_GPDMACH_TypeDef *)Channel_p( config->channelNum() );
avbotz 0:2381a319fc35 358
avbotz 0:2381a319fc35 359 setups[config->channelNum() & 0x7] = config;
avbotz 0:2381a319fc35 360
avbotz 0:2381a319fc35 361 // Reset the Interrupt status
avbotz 0:2381a319fc35 362 LPC_GPDMA->DMACIntTCClear = IntTCClear_Ch( config->channelNum() );
avbotz 0:2381a319fc35 363 LPC_GPDMA->DMACIntErrClr = IntErrClr_Ch ( config->channelNum() );
avbotz 0:2381a319fc35 364
avbotz 0:2381a319fc35 365 // Clear DMA configure
avbotz 0:2381a319fc35 366 pChannel->DMACCControl = 0x00;
avbotz 0:2381a319fc35 367 pChannel->DMACCConfig = 0x00;
avbotz 0:2381a319fc35 368
avbotz 0:2381a319fc35 369 // Assign Linker List Item value
avbotz 0:2381a319fc35 370 pChannel->DMACCLLI = config->dmaLLI();
avbotz 0:2381a319fc35 371
avbotz 0:2381a319fc35 372 // Set value to Channel Control Registers
avbotz 0:2381a319fc35 373 switch (config->transferType()) {
avbotz 0:2381a319fc35 374
avbotz 0:2381a319fc35 375 // Memory to memory
avbotz 0:2381a319fc35 376 case m2m:
avbotz 0:2381a319fc35 377 // Assign physical source and destination address
avbotz 0:2381a319fc35 378 pChannel->DMACCSrcAddr = config->srcMemAddr();
avbotz 0:2381a319fc35 379 pChannel->DMACCDestAddr = config->dstMemAddr();
avbotz 0:2381a319fc35 380 pChannel->DMACCControl
avbotz 0:2381a319fc35 381 = CxControl_TransferSize(config->transferSize())
avbotz 0:2381a319fc35 382 | CxControl_SBSize(_32)
avbotz 0:2381a319fc35 383 | CxControl_DBSize(_32)
avbotz 0:2381a319fc35 384 | CxControl_SWidth(config->transferWidth())
avbotz 0:2381a319fc35 385 | CxControl_DWidth(config->transferWidth())
avbotz 0:2381a319fc35 386 | CxControl_SI()
avbotz 0:2381a319fc35 387 | CxControl_DI()
avbotz 0:2381a319fc35 388 | CxControl_I();
avbotz 0:2381a319fc35 389 break;
avbotz 0:2381a319fc35 390
avbotz 0:2381a319fc35 391 // Memory to peripheral
avbotz 0:2381a319fc35 392 case m2p:
avbotz 0:2381a319fc35 393 // Assign physical source
avbotz 0:2381a319fc35 394 pChannel->DMACCSrcAddr = config->srcMemAddr();
avbotz 0:2381a319fc35 395 // Assign peripheral destination address
avbotz 0:2381a319fc35 396 pChannel->DMACCDestAddr = (uint32_t)LUTPerAddr(config->dstConn());
avbotz 0:2381a319fc35 397 pChannel->DMACCControl
avbotz 0:2381a319fc35 398 = /*DMACCControl;*/CxControl_TransferSize((uint32_t)config->transferSize())
avbotz 0:2381a319fc35 399 | CxControl_SBSize((uint32_t)LUTPerBurst(config->dstConn()))
avbotz 0:2381a319fc35 400 | CxControl_DBSize((uint32_t)LUTPerBurst(config->dstConn()))
avbotz 0:2381a319fc35 401 | CxControl_SWidth((uint32_t)LUTPerWid(config->dstConn()))
avbotz 0:2381a319fc35 402 | CxControl_DWidth((uint32_t)LUTPerWid(config->dstConn()))
avbotz 0:2381a319fc35 403 | CxControl_SI()
avbotz 0:2381a319fc35 404 | CxControl_I();
avbotz 0:2381a319fc35 405 break;
avbotz 0:2381a319fc35 406
avbotz 0:2381a319fc35 407 // Peripheral to memory
avbotz 0:2381a319fc35 408 case p2m:
avbotz 0:2381a319fc35 409 // Assign peripheral source address
avbotz 0:2381a319fc35 410 pChannel->DMACCSrcAddr = (uint32_t)LUTPerAddr(config->srcConn());
avbotz 0:2381a319fc35 411 // Assign memory destination address
avbotz 0:2381a319fc35 412 pChannel->DMACCDestAddr = config->dstMemAddr();
avbotz 0:2381a319fc35 413 pChannel->DMACCControl
avbotz 0:2381a319fc35 414 = /*DMACCControl;*/CxControl_TransferSize((uint32_t)config->transferSize())
avbotz 0:2381a319fc35 415 | CxControl_SBSize((uint32_t)LUTPerBurst(config->srcConn()))
avbotz 0:2381a319fc35 416 | CxControl_DBSize((uint32_t)LUTPerBurst(config->srcConn()))
avbotz 0:2381a319fc35 417 | CxControl_SWidth((uint32_t)LUTPerWid(config->srcConn()))
avbotz 0:2381a319fc35 418 | CxControl_DWidth((uint32_t)LUTPerWid(config->srcConn()))
avbotz 0:2381a319fc35 419 | CxControl_DI()
avbotz 0:2381a319fc35 420 | CxControl_I();
avbotz 0:2381a319fc35 421 break;
avbotz 0:2381a319fc35 422
avbotz 0:2381a319fc35 423 // Peripheral to peripheral
avbotz 0:2381a319fc35 424 case p2p:
avbotz 0:2381a319fc35 425 // Assign peripheral source address
avbotz 0:2381a319fc35 426 pChannel->DMACCSrcAddr = (uint32_t)LUTPerAddr(config->srcConn());
avbotz 0:2381a319fc35 427 // Assign peripheral destination address
avbotz 0:2381a319fc35 428 pChannel->DMACCDestAddr = (uint32_t)LUTPerAddr(config->dstConn());
avbotz 0:2381a319fc35 429 pChannel->DMACCControl
avbotz 0:2381a319fc35 430 = CxControl_TransferSize((uint32_t)config->transferSize())
avbotz 0:2381a319fc35 431 | CxControl_SBSize((uint32_t)LUTPerBurst(config->srcConn()))
avbotz 0:2381a319fc35 432 | CxControl_DBSize((uint32_t)LUTPerBurst(config->dstConn()))
avbotz 0:2381a319fc35 433 | CxControl_SWidth((uint32_t)LUTPerWid(config->srcConn()))
avbotz 0:2381a319fc35 434 | CxControl_DWidth((uint32_t)LUTPerWid(config->dstConn()))
avbotz 0:2381a319fc35 435 | CxControl_I();
avbotz 0:2381a319fc35 436 break;
avbotz 0:2381a319fc35 437
avbotz 0:2381a319fc35 438 // GPIO to memory
avbotz 0:2381a319fc35 439 case g2m:
avbotz 0:2381a319fc35 440 // Assign GPIO source address
avbotz 0:2381a319fc35 441 pChannel->DMACCSrcAddr = config->srcMemAddr();
avbotz 0:2381a319fc35 442 // Assign memory destination address
avbotz 0:2381a319fc35 443 pChannel->DMACCDestAddr = config->dstMemAddr();
avbotz 0:2381a319fc35 444 pChannel->DMACCControl
avbotz 0:2381a319fc35 445 = CxControl_TransferSize((uint32_t)config->transferSize())
avbotz 0:2381a319fc35 446 | CxControl_SBSize((uint32_t)LUTPerBurst(config->srcConn()))
avbotz 0:2381a319fc35 447 | CxControl_DBSize((uint32_t)LUTPerBurst(config->srcConn()))
avbotz 0:2381a319fc35 448 | CxControl_SWidth((uint32_t)LUTPerWid(config->srcConn()))
avbotz 0:2381a319fc35 449 | CxControl_DWidth((uint32_t)LUTPerWid(config->srcConn()))
avbotz 0:2381a319fc35 450 | CxControl_DI()
avbotz 0:2381a319fc35 451 | CxControl_I();
avbotz 0:2381a319fc35 452 break;
avbotz 0:2381a319fc35 453
avbotz 0:2381a319fc35 454 // Memory to GPIO
avbotz 0:2381a319fc35 455 case m2g:
avbotz 0:2381a319fc35 456 // Assign physical source
avbotz 0:2381a319fc35 457 pChannel->DMACCSrcAddr = config->srcMemAddr();
avbotz 0:2381a319fc35 458 // Assign peripheral destination address
avbotz 0:2381a319fc35 459 pChannel->DMACCDestAddr = config->dstMemAddr();
avbotz 0:2381a319fc35 460 pChannel->DMACCControl
avbotz 0:2381a319fc35 461 = CxControl_TransferSize((uint32_t)config->transferSize())
avbotz 0:2381a319fc35 462 | CxControl_SBSize((uint32_t)LUTPerBurst(config->dstConn()))
avbotz 0:2381a319fc35 463 | CxControl_DBSize((uint32_t)LUTPerBurst(config->dstConn()))
avbotz 0:2381a319fc35 464 | CxControl_SWidth((uint32_t)LUTPerWid(config->dstConn()))
avbotz 0:2381a319fc35 465 | CxControl_DWidth((uint32_t)LUTPerWid(config->dstConn()))
avbotz 0:2381a319fc35 466 | CxControl_SI()
avbotz 0:2381a319fc35 467 | CxControl_I();
avbotz 0:2381a319fc35 468 break;
avbotz 0:2381a319fc35 469
avbotz 0:2381a319fc35 470 // Do not support any more transfer type, return ERROR
avbotz 0:2381a319fc35 471 default:
avbotz 0:2381a319fc35 472 return;// 0;
avbotz 0:2381a319fc35 473 }
avbotz 0:2381a319fc35 474
avbotz 0:2381a319fc35 475 // Re-Configure DMA Request Select for source peripheral
avbotz 0:2381a319fc35 476 if (config->srcConn() > 15) {
avbotz 0:2381a319fc35 477 LPC_SC->DMAREQSEL |= (1 << (config->srcConn() - 16));
avbotz 0:2381a319fc35 478 }
avbotz 0:2381a319fc35 479 else {
avbotz 0:2381a319fc35 480 LPC_SC->DMAREQSEL &= ~(1 << (config->srcConn() - 8));
avbotz 0:2381a319fc35 481 }
avbotz 0:2381a319fc35 482
avbotz 0:2381a319fc35 483 // Re-Configure DMA Request Select for destination peripheral
avbotz 0:2381a319fc35 484 if (config->dstConn() > 15) {
avbotz 0:2381a319fc35 485 LPC_SC->DMAREQSEL |= (1 << (config->dstConn() - 16));
avbotz 0:2381a319fc35 486 }
avbotz 0:2381a319fc35 487 else {
avbotz 0:2381a319fc35 488 LPC_SC->DMAREQSEL &= ~(1 << (config->dstConn() - 8));
avbotz 0:2381a319fc35 489 }
avbotz 0:2381a319fc35 490
avbotz 0:2381a319fc35 491 // Enable DMA channels, little endian
avbotz 0:2381a319fc35 492 LPC_GPDMA->DMACConfig = _E;
avbotz 0:2381a319fc35 493 pChannel->DMACCConfig |= _E; // copied from MODDMA::Enable()
avbotz 0:2381a319fc35 494 while (!(LPC_GPDMA->DMACConfig & _E));
avbotz 0:2381a319fc35 495
avbotz 0:2381a319fc35 496 // Calculate absolute value for Connection number
avbotz 0:2381a319fc35 497 uint32_t tmp1 = config->srcConn(); tmp1 = ((tmp1 > 15) ? (tmp1 - 8) : tmp1);
avbotz 0:2381a319fc35 498 uint32_t tmp2 = config->dstConn(); tmp2 = ((tmp2 > 15) ? (tmp2 - 8) : tmp2);
avbotz 0:2381a319fc35 499
avbotz 0:2381a319fc35 500 if (config->dmacSync()) {
avbotz 0:2381a319fc35 501 uint32_t tmp3 = config->dmacSync(); tmp3 = ((tmp3 > 15) ? (tmp3 - 8) : tmp3);
avbotz 0:2381a319fc35 502 LPC_GPDMA->DMACSync |= Sync_Src( tmp3 );
avbotz 0:2381a319fc35 503 }
avbotz 0:2381a319fc35 504
avbotz 0:2381a319fc35 505 uint32_t tfer_type = (uint32_t)config->transferType();
avbotz 0:2381a319fc35 506 if (tfer_type == g2m || tfer_type == m2g) {
avbotz 0:2381a319fc35 507 tfer_type -= 2; // Adjust psuedo transferType to a real transferType.
avbotz 0:2381a319fc35 508 }
avbotz 0:2381a319fc35 509
avbotz 0:2381a319fc35 510 // Configure DMA Channel, enable Error Counter and Terminate counter
avbotz 0:2381a319fc35 511 pChannel->DMACCConfig
avbotz 0:2381a319fc35 512 = /*DMACCConfig;*/CxConfig_IE()
avbotz 0:2381a319fc35 513 | CxConfig_ITC()
avbotz 0:2381a319fc35 514 | CxConfig_TransferType(tfer_type)
avbotz 0:2381a319fc35 515 | CxConfig_SrcPeripheral(tmp1)
avbotz 0:2381a319fc35 516 | CxConfig_DestPeripheral(tmp2);
avbotz 0:2381a319fc35 517
avbotz 0:2381a319fc35 518 return;// pChannel->DMACCControl;
avbotz 0:2381a319fc35 519 }
avbotz 0:2381a319fc35 520
avbotz 0:2381a319fc35 521 extern "C" void MODDMA_Cache_IRQHandler()
avbotz 0:2381a319fc35 522 {
avbotz 0:2381a319fc35 523 p6_TOGGLE;
avbotz 0:2381a319fc35 524
avbotz 0:2381a319fc35 525 /*if (moddma_p == (class MODDMA *)NULL) {
avbotz 0:2381a319fc35 526 if (oldDMAHandler) {
avbotz 0:2381a319fc35 527 ((MODDMA_FN)oldDMAHandler)();
avbotz 0:2381a319fc35 528 return;
avbotz 0:2381a319fc35 529 }
avbotz 0:2381a319fc35 530 else {
avbotz 0:2381a319fc35 531 error("Interrupt without instance");
avbotz 0:2381a319fc35 532 }
avbotz 0:2381a319fc35 533 }*/
avbotz 0:2381a319fc35 534
avbotz 0:2381a319fc35 535
avbotz 0:2381a319fc35 536 // SEE UNROLLED VERSION BELOW. They are equivalent.
avbotz 0:2381a319fc35 537 for (int channel_number = 0; channel_number < 2; channel_number++)
avbotz 0:2381a319fc35 538 {
avbotz 0:2381a319fc35 539 uint32_t channel_mask = (1UL << channel_number);
avbotz 0:2381a319fc35 540
avbotz 0:2381a319fc35 541 // Since we only have one if statement inside anyway, I took this out
avbotz 0:2381a319fc35 542 //if (LPC_GPDMA->DMACIntStat & channel_mask)
avbotz 0:2381a319fc35 543 //{
avbotz 0:2381a319fc35 544 if (LPC_GPDMA->DMACIntTCStat & channel_mask)
avbotz 0:2381a319fc35 545 {
avbotz 0:2381a319fc35 546 moddma_p->setups[channel_number]->isrIntTCStat->call();
avbotz 0:2381a319fc35 547 LPC_GPDMA->DMACIntTCClear = channel_mask;
avbotz 0:2381a319fc35 548 }
avbotz 0:2381a319fc35 549
avbotz 0:2381a319fc35 550 //if (LPC_GPDMA->DMACIntErrStat & channel_mask)
avbotz 0:2381a319fc35 551 //{
avbotz 0:2381a319fc35 552 // removed for speed
avbotz 0:2381a319fc35 553 //moddma_p->setups[channel_number]->isrIntErrStat->call();
avbotz 0:2381a319fc35 554 LPC_GPDMA->DMACIntErrClr = channel_mask;
avbotz 0:2381a319fc35 555 //}
avbotz 0:2381a319fc35 556 //}
avbotz 0:2381a319fc35 557 }
avbotz 0:2381a319fc35 558
avbotz 0:2381a319fc35 559
avbotz 0:2381a319fc35 560 /*
avbotz 0:2381a319fc35 561 // This is some nasty code
avbotz 0:2381a319fc35 562 uint32_t channel_mask;
avbotz 0:2381a319fc35 563 channel_mask = (1UL << 0);
avbotz 0:2381a319fc35 564
avbotz 0:2381a319fc35 565 // Since we only have one if statement inside anyway, I took this out
avbotz 0:2381a319fc35 566 //if (LPC_GPDMA->DMACIntStat & channel_mask)
avbotz 0:2381a319fc35 567 //{
avbotz 0:2381a319fc35 568 if (LPC_GPDMA->DMACIntTCStat & channel_mask)
avbotz 0:2381a319fc35 569 {
avbotz 0:2381a319fc35 570 moddma_p->setups[0]->isrIntTCStat->call();
avbotz 0:2381a319fc35 571 LPC_GPDMA->DMACIntTCClear = channel_mask;
avbotz 0:2381a319fc35 572 }
avbotz 0:2381a319fc35 573
avbotz 0:2381a319fc35 574 //if (LPC_GPDMA->DMACIntErrStat & channel_mask)
avbotz 0:2381a319fc35 575 //{
avbotz 0:2381a319fc35 576 // removed for speed
avbotz 0:2381a319fc35 577 //moddma_p->setups[channel_number]->isrIntErrStat->call();
avbotz 0:2381a319fc35 578 LPC_GPDMA->DMACIntErrClr = channel_mask;
avbotz 0:2381a319fc35 579 //}
avbotz 0:2381a319fc35 580 //}
avbotz 0:2381a319fc35 581 channel_mask = (1UL << 1);
avbotz 0:2381a319fc35 582 // Since we only have one if statement inside anyway, I took this out
avbotz 0:2381a319fc35 583 //if (LPC_GPDMA->DMACIntStat & channel_mask)
avbotz 0:2381a319fc35 584 //{
avbotz 0:2381a319fc35 585 if (LPC_GPDMA->DMACIntTCStat & channel_mask)
avbotz 0:2381a319fc35 586 {
avbotz 0:2381a319fc35 587 moddma_p->setups[1]->isrIntTCStat->call();
avbotz 0:2381a319fc35 588 LPC_GPDMA->DMACIntTCClear = channel_mask;
avbotz 0:2381a319fc35 589 }
avbotz 0:2381a319fc35 590
avbotz 0:2381a319fc35 591 //if (LPC_GPDMA->DMACIntErrStat & channel_mask)
avbotz 0:2381a319fc35 592 //{
avbotz 0:2381a319fc35 593 // removed for speed
avbotz 0:2381a319fc35 594 //moddma_p->setups[channel_number]->isrIntErrStat->call();
avbotz 0:2381a319fc35 595 LPC_GPDMA->DMACIntErrClr = channel_mask;
avbotz 0:2381a319fc35 596 //}
avbotz 0:2381a319fc35 597 //}*/
avbotz 0:2381a319fc35 598
avbotz 0:2381a319fc35 599 p6_TOGGLE;
avbotz 0:2381a319fc35 600 }
avbotz 0:2381a319fc35 601
avbotz 0:2381a319fc35 602 void MODDMA_Cache::init()
avbotz 0:2381a319fc35 603 {
avbotz 0:2381a319fc35 604 NVIC_SetVector(DMA_IRQn, (uint32_t)MODDMA_Cache_IRQHandler);
avbotz 0:2381a319fc35 605 NVIC_EnableIRQ(DMA_IRQn);
avbotz 0:2381a319fc35 606 }