A simple library to access the DMA functionality.

Fork of SimpleDMA by Erik -

Committer:
Sissors
Date:
Fri Oct 18 07:44:42 2013 +0000
Revision:
0:d77ea45fa625
Child:
1:0b73b00bcee8
v0.1, KL25, no interrupt

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sissors 0:d77ea45fa625 1 #include "SimpleDMA.h"
Sissors 0:d77ea45fa625 2
Sissors 0:d77ea45fa625 3 #define DMA_CHANNELS 4
Sissors 0:d77ea45fa625 4
Sissors 0:d77ea45fa625 5 SimpleDMA::SimpleDMA(int channel) {
Sissors 0:d77ea45fa625 6 this->channel(channel);
Sissors 0:d77ea45fa625 7 trigger(Trigger_ALWAYS);
Sissors 0:d77ea45fa625 8
Sissors 0:d77ea45fa625 9 //Enable DMA
Sissors 0:d77ea45fa625 10 SIM->SCGC6 |= 1<<1; //Enable clock to DMA mux
Sissors 0:d77ea45fa625 11 SIM->SCGC7 |= 1<<8; //Enable clock to DMA
Sissors 0:d77ea45fa625 12
Sissors 0:d77ea45fa625 13 DMA0->DMA[_channel].DCR |= (1<<29) + (1<<30); //Set to always use DMAMUX (If no trigger is needed we route via alwayson)
Sissors 0:d77ea45fa625 14 }
Sissors 0:d77ea45fa625 15
Sissors 0:d77ea45fa625 16 int SimpleDMA::setMemory(uint32_t address, int wordsize, bool source, bool autoinc) {
Sissors 0:d77ea45fa625 17 //Check if it is an allowed address
Sissors 0:d77ea45fa625 18 switch ((uint32_t) address >> 20) {
Sissors 0:d77ea45fa625 19 case 0x000:
Sissors 0:d77ea45fa625 20 case 0x1FF:
Sissors 0:d77ea45fa625 21 case 0x200:
Sissors 0:d77ea45fa625 22 case 0x400:
Sissors 0:d77ea45fa625 23 break;
Sissors 0:d77ea45fa625 24 default:
Sissors 0:d77ea45fa625 25 return -1;
Sissors 0:d77ea45fa625 26 }
Sissors 0:d77ea45fa625 27
Sissors 0:d77ea45fa625 28 char _size;
Sissors 0:d77ea45fa625 29 switch (wordsize) {
Sissors 0:d77ea45fa625 30 case 8:
Sissors 0:d77ea45fa625 31 _size = 1;
Sissors 0:d77ea45fa625 32 break;
Sissors 0:d77ea45fa625 33 case 16:
Sissors 0:d77ea45fa625 34 _size = 2;
Sissors 0:d77ea45fa625 35 break;
Sissors 0:d77ea45fa625 36 case 32:
Sissors 0:d77ea45fa625 37 _size = 0;
Sissors 0:d77ea45fa625 38 break;
Sissors 0:d77ea45fa625 39 default:
Sissors 0:d77ea45fa625 40 _size = 1;
Sissors 0:d77ea45fa625 41 }
Sissors 0:d77ea45fa625 42
Sissors 0:d77ea45fa625 43 //Check if source or destination
Sissors 0:d77ea45fa625 44 if (source) {
Sissors 0:d77ea45fa625 45 DMA0->DMA[_channel].SAR = address;
Sissors 0:d77ea45fa625 46 DMA0->DMA[_channel].DCR &= ~(7<<20);
Sissors 0:d77ea45fa625 47 DMA0->DMA[_channel].DCR |= autoinc << 22;
Sissors 0:d77ea45fa625 48 DMA0->DMA[_channel].DCR |= _size << 20;
Sissors 0:d77ea45fa625 49 } else {
Sissors 0:d77ea45fa625 50 DMA0->DMA[_channel].DAR = address;
Sissors 0:d77ea45fa625 51 DMA0->DMA[_channel].DCR &= ~(7<<17);
Sissors 0:d77ea45fa625 52 DMA0->DMA[_channel].DCR |= autoinc << 19;
Sissors 0:d77ea45fa625 53 DMA0->DMA[_channel].DCR |= _size << 17;
Sissors 0:d77ea45fa625 54 }
Sissors 0:d77ea45fa625 55 return 0;
Sissors 0:d77ea45fa625 56 };
Sissors 0:d77ea45fa625 57
Sissors 0:d77ea45fa625 58 int SimpleDMA::trigger(SimpleDMA_Trigger trig){
Sissors 0:d77ea45fa625 59 DMAMUX0->CHCFG[_channel] = 0;
Sissors 0:d77ea45fa625 60 DMAMUX0->CHCFG[_channel] = trig;
Sissors 0:d77ea45fa625 61 return 0;
Sissors 0:d77ea45fa625 62 }
Sissors 0:d77ea45fa625 63
Sissors 0:d77ea45fa625 64 int SimpleDMA::start(int length) {
Sissors 0:d77ea45fa625 65 if (length > 0xFFFFF)
Sissors 0:d77ea45fa625 66 return -1;
Sissors 0:d77ea45fa625 67
Sissors 0:d77ea45fa625 68 //Set length
Sissors 0:d77ea45fa625 69 DMA0->DMA[_channel].DSR_BCR &= ~0xFFFFFF;
Sissors 0:d77ea45fa625 70 DMA0->DMA[_channel].DSR_BCR |= length;
Sissors 0:d77ea45fa625 71
Sissors 0:d77ea45fa625 72 //Start
Sissors 0:d77ea45fa625 73 //DMA0->DMA[_channel].DCR|=1<<16;
Sissors 0:d77ea45fa625 74 DMAMUX0->CHCFG[_channel] |= 1<<7;
Sissors 0:d77ea45fa625 75
Sissors 0:d77ea45fa625 76 return 0;
Sissors 0:d77ea45fa625 77 }
Sissors 0:d77ea45fa625 78
Sissors 0:d77ea45fa625 79 void SimpleDMA::channel(int chan) {
Sissors 0:d77ea45fa625 80 if (chan >= 0 && chan < DMA_CHANNELS)
Sissors 0:d77ea45fa625 81 _channel = chan;
Sissors 0:d77ea45fa625 82 else
Sissors 0:d77ea45fa625 83 _channel = 3;
Sissors 0:d77ea45fa625 84 }
Sissors 0:d77ea45fa625 85
Sissors 0:d77ea45fa625 86 bool SimpleDMA::isBusy( void ) {
Sissors 0:d77ea45fa625 87 return (DMA0->DMA[_channel].DSR_BCR & (1<<25) == 1<<25);
Sissors 0:d77ea45fa625 88 }