A simple library to access the DMA functionality.
Fork of SimpleDMA by
SimpleDMA_KL25.cpp@5:d9f46ef80e20, 2014-01-04 (annotated)
- 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?
User | Revision | Line number | New 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 |