A simple library to access the DMA functionality.
Fork of SimpleDMA by
Diff: SimpleDMA_KL25.cpp
- Revision:
- 2:fe2fcaa72434
- Parent:
- 1:0b73b00bcee8
- Child:
- 3:34f5bf8adfa0
--- a/SimpleDMA_KL25.cpp Fri Dec 20 20:48:17 2013 +0000 +++ b/SimpleDMA_KL25.cpp Sun Dec 22 21:42:49 2013 +0000 @@ -13,7 +13,7 @@ trigger(Trigger_ALWAYS); - DMA0->DMA[_channel].DCR |= (1<<29) + (1<<30); //Set to always use DMAMUX (If no trigger is needed we route via alwayson) + DCR = (1<<29) + (1<<30); //Set to always use DMAMUX (If no trigger is needed we route via alwayson) uint32_t handler = NULL; switch (_channel) { @@ -39,7 +39,7 @@ irq_owner[_channel] = this; } -int SimpleDMA::setMemory(uint32_t address, int wordsize, bool source, bool autoinc) { +int SimpleDMA::setAddress(uint32_t address, int wordsize, bool source, bool autoinc) { //Check if it is an allowed address switch ((uint32_t) address >> 20) { case 0x000: @@ -68,39 +68,47 @@ //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; + SAR = address; + DCR &= ~(7<<20); + DCR |= autoinc << 22; + 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; + DAR = address; + DCR &= ~(7<<17); + DCR |= autoinc << 19; + DCR |= _size << 17; } return 0; }; int SimpleDMA::trigger(SimpleDMA_Trigger trig){ - DMAMUX0->CHCFG[_channel] = trig; + CHCFG = trig; return 0; } int SimpleDMA::start(int length) { - + while(isBusy()); + DMA0->DMA[_channel].DSR_BCR |= DMA_DSR_BCR_DONE_MASK ; + if (length > 0xFFFFF) return -1; - //Set length - DMA0->DMA[_channel].DSR_BCR &= ~0xFFFFFF; - DMA0->DMA[_channel].DSR_BCR |= length; + if (irq_en) + DCR |= (1UL<<31); + else + DCR &= ~(1UL<<31); - //Enable interrupts - if (irq_en) - DMA0->DMA[_channel].DCR |= (uint32_t)(1<<31); - else - DMA0->DMA[_channel].DCR &= ~(1<<31); + //Set registers: + DMA0->DMA[_channel].SAR = SAR; + DMA0->DMA[_channel].DAR = DAR; + DMA0->DMA[_channel].DCR = DCR; + + //Set trigger + DMAMUX0->CHCFG[_channel] = CHCFG; + + //Set length + DMA0->DMA[_channel].DSR_BCR = length; //Start DMAMUX0->CHCFG[_channel] |= 1<<7; @@ -116,11 +124,13 @@ } bool SimpleDMA::isBusy( void ) { - return (DMA0->DMA[_channel].DSR_BCR & (1<<25) == 1<<25); + //Busy bit doesn't work as I expect it to do, so just check if counter is at zero + //return (DMA0->DMA[_channel].DSR_BCR & (1<<25) == 1<<25); + return (DMA0->DMA[_channel].DSR_BCR &0xFFFFFF); } void SimpleDMA::irq_handler(void) { DMAMUX0->CHCFG[_channel] = 0; - DMA0->DMA[0].DSR_BCR |= DMA_DSR_BCR_DONE_MASK ; + DMA0->DMA[_channel].DSR_BCR |= DMA_DSR_BCR_DONE_MASK ; _callback.call(); }