xypad theremin for LPC1768

Dependencies:   MODDMA mbed

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!");
}