Satellite Observers Workbench. NOT yet complete, just published for forum posters to \"cherry pick\" pieces of code as requiered as an example.
dma.c
00001 /**************************************************************************** 00002 * Copyright 2010 Andy Kirkham, Stellar Technologies Ltd 00003 * 00004 * This file is part of the Satellite Observers Workbench (SOWB). 00005 * 00006 * SOWB is free software: you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation, either version 3 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * SOWB is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with SOWB. If not, see <http://www.gnu.org/licenses/>. 00018 * 00019 * $Id: main.cpp 5 2010-07-12 20:51:11Z ajk $ 00020 * 00021 ***************************************************************************/ 00022 00023 #include "sowb.h" 00024 #include "debug.h" 00025 #include "dma.h" 00026 00027 uint32_t channel_in_use_flags = 0; 00028 00029 /* Declare callback functions here before placing 00030 in the array below. */ 00031 int flash_read_dma0_irq(int); 00032 int flash_read_dma1_irq(int); 00033 int flash_write_dma0_irq(int); 00034 00035 /* Make sure each array definition below ends with 00036 a NULL,NULL struct to mark the end of the array. */ 00037 00038 const DMA_CALLBACKS dma_channel0[] = { 00039 { flash_read_dma0_irq, flash_read_dma0_irq }, 00040 { flash_write_dma0_irq, flash_write_dma0_irq }, 00041 { NULL, NULL } 00042 }; 00043 00044 const DMA_CALLBACKS dma_channel1[] = { 00045 { flash_read_dma1_irq, flash_read_dma1_irq }, 00046 { NULL, NULL } 00047 }; 00048 00049 const DMA_CALLBACKS dma_channel2[] = { 00050 { NULL, NULL } 00051 }; 00052 00053 const DMA_CALLBACKS dma_channel3[] = { 00054 { NULL, NULL } 00055 }; 00056 00057 const DMA_CALLBACKS dma_channel4[] = { 00058 { NULL, NULL } 00059 }; 00060 00061 const DMA_CALLBACKS dma_channel5[] = { 00062 { NULL, NULL } 00063 }; 00064 00065 const DMA_CALLBACKS dma_channel6[] = { 00066 { NULL, NULL } 00067 }; 00068 00069 const DMA_CALLBACKS dma_channel7[] = { 00070 { NULL, NULL } 00071 }; 00072 00073 /* Don't change anything below here. */ 00074 00075 /* An array of pointers to the channel ISR handlers. */ 00076 const DMA_CALLBACKS *dma_channels[8] = { 00077 dma_channel0, dma_channel1, dma_channel2, dma_channel3, 00078 dma_channel4, dma_channel5, dma_channel6, dma_channel7 00079 }; 00080 00081 /** DMA_IRQHandler 00082 */ 00083 extern "C" void DMA_IRQHandler(void) __irq { 00084 for (int channel_number = 0; channel_number < 8; channel_number++) { 00085 if (LPC_GPDMA->DMACIntStat & (1UL << channel_number)) { 00086 if (LPC_GPDMA->DMACIntTCStat & (1UL << channel_number)) { 00087 int irq_idx = 0; 00088 while (dma_channels[channel_number][irq_idx].TcCallback != NULL) { 00089 if ((dma_channels[channel_number][irq_idx].TcCallback)(channel_number)) { 00090 LPC_GPDMA->DMACIntTCClear = (1UL << channel_number); 00091 break; 00092 } 00093 irq_idx++; 00094 } 00095 } 00096 if (LPC_GPDMA->DMACIntErrStat & (1UL << channel_number)) { 00097 int irq_idx = 0; 00098 while (dma_channels[channel_number][irq_idx].ErrCallback != NULL) { 00099 if ((dma_channels[channel_number][irq_idx].ErrCallback)(channel_number)) { 00100 LPC_GPDMA->DMACIntErrClr = (1UL << channel_number); 00101 break; 00102 } 00103 irq_idx++; 00104 } 00105 } 00106 } 00107 } 00108 00109 /* IRQ should be handled by now, check to make sure. */ 00110 if (LPC_GPDMA->DMACIntStat) { 00111 LPC_GPDMA->DMACIntTCClear = (uint32_t)0xFF; /* If not, clear anyway! */ 00112 } 00113 if (LPC_GPDMA->DMACIntErrStat) { 00114 LPC_GPDMA->DMACIntErrClr = (uint32_t)0xFF; /* If not, clear anyway! */ 00115 } 00116 } 00117 00118 00119 /** DMA_init 00120 */ 00121 void DMA_init(void) { 00122 DEBUG_INIT_START; 00123 LPC_SC->PCONP |= (1UL << 29); 00124 LPC_GPDMA->DMACConfig = 1; 00125 NVIC_SetVector(DMA_IRQn, (uint32_t)DMA_IRQHandler); 00126 NVIC_EnableIRQ(DMA_IRQn); 00127 DEBUG_INIT_END; 00128 } 00129 00130 /** DMA_process 00131 */ 00132 void DMA_process(void) { 00133 /* Nothing to do. */ 00134 } 00135 00136 /** dma_request_channel 00137 * 00138 * Used to request control of a DMA channel. Allows modules 00139 * to share channels if needed. 00140 * 00141 * @param int channel The channel being requested. 00142 * @return bool true if given control, false if another is already in control. 00143 */ 00144 bool DMA_request_channel(int channel) { 00145 if (!(channel_in_use_flags & (1UL << channel))) { 00146 channel_in_use_flags |= (1UL << channel); 00147 return true; 00148 } 00149 return false; 00150 } 00151 00152 /** dma_release_channel 00153 * 00154 * Used to release a previously requested channel. 00155 * 00156 * @param int channel The channel to release. 00157 */ 00158 void DMA_release_channel(int channel) { 00159 channel_in_use_flags &= ~(1UL << channel); 00160 } 00161
Generated on Tue Jul 12 2022 18:05:34 by 1.7.2