Signal Generator

Dependencies:   IniManager RA8875 Watchdog mbed-rtos mbed

Fork of speaker_demo_Analog by jim hamblen

Revision:
6:1f48212fbaf9
Parent:
5:49dd0c647a40
--- a/SignalGenDAC.cpp	Mon Jan 16 22:57:59 2017 +0000
+++ b/SignalGenDAC.cpp	Sat May 20 19:52:23 2017 +0000
@@ -1,8 +1,11 @@
+//
+// Signal Generate DAC Driver
+//
+// Derived from AN10917: Memory to DAC data transfers using the LPC1700's DMA
+// 
 
 #include "SignalGenDAC.h"
 
-DigitalOut led(LED1);
-
 #define PI 3.14159      // for the sine-wave
 
 /// The linked list structure used to control the DMA transfer
@@ -36,13 +39,7 @@
 void SignalGenDAC::Start(bool oneShot) {
     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;
@@ -57,9 +54,10 @@
     /* Load DMA Channel0 */
     LPC_GPDMACH0->DMACCSrcAddr   = (uint32_t)DACsignal;
     LPC_GPDMACH0->DMACCDestAddr  = (uint32_t)&LPC_DAC->DACR;
-    LPC_GPDMACH0->DMACCLLI       = (uint32_t)&llio;
+    LPC_GPDMACH0->DMACCLLI       = (oneShot) ? 0 : (uint32_t)&llio;
 
-    LPC_GPDMACH0->DMACCControl = numSamples   // transfer size (0 - 11) = 64
+    int playSampleCount = numSamples + oneShot;
+    LPC_GPDMACH0->DMACCControl = playSampleCount  // 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
@@ -83,7 +81,7 @@
                   | (0 << 18);        // (27) = no HALT
 
     /* DACclk = 25 MHz, so 10 usec interval */
-    LPC_DAC->DACCNTVAL = 20;               // 16-bit reload value
+    LPC_DAC->DACCNTVAL = 18;               // 16-bit reload value
     /* DMA, timer running, dbuff */
     LPC_DAC->DACCTRL = 
           1<<3          // DMA_ENA dma burst is enabled
@@ -98,11 +96,10 @@
         wait_ms(1);
     aout->write(offset / maxV);
     isOn = false;
-    led = 0;
 }
 
 
-void SignalGenDAC::PrepareWaveform(SG_Mode mode, float _frequency, float _dutycycle, float _voltage, float _offset) {
+void SignalGenDAC::PrepareWaveform(SG_Waveform mode, float _frequency, float _dutycycle, float _voltage, float _offset) {
     int x, dcCount, firstQtr, lastQtr;
     frequency = _frequency;
     dutycycle = _dutycycle;
@@ -112,7 +109,7 @@
     float mid = rangelimit(offset, minV, maxV);
     float low = rangelimit(offset - voltage/2, minV, maxV);
     float v;
-    numSamples = 32;    // Ideally, compute this based on the frequency for good resolution
+    numSamples = 128;    // Ideally, compute this based on the frequency for good resolution
     dcCount = dutycycle/100.0 * numSamples;
     firstQtr = dcCount / 2;
     lastQtr = dcCount + (numSamples - dcCount)/2;
@@ -133,16 +130,20 @@
                 v = rangelimit(v, minV, maxV);
                 VoltSignal[x] = v;
             }
+            VoltSignal[numSamples] = rangelimit(offset, minV, maxV);
             break;
         case SG_SQUARE:
             for (x=0; x<numSamples; x++) {
-                if (x < dcCount) {
+                if (0 && x == 0) {
+                    v = rangelimit(offset, minV, maxV);                    
+                } else if (x < dcCount) {
                     v = rangelimit(offset + voltage/2, minV, maxV);
                 } else {
                     v = rangelimit(offset - voltage/2, minV, maxV);
                 }
                 VoltSignal[x] = v;
             }
+            VoltSignal[numSamples] = rangelimit(offset, minV, maxV);
             break;
         case SG_TRIANGLE:
             for (x=0; x<numSamples; x++) {
@@ -161,6 +162,7 @@
                 }
                 VoltSignal[x] = v;
             }
+            VoltSignal[numSamples] = rangelimit(offset, minV, maxV);
             break;
         case SG_SAWTOOTH:
             for (x=0; x<numSamples; x++) {
@@ -172,12 +174,13 @@
                 v = rangelimit(v, minV, maxV);
                 VoltSignal[x] = v;
             }
+            VoltSignal[numSamples] = rangelimit(offset, minV, maxV);
             break;
         case SG_USER:
             break;
     }
     //printf("DAC Data %3.2f %3.2f\r\n", voltage, offset);
-    for (x=0; x<numSamples; x++) {
+    for (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]);
     }