Signal Generator

Dependencies:   IniManager RA8875 Watchdog mbed-rtos mbed

Fork of speaker_demo_Analog by jim hamblen

Revision:
4:10281ddb673d
Parent:
3:d22f3e52d06a
Child:
5:49dd0c647a40
--- a/SignalGenDAC.cpp	Mon Jan 16 04:33:06 2017 +0000
+++ b/SignalGenDAC.cpp	Mon Jan 16 21:05:13 2017 +0000
@@ -1,6 +1,8 @@
 
 #include "SignalGenDAC.h"
 
+DigitalOut led(LED1);
+
 #define PI 3.14159
 
 /// The linked list structure used to control the DMA transfer
@@ -26,21 +28,86 @@
 SignalGenDAC::SignalGenDAC(PinName _aout, float _minV, float _maxV) :
     minV(_minV), maxV(_maxV) {
     aout = new AnalogOut(_aout);
+#if 1
+    #include "mbed.h"
+    aout->write(0.25);
+    wait_ms(25);
+    aout->write(0.50);
+    wait_ms(25);
+    aout->write(0.75);
+    wait_ms(25);
+    aout->write(1.00);
+    wait_ms(25);
+#endif
 }
 
 SignalGenDAC::~SignalGenDAC() {
 }
 
 void SignalGenDAC::Start(bool oneShot) {
-    printf("Start(%d)\r\n", oneShot ? 1 : 0);
-    LPC_GPDMACH0->DMACCLLI       = (oneShot) ? 0 : (uint32_t) &llio;
+    printf("Start(%d) w/%d samples\r\n", oneShot ? 1 : 0, numSamples);
     isOn = (oneShot) ? false : true;
+    led = 1;
+    
+    for (int x=0; x<numSamples; x++) {
+        DACsignal[x] = ((uint16_t)(VoltSignal[x]/maxV * 1023) << 6);
+        printf("%3d, %5.3f, %d\r\n", x, VoltSignal[x], DACsignal[x]);
+    }
+
+    llio.source = (uint32_t)DACsignal;
+    llio.destination = (uint32_t)&LPC_DAC->DACR;
+    llio.next = (uint32_t)&llio;
+    llio.control = (1<<26) | (2<<21) | (2<<18) | numSamples;
+
+    LPC_SC->PCONP |= (1<<29);
+
+    /* Enable GPDMA  and sync logic */
+    LPC_GPDMA->DMACConfig        = 1;
+    LPC_GPDMA->DMACSync          = (1<<6); 
+
+    /* Load DMA Channel0 */
+    LPC_GPDMACH0->DMACCSrcAddr   = (uint32_t)DACsignal;
+    LPC_GPDMACH0->DMACCDestAddr  = (uint32_t)&LPC_DAC->DACR;
+    LPC_GPDMACH0->DMACCLLI       = (uint32_t)&llio;        // Free Running
+    //LPC_GPDMACH0->DMACCLLI       = 0;                     // One-Shot
+    
+    LPC_GPDMACH0->DMACCControl = numSamples   // transfer size (0 - 11) = 64
+                  | (0 << 12)         // source burst size (12 - 14) = 1
+                  | (0 << 15)         // destination burst size (15 - 17) = 1
+                  | (2 << 18)         // source width (18 - 20) = 32 bit
+                  | (2 << 21)         // destination width (21 - 23) = 32 bit
+                  | (0 << 24)         // source AHB select (24) = AHB 0
+                  | (0 << 25)         // destination AHB select (25) = AHB 0
+                  | (1 << 26)         // source increment (26) = increment
+                  | (0 << 27)         // destination increment (27) = no increment
+                  | (0 << 28)         // mode select (28) = access in user mode
+                  | (0 << 29)         // (29) = access not bufferable
+                  | (0 << 30)         // (30) = access not cacheable
+                  | (0 << 31);        // terminal count interrupt disabled
+
+    LPC_GPDMACH0->DMACCConfig = 1
+                  | (0 << 1)          // source peripheral (1 - 5) = none
+                  | (7 << 6)          // destination peripheral (6 - 10) = DAC
+                  | (1 << 11)         // flow control (11 - 13) = mem to per
+                  | (0 << 14)         // (14) = mask out error interrupt
+                  | (0 << 15)         // (15) = mask out terminal count interrupt
+                  | (0 << 16)         // (16) = no locked transfers
+                  | (0 << 18);        // (27) = no HALT
+
+    /* DACclk = 25 MHz, so 10 usec interval */
+    LPC_DAC->DACCNTVAL = 20;               // 16-bit reload value
+    /* DMA, timer running, dbuff */
+    LPC_DAC->DACCTRL = 
+          1<<3          // DMA_ENA dma burst is enabled
+        | 1<<2          // CNT_ENA Timeout couner is enabled
+        | 1<<1;         // DBLBUF_ENA double-buffering enabled
 }
 
 void SignalGenDAC::Stop(void) {
     printf("Stop()\r\n");
     LPC_GPDMACH0->DMACCLLI       = 0;
     isOn = false;
+    led = 0;
 }
 
 
@@ -50,16 +117,16 @@
     float mid = rangelimit(offset, minV, maxV);
     float low = rangelimit(offset - voltage/2, minV, maxV);
     float v;
-    int numSamples = 32;    // Ideally, compute this based on the frequency for good resolution
+    numSamples = 32;    // Ideally, compute this based on the frequency for good resolution
     dcCount = dutycycle/100.0 * numSamples;
     firstQtr = dcCount / 2;
     lastQtr = dcCount + (numSamples - dcCount)/2;
     
     // Set the timebased based on the frequency
     if (isOn) {
-        // stop the signal during the change
-        isOn = false;
+        Stop();
     }
+    printf("Generate wave for mode: %d\r\n", mode);
     switch (mode) {
         case SG_SINE:
             for (x=0; x<numSamples; x++) {
@@ -116,59 +183,10 @@
     }
     //printf("DAC Data %3.2f %3.2f\r\n", voltage, offset);
     for (x=0; x<numSamples; x++) {
-        DACsignal[x] = ((uint16_t)(VoltSignal[x]/maxV * 1023) << 6) | (1 << 16);
-        //printf("%3d, %5.3f, %d\r\n", x, VoltSignal[x], DACsignal[x]);
+        DACsignal[x] = ((uint16_t)(VoltSignal[x]/maxV * 1023) << 6);
+        printf("%3d, %5.3f, %d\r\n", x, VoltSignal[x], DACsignal[x]);
     }
-    llio.source = (uint32_t)&DACsignal;
-    llio.destination = (uint32_t)&LPC_DAC->DACR;
-    llio.next = (uint32_t)&llio;
-    llio.control = (1<<26) | (2<<21) | (2<<18) | numSamples;
-
-    LPC_SC->PCONP |= (1<<29);
-
-    /* Enable GPDMA  and sync logic */
-    LPC_GPDMA->DMACConfig = 1;
-    LPC_GPDMA->DMACSync          = (1<<6); 
-
-    /* Load DMA Channel0 */
-    LPC_GPDMACH0->DMACCSrcAddr   = (uint32_t) &DACsignal[0];
-    LPC_GPDMACH0->DMACCDestAddr  = (uint32_t) &LPC_DAC->DACR;
-
-    // Free Running
-    LPC_GPDMACH0->DMACCLLI       = (uint32_t) &llio;
-    // One-Shot
-//    LPC_GPDMACH0->DMACCLLI       = 0;
-    
-    LPC_DAC->DACCNTVAL = numSamples   // transfer size (0 - 11) = 64
-                  | (0 << 12)         // source burst size (12 - 14) = 1
-                  | (0 << 15)         // destination burst size (15 - 17) = 1
-                  | (2 << 18)         // source width (18 - 20) = 32 bit
-                  | (2 << 21)         // destination width (21 - 23) = 32 bit
-                  | (0 << 24)         // source AHB select (24) = AHB 0
-                  | (0 << 25)         // destination AHB select (25) = AHB 0
-                  | (1 << 26)         // source increment (26) = increment
-                  | (0 << 27)         // destination increment (27) = no increment
-                  | (0 << 28)         // mode select (28) = access in user mode
-                  | (0 << 29)         // (29) = access not bufferable
-                  | (0 << 30)         // (30) = access not cacheable
-                  | (0 << 31);        // terminal count interrupt disabled
-
-    LPC_GPDMA->DMACConfig = 1
-                  | (0 << 1)          // source peripheral (1 - 5) = none
-                  | (7 << 6)          // destination peripheral (6 - 10) = DAC
-                  | (1 << 11)         // flow control (11 - 13) = mem to per
-                  | (0 << 14)         // (14) = mask out error interrupt
-                  | (0 << 15)         // (15) = mask out terminal count interrupt
-                  | (0 << 16)         // (16) = no locked transfers
-                  | (0 << 18);        // (27) = no HALT
-
-    /* DACclk = 25 MHz, so 10 usec interval */
-    LPC_DAC->DACCNTVAL = 250;               // 16-bit reload value
-    /* DMA, timer running, dbuff */
-    LPC_DAC->DACCTRL = 
-        1<<3            // DMA_ENA dma burst is enabled
-        | 1<<2          // CNT_ENA Timeout couner is enabled
-        | 1<<1;         // DBLBUF_ENA double-buffering enabled
+    Start(false);
 }
 
 float SignalGenDAC::rangelimit(float value, float min, float max) {