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