Signal Generator
Dependencies: IniManager RA8875 Watchdog mbed-rtos mbed
Fork of speaker_demo_Analog by
Diff: SignalGenDAC.cpp
- 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]); }