A simple library to access the DMA functionality.
Fork of SimpleDMA by
SimpleDMA_KL25.cpp
00001 #ifdef TARGET_KL25Z 00002 #include "SimpleDMA.h" 00003 00004 00005 00006 SimpleDMA *SimpleDMA::irq_owner[4] = {NULL}; 00007 00008 SimpleDMA::SimpleDMA(int channel) { 00009 this->channel(channel); 00010 00011 //Enable DMA 00012 SIM->SCGC6 |= 1<<1; //Enable clock to DMA mux 00013 SIM->SCGC7 |= 1<<8; //Enable clock to DMA 00014 00015 trigger(Trigger_ALWAYS); 00016 00017 NVIC_SetVector(DMA0_IRQn, (uint32_t)&irq_handler0); 00018 NVIC_SetVector(DMA1_IRQn, (uint32_t)&irq_handler1); 00019 NVIC_SetVector(DMA2_IRQn, (uint32_t)&irq_handler2); 00020 NVIC_SetVector(DMA3_IRQn, (uint32_t)&irq_handler3); 00021 NVIC_EnableIRQ(DMA0_IRQn); 00022 NVIC_EnableIRQ(DMA1_IRQn); 00023 NVIC_EnableIRQ(DMA2_IRQn); 00024 NVIC_EnableIRQ(DMA3_IRQn); 00025 } 00026 00027 00028 int SimpleDMA::start(int length) { 00029 if (auto_channel) 00030 _channel = getFreeChannel(); 00031 else 00032 while(isBusy()); 00033 00034 if (length > DMA_DSR_BCR_BCR_MASK) 00035 return -1; 00036 00037 irq_owner[_channel] = this; 00038 00039 DMA0->DMA[_channel].SAR = _source; 00040 DMA0->DMA[_channel].DAR = _destination; 00041 DMA0->DMA[_channel].DSR_BCR = length; 00042 DMAMUX0->CHCFG[_channel] = _trigger; 00043 00044 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); 00045 switch (source_size) { 00046 case 8: 00047 config |= 1 << DMA_DCR_SSIZE_SHIFT; 00048 break; 00049 case 16: 00050 config |= 2 << DMA_DCR_SSIZE_SHIFT; 00051 break; 00052 } 00053 switch (destination_size) { 00054 case 8: 00055 config |= 1 << DMA_DCR_DSIZE_SHIFT; 00056 break; 00057 case 16: 00058 config |= 2 << DMA_DCR_DSIZE_SHIFT; 00059 break; 00060 } 00061 00062 DMA0->DMA[_channel].DCR = config; 00063 00064 //Start 00065 DMAMUX0->CHCFG[_channel] |= 1<<7; 00066 00067 return 0; 00068 } 00069 00070 bool SimpleDMA::isBusy( int channel ) { 00071 //Busy bit doesn't work as I expect it to do, so just check if counter is at zero 00072 //return (DMA0->DMA[_channel].DSR_BCR & (1<<25) == 1<<25); 00073 if (channel == -1) 00074 channel = _channel; 00075 00076 return (DMA0->DMA[channel].DSR_BCR & 0xFFFFFF); 00077 } 00078 00079 00080 /*****************************************************************/ 00081 void SimpleDMA::irq_handler(void) { 00082 DMAMUX0->CHCFG[_channel] = 0; 00083 DMA0->DMA[_channel].DSR_BCR |= DMA_DSR_BCR_DONE_MASK ; 00084 _callback.call(); 00085 } 00086 00087 void SimpleDMA::irq_handler0( void ) { 00088 if (irq_owner[0]!=NULL) 00089 irq_owner[0]->irq_handler(); 00090 } 00091 00092 void SimpleDMA::irq_handler1( void ) { 00093 if (irq_owner[1]!=NULL) 00094 irq_owner[1]->irq_handler(); 00095 } 00096 00097 void SimpleDMA::irq_handler2( void ) { 00098 if (irq_owner[2]!=NULL) 00099 irq_owner[2]->irq_handler(); 00100 } 00101 00102 void SimpleDMA::irq_handler3( void ) { 00103 if (irq_owner[3]!=NULL) 00104 irq_owner[3]->irq_handler(); 00105 } 00106 #endif
Generated on Fri Jul 15 2022 17:30:44 by 1.7.2