Fork of Andy Kirkham's MODDMA GPDMA Controller for Mbed OS 6
Read MODDMA for more info.
Revision 19:bf3ae4c3635d, committed 17 months ago
- Comitter:
- hudakz
- Date:
- Mon Dec 12 15:05:21 2022 +0000
- Parent:
- 18:31f858967e93
- Child:
- 20:01d0a680e45a
- Commit message:
- Fork of Andy Kirkham's MODDMA GPDMA Controller for Mbed OS 6.; The examples are updated in order to compile with Mbed OS 6.
Changed in this revision
--- a/example1.h Sat Dec 10 09:59:10 2022 +0000 +++ b/example1.h Mon Dec 12 15:05:21 2022 +0000 @@ -1,81 +1,89 @@ #include "mbed.h" #include "MODDMA.h" -#include "MODSERIAL.h" -DigitalOut led1(LED1); -DigitalOut led2(LED2); -DigitalOut led3(LED3); -DigitalOut led4(LED4); -MODDMA dma; -MODSERIAL pc(USBTX, USBRX); +DigitalOut led1(LED1); +DigitalOut led2(LED2); +DigitalOut led3(LED3); +DigitalOut led4(LED4); +MODDMA dma; // Function prototypes for IRQ callbacks. // See definitions following main() below. -void dmaTCCallback(void); -void dmaERRCallback(void); -void TC0_callback(void); -void ERR0_callback(void); +void dmaTCCallback(void); +void dmaERRCallback(void); +void TC0_callback(void); +void ERR0_callback(void); + +/** + * @brief + * @note + * @param + * @retval + */ +int main() +{ + char s[] = "**DMA** ABCDEFGHIJKLMNOPQRSTUVWXYZ **DMA**"; + + printf("\r\nStarting\r\n"); -int main() { - char s[] = "**DMA** ABCDEFGHIJKLMNOPQRSTUVWXYZ **DMA**"; - - pc.baud(PC_BAUD); - - dma.attach_tc( &dmaTCCallback ); - dma.attach_err( &dmaERRCallback ); - - MODDMA_Config *config = new MODDMA_Config; - config - ->channelNum ( MODDMA::Channel_0 ) - ->srcMemAddr ( (uint32_t) &s ) - ->dstMemAddr ( 0 ) - ->transferSize ( sizeof(s) ) - ->transferType ( MODDMA::m2p ) - ->transferWidth ( 0 ) - ->srcConn ( 0 ) - ->dstConn ( MODDMA::UART0_Tx ) - ->dmaLLI ( 0 ) - ->attach_tc ( &TC0_callback ) - ->attach_err ( &ERR0_callback ) - ; // config end - + dma.attach_tc(&dmaTCCallback); + dma.attach_err(&dmaERRCallback); + + MODDMA_Config* config = new MODDMA_Config; + + config->channelNum(MODDMA::Channel_0); + config->srcMemAddr((uint32_t) & s); + config->dstMemAddr(0); + config->transferSize(sizeof(s)); + config->transferType(MODDMA::m2p); + config->transferWidth(0); + config->srcConn(0); + config->dstConn(MODDMA::UART0_Tx); + config->dmaLLI(0)->attach_tc(&TC0_callback); + config->attach_err(&ERR0_callback); + // Setup the configuration. dma.Setup(config); - + //dma.Enable( MODDMA::Channel_0 ); //dma.Enable( config->channelNum() ); - dma.Enable( config ); - + dma.Enable(config); + while (1) { led1 = !led1; - wait(0.25); + ThisThread::sleep_for(250ms); } } // Main controller TC IRQ callback -void dmaTCCallback(void) { +void dmaTCCallback(void) +{ led2 = 1; } // Main controller ERR IRQ callback -void dmaERRCallback(void) { - error("Oh no! My Mbed exploded! :( Only kidding, find the problem"); +void dmaERRCallback(void) +{ + printf("Oh no! My Mbed exploded! :( Only kidding, find the problem"); } // Configuration callback on TC -void TC0_callback(void) { - MODDMA_Config *config = dma.getConfig(); - dma.haltAndWaitChannelComplete( (MODDMA::CHANNELS)config->channelNum()); - dma.Disable( (MODDMA::CHANNELS)config->channelNum() ); - - // Configurations have two IRQ callbacks for TC and Err so you - // know which you are processing. However, if you want to use - // a single callback function you can tell what type of IRQ +void TC0_callback(void) +{ + MODDMA_Config* config = dma.getConfig(); + + dma.haltAndWaitChannelComplete((MODDMA::CHANNELS) config->channelNum()); + dma.Disable((MODDMA::CHANNELS) config->channelNum()); + + // Configurations have two IRQ callbacks for TC and Err so you + // know which you are processing. However, if you want to use + // a single callback function you can tell what type of IRQ // is being processed thus:- - if (dma.irqType() == MODDMA::TcIrq) { + if (dma.irqType() == MODDMA::TcIrq) { led3 = 1; dma.clearTcIrq(); } + if (dma.irqType() == MODDMA::ErrIrq) { led4 = 1; dma.clearErrIrq(); @@ -83,7 +91,7 @@ } // Configuration cakllback on Error -void ERR0_callback(void) { - error("Oh no! My Mbed exploded! :( Only kidding, find the problem"); +void ERR0_callback(void) +{ + printf("Oh no! My Mbed exploded! :( Only kidding, find the problem"); } -
--- a/example2.h Sat Dec 10 09:59:10 2022 +0000 +++ b/example2.h Mon Dec 12 15:05:21 2022 +0000 @@ -2,136 +2,141 @@ * This example was provided to support Mbed forum thread:- * http://mbed.org/forum/mbed/topic/1798 */ - #include "mbed.h" #include "MODDMA.h" -#define SAMPLE_BUFFER_LENGTH 32 +#define SAMPLE_BUFFER_LENGTH 32 -DigitalOut led1(LED1); -DigitalOut led2(LED2); +DigitalOut led1(LED1); +DigitalOut led2(LED2); -MODDMA dma; -Serial pc(USBTX, USBRX); +MODDMA dma; // ISR set's this when transfer complete. -bool dmaTransferComplete = false; +bool dmaTransferComplete = false; // Function prototypes for IRQ callbacks. // See definitions following main() below. -void TC0_callback(void); -void ERR0_callback(void); +void TC0_callback(void); +void ERR0_callback(void); -int main() { - +/** + * @brief + * @note + * @param + * @retval + */ +int main() +{ // Create a buffer to hold the ADC samples and clear it. // Note, we are going to sample two ADC inputs so they // end up in this buffer "interleaved". So you will want // a buffer twice this size to a real life given sample // frequency. See the printf() output for details. - uint32_t adcInputBuffer[SAMPLE_BUFFER_LENGTH]; + uint32_t adcInputBuffer[SAMPLE_BUFFER_LENGTH]; memset(adcInputBuffer, 0, sizeof(adcInputBuffer)); - + // We use the ADC irq to trigger DMA and the manual says // that in this case the NVIC for ADC must be disabled. NVIC_DisableIRQ(ADC_IRQn); - + // Power up the ADC and set PCLK - LPC_SC->PCONP |= (1UL << 12); - LPC_SC->PCLKSEL0 &= ~(3UL << 24); // PCLK = CCLK/4 96M/4 = 24MHz - + LPC_SC->PCONP |= (1UL << 12); + LPC_SC->PCLKSEL0 &= ~(3UL << 24); // PCLK = CCLK/4 96M/4 = 24MHz + // Enable the ADC, 12MHz, ADC0.0 & .1 - LPC_ADC->ADCR = (1UL << 21) | (1UL << 8) | (3UL << 0); - + LPC_ADC->ADCR = (1UL << 21) | (1UL << 8) | (3UL << 0); + // Set the pin functions to ADC - LPC_PINCON->PINSEL1 &= ~(3UL << 14); /* P0.23, Mbed p15. */ - LPC_PINCON->PINSEL1 |= (1UL << 14); - LPC_PINCON->PINSEL1 &= ~(3UL << 16); /* P0.24, Mbed p16. */ - LPC_PINCON->PINSEL1 |= (1UL << 16); - + LPC_PINCON->PINSEL1 &= ~(3UL << 14); /* P0.23, Mbed p15. */ + LPC_PINCON->PINSEL1 |= (1UL << 14); + LPC_PINCON->PINSEL1 &= ~(3UL << 16); /* P0.24, Mbed p16. */ + LPC_PINCON->PINSEL1 |= (1UL << 16); + // Setup the serial port to print out results. - pc.baud(115200); - pc.printf("ADC with DMA example\n"); - pc.printf("====================\n"); - + printf("ADC with DMA example\n"); + printf("====================\n"); + // Prepare an ADC configuration. - MODDMA_Config *conf = new MODDMA_Config; - conf - ->channelNum ( MODDMA::Channel_0 ) - ->srcMemAddr ( 0 ) - ->dstMemAddr ( (uint32_t)adcInputBuffer ) - ->transferSize ( SAMPLE_BUFFER_LENGTH ) - ->transferType ( MODDMA::p2m ) - ->transferWidth ( MODDMA::word ) - ->srcConn ( MODDMA::ADC ) - ->dstConn ( 0 ) - ->dmaLLI ( 0 ) - ->attach_tc ( &TC0_callback ) - ->attach_err ( &ERR0_callback ) - ; // end conf. - + MODDMA_Config* conf = new MODDMA_Config; + conf->channelNum(MODDMA::Channel_0); + conf->srcMemAddr(0); + conf->dstMemAddr((uint32_t) adcInputBuffer); + conf->transferSize(SAMPLE_BUFFER_LENGTH); + conf->transferType(MODDMA::p2m); + conf->transferWidth(MODDMA::word); + conf->srcConn(MODDMA::ADC); + conf->dstConn(0); + conf->dmaLLI(0); + conf->attach_tc(&TC0_callback); + conf->attach_err(&ERR0_callback); + // Prepare configuration. - dma.Setup( conf ); - + dma.Setup(conf); + // Enable configuration. - dma.Enable( conf ); - + dma.Enable(conf); + // Enable ADC irq flag (to DMA). // Note, don't set the individual flags, // just set the global flag. LPC_ADC->ADINTEN = 0x100; // Enable burst mode on inputs 0 and 1. - LPC_ADC->ADCR |= (1UL << 16); - + LPC_ADC->ADCR |= (1UL << 16); + while (1) { + // When transfer complete do this block. if (dmaTransferComplete) { - delete conf; // No memory leaks, delete the configuration. + delete conf; // No memory leaks, delete the configuration. dmaTransferComplete = false; for (int i = 0; i < SAMPLE_BUFFER_LENGTH; i++) { - int channel = (adcInputBuffer[i] >> 24) & 0x7; - int iVal = (adcInputBuffer[i] >> 4) & 0xFFF; - double fVal = 3.3 * (double)((double)iVal) / ((double)0x1000); // scale to 0v to 3.3v - pc.printf("Array index %02d : ADC input channel %d = 0x%03x %01.3f volts\n", i, channel, iVal, fVal); + int channel = (adcInputBuffer[i] >> 24) & 0x7; + int iVal = (adcInputBuffer[i] >> 4) & 0xFFF; + double fVal = 3.3 * (double)((double)iVal) / ((double)0x1000); // scale to 0v to 3.3v + + printf("Array index %02d : ADC input channel %d = 0x%03x %01.3f volts\n", i, channel, iVal, fVal); } } - + // Just flash LED1 for something to do. led1 = !led1; - wait(0.25); + ThisThread::sleep_for(250ms); } } // Configuration callback on TC -void TC0_callback(void) { - - MODDMA_Config *config = dma.getConfig(); - +void TC0_callback(void) +{ + MODDMA_Config* config = dma.getConfig(); + // Disbale burst mode and switch off the IRQ flag. LPC_ADC->ADCR &= ~(1UL << 16); - LPC_ADC->ADINTEN = 0; - + LPC_ADC->ADINTEN = 0; + // Finish the DMA cycle by shutting down the channel. - dma.haltAndWaitChannelComplete( (MODDMA::CHANNELS)config->channelNum()); - dma.Disable( (MODDMA::CHANNELS)config->channelNum() ); - + dma.haltAndWaitChannelComplete((MODDMA::CHANNELS) config->channelNum()); + dma.Disable((MODDMA::CHANNELS) config->channelNum()); + // Tell main() while(1) loop to print the results. - dmaTransferComplete = true; - + dmaTransferComplete = true; + // Switch on LED2 to show transfer complete. - led2 = 1; - + led2 = 1; + // Clear DMA IRQ flags. - if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); - if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq(); + if (dma.irqType() == MODDMA::TcIrq) + dma.clearTcIrq(); + if (dma.irqType() == MODDMA::ErrIrq) + dma.clearErrIrq(); } // Configuration callback on Error -void ERR0_callback(void) { +void ERR0_callback(void) +{ // Switch off burst conversions. LPC_ADC->ADCR |= ~(1UL << 16); LPC_ADC->ADINTEN = 0; error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem"); } -
--- a/example3.h Sat Dec 10 09:59:10 2022 +0000 +++ b/example3.h Mon Dec 12 15:05:21 2022 +0000 @@ -1,131 +1,142 @@ /* - * Demonstrates capturing the GPIO P0.4 to P0.7 "nibble" to memory + * Demonstrates capturing the GPIO P0.4 to P0.7 "nibble" to memory * using GPDMA. The transfers from port pins to memory buffer are * triggered using Timer1 MAT1.0 match compare. * * In this example all inputs have pullups. So with nothing connected - * the P0.4/7 reads as 0xF. Connecting a wire from one or more of the four + * the P0.4/7 reads as 0xF. Connecting a wire from one or more of the four * inputs to ground will show up in the captured buffer sequence. */ - #include "mbed.h" #include "MODDMA.h" -#include "iomacros.h" // within MODDMA library. +#include "iomacros.h" // within MODDMA library. // How long between grabbing GPIO FIO0PIN register. + // Value is in microseconds. (500000 is half a second). #define SAMPLE_PERIOD 500000 #define NUM_OF_SAMPLES 5 -Serial pc(USBTX, USBRX); +DigitalOut led1(LED1); +DigitalOut led2(LED2); +DigitalOut led3(LED3); -DigitalOut led1(LED1); -DigitalOut led2(LED2); -DigitalOut led3(LED3); +uint32_t buffer[NUM_OF_SAMPLES]; -uint32_t buffer[NUM_OF_SAMPLES]; +bool dmaTransferComplete; -bool dmaTransferComplete; +MODDMA dma; +MODDMA_Config* conf; -MODDMA dma; -MODDMA_Config *conf; +void TC0_callback(void); +void ERR0_callback(void); -void TC0_callback(void); -void ERR0_callback(void); +/** + * @brief + * @note + * @param + * @retval + */ +int main() +{ + volatile int life_counter = 0; -int main() { - volatile int life_counter = 0; - // Macros defined in iomacros.h, saves messing with DigitalIn - p30_AS_INPUT; p30_MODE( PIN_PULLUP ); // P0.4 - p29_AS_INPUT; p29_MODE( PIN_PULLUP ); // P0.5 - p8_AS_INPUT; p8_MODE( PIN_PULLUP ); // P0.6 - p7_AS_INPUT; p7_MODE( PIN_PULLUP ); // P0.7 - + p30_AS_INPUT; + p30_MODE(PIN_PULLUP); // P0.4 + p29_AS_INPUT; + p29_MODE(PIN_PULLUP); // P0.5 + p8_AS_INPUT; + p8_MODE(PIN_PULLUP); // P0.6 + p7_AS_INPUT; + p7_MODE(PIN_PULLUP); // P0.7 + // Clear the buffer. memset(buffer, 0, sizeof(buffer)); - - // Setup the serial port to print out results. - pc.baud(115200); - pc.printf("Starting up...\n"); - + + printf("Starting up...\n"); + // Set-up timer1 as a periodic timer. - LPC_SC->PCONP |= (1UL << 2); // TIM1 On - LPC_SC->PCLKSEL0 |= (3UL << 4); // CCLK/8 = 12MHz - LPC_TIM1->PR = 11; // TC clocks at 1MHz. - LPC_TIM1->MCR = 2; // Reset TCR to zero on match. - LPC_TIM1->MR0 = SAMPLE_PERIOD; - + LPC_SC->PCONP |= (1UL << 2); // TIM1 On + LPC_SC->PCLKSEL0 |= (3UL << 4); // CCLK/8 = 12MHz + LPC_TIM1->PR = 11; // TC clocks at 1MHz. + LPC_TIM1->MCR = 2; // Reset TCR to zero on match. + LPC_TIM1->MR0 = SAMPLE_PERIOD; + // Prepare the GPDMA system. conf = new MODDMA_Config; - conf - ->channelNum ( MODDMA::Channel_0 ) - ->srcMemAddr ( (uint32_t)&LPC_GPIO0->FIOPIN ) - ->dstMemAddr ( (uint32_t)&buffer[0] ) - ->transferSize ( NUM_OF_SAMPLES ) - ->transferType ( MODDMA::g2m ) // pseudo transfer code MODDMA understands. - ->transferWidth ( MODDMA::word ) - ->srcConn ( MODDMA::MAT1_0 ) - ->dmacSync ( MODDMA::MAT1_0 ) - ->attach_tc ( TC0_callback ) - ->attach_err ( ERR0_callback ) - ; // end conf. - + conf->channelNum(MODDMA::Channel_0); + conf->srcMemAddr((uint32_t) & LPC_GPIO0->FIOPIN); + conf->dstMemAddr((uint32_t) & buffer[0]); + conf->transferSize(NUM_OF_SAMPLES); + conf->transferType(MODDMA::g2m); // pseudo transfer code MODDMA understands. + conf->transferWidth(MODDMA::word); + conf->srcConn(MODDMA::MAT1_0); + conf->dmacSync(MODDMA::MAT1_0); + conf->attach_tc(TC0_callback); + conf->attach_err(ERR0_callback); + ; // end conf. + // Prepare configuration. - if (!dma.Setup( conf )) { + if (!dma.Setup(conf)) { error("Doh!"); } - - // Enable GPDMA to be ready for the TIM1 "ticks". - dma.Enable( conf ); - + + // Enable GPDMA to be ready for the TIM1 "ticks". + dma.Enable(conf); + // Begin. LPC_TIM1->TCR = 1; - - while (1) { + + while (1) { if (life_counter++ > 1000000) { - led1 = !led1; // Show some sort of life. + led1 = !led1; // Show some sort of life. life_counter = 0; } - + if (dmaTransferComplete) { dmaTransferComplete = false; for (int i = 0; i < NUM_OF_SAMPLES; i++) { - int val = (buffer[i] >> 4) & 0xF; - pc.printf("Buffer index %d = 0x%x\n", i, val); + int val = (buffer[i] >> 4) & 0xF; + printf("Buffer index %d = 0x%x\n", i, val); } - pc.printf("Done.\n"); - + + printf("Done.\n"); + // Schedule another grab. - if (dma.Setup( conf )) { - dma.Enable( conf ); - } + if (dma.Setup(conf)) { + dma.Enable(conf); + } } - } + } } // Configuration callback on TC -void TC0_callback(void) { - +void TC0_callback(void) +{ // Just show sample sequence grab complete. - led3 = !led3; - + led3 = !led3; + // Get configuration pointer. - MODDMA_Config *config = dma.getConfig(); - + MODDMA_Config* config = dma.getConfig(); + // Finish the DMA cycle by shutting down the channel. - dma.Disable( (MODDMA::CHANNELS)config->channelNum() ); - + + dma.Disable((MODDMA::CHANNELS) config->channelNum()); + // Tell main() while(1) loop to print the results. - dmaTransferComplete = true; - + dmaTransferComplete = true; + // Clear DMA IRQ flags. - if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); - if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq(); + if (dma.irqType() == MODDMA::TcIrq) + dma.clearTcIrq(); + if (dma.irqType() == MODDMA::ErrIrq) + dma.clearErrIrq(); } // Configuration callback on Error -void ERR0_callback(void) { +void ERR0_callback(void) +{ error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem"); }
--- a/example4.h Sat Dec 10 09:59:10 2022 +0000 +++ b/example4.h Mon Dec 12 15:05:21 2022 +0000 @@ -7,72 +7,79 @@ #include "MODDMA.h" // Make the buffer size match the number of degrees + // in a circle since we are going to output a sinewave. #define BUFFER_SIZE 360 // Set DAC output power mode. + #define DAC_POWER_MODE (1 << 16) -DigitalOut led1(LED1); -DigitalOut led3(LED3); -DigitalOut led4(LED4); +DigitalOut led1(LED1); +DigitalOut led3(LED3); +DigitalOut led4(LED4); + +int buffer[2][BUFFER_SIZE]; + +AnalogOut signal(p18); -int buffer[2][BUFFER_SIZE]; +MODDMA dma; +MODDMA_Config* conf0, *conf1; -AnalogOut signal(p18); +void TC0_callback(void); +void ERR0_callback(void); -MODDMA dma; -MODDMA_Config *conf0, *conf1; +void TC1_callback(void); +void ERR1_callback(void); -void TC0_callback(void); -void ERR0_callback(void); - -void TC1_callback(void); -void ERR1_callback(void); +/** + * @brief + * @note + * @param + * @retval + */ +int main() +{ + volatile int life_counter = 0; -int main() { - volatile int life_counter = 0; - // Create a sinewave buffer for testing. - for (int i = 0; i <= 90; i++) buffer[0][i] = (512 * sin(3.14159/180.0 * i)) + 512; - for (int i = 91; i <= 180; i++) buffer[0][i] = buffer[0][180 - i]; - for (int i = 181; i <= 270; i++) buffer[0][i] = 512 - (buffer[0][i - 180] - 512); - for (int i = 271; i < 360; i++) buffer[0][i] = 512 - (buffer[0][360 - i] - 512); - + for (int i = 0; i <= 90; i++) + buffer[0][i] = (512 * sin(3.14159 / 180.0 * i)) + 512; + for (int i = 91; i <= 180; i++) + buffer[0][i] = buffer[0][180 - i]; + for (int i = 181; i <= 270; i++) + buffer[0][i] = 512 - (buffer[0][i - 180] - 512); + for (int i = 271; i < 360; i++) + buffer[0][i] = 512 - (buffer[0][360 - i] - 512); + // Adjust the sinewave buffer for use with DAC hardware. for (int i = 0; i < 360; i++) { buffer[0][i] = DAC_POWER_MODE | ((buffer[0][i] << 6) & 0xFFC0); - buffer[1][i] = buffer[0][i]; // Just create a copy of buffer0 to continue sinewave. + buffer[1][i] = buffer[0][i]; // Just create a copy of buffer0 to continue sinewave. } - + // Prepare the GPDMA system for buffer0. conf0 = new MODDMA_Config; - conf0 - ->channelNum ( MODDMA::Channel_0 ) - ->srcMemAddr ( (uint32_t) &buffer[0] ) - ->dstMemAddr ( MODDMA::DAC ) - ->transferSize ( 360 ) - ->transferType ( MODDMA::m2p ) - ->dstConn ( MODDMA::DAC ) - ->attach_tc ( &TC0_callback ) - ->attach_err ( &ERR0_callback ) - ; // config end - - + conf0->channelNum(MODDMA::Channel_0); + conf0->srcMemAddr((uint32_t) & buffer[0]); + conf0->dstMemAddr(MODDMA::DAC); + conf0->transferSize(360); + conf0->transferType(MODDMA::m2p); + conf0->dstConn(MODDMA::DAC); + conf0->attach_tc(&TC0_callback); + conf0->attach_err(&ERR0_callback); + // Prepare the GPDMA system for buffer1. conf1 = new MODDMA_Config; - conf1 - ->channelNum ( MODDMA::Channel_1 ) - ->srcMemAddr ( (uint32_t) &buffer[1] ) - ->dstMemAddr ( MODDMA::DAC ) - ->transferSize ( 360 ) - ->transferType ( MODDMA::m2p ) - ->dstConn ( MODDMA::DAC ) - ->attach_tc ( &TC1_callback ) - ->attach_err ( &ERR1_callback ) - ; // config end + conf1->channelNum(MODDMA::Channel_1); + conf1->srcMemAddr((uint32_t) & buffer[1]); + conf1->dstMemAddr(MODDMA::DAC); + conf1->transferSize(360); + conf1->transferType(MODDMA::m2p); + conf1->dstConn(MODDMA::DAC); + conf1->attach_tc(&TC1_callback); + conf1->attach_err(&ERR1_callback); - // Calculating the transfer frequency: // By default, the Mbed library sets the PCLK_DAC clock value // to 24MHz. One complete sinewave cycle in each buffer is 360 @@ -83,74 +90,79 @@ // alter PCLK_DAC from CCLK/4 to CCLK/8. // For our demo we are going to have the sinewave run at 1kHz. // That's 24000000/360000 which is approx 66. Experimentation - // however showed 65 to get closer to 1kHz (on my Mbed and scope + // however showed 65 to get closer to 1kHz (on my Mbed and scope // at least). - LPC_DAC->DACCNTVAL = 65; // 6500 for 10Hz + LPC_DAC->DACCNTVAL = 65; // 6500 for 10Hz // Prepare first configuration. - if (!dma.Prepare( conf0 )) { + 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); - - while (1) { + + while (1) { + // There's not a lot to do as DMA and interrupts are // now handling the buffer transfers. So we'll just // flash led1 to show the Mbed is alive and kicking. if (life_counter++ > 1000000) { - led1 = !led1; // Show some sort of life. + led1 = !led1; // Show some sort of life. life_counter = 0; } - } + } } // Configuration callback on TC -void TC0_callback(void) { - +void TC0_callback(void) +{ // Just show sending buffer0 complete. - led3 = !led3; - + led3 = !led3; + // Get configuration pointer. - MODDMA_Config *config = dma.getConfig(); - + MODDMA_Config* config = dma.getConfig(); + // Finish the DMA cycle by shutting down the channel. - dma.Disable( (MODDMA::CHANNELS)config->channelNum() ); - + dma.Disable((MODDMA::CHANNELS) config->channelNum()); + // Swap to buffer1 - dma.Prepare( conf1 ); + dma.Prepare(conf1); // Clear DMA IRQ flags. - if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); + if (dma.irqType() == MODDMA::TcIrq) + dma.clearTcIrq(); } // Configuration callback on Error -void ERR0_callback(void) { +void ERR0_callback(void) +{ error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem"); } // Configuration callback on TC -void TC1_callback(void) { - +void TC1_callback(void) +{ // Just show sending buffer1 complete. - led4 = !led4; - + led4 = !led4; + // Get configuration pointer. - MODDMA_Config *config = dma.getConfig(); - + MODDMA_Config* config = dma.getConfig(); + // Finish the DMA cycle by shutting down the channel. - dma.Disable( (MODDMA::CHANNELS)config->channelNum() ); - + dma.Disable((MODDMA::CHANNELS) config->channelNum()); + // Swap to buffer0 - dma.Prepare( conf0 ); - + dma.Prepare(conf0); + // Clear DMA IRQ flags. - if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); + if (dma.irqType() == MODDMA::TcIrq) + dma.clearTcIrq(); } // Configuration callback on Error -void ERR1_callback(void) { +void ERR1_callback(void) +{ error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem"); }