Signal Generator
Dependencies: IniManager RA8875 Watchdog mbed-rtos mbed
Fork of speaker_demo_Analog by
Revision 4:10281ddb673d, committed 2017-01-16
- Comitter:
- WiredHome
- Date:
- Mon Jan 16 21:05:13 2017 +0000
- Parent:
- 3:d22f3e52d06a
- Child:
- 5:49dd0c647a40
- Commit message:
- Basic functions (excluding frequency) are working. Waveform, amplitude, offset, start/stop.
Changed in this revision
--- 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) {
--- a/SignalGenDAC.h Mon Jan 16 04:33:06 2017 +0000 +++ b/SignalGenDAC.h Mon Jan 16 21:05:13 2017 +0000 @@ -63,6 +63,7 @@ float maxV; // Based on the A/D hardware /// range limit a value. float rangelimit(float value, float min, float max); + int numSamples; // private container for number of samples }; #endif // SIGNALGENDAC_H \ No newline at end of file
--- a/SignalGenDisplay.cpp Mon Jan 16 04:33:06 2017 +0000 +++ b/SignalGenDisplay.cpp Mon Jan 16 21:05:13 2017 +0000 @@ -317,6 +317,7 @@ for (int i=0; i<radio_CyclesCount; i++) { if (lcd->Intersect(radio_Cycles[i], point)) { pulseMode = i; + signal->Stop(); ShowCyclesControl(); } } @@ -346,6 +347,7 @@ for (int i=0; i<ModeCount; i++) { if (strcmp(ModeNames[i], buf) == 0) { mode = (SG_Mode)i; + printf("Read ini mode is %d\r\n", mode); break; } } @@ -490,6 +492,14 @@ printf(" ?: This help <cr>: Save number\r\n"); printf(" #: Dump RA8875 <esc>: Exit number entry\r\n"); //printf(" 4: Reverse sawtoothSignal\r\n"); + + printf(" Settings:\r\n"); + printf(" Mode: %d - %s\r\n", mode, ModeNames[mode]); + printf(" Freq: %f\r\n", frequency); + printf(" Duty: %f\r\n", dutycycle); + printf(" Volt: %f\r\n", voltage); + printf(" Offs: %f\r\n", offset); + printf(" Puls: %d - %s\r\n", pulseMode, radio_CyclesLabels[pulseMode]); } SignalGenDisplay::OM_Changes SignalGenDisplay::Poll(char c) { @@ -754,6 +764,7 @@ bool SignalGenDisplay::SetWaveformMode(SG_Mode _mode, bool force) { if (/* _mode >= SG_SINE && */ _mode <= SG_USER) { mode = _mode; + printf("mode is %d\r\n", mode); DrawModeButtons(); return true; } else { @@ -1210,7 +1221,7 @@ if (textLen == 0) { lcd->fillrect(UI_START_STOP, UI_BackColor); if (showIt) { - DrawButton(UI_START_STOP, false, SG_START, true, pulseMode ? 2 : signal->isRunning()); + DrawButton(UI_START_STOP, signal->isRunning(), SG_START, true, pulseMode ? 2 : signal->isRunning()); } } } @@ -1303,7 +1314,7 @@ printf("-> resetDataEntry(next: %d) curr:%d, save:%d\r\n", nextMode, last, save); EntryMd = nextMode; if (last != OM_NONE) - signal->PrepareWaveform(SG_SAWTOOTH, frequency, dutycycle, voltage, offset); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); switch (last) { case OM_NONE: updateDutyCycle();
--- a/main.cpp Mon Jan 16 04:33:06 2017 +0000 +++ b/main.cpp Mon Jan 16 21:05:13 2017 +0000 @@ -12,23 +12,12 @@ RawSerial pc(USBTX, USBRX); LocalFileSystem local("local"); +//AnalogOut aout(p18); SignalGenDAC g_signal(p18); SignalGenDisplay ui(&lcd, &g_signal); Watchdog wd; -/* CPU Available indicator - */ -DigitalOut g_availableLed(LED1); //<! Led used to indicate the program is alive -void AvailableLedIndicator(); //<! Ticker callback -Ticker g_available; - - - - - -/* Program Entry Point - */ int main() { pc.baud(460800); @@ -38,6 +27,16 @@ wd.Configure(30.0); //ini.SetFile("/local/SigGen.ini", 2); +#if 0 + aout = 0.25; + wait_ms(25); + aout = 0.50; + wait_ms(25); + aout = 0.75; + wait_ms(25); + aout = 1.00; + wait_ms(25); +#endif lcd.init(480,272,16, true, true, true); while (true) {