MODDMA GPDMA Controller New features: transfer pins to memory buffer under periodic timer control and send double buffers to DAC

Dependents:   FirstTest WaveSim IO-dma-memmem DACDMAfuncgenlib ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers example3.h Source File

example3.h

00001 /*
00002  * Demonstrates capturing the GPIO P0.4 to P0.7 "nibble" to memory 
00003  * using GPDMA. The transfers from port pins to memory buffer are
00004  * triggered using Timer1 MAT1.0 match compare.
00005  *
00006  * In this example all inputs have pullups. So with nothing connected
00007  * the P0.4/7 reads as 0xF. Connecting a wire from one or more of the four 
00008  * inputs to ground will show up in the captured buffer sequence.
00009  */
00010  
00011 #include "mbed.h"
00012 #include "MODDMA.h"
00013 #include "iomacros.h" // within MODDMA library.
00014 
00015 // How long between grabbing GPIO FIO0PIN register.
00016 // Value is in microseconds. (500000 is half a second).
00017 #define SAMPLE_PERIOD   500000
00018 
00019 #define NUM_OF_SAMPLES  5
00020 
00021 Serial pc(USBTX, USBRX);
00022 
00023 DigitalOut led1(LED1);
00024 DigitalOut led2(LED2);
00025 DigitalOut led3(LED3);
00026 
00027 uint32_t buffer[NUM_OF_SAMPLES];
00028 
00029 bool dmaTransferComplete;
00030 
00031 MODDMA dma;
00032 MODDMA_Config *conf;
00033 
00034 void TC0_callback(void);
00035 void ERR0_callback(void);
00036 
00037 int main() {
00038     volatile int life_counter = 0;
00039      
00040     // Macros defined in iomacros.h, saves messing with DigitalIn
00041     p30_AS_INPUT; p30_MODE( PIN_PULLUP ); // P0.4
00042     p29_AS_INPUT; p29_MODE( PIN_PULLUP ); // P0.5
00043     p8_AS_INPUT;  p8_MODE( PIN_PULLUP );  // P0.6
00044     p7_AS_INPUT;  p7_MODE( PIN_PULLUP );  // P0.7
00045     
00046     // Clear the buffer.
00047     memset(buffer, 0, sizeof(buffer));
00048     
00049     // Setup the serial port to print out results.
00050     pc.baud(115200);
00051     pc.printf("Starting up...\n");
00052     
00053     // Set-up timer1 as a periodic timer.
00054     LPC_SC->PCONP    |= (1UL << 2); // TIM1 On
00055     LPC_SC->PCLKSEL0 |= (3UL << 4); // CCLK/8 = 12MHz
00056     LPC_TIM1->PR      = 11;         // TC clocks at 1MHz.
00057     LPC_TIM1->MCR     = 2;          // Reset TCR to zero on match.
00058     LPC_TIM1->MR0     = SAMPLE_PERIOD;
00059     
00060     // Prepare the GPDMA system.
00061     conf = new MODDMA_Config;
00062     conf
00063      ->channelNum    ( MODDMA::Channel_0 )
00064      ->srcMemAddr    ( (uint32_t)&LPC_GPIO0->FIOPIN )
00065      ->dstMemAddr    ( (uint32_t)&buffer[0] )
00066      ->transferSize  ( NUM_OF_SAMPLES )
00067      ->transferType  ( MODDMA::g2m ) // pseudo transfer code MODDMA understands.
00068      ->transferWidth ( MODDMA::word )
00069      ->srcConn       ( MODDMA::MAT1_0 )
00070      ->dmacSync      ( MODDMA::MAT1_0 ) 
00071      ->attach_tc     ( TC0_callback )
00072      ->attach_err    ( ERR0_callback )
00073     ; // end conf.
00074     
00075     // Prepare configuration.
00076     if (!dma.Setup( conf )) {
00077         error("Doh!");
00078     }
00079     
00080     // Enable GPDMA to be ready for the TIM1 "ticks".       
00081     dma.Enable( conf );
00082     
00083     // Begin.
00084     LPC_TIM1->TCR = 1;
00085        
00086     while (1) { 
00087         if (life_counter++ > 1000000) {
00088             led1 = !led1; // Show some sort of life.
00089             life_counter = 0;
00090         }
00091         
00092         if (dmaTransferComplete) {
00093             dmaTransferComplete = false;
00094             for (int i = 0; i < NUM_OF_SAMPLES; i++) {
00095                 int val = (buffer[i] >> 4) & 0xF; 
00096                 pc.printf("Buffer index %d = 0x%x\n", i, val);
00097             }
00098             pc.printf("Done.\n");
00099             
00100             // Schedule another grab.
00101             if (dma.Setup( conf )) {        
00102                 dma.Enable( conf );                
00103             }            
00104         }
00105     }       
00106 }
00107 
00108 // Configuration callback on TC
00109 void TC0_callback(void) {
00110     
00111     // Just show sample sequence grab complete.
00112     led3 = !led3; 
00113         
00114     // Get configuration pointer.
00115     MODDMA_Config *config = dma.getConfig();
00116     
00117     // Finish the DMA cycle by shutting down the channel.
00118     dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
00119     
00120     // Tell main() while(1) loop to print the results.
00121     dmaTransferComplete = true;            
00122     
00123     // Clear DMA IRQ flags.
00124     if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();    
00125     if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq();    
00126 }
00127 
00128 // Configuration callback on Error
00129 void ERR0_callback(void) {
00130     error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem");
00131 }