A simple library to access the DMA functionality.

Fork of SimpleDMA by Erik -

Committer:
Sissors
Date:
Sat Jan 04 14:42:33 2014 +0000
Revision:
5:d9f46ef80e20
Parent:
4:c3a84c6c432c
Refactored code, added LPC1768 support

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sissors 5:d9f46ef80e20 1 #ifdef TARGET_KL25Z
Sissors 0:d77ea45fa625 2 #include "SimpleDMA.h"
Sissors 0:d77ea45fa625 3
Sissors 3:34f5bf8adfa0 4
Sissors 0:d77ea45fa625 5
Sissors 1:0b73b00bcee8 6 SimpleDMA *SimpleDMA::irq_owner[4] = {NULL};
Sissors 1:0b73b00bcee8 7
Sissors 0:d77ea45fa625 8 SimpleDMA::SimpleDMA(int channel) {
Sissors 0:d77ea45fa625 9 this->channel(channel);
Sissors 1:0b73b00bcee8 10
Sissors 0:d77ea45fa625 11 //Enable DMA
Sissors 0:d77ea45fa625 12 SIM->SCGC6 |= 1<<1; //Enable clock to DMA mux
Sissors 0:d77ea45fa625 13 SIM->SCGC7 |= 1<<8; //Enable clock to DMA
Sissors 0:d77ea45fa625 14
Sissors 1:0b73b00bcee8 15 trigger(Trigger_ALWAYS);
Sissors 3:34f5bf8adfa0 16
Sissors 3:34f5bf8adfa0 17 NVIC_SetVector(DMA0_IRQn, (uint32_t)&irq_handler0);
Sissors 3:34f5bf8adfa0 18 NVIC_SetVector(DMA1_IRQn, (uint32_t)&irq_handler1);
Sissors 3:34f5bf8adfa0 19 NVIC_SetVector(DMA2_IRQn, (uint32_t)&irq_handler2);
Sissors 3:34f5bf8adfa0 20 NVIC_SetVector(DMA3_IRQn, (uint32_t)&irq_handler3);
Sissors 3:34f5bf8adfa0 21 NVIC_EnableIRQ(DMA0_IRQn);
Sissors 3:34f5bf8adfa0 22 NVIC_EnableIRQ(DMA1_IRQn);
Sissors 3:34f5bf8adfa0 23 NVIC_EnableIRQ(DMA2_IRQn);
Sissors 3:34f5bf8adfa0 24 NVIC_EnableIRQ(DMA3_IRQn);
Sissors 0:d77ea45fa625 25 }
Sissors 0:d77ea45fa625 26
Sissors 3:34f5bf8adfa0 27
Sissors 4:c3a84c6c432c 28 int SimpleDMA::start(int length) {
Sissors 3:34f5bf8adfa0 29 if (auto_channel)
Sissors 3:34f5bf8adfa0 30 _channel = getFreeChannel();
Sissors 3:34f5bf8adfa0 31 else
Sissors 3:34f5bf8adfa0 32 while(isBusy());
Sissors 2:fe2fcaa72434 33
Sissors 5:d9f46ef80e20 34 if (length > DMA_DSR_BCR_BCR_MASK)
Sissors 0:d77ea45fa625 35 return -1;
Sissors 4:c3a84c6c432c 36
Sissors 5:d9f46ef80e20 37 irq_owner[_channel] = this;
Sissors 5:d9f46ef80e20 38
Sissors 5:d9f46ef80e20 39 DMA0->DMA[_channel].SAR = _source;
Sissors 5:d9f46ef80e20 40 DMA0->DMA[_channel].DAR = _destination;
Sissors 5:d9f46ef80e20 41 DMA0->DMA[_channel].DSR_BCR = length;
Sissors 5:d9f46ef80e20 42 DMAMUX0->CHCFG[_channel] = _trigger;
Sissors 0:d77ea45fa625 43
Sissors 5:d9f46ef80e20 44 uint32_t config = DMA_DCR_EINT_MASK | DMA_DCR_ERQ_MASK | DMA_DCR_CS_MASK | (source_inc << DMA_DCR_SINC_SHIFT) | (destination_inc << DMA_DCR_DINC_SHIFT);
Sissors 5:d9f46ef80e20 45 switch (source_size) {
Sissors 5:d9f46ef80e20 46 case 8:
Sissors 5:d9f46ef80e20 47 config |= 1 << DMA_DCR_SSIZE_SHIFT;
Sissors 5:d9f46ef80e20 48 break;
Sissors 5:d9f46ef80e20 49 case 16:
Sissors 5:d9f46ef80e20 50 config |= 2 << DMA_DCR_SSIZE_SHIFT;
Sissors 5:d9f46ef80e20 51 break;
Sissors 5:d9f46ef80e20 52 }
Sissors 5:d9f46ef80e20 53 switch (destination_size) {
Sissors 5:d9f46ef80e20 54 case 8:
Sissors 5:d9f46ef80e20 55 config |= 1 << DMA_DCR_DSIZE_SHIFT;
Sissors 5:d9f46ef80e20 56 break;
Sissors 5:d9f46ef80e20 57 case 16:
Sissors 5:d9f46ef80e20 58 config |= 2 << DMA_DCR_DSIZE_SHIFT;
Sissors 5:d9f46ef80e20 59 break;
Sissors 5:d9f46ef80e20 60 }
Sissors 2:fe2fcaa72434 61
Sissors 5:d9f46ef80e20 62 DMA0->DMA[_channel].DCR = config;
Sissors 5:d9f46ef80e20 63
Sissors 0:d77ea45fa625 64 //Start
Sissors 0:d77ea45fa625 65 DMAMUX0->CHCFG[_channel] |= 1<<7;
Sissors 0:d77ea45fa625 66
Sissors 0:d77ea45fa625 67 return 0;
Sissors 0:d77ea45fa625 68 }
Sissors 0:d77ea45fa625 69
Sissors 3:34f5bf8adfa0 70 bool SimpleDMA::isBusy( int channel ) {
Sissors 2:fe2fcaa72434 71 //Busy bit doesn't work as I expect it to do, so just check if counter is at zero
Sissors 2:fe2fcaa72434 72 //return (DMA0->DMA[_channel].DSR_BCR & (1<<25) == 1<<25);
Sissors 3:34f5bf8adfa0 73 if (channel == -1)
Sissors 3:34f5bf8adfa0 74 channel = _channel;
Sissors 3:34f5bf8adfa0 75
Sissors 3:34f5bf8adfa0 76 return (DMA0->DMA[channel].DSR_BCR & 0xFFFFFF);
Sissors 1:0b73b00bcee8 77 }
Sissors 1:0b73b00bcee8 78
Sissors 5:d9f46ef80e20 79
Sissors 5:d9f46ef80e20 80 /*****************************************************************/
Sissors 1:0b73b00bcee8 81 void SimpleDMA::irq_handler(void) {
Sissors 1:0b73b00bcee8 82 DMAMUX0->CHCFG[_channel] = 0;
Sissors 2:fe2fcaa72434 83 DMA0->DMA[_channel].DSR_BCR |= DMA_DSR_BCR_DONE_MASK ;
Sissors 1:0b73b00bcee8 84 _callback.call();
Sissors 1:0b73b00bcee8 85 }
Sissors 5:d9f46ef80e20 86
Sissors 5:d9f46ef80e20 87 void SimpleDMA::irq_handler0( void ) {
Sissors 5:d9f46ef80e20 88 if (irq_owner[0]!=NULL)
Sissors 5:d9f46ef80e20 89 irq_owner[0]->irq_handler();
Sissors 5:d9f46ef80e20 90 }
Sissors 5:d9f46ef80e20 91
Sissors 5:d9f46ef80e20 92 void SimpleDMA::irq_handler1( void ) {
Sissors 5:d9f46ef80e20 93 if (irq_owner[1]!=NULL)
Sissors 5:d9f46ef80e20 94 irq_owner[1]->irq_handler();
Sissors 5:d9f46ef80e20 95 }
Sissors 5:d9f46ef80e20 96
Sissors 5:d9f46ef80e20 97 void SimpleDMA::irq_handler2( void ) {
Sissors 5:d9f46ef80e20 98 if (irq_owner[2]!=NULL)
Sissors 5:d9f46ef80e20 99 irq_owner[2]->irq_handler();
Sissors 5:d9f46ef80e20 100 }
Sissors 5:d9f46ef80e20 101
Sissors 5:d9f46ef80e20 102 void SimpleDMA::irq_handler3( void ) {
Sissors 5:d9f46ef80e20 103 if (irq_owner[3]!=NULL)
Sissors 5:d9f46ef80e20 104 irq_owner[3]->irq_handler();
Sissors 5:d9f46ef80e20 105 }
Sissors 5:d9f46ef80e20 106 #endif