tom dunigan / Mbed 2 deprecated teensy_dma_dac

Dependencies:   USBDevice mbed

Revision:
0:a57be408001f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Oct 05 14:23:37 2015 +0000
@@ -0,0 +1,107 @@
+// DMA output to DAC controlled by PDB   
+// https://forum.pjrc.com/threads/28101-Using-the-DAC-with-DMA-on-Teensy-3-1
+
+#include "mbed.h"
+#include "USBSerial.h"
+
+#define PRREG(x) pc.printf(#x" 0x%0x\n",x)
+
+USBSerial  pc;          // Virtual serial port over USB
+
+#define PDB_CONFIG (PDB_SC_TRGSEL(15) | PDB_SC_PDBEN_MASK | PDB_SC_CONT_MASK | PDB_SC_PDBIE_MASK | PDB_SC_DMAEN_MASK)
+// 48mhz bus   128 khz
+#define PDB_PERIOD (375-1)
+
+#define CHNL 0
+#define DMAMUX_SOURCE_PDB       48
+
+AnalogIn adc(A0);
+
+
+static volatile uint16_t sinetable[] = {
+   2047,    2147,    2248,    2348,    2447,    2545,    2642,    2737,
+   2831,    2923,    3012,    3100,    3185,    3267,    3346,    3422,
+   3495,    3564,    3630,    3692,    3750,    3804,    3853,    3898,
+   3939,    3975,    4007,    4034,    4056,    4073,    4085,    4093,
+   4095,    4093,    4085,    4073,    4056,    4034,    4007,    3975,
+   3939,    3898,    3853,    3804,    3750,    3692,    3630,    3564,
+   3495,    3422,    3346,    3267,    3185,    3100,    3012,    2923,
+   2831,    2737,    2642,    2545,    2447,    2348,    2248,    2147,
+   2047,    1948,    1847,    1747,    1648,    1550,    1453,    1358,
+   1264,    1172,    1083,     995,     910,     828,     749,     673,
+    600,     531,     465,     403,     345,     291,     242,     197,
+    156,     120,      88,      61,      39,      22,      10,       2,
+      0,       2,      10,      22,      39,      61,      88,     120,
+    156,     197,     242,     291,     345,     403,     465,     531,
+    600,     673,     749,     828,     910,     995,    1083,    1172,
+   1264,    1358,    1453,    1550,    1648,    1747,    1847,    1948,
+};
+
+int main() {
+    wait(2.0);
+    pc.printf("SystemCoreClock %d  %s %s\n",SystemCoreClock,__TIME__,__DATE__);
+  // DAC init
+  SIM->SCGC2 |= SIM_SCGC2_DAC0_MASK; // enable DAC clock
+  DAC0->C0 = DAC_C0_DACEN_MASK | DAC_C0_DACRFS_MASK; // enable the DAC module, 3.3V reference
+  // slowly ramp up to DC voltage, approx 1/4 second
+  for (int16_t i=0; i<2048; i+=8) {
+    *(int16_t *)&(DAC0->DAT[0]) = i;  
+    wait(0.001);
+  }
+  
+  // PDB init  set the programmable delay block to trigger DMA requests
+  SIM->SCGC6 |= SIM_SCGC6_PDB_MASK; // enable PDB clock
+  PDB0->IDLY = 0; // interrupt delay register
+  PDB0->MOD = PDB_PERIOD; // modulus register, sets period
+  PDB0->SC = PDB_CONFIG | PDB_SC_LDOK_MASK; // load registers from buffers
+  PDB0->SC = PDB_CONFIG | PDB_SC_SWTRIG_MASK; // reset and restart
+  PDB0->CH[0].C1 = 0x0101; // enable PDB
+
+  // DMA init  continuous loop
+  SIM->SCGC7 |= SIM_SCGC7_DMA_MASK;       // DMA clock
+  SIM->SCGC6 |= SIM_SCGC6_DMAMUX_MASK;    // Enable clock to DMA mux
+  DMAMUX->CHCFG[CHNL] = DMAMUX_CHCFG_ENBL_MASK | /*DMAMUX_CHCFG_TRIG_MASK |*/
+    DMAMUX_CHCFG_SOURCE(DMAMUX_SOURCE_PDB);  // associate DMA channel with PDB trigger
+  int bytes = sizeof(sinetable);
+  DMA0->CR = DMA_CR_EMLM_MASK | DMA_CR_EDBG_MASK;  // ? needed for circular
+  DMA0->CERQ = CHNL;   //disable channel
+  DMA0->CERR = CHNL;    // clear errors on channel
+  DMA0->TCD[CHNL].SADDR = (uint32_t)sinetable;
+  DMA0->TCD[CHNL].SOFF = 2;
+  DMA0->TCD[CHNL].ATTR = DMA_ATTR_SSIZE(1) | DMA_ATTR_DSIZE(1);  //16-bit
+  DMA0->TCD[CHNL].NBYTES_MLNO = 2;
+  DMA0->TCD[CHNL].SLAST = -bytes;
+  DMA0->TCD[CHNL].DADDR = (uint32_t)&(DAC0->DAT[0]);
+  DMA0->TCD[CHNL].DOFF = 0;
+  DMA0->TCD[CHNL].CITER_ELINKYES = bytes/2;
+  DMA0->TCD[CHNL].DLAST_SGA = 0;
+  DMA0->TCD[CHNL].BITER_ELINKYES = bytes/2;
+
+  DMA0->SERQ = CHNL;  // enable
+#if 0
+  PRREG(SIM->SCGC2);
+  PRREG(SIM->SCGC6);
+  PRREG(SIM->SCGC7);
+  PRREG(PDB0->MOD);
+  PRREG(DMAMUX->CHCFG[CHNL]);
+  PRREG(DAC0->C0);
+  PRREG(DMA0->CR);
+  PRREG(DMA0->TCD[CHNL].CSR);
+  PRREG(DMA0->TCD[CHNL].ATTR);
+  PRREG(DMA0->TCD[CHNL].SOFF);
+  PRREG(DMA0->TCD[CHNL].DOFF);
+  PRREG(DMA0->TCD[CHNL].NBYTES_MLNO);
+  PRREG(DMA0->TCD[CHNL].BITER_ELINKYES);
+  PRREG(DMA0->TCD[CHNL].CITER_ELINKYES);
+  PRREG(DMA0->TCD[CHNL].SLAST);
+  PRREG(DMA0->TCD[CHNL].DLAST_SGA);
+  PRREG(DMA0->TCD[CHNL].SADDR);
+  PRREG(DMA0->TCD[CHNL].DADDR);
+  //while(1);
+#endif
+
+  while(1) {
+      pc.printf("%d\n",adc.read_u16());  // sample DAC output, jumper DAC to A0
+  }
+}
+