Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
- Committer:
- manitou
- Date:
- 2015-10-05
- Revision:
- 0:a57be408001f
File content as of revision 0:a57be408001f:
// 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
}
}