DMA library for the KL25Z

Dependents:   SimpleDMA_HelloWorld RTOS_SPI spiDMAtest Pinscape_Controller_v1 ... more

Introduction

SimpleDMA is a standard library for different DMA peripherals. Currently the LPC1768, KL46Z and KL25Z are supported. It provided one set of functions for different peripherals. It does not allow for usage of all the advanced functions, partially because the goal was to provide a simple interface, and partially because they are different for different microcontrollers.

Examples

Helloworld: http://mbed.org/users/Sissors/code/SimpleDMA_HelloWorld/

Example in a library (SPI): http://mbed.org/users/Sissors/code/RTOS_SPI/

Committer:
Tomo2k
Date:
Fri Jun 27 10:12:27 2014 +0000
Revision:
7:d3be727fa9d2
Child:
8:876f3b55e6f5
Added support for KL46

Who changed what in which revision?

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