Mirror with some correction

Dependencies:   mbed FastIO FastPWM USBDevice

Committer:
arnoz
Date:
Fri Oct 01 08:19:46 2021 +0000
Revision:
116:7a67265d7c19
Parent:
45:c42166b2878c
- Correct information regarding your last merge

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mjr 45:c42166b2878c 1 #ifdef TARGET_LPC1768
mjr 45:c42166b2878c 2
mjr 45:c42166b2878c 3 #include "SimpleDMA.h"
mjr 45:c42166b2878c 4
mjr 45:c42166b2878c 5 SimpleDMA *SimpleDMA::irq_owner[8] = {NULL};
mjr 45:c42166b2878c 6 LPC_GPDMACH_TypeDef *LPC_GPDMACH[8] = {LPC_GPDMACH0, LPC_GPDMACH1, LPC_GPDMACH2, LPC_GPDMACH3, LPC_GPDMACH4, LPC_GPDMACH5, LPC_GPDMACH6, LPC_GPDMACH7};
mjr 45:c42166b2878c 7 uint32_t getTransferType(SimpleDMA_Trigger trig, uint32_t source, uint32_t destination);
mjr 45:c42166b2878c 8
mjr 45:c42166b2878c 9 SimpleDMA::SimpleDMA(int channel) {
mjr 45:c42166b2878c 10 this->channel(channel);
mjr 45:c42166b2878c 11
mjr 45:c42166b2878c 12 //Power up
mjr 45:c42166b2878c 13 LPC_SC->PCONP |= 1<<29;
mjr 45:c42166b2878c 14 LPC_GPDMA->DMACConfig = 1;
mjr 45:c42166b2878c 15 trigger(Trigger_ALWAYS);
mjr 45:c42166b2878c 16
mjr 45:c42166b2878c 17 NVIC_SetVector(DMA_IRQn, (uint32_t)&irq_handler0);
mjr 45:c42166b2878c 18 NVIC_EnableIRQ(DMA_IRQn);
mjr 45:c42166b2878c 19 }
mjr 45:c42166b2878c 20
mjr 45:c42166b2878c 21 int SimpleDMA::start(uint32_t length) {
mjr 45:c42166b2878c 22 if (auto_channel)
mjr 45:c42166b2878c 23 _channel = getFreeChannel();
mjr 45:c42166b2878c 24 else
mjr 45:c42166b2878c 25 while(isBusy());
mjr 45:c42166b2878c 26
mjr 45:c42166b2878c 27 uint32_t control = (source_inc << 26) | (destination_inc << 27) | (1UL << 31);
mjr 45:c42166b2878c 28 switch (source_size) {
mjr 45:c42166b2878c 29 case 16:
mjr 45:c42166b2878c 30 control |= (1<<18) | (length >> 1);
mjr 45:c42166b2878c 31 break;
mjr 45:c42166b2878c 32 case 32:
mjr 45:c42166b2878c 33 control |= (2<<18) | (length >> 2);
mjr 45:c42166b2878c 34 break;
mjr 45:c42166b2878c 35 default:
mjr 45:c42166b2878c 36 control |= length;
mjr 45:c42166b2878c 37 }
mjr 45:c42166b2878c 38 switch (destination_size) {
mjr 45:c42166b2878c 39 case 16:
mjr 45:c42166b2878c 40 control |= (1<<21);
mjr 45:c42166b2878c 41 break;
mjr 45:c42166b2878c 42 case 32:
mjr 45:c42166b2878c 43 control |= (2<<21);
mjr 45:c42166b2878c 44 break;
mjr 45:c42166b2878c 45 }
mjr 45:c42166b2878c 46
mjr 45:c42166b2878c 47 LPC_GPDMACH[_channel]->DMACCSrcAddr = _source;
mjr 45:c42166b2878c 48 LPC_GPDMACH[_channel]->DMACCDestAddr = _destination;
mjr 45:c42166b2878c 49 LPC_GPDMACH[_channel]->DMACCLLI = 0;
mjr 45:c42166b2878c 50 LPC_GPDMACH[_channel]->DMACCControl = control; //Enable interrupt also
mjr 45:c42166b2878c 51
mjr 45:c42166b2878c 52 irq_owner[_channel] = this;
mjr 45:c42166b2878c 53
mjr 45:c42166b2878c 54 if (_trigger != Trigger_ALWAYS) {
mjr 45:c42166b2878c 55 if (_trigger & 16)
mjr 45:c42166b2878c 56 LPC_SC->DMAREQSEL |= 1 << (_trigger - 24);
mjr 45:c42166b2878c 57 else
mjr 45:c42166b2878c 58 LPC_SC->DMAREQSEL &= ~(1 << (_trigger - 24));
mjr 45:c42166b2878c 59
mjr 45:c42166b2878c 60 LPC_GPDMACH[_channel]->DMACCConfig = ((_trigger & 15) << 1) + ((_trigger & 15) << 6) + (getTransferType(_trigger, _source, _destination) << 11) + (1<<15) +1; //Both parts of the transfer get triggered at same time
mjr 45:c42166b2878c 61 } else
mjr 45:c42166b2878c 62 LPC_GPDMACH[_channel]->DMACCConfig = (getTransferType(_trigger, _source, _destination) << 11) + 1 + (1<<15); //Enable channel
mjr 45:c42166b2878c 63
mjr 45:c42166b2878c 64 return 0;
mjr 45:c42166b2878c 65 }
mjr 45:c42166b2878c 66
mjr 45:c42166b2878c 67 bool SimpleDMA::isBusy( int channel ) {
mjr 45:c42166b2878c 68 if (channel == -1)
mjr 45:c42166b2878c 69 channel = _channel;
mjr 45:c42166b2878c 70 return (LPC_GPDMA->DMACEnbldChns & (1<<channel));
mjr 45:c42166b2878c 71 }
mjr 45:c42166b2878c 72
mjr 45:c42166b2878c 73 void SimpleDMA::irq_handler0(void) {
mjr 45:c42166b2878c 74 while(LPC_GPDMA->DMACIntTCStat != 0) {
mjr 45:c42166b2878c 75
mjr 45:c42166b2878c 76 uint32_t intloc = 31 - __CLZ(LPC_GPDMA->DMACIntTCStat & 0xFF);
mjr 45:c42166b2878c 77 if (irq_owner[intloc]!=NULL)
mjr 45:c42166b2878c 78 irq_owner[intloc]->irq_handler();
mjr 45:c42166b2878c 79 }
mjr 45:c42166b2878c 80 }
mjr 45:c42166b2878c 81
mjr 45:c42166b2878c 82 void SimpleDMA::irq_handler(void) {
mjr 45:c42166b2878c 83 LPC_GPDMA->DMACIntTCClear = 1<<_channel;
mjr 45:c42166b2878c 84 _callback.call();
mjr 45:c42166b2878c 85 }
mjr 45:c42166b2878c 86
mjr 45:c42166b2878c 87 static inline bool isMemory(uint32_t addr)
mjr 45:c42166b2878c 88 {
mjr 45:c42166b2878c 89 return (addr >> 28) == 0 || (addr >> 28) == 1 || ((addr >= 0x2007C000) && (addr < (0x2007C000 + 0x8000)));
mjr 45:c42166b2878c 90 }
mjr 45:c42166b2878c 91
mjr 45:c42166b2878c 92 uint32_t getTransferType(SimpleDMA_Trigger trig, uint32_t source, uint32_t destination) {
mjr 45:c42166b2878c 93 //If it is always, simply put it on memory-to-memory
mjr 45:c42166b2878c 94 if (trig == Trigger_ALWAYS)
mjr 45:c42166b2878c 95 return 0;
mjr 45:c42166b2878c 96 else if (isMemory(source)) { //if source is RAM/Flash
mjr 45:c42166b2878c 97 if (isMemory(destination)) //if destination is RAM/flash
mjr 45:c42166b2878c 98 return 3; //Return p2p for m2m with a trigger (since I have no idea wtf you are trying to do)
mjr 45:c42166b2878c 99 else
mjr 45:c42166b2878c 100 return 1; //Source is memory, destination is peripheral, so m2p
mjr 45:c42166b2878c 101 }
mjr 45:c42166b2878c 102 else {
mjr 45:c42166b2878c 103 if (isMemory(destination))
mjr 45:c42166b2878c 104 return 2; //Source is peripheral, destination is memory
mjr 45:c42166b2878c 105 else
mjr 45:c42166b2878c 106 return 3; //Both source and destination are peripherals
mjr 45:c42166b2878c 107 }
mjr 45:c42166b2878c 108
mjr 45:c42166b2878c 109 }
mjr 45:c42166b2878c 110 #endif