Fork of Andy Kirkham's MODDMA GPDMA Controller for Mbed OS 6

Read MODDMA for more info.

Files at this revision

API Documentation at this revision

Comitter:
hudakz
Date:
Mon Dec 12 15:05:21 2022 +0000
Parent:
18:31f858967e93
Child:
20:01d0a680e45a
Commit message:
Fork of Andy Kirkham's MODDMA GPDMA Controller for Mbed OS 6.; The examples are updated in order to compile with Mbed OS 6.

Changed in this revision

example1.h Show annotated file Show diff for this revision Revisions of this file
example2.h Show annotated file Show diff for this revision Revisions of this file
example3.h Show annotated file Show diff for this revision Revisions of this file
example4.h Show annotated file Show diff for this revision Revisions of this file
--- a/example1.h	Sat Dec 10 09:59:10 2022 +0000
+++ b/example1.h	Mon Dec 12 15:05:21 2022 +0000
@@ -1,81 +1,89 @@
 #include "mbed.h"
 #include "MODDMA.h"
-#include "MODSERIAL.h"
 
-DigitalOut led1(LED1);
-DigitalOut led2(LED2);
-DigitalOut led3(LED3);
-DigitalOut led4(LED4);
-MODDMA dma;
-MODSERIAL pc(USBTX, USBRX);
+DigitalOut  led1(LED1);
+DigitalOut  led2(LED2);
+DigitalOut  led3(LED3);
+DigitalOut  led4(LED4);
+MODDMA      dma;
 
 // Function prototypes for IRQ callbacks.
 // See definitions following main() below.
-void dmaTCCallback(void);
-void dmaERRCallback(void);
-void TC0_callback(void);
-void ERR0_callback(void);
+void        dmaTCCallback(void);
+void        dmaERRCallback(void);
+void        TC0_callback(void);
+void        ERR0_callback(void);
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+int main()
+{
+    char    s[] = "**DMA** ABCDEFGHIJKLMNOPQRSTUVWXYZ **DMA**";
+
+    printf("\r\nStarting\r\n");
 
-int main() {
-    char s[] = "**DMA** ABCDEFGHIJKLMNOPQRSTUVWXYZ **DMA**";
-    
-    pc.baud(PC_BAUD);
-    
-    dma.attach_tc( &dmaTCCallback );
-    dma.attach_err( &dmaERRCallback );
-    
-    MODDMA_Config *config = new MODDMA_Config;
-    config
-     ->channelNum    ( MODDMA::Channel_0 )
-     ->srcMemAddr    ( (uint32_t) &s )
-     ->dstMemAddr    ( 0 )
-     ->transferSize  ( sizeof(s) )
-     ->transferType  ( MODDMA::m2p )
-     ->transferWidth ( 0 )
-     ->srcConn       ( 0 )
-     ->dstConn       ( MODDMA::UART0_Tx )
-     ->dmaLLI        ( 0 )
-     ->attach_tc     ( &TC0_callback )
-     ->attach_err    ( &ERR0_callback )
-    ; // config end
-    
+    dma.attach_tc(&dmaTCCallback);
+    dma.attach_err(&dmaERRCallback);
+
+    MODDMA_Config*  config = new MODDMA_Config;
+
+    config->channelNum(MODDMA::Channel_0);
+    config->srcMemAddr((uint32_t) & s);
+    config->dstMemAddr(0);
+    config->transferSize(sizeof(s));
+    config->transferType(MODDMA::m2p);
+    config->transferWidth(0);
+    config->srcConn(0);
+    config->dstConn(MODDMA::UART0_Tx);
+    config->dmaLLI(0)->attach_tc(&TC0_callback);
+    config->attach_err(&ERR0_callback);
+
     // Setup the configuration.
     dma.Setup(config);
-    
+
     //dma.Enable( MODDMA::Channel_0 );
     //dma.Enable( config->channelNum() );
-    dma.Enable( config );
-    
+    dma.Enable(config);
+
     while (1) {
         led1 = !led1;
-        wait(0.25);        
+        ThisThread::sleep_for(250ms);
     }
 }
 
 // Main controller TC IRQ callback
-void dmaTCCallback(void) {
+void dmaTCCallback(void)
+{
     led2 = 1;
 }
 
 // Main controller ERR IRQ callback
-void dmaERRCallback(void) {
-    error("Oh no! My Mbed exploded! :( Only kidding, find the problem");
+void dmaERRCallback(void)
+{
+    printf("Oh no! My Mbed exploded! :( Only kidding, find the problem");
 }
 
 // Configuration callback on TC
-void TC0_callback(void) {
-    MODDMA_Config *config = dma.getConfig();
-    dma.haltAndWaitChannelComplete( (MODDMA::CHANNELS)config->channelNum());
-    dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
-    
-    // Configurations have two IRQ callbacks for TC and Err so you 
-    // know which you are processing. However, if you want to use 
-    // a single callback function you can tell what type of IRQ 
+void TC0_callback(void)
+{
+    MODDMA_Config*  config = dma.getConfig();
+
+    dma.haltAndWaitChannelComplete((MODDMA::CHANNELS) config->channelNum());
+    dma.Disable((MODDMA::CHANNELS) config->channelNum());
+
+    // Configurations have two IRQ callbacks for TC and Err so you
+    // know which you are processing. However, if you want to use
+    // a single callback function you can tell what type of IRQ
     // is being processed thus:-
-    if (dma.irqType() == MODDMA::TcIrq)  {
+    if (dma.irqType() == MODDMA::TcIrq) {
         led3 = 1;
         dma.clearTcIrq();
     }
+
     if (dma.irqType() == MODDMA::ErrIrq) {
         led4 = 1;
         dma.clearErrIrq();
@@ -83,7 +91,7 @@
 }
 
 // Configuration cakllback on Error
-void ERR0_callback(void) {
-    error("Oh no! My Mbed exploded! :( Only kidding, find the problem");
+void ERR0_callback(void)
+{
+    printf("Oh no! My Mbed exploded! :( Only kidding, find the problem");
 }
-
--- a/example2.h	Sat Dec 10 09:59:10 2022 +0000
+++ b/example2.h	Mon Dec 12 15:05:21 2022 +0000
@@ -2,136 +2,141 @@
  * This example was provided to support Mbed forum thread:-
  * http://mbed.org/forum/mbed/topic/1798
  */
- 
 #include "mbed.h"
 #include "MODDMA.h"
 
-#define SAMPLE_BUFFER_LENGTH 32
+#define SAMPLE_BUFFER_LENGTH    32
 
-DigitalOut led1(LED1);
-DigitalOut led2(LED2);
+DigitalOut  led1(LED1);
+DigitalOut  led2(LED2);
 
-MODDMA dma;
-Serial pc(USBTX, USBRX);
+MODDMA      dma;
 
 // ISR set's this when transfer complete.
-bool dmaTransferComplete = false;
+bool        dmaTransferComplete = false;
 
 // Function prototypes for IRQ callbacks.
 // See definitions following main() below.
-void TC0_callback(void);
-void ERR0_callback(void);
+void        TC0_callback(void);
+void        ERR0_callback(void);
 
-int main() {
-
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+int main()
+{
     // Create a buffer to hold the ADC samples and clear it.
     // Note, we are going to sample two ADC inputs so they
     // end up in this buffer "interleaved". So you will want
     // a buffer twice this size to a real life given sample
     // frequency. See the printf() output for details.
-    uint32_t adcInputBuffer[SAMPLE_BUFFER_LENGTH];    
+    uint32_t    adcInputBuffer[SAMPLE_BUFFER_LENGTH];
     memset(adcInputBuffer, 0, sizeof(adcInputBuffer));
-    
+
     // We use the ADC irq to trigger DMA and the manual says
     // that in this case the NVIC for ADC must be disabled.
     NVIC_DisableIRQ(ADC_IRQn);
-    
+
     // Power up the ADC and set PCLK
-    LPC_SC->PCONP    |=  (1UL << 12);
-    LPC_SC->PCLKSEL0 &= ~(3UL << 24); // PCLK = CCLK/4 96M/4 = 24MHz
-    
+    LPC_SC->PCONP |= (1UL << 12);
+    LPC_SC->PCLKSEL0 &= ~(3UL << 24);       // PCLK = CCLK/4 96M/4 = 24MHz
+
     // Enable the ADC, 12MHz,  ADC0.0 & .1
-    LPC_ADC->ADCR  = (1UL << 21) | (1UL << 8) | (3UL << 0); 
-    
+    LPC_ADC->ADCR = (1UL << 21) | (1UL << 8) | (3UL << 0);
+
     // Set the pin functions to ADC
-    LPC_PINCON->PINSEL1 &= ~(3UL << 14);  /* P0.23, Mbed p15. */
-    LPC_PINCON->PINSEL1 |=  (1UL << 14);
-    LPC_PINCON->PINSEL1 &= ~(3UL << 16);  /* P0.24, Mbed p16. */
-    LPC_PINCON->PINSEL1 |=  (1UL << 16);
-    
+    LPC_PINCON->PINSEL1 &= ~(3UL << 14);    /* P0.23, Mbed p15. */
+    LPC_PINCON->PINSEL1 |= (1UL << 14);
+    LPC_PINCON->PINSEL1 &= ~(3UL << 16);    /* P0.24, Mbed p16. */
+    LPC_PINCON->PINSEL1 |= (1UL << 16);
+
     // Setup the serial port to print out results.
-    pc.baud(115200);
-    pc.printf("ADC with DMA example\n");
-    pc.printf("====================\n");
-    
+    printf("ADC with DMA example\n");
+    printf("====================\n");
+
     // Prepare an ADC configuration.
-    MODDMA_Config *conf = new MODDMA_Config;
-    conf
-     ->channelNum    ( MODDMA::Channel_0 )
-     ->srcMemAddr    ( 0 )
-     ->dstMemAddr    ( (uint32_t)adcInputBuffer )
-     ->transferSize  ( SAMPLE_BUFFER_LENGTH )
-     ->transferType  ( MODDMA::p2m )
-     ->transferWidth ( MODDMA::word )
-     ->srcConn       ( MODDMA::ADC )
-     ->dstConn       ( 0 )
-     ->dmaLLI        ( 0 )
-     ->attach_tc     ( &TC0_callback )
-     ->attach_err    ( &ERR0_callback )
-    ; // end conf.
-    
+    MODDMA_Config*  conf = new MODDMA_Config;
+    conf->channelNum(MODDMA::Channel_0);
+    conf->srcMemAddr(0);
+    conf->dstMemAddr((uint32_t) adcInputBuffer);
+    conf->transferSize(SAMPLE_BUFFER_LENGTH);
+    conf->transferType(MODDMA::p2m);
+    conf->transferWidth(MODDMA::word);
+    conf->srcConn(MODDMA::ADC);
+    conf->dstConn(0);
+    conf->dmaLLI(0);
+    conf->attach_tc(&TC0_callback);
+    conf->attach_err(&ERR0_callback);
+
     // Prepare configuration.
-    dma.Setup( conf );
-    
+    dma.Setup(conf);
+
     // Enable configuration.
-    dma.Enable( conf );
-    
+    dma.Enable(conf);
+
     // Enable ADC irq flag (to DMA).
     // Note, don't set the individual flags,
     // just set the global flag.
     LPC_ADC->ADINTEN = 0x100;
 
     // Enable burst mode on inputs 0 and 1.
-    LPC_ADC->ADCR |= (1UL << 16); 
-    
+    LPC_ADC->ADCR |= (1UL << 16);
+
     while (1) {
+
         // When transfer complete do this block.
         if (dmaTransferComplete) {
-            delete conf; // No memory leaks, delete the configuration.
+            delete conf;                    // No memory leaks, delete the configuration.
             dmaTransferComplete = false;
             for (int i = 0; i < SAMPLE_BUFFER_LENGTH; i++) {
-                int channel = (adcInputBuffer[i] >> 24) & 0x7;
-                int iVal = (adcInputBuffer[i] >> 4) & 0xFFF;
-                double fVal = 3.3 * (double)((double)iVal) / ((double)0x1000); // scale to 0v to 3.3v
-                pc.printf("Array index %02d : ADC input channel %d = 0x%03x %01.3f volts\n", i, channel, iVal, fVal);                  
+                int     channel = (adcInputBuffer[i] >> 24) & 0x7;
+                int     iVal = (adcInputBuffer[i] >> 4) & 0xFFF;
+                double  fVal = 3.3 * (double)((double)iVal) / ((double)0x1000); // scale to 0v to 3.3v
+
+                printf("Array index %02d : ADC input channel %d = 0x%03x %01.3f volts\n", i, channel, iVal, fVal);
             }
         }
-        
+
         // Just flash LED1 for something to do.
         led1 = !led1;
-        wait(0.25);        
+        ThisThread::sleep_for(250ms);
     }
 }
 
 // Configuration callback on TC
-void TC0_callback(void) {
-    
-    MODDMA_Config *config = dma.getConfig();
-    
+void TC0_callback(void)
+{
+    MODDMA_Config*  config = dma.getConfig();
+
     // Disbale burst mode and switch off the IRQ flag.
     LPC_ADC->ADCR &= ~(1UL << 16);
-    LPC_ADC->ADINTEN = 0;    
-    
+    LPC_ADC->ADINTEN = 0;
+
     // Finish the DMA cycle by shutting down the channel.
-    dma.haltAndWaitChannelComplete( (MODDMA::CHANNELS)config->channelNum());
-    dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
-    
+    dma.haltAndWaitChannelComplete((MODDMA::CHANNELS) config->channelNum());
+    dma.Disable((MODDMA::CHANNELS) config->channelNum());
+
     // Tell main() while(1) loop to print the results.
-    dmaTransferComplete = true;            
-    
+    dmaTransferComplete = true;
+
     // Switch on LED2 to show transfer complete.
-    led2 = 1;        
-    
+    led2 = 1;
+
     // Clear DMA IRQ flags.
-    if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();    
-    if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq();
+    if (dma.irqType() == MODDMA::TcIrq)
+        dma.clearTcIrq();
+    if (dma.irqType() == MODDMA::ErrIrq)
+        dma.clearErrIrq();
 }
 
 // Configuration callback on Error
-void ERR0_callback(void) {
+void ERR0_callback(void)
+{
     // Switch off burst conversions.
     LPC_ADC->ADCR |= ~(1UL << 16);
     LPC_ADC->ADINTEN = 0;
     error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem");
 }
-
--- a/example3.h	Sat Dec 10 09:59:10 2022 +0000
+++ b/example3.h	Mon Dec 12 15:05:21 2022 +0000
@@ -1,131 +1,142 @@
 /*
- * Demonstrates capturing the GPIO P0.4 to P0.7 "nibble" to memory 
+ * Demonstrates capturing the GPIO P0.4 to P0.7 "nibble" to memory
  * using GPDMA. The transfers from port pins to memory buffer are
  * triggered using Timer1 MAT1.0 match compare.
  *
  * In this example all inputs have pullups. So with nothing connected
- * the P0.4/7 reads as 0xF. Connecting a wire from one or more of the four 
+ * the P0.4/7 reads as 0xF. Connecting a wire from one or more of the four
  * inputs to ground will show up in the captured buffer sequence.
  */
- 
 #include "mbed.h"
 #include "MODDMA.h"
-#include "iomacros.h" // within MODDMA library.
+#include "iomacros.h"   // within MODDMA library.
 
 // How long between grabbing GPIO FIO0PIN register.
+
 // Value is in microseconds. (500000 is half a second).
 #define SAMPLE_PERIOD   500000
 
 #define NUM_OF_SAMPLES  5
 
-Serial pc(USBTX, USBRX);
+DigitalOut      led1(LED1);
+DigitalOut      led2(LED2);
+DigitalOut      led3(LED3);
 
-DigitalOut led1(LED1);
-DigitalOut led2(LED2);
-DigitalOut led3(LED3);
+uint32_t        buffer[NUM_OF_SAMPLES];
 
-uint32_t buffer[NUM_OF_SAMPLES];
+bool            dmaTransferComplete;
 
-bool dmaTransferComplete;
+MODDMA          dma;
+MODDMA_Config*  conf;
 
-MODDMA dma;
-MODDMA_Config *conf;
+void            TC0_callback(void);
+void            ERR0_callback(void);
 
-void TC0_callback(void);
-void ERR0_callback(void);
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+int main()
+{
+    volatile int    life_counter = 0;
 
-int main() {
-    volatile int life_counter = 0;
-     
     // Macros defined in iomacros.h, saves messing with DigitalIn
-    p30_AS_INPUT; p30_MODE( PIN_PULLUP ); // P0.4
-    p29_AS_INPUT; p29_MODE( PIN_PULLUP ); // P0.5
-    p8_AS_INPUT;  p8_MODE( PIN_PULLUP );  // P0.6
-    p7_AS_INPUT;  p7_MODE( PIN_PULLUP );  // P0.7
-    
+    p30_AS_INPUT;
+    p30_MODE(PIN_PULLUP);               // P0.4
+    p29_AS_INPUT;
+    p29_MODE(PIN_PULLUP);               // P0.5
+    p8_AS_INPUT;
+    p8_MODE(PIN_PULLUP);                // P0.6
+    p7_AS_INPUT;
+    p7_MODE(PIN_PULLUP);                // P0.7
+
     // Clear the buffer.
     memset(buffer, 0, sizeof(buffer));
-    
-    // Setup the serial port to print out results.
-    pc.baud(115200);
-    pc.printf("Starting up...\n");
-    
+
+    printf("Starting up...\n");
+
     // Set-up timer1 as a periodic timer.
-    LPC_SC->PCONP    |= (1UL << 2); // TIM1 On
-    LPC_SC->PCLKSEL0 |= (3UL << 4); // CCLK/8 = 12MHz
-    LPC_TIM1->PR      = 11;         // TC clocks at 1MHz.
-    LPC_TIM1->MCR     = 2;          // Reset TCR to zero on match.
-    LPC_TIM1->MR0     = SAMPLE_PERIOD;
-    
+    LPC_SC->PCONP |= (1UL << 2);        // TIM1 On
+    LPC_SC->PCLKSEL0 |= (3UL << 4);     // CCLK/8 = 12MHz
+    LPC_TIM1->PR = 11;                  // TC clocks at 1MHz.
+    LPC_TIM1->MCR = 2;                  // Reset TCR to zero on match.
+    LPC_TIM1->MR0 = SAMPLE_PERIOD;
+
     // Prepare the GPDMA system.
     conf = new MODDMA_Config;
-    conf
-     ->channelNum    ( MODDMA::Channel_0 )
-     ->srcMemAddr    ( (uint32_t)&LPC_GPIO0->FIOPIN )
-     ->dstMemAddr    ( (uint32_t)&buffer[0] )
-     ->transferSize  ( NUM_OF_SAMPLES )
-     ->transferType  ( MODDMA::g2m ) // pseudo transfer code MODDMA understands.
-     ->transferWidth ( MODDMA::word )
-     ->srcConn       ( MODDMA::MAT1_0 )
-     ->dmacSync      ( MODDMA::MAT1_0 ) 
-     ->attach_tc     ( TC0_callback )
-     ->attach_err    ( ERR0_callback )
-    ; // end conf.
-    
+    conf->channelNum(MODDMA::Channel_0);
+    conf->srcMemAddr((uint32_t) & LPC_GPIO0->FIOPIN);
+    conf->dstMemAddr((uint32_t) & buffer[0]);
+    conf->transferSize(NUM_OF_SAMPLES);
+    conf->transferType(MODDMA::g2m);    // pseudo transfer code MODDMA understands.
+    conf->transferWidth(MODDMA::word);
+    conf->srcConn(MODDMA::MAT1_0);
+    conf->dmacSync(MODDMA::MAT1_0);
+    conf->attach_tc(TC0_callback);
+    conf->attach_err(ERR0_callback);
+    ;                                   // end conf.
+
     // Prepare configuration.
-    if (!dma.Setup( conf )) {
+    if (!dma.Setup(conf)) {
         error("Doh!");
     }
-    
-    // Enable GPDMA to be ready for the TIM1 "ticks".       
-    dma.Enable( conf );
-    
+
+    // Enable GPDMA to be ready for the TIM1 "ticks".
+    dma.Enable(conf);
+
     // Begin.
     LPC_TIM1->TCR = 1;
-       
-    while (1) { 
+
+    while (1) {
         if (life_counter++ > 1000000) {
-            led1 = !led1; // Show some sort of life.
+            led1 = !led1;               // Show some sort of life.
             life_counter = 0;
         }
-        
+
         if (dmaTransferComplete) {
             dmaTransferComplete = false;
             for (int i = 0; i < NUM_OF_SAMPLES; i++) {
-                int val = (buffer[i] >> 4) & 0xF; 
-                pc.printf("Buffer index %d = 0x%x\n", i, val);
+                int val = (buffer[i] >> 4) & 0xF;
+                printf("Buffer index %d = 0x%x\n", i, val);
             }
-            pc.printf("Done.\n");
-            
+
+            printf("Done.\n");
+
             // Schedule another grab.
-            if (dma.Setup( conf )) {        
-                dma.Enable( conf );                
-            }            
+            if (dma.Setup(conf)) {
+                dma.Enable(conf);
+            }
         }
-    }       
+    }
 }
 
 // Configuration callback on TC
-void TC0_callback(void) {
-    
+void TC0_callback(void)
+{
     // Just show sample sequence grab complete.
-    led3 = !led3; 
-        
+    led3 = !led3;
+
     // Get configuration pointer.
-    MODDMA_Config *config = dma.getConfig();
-    
+    MODDMA_Config*  config = dma.getConfig();
+
     // Finish the DMA cycle by shutting down the channel.
-    dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
-    
+
+    dma.Disable((MODDMA::CHANNELS) config->channelNum());
+
     // Tell main() while(1) loop to print the results.
-    dmaTransferComplete = true;            
-    
+    dmaTransferComplete = true;
+
     // Clear DMA IRQ flags.
-    if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();    
-    if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq();    
+    if (dma.irqType() == MODDMA::TcIrq)
+        dma.clearTcIrq();
+    if (dma.irqType() == MODDMA::ErrIrq)
+        dma.clearErrIrq();
 }
 
 // Configuration callback on Error
-void ERR0_callback(void) {
+void ERR0_callback(void)
+{
     error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem");
 }
--- a/example4.h	Sat Dec 10 09:59:10 2022 +0000
+++ b/example4.h	Mon Dec 12 15:05:21 2022 +0000
@@ -7,72 +7,79 @@
 #include "MODDMA.h"
 
 // Make the buffer size match the number of degrees
+
 // in a circle since we are going to output a sinewave.
 #define BUFFER_SIZE 360
 
 // Set DAC output power mode.
+
 #define DAC_POWER_MODE  (1 << 16)
 
-DigitalOut led1(LED1);
-DigitalOut led3(LED3);
-DigitalOut led4(LED4);
+DigitalOut      led1(LED1);
+DigitalOut      led3(LED3);
+DigitalOut      led4(LED4);
+
+int             buffer[2][BUFFER_SIZE];
+
+AnalogOut       signal(p18);
 
-int buffer[2][BUFFER_SIZE];
+MODDMA          dma;
+MODDMA_Config*  conf0, *conf1;
 
-AnalogOut signal(p18);
+void            TC0_callback(void);
+void            ERR0_callback(void);
 
-MODDMA dma;
-MODDMA_Config *conf0, *conf1;
+void            TC1_callback(void);
+void            ERR1_callback(void);
 
-void TC0_callback(void);
-void ERR0_callback(void);
-
-void TC1_callback(void);
-void ERR1_callback(void);
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+int main()
+{
+    volatile int    life_counter = 0;
 
-int main() {
-    volatile int life_counter = 0;
-    
     // Create a sinewave buffer for testing.
-    for (int i =   0; i <=  90; i++) buffer[0][i] =  (512 * sin(3.14159/180.0 * i)) + 512;                
-    for (int i =  91; i <= 180; i++) buffer[0][i] =  buffer[0][180 - i];
-    for (int i = 181; i <= 270; i++) buffer[0][i] =  512 - (buffer[0][i - 180] - 512);
-    for (int i = 271; i <  360; i++) buffer[0][i] =  512 - (buffer[0][360 - i] - 512);
-    
+    for (int i = 0; i <= 90; i++)
+        buffer[0][i] = (512 * sin(3.14159 / 180.0 * i)) + 512;
+    for (int i = 91; i <= 180; i++)
+        buffer[0][i] = buffer[0][180 - i];
+    for (int i = 181; i <= 270; i++)
+        buffer[0][i] = 512 - (buffer[0][i - 180] - 512);
+    for (int i = 271; i < 360; i++)
+        buffer[0][i] = 512 - (buffer[0][360 - i] - 512);
+
     // Adjust the sinewave buffer for use with DAC hardware.
     for (int i = 0; i < 360; i++) {
         buffer[0][i] = DAC_POWER_MODE | ((buffer[0][i] << 6) & 0xFFC0);
-        buffer[1][i] = buffer[0][i]; // Just create a copy of buffer0 to continue sinewave.
+        buffer[1][i] = buffer[0][i];    // Just create a copy of buffer0 to continue sinewave.
     }
-    
+
     // Prepare the GPDMA system for buffer0.
     conf0 = new MODDMA_Config;
-    conf0
-     ->channelNum    ( MODDMA::Channel_0 )
-     ->srcMemAddr    ( (uint32_t) &buffer[0] )
-     ->dstMemAddr    ( MODDMA::DAC )
-     ->transferSize  ( 360 )
-     ->transferType  ( MODDMA::m2p )
-     ->dstConn       ( MODDMA::DAC )
-     ->attach_tc     ( &TC0_callback )
-     ->attach_err    ( &ERR0_callback )     
-    ; // config end
-    
-    
+    conf0->channelNum(MODDMA::Channel_0);
+    conf0->srcMemAddr((uint32_t) & buffer[0]);
+    conf0->dstMemAddr(MODDMA::DAC);
+    conf0->transferSize(360);
+    conf0->transferType(MODDMA::m2p);
+    conf0->dstConn(MODDMA::DAC);
+    conf0->attach_tc(&TC0_callback);
+    conf0->attach_err(&ERR0_callback);
+
     // Prepare the GPDMA system for buffer1.
     conf1 = new MODDMA_Config;
-    conf1
-     ->channelNum    ( MODDMA::Channel_1 )
-     ->srcMemAddr    ( (uint32_t) &buffer[1] )
-     ->dstMemAddr    ( MODDMA::DAC )
-     ->transferSize  ( 360 )
-     ->transferType  ( MODDMA::m2p )
-     ->dstConn       ( MODDMA::DAC )
-     ->attach_tc     ( &TC1_callback )
-     ->attach_err    ( &ERR1_callback )     
-    ; // config end
+    conf1->channelNum(MODDMA::Channel_1);
+    conf1->srcMemAddr((uint32_t) & buffer[1]);
+    conf1->dstMemAddr(MODDMA::DAC);
+    conf1->transferSize(360);
+    conf1->transferType(MODDMA::m2p);
+    conf1->dstConn(MODDMA::DAC);
+    conf1->attach_tc(&TC1_callback);
+    conf1->attach_err(&ERR1_callback);
 
-    
     // Calculating the transfer frequency:
     // By default, the Mbed library sets the PCLK_DAC clock value
     // to 24MHz. One complete sinewave cycle in each buffer is 360
@@ -83,74 +90,79 @@
     // alter PCLK_DAC from CCLK/4 to CCLK/8.
     // For our demo we are going to have the sinewave run at 1kHz.
     // That's 24000000/360000 which is approx 66. Experimentation
-    // however showed 65 to get closer to 1kHz (on my Mbed and scope 
+    // however showed 65 to get closer to 1kHz (on my Mbed and scope
     // at least).
-    LPC_DAC->DACCNTVAL = 65; // 6500 for 10Hz
+    LPC_DAC->DACCNTVAL = 65;            // 6500 for 10Hz
 
     // Prepare first configuration.
-    if (!dma.Prepare( conf0 )) {
+    if (!dma.Prepare(conf0)) {
         error("Doh!");
     }
-    
+
     // Begin (enable DMA and counter). Note, don't enable
     // DBLBUF_ENA as we are using DMA double buffering.
     LPC_DAC->DACCTRL |= (3UL << 2);
-    
-    while (1) { 
+
+    while (1) {
+
         // There's not a lot to do as DMA and interrupts are
         // now handling the buffer transfers. So we'll just
         // flash led1 to show the Mbed is alive and kicking.
         if (life_counter++ > 1000000) {
-            led1 = !led1; // Show some sort of life.
+            led1 = !led1;               // Show some sort of life.
             life_counter = 0;
         }
-    } 
+    }
 }
 
 // Configuration callback on TC
-void TC0_callback(void) {
-    
+void TC0_callback(void)
+{
     // Just show sending buffer0 complete.
-    led3 = !led3; 
-        
+    led3 = !led3;
+
     // Get configuration pointer.
-    MODDMA_Config *config = dma.getConfig();
-    
+    MODDMA_Config*  config = dma.getConfig();
+
     // Finish the DMA cycle by shutting down the channel.
-    dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
-   
+    dma.Disable((MODDMA::CHANNELS) config->channelNum());
+
     // Swap to buffer1
-    dma.Prepare( conf1 );
+    dma.Prepare(conf1);
 
     // Clear DMA IRQ flags.
-    if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); 
+    if (dma.irqType() == MODDMA::TcIrq)
+        dma.clearTcIrq();
 }
 
 // Configuration callback on Error
-void ERR0_callback(void) {
+void ERR0_callback(void)
+{
     error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem");
 }
 
 // Configuration callback on TC
-void TC1_callback(void) {
-    
+void TC1_callback(void)
+{
     // Just show sending buffer1 complete.
-    led4 = !led4; 
-        
+    led4 = !led4;
+
     // Get configuration pointer.
-    MODDMA_Config *config = dma.getConfig();
-    
+    MODDMA_Config*  config = dma.getConfig();
+
     // Finish the DMA cycle by shutting down the channel.
-    dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
-    
+    dma.Disable((MODDMA::CHANNELS) config->channelNum());
+
     // Swap to buffer0
-    dma.Prepare( conf0 );
-    
+    dma.Prepare(conf0);
+
     // Clear DMA IRQ flags.
-    if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); 
+    if (dma.irqType() == MODDMA::TcIrq)
+        dma.clearTcIrq();
 }
 
 // Configuration callback on Error
-void ERR1_callback(void) {
+void ERR1_callback(void)
+{
     error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem");
 }