Hello,
I've been trying to create a repetitive pulsed output to the DAC using the MODDMA library.
I have found that when calling dma.Setup and dma.Enable or the equivalent Prepare function, the DMA call back does not always occur. (I have not tested the physical output so this may or may not be occurring every pulse).
The code below sets up the DMA configuration, attaches a timeout function "myhandler", enables the DMA transfer, and repeats this 1000 times. The PC serial connection, receives notification if the call back has occurred or not. Out of the 1000 times 971 call backs were made. This number changes with different timing parameters.
Please let me know if this is a DMA problem or I am just doing something fundamentally wrong.
Thanks,
Jeff
#include "mbed.h"
#include "MODDMA.h"
#define BUFFER_SIZE 100
Serial pc(USBTX, USBRX);
DigitalOut led4(LED4);
int buffer[BUFFER_SIZE];
AnalogOut signal(p18);
MODDMA dma;
MODDMA_Config *conf0, *conf1;
void TC0_callback(void);
void ERR0_callback(void);
Timeout timeOutEMS;
bool dmaTransferComplete = false;
bool timerComplete = false;
void myhandler() {
pc.printf("timerComplete\r\n");
timerComplete = true;
}
int main() {
signal = 0;
pc.baud(115200);
pc.printf("Hello World\r\n");
volatile int life_counter = 0;
LPC_SC->PCLKSEL0 &= ~(3 << 22); // PCLK_DAC ck/4 (00)
//CCLK = 96000000 Hz
// fill buffer for use with DAC hardware.
for (int i = 0; i < 100; i++) {
buffer[i] = (0xFFFF & 0xFFC0);
}
// Prepare the GPDMA system for buffer0.
conf0 = new MODDMA_Config;
conf0
->channelNum ( MODDMA::Channel_0 )
->srcMemAddr ( (uint32_t) &buffer )
->dstMemAddr ( MODDMA::DAC )
->transferSize ( BUFFER_SIZE )
->transferType ( MODDMA::m2p )
->dstConn ( MODDMA::DAC )
->attach_tc ( &TC0_callback )
->attach_err ( &ERR0_callback )
; // config end
// Calculating the transfer frequency:
// By default, the Mbed library sets the PCLK_DAC clock value
// to 24MHz.
LPC_DAC->DACCNTVAL = 24; // 1Msps
timerComplete = true;
int pulseCount = 0;
int maxPulseCount = 1000;
while (1) {
if (life_counter++ > 10000000) {
led4 = !led4; // Show some sort of life.
life_counter = 0;
}
if(timerComplete & pulseCount < maxPulseCount ){
timerComplete = false;
pc.printf("attach timer\r\n");
timeOutEMS.attach_us(&myhandler, 6000);
wait_us(500);
if (dma.Setup( conf0 )) {
dma.Enable( conf0 );
if (pulseCount == 0)
{
// Begin (enable DMA and counter)
LPC_DAC->DACCTRL |= (3UL << 2);
}
}else{
pc.printf("DMA Setup Error\r\n");
}
wait_us(100);
pulseCount++;
}
}
}
// Configuration callback on TC
void TC0_callback(void) {
signal = 0;
// Just show sending buffer0 complete.
pc.printf("TC0_callback\r\n");
// Get configuration pointer.
MODDMA_Config *config = dma.getConfig();
// Finish the DMA cycle by shutting down the channel.
dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
// Tell main() while(1) loop to print the results.
dmaTransferComplete = true;
// Clear DMA IRQ flags.
if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq();
}
// Configuration callback on Error
void ERR0_callback(void) {
pc.printf("ERR0_callback\r\n");
}
Hello,
I've been trying to create a repetitive pulsed output to the DAC using the MODDMA library.
I have found that when calling dma.Setup and dma.Enable or the equivalent Prepare function, the DMA call back does not always occur. (I have not tested the physical output so this may or may not be occurring every pulse).
The code below sets up the DMA configuration, attaches a timeout function "myhandler", enables the DMA transfer, and repeats this 1000 times. The PC serial connection, receives notification if the call back has occurred or not. Out of the 1000 times 971 call backs were made. This number changes with different timing parameters.
Please let me know if this is a DMA problem or I am just doing something fundamentally wrong.
Thanks, Jeff