A simple library to access the DMA functionality.
Fork of SimpleDMA by
Diff: SimpleDMA_KL25.cpp
- Revision:
- 0:d77ea45fa625
- Child:
- 1:0b73b00bcee8
diff -r 000000000000 -r d77ea45fa625 SimpleDMA_KL25.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SimpleDMA_KL25.cpp Fri Oct 18 07:44:42 2013 +0000 @@ -0,0 +1,88 @@ +#include "SimpleDMA.h" + +#define DMA_CHANNELS 4 + +SimpleDMA::SimpleDMA(int channel) { + this->channel(channel); + trigger(Trigger_ALWAYS); + + //Enable DMA + SIM->SCGC6 |= 1<<1; //Enable clock to DMA mux + SIM->SCGC7 |= 1<<8; //Enable clock to DMA + + DMA0->DMA[_channel].DCR |= (1<<29) + (1<<30); //Set to always use DMAMUX (If no trigger is needed we route via alwayson) +} + +int SimpleDMA::setMemory(uint32_t address, int wordsize, bool source, bool autoinc) { + //Check if it is an allowed address + switch ((uint32_t) address >> 20) { + case 0x000: + case 0x1FF: + case 0x200: + case 0x400: + break; + default: + return -1; + } + + char _size; + switch (wordsize) { + case 8: + _size = 1; + break; + case 16: + _size = 2; + break; + case 32: + _size = 0; + break; + default: + _size = 1; + } + + //Check if source or destination + if (source) { + DMA0->DMA[_channel].SAR = address; + DMA0->DMA[_channel].DCR &= ~(7<<20); + DMA0->DMA[_channel].DCR |= autoinc << 22; + DMA0->DMA[_channel].DCR |= _size << 20; + } else { + DMA0->DMA[_channel].DAR = address; + DMA0->DMA[_channel].DCR &= ~(7<<17); + DMA0->DMA[_channel].DCR |= autoinc << 19; + DMA0->DMA[_channel].DCR |= _size << 17; + } + return 0; +}; + +int SimpleDMA::trigger(SimpleDMA_Trigger trig){ + DMAMUX0->CHCFG[_channel] = 0; + DMAMUX0->CHCFG[_channel] = trig; + return 0; +} + +int SimpleDMA::start(int length) { + if (length > 0xFFFFF) + return -1; + + //Set length + DMA0->DMA[_channel].DSR_BCR &= ~0xFFFFFF; + DMA0->DMA[_channel].DSR_BCR |= length; + + //Start + //DMA0->DMA[_channel].DCR|=1<<16; + DMAMUX0->CHCFG[_channel] |= 1<<7; + + return 0; +} + +void SimpleDMA::channel(int chan) { + if (chan >= 0 && chan < DMA_CHANNELS) + _channel = chan; + else + _channel = 3; +} + +bool SimpleDMA::isBusy( void ) { + return (DMA0->DMA[_channel].DSR_BCR & (1<<25) == 1<<25); +} \ No newline at end of file