EmbedEd
/
mbed_theremin
xypad theremin for LPC1768
dma.cpp
- Committer:
- exopiped
- Date:
- 2016-03-14
- Revision:
- 2:c5eeaf1c8e69
- Parent:
- 1:aa184d2eb2e3
File content as of revision 2:c5eeaf1c8e69:
/* * dma.cpp * Send a buffer repeatedly to the DAC using DMA. */ #include "mbed.h" #include "note.h" #include "MODDMA.h" #include "dma.h" int buffer[2][DMA_BUFSIZE]; AnalogOut sig(p18); // analog output object ( uses pin 18) DigitalOut led2(LED1); DigitalOut led3(LED2); MODDMA dma; MODDMA_Config *conf0, *conf1; int *dma_get_bufptr(int bufno) { return buffer[bufno]; } void dma_init(void) { // Prepare the GPDMA system for buffer0. conf0 = new MODDMA_Config; conf0 ->channelNum ( MODDMA::Channel_0 ) ->srcMemAddr ( (uint32_t) &buffer[0] ) ->dstMemAddr ( MODDMA::DAC ) ->transferSize ( 512 ) ->transferType ( MODDMA::m2p ) ->dstConn ( MODDMA::DAC ) ->attach_tc ( &TC0_callback ) ->attach_err ( &ERR0_callback ) ; // config end // Prepare the GPDMA system for buffer1. conf1 = new MODDMA_Config; conf1 ->channelNum ( MODDMA::Channel_1 ) ->srcMemAddr ( (uint32_t) &buffer[1] ) ->dstMemAddr ( MODDMA::DAC ) ->transferSize ( 512 ) ->transferType ( MODDMA::m2p ) ->dstConn ( MODDMA::DAC ) ->attach_tc ( &TC1_callback ) ->attach_err ( &ERR1_callback ) ; // config end // // By default, the Mbed library sets the PCLK_DAC clock value // to 24MHz. One wave cycle in each buffer is DMA_BUFSIZE // (512) points long. The sample rate of the output is to be // WAVE_SAMPLE_RATE (22050) samples per second, regardless of. // wave frequency. So the DACCNTVAL will be 24000000/22050 // or 1088. // LPC_DAC->DACCNTVAL = 1088; // for 22050 sample rate // // the wave templates will be one dma buffer long, so the // lowest frequency that can be produced is // WAVE_SAMPLE_RATE/DMA_BUFSIZE = 22050/512 = 43 Hz // the highest frequency wave that can be produced is // roughly half the sample rate, or 11025 Hz. // } void dma_enable(void) { // Prepare first configuration. if (!dma.Prepare( conf0 )) { error("Doh!"); } // Begin (enable DMA and counter). Note, don't enable // DBLBUF_ENA as we are using DMA double buffering. LPC_DAC->DACCTRL |= (3UL << 2); } void dma_disable(void) { // Get configuration pointer. MODDMA_Config *config = dma.getConfig(); // Finish the DMA cycle by shutting down the channel. dma.Disable((MODDMA::CHANNELS)config->channelNum()); } // Configuration callback on TC void TC0_callback(void) { dma_disable(); if (note_active()) { // Notify note.cpp that it is time to refill buffer[0] note_set_bufno(0); // Swap to buffer1 dma.Prepare( conf1 ); } // Clear DMA IRQ flags. if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); } // Configuration callback on Error void ERR0_callback(void) { led2=1; error("Oh no! My Mbed EXPLODED!"); } // Configuration callback on TC void TC1_callback(void) { dma_disable(); if (note_active()) { // Notify note.cpp that it is time to refill buffer[1] note_set_bufno(1); // Swap to buffer0 dma.Prepare( conf0 ); } // Clear DMA IRQ flags. if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); } // Configuration callback on Error void ERR1_callback(void) { led3=1; error("Oh no! My Mbed EXPLODED!"); }