Satellite Observers Workbench. NOT yet complete, just published for forum posters to \"cherry pick\" pieces of code as requiered as an example.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers dma.c Source File

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