Fork of Andy Kirkham's MODDMA GPDMA Controller for Mbed OS 6

Read MODDMA for more info.

Committer:
hudakz
Date:
Mon Dec 12 15:08:37 2022 +0000
Revision:
20:01d0a680e45a
Parent:
19:bf3ae4c3635d
Fork of Andy Kirkham's MODDMA GPDMA Controller for Mbed OS 6.; The examples are updated in order to compile with Mbed OS 6.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AjK 12:1dfee7208043 1 /*
AjK 12:1dfee7208043 2 * This example was provided to support Mbed forum thread:-
AjK 12:1dfee7208043 3 * http://mbed.org/forum/mbed/topic/1798
AjK 12:1dfee7208043 4 */
AjK 12:1dfee7208043 5 #include "mbed.h"
AjK 12:1dfee7208043 6 #include "MODDMA.h"
AjK 12:1dfee7208043 7
hudakz 19:bf3ae4c3635d 8 #define SAMPLE_BUFFER_LENGTH 32
AjK 12:1dfee7208043 9
hudakz 19:bf3ae4c3635d 10 DigitalOut led1(LED1);
hudakz 19:bf3ae4c3635d 11 DigitalOut led2(LED2);
AjK 12:1dfee7208043 12
hudakz 19:bf3ae4c3635d 13 MODDMA dma;
AjK 12:1dfee7208043 14
AjK 12:1dfee7208043 15 // ISR set's this when transfer complete.
hudakz 19:bf3ae4c3635d 16 bool dmaTransferComplete = false;
AjK 12:1dfee7208043 17
AjK 12:1dfee7208043 18 // Function prototypes for IRQ callbacks.
AjK 12:1dfee7208043 19 // See definitions following main() below.
hudakz 19:bf3ae4c3635d 20 void TC0_callback(void);
hudakz 19:bf3ae4c3635d 21 void ERR0_callback(void);
AjK 12:1dfee7208043 22
hudakz 19:bf3ae4c3635d 23 /**
hudakz 19:bf3ae4c3635d 24 * @brief
hudakz 19:bf3ae4c3635d 25 * @note
hudakz 19:bf3ae4c3635d 26 * @param
hudakz 19:bf3ae4c3635d 27 * @retval
hudakz 19:bf3ae4c3635d 28 */
hudakz 19:bf3ae4c3635d 29 int main()
hudakz 19:bf3ae4c3635d 30 {
AjK 12:1dfee7208043 31 // Create a buffer to hold the ADC samples and clear it.
AjK 12:1dfee7208043 32 // Note, we are going to sample two ADC inputs so they
AjK 12:1dfee7208043 33 // end up in this buffer "interleaved". So you will want
AjK 12:1dfee7208043 34 // a buffer twice this size to a real life given sample
AjK 12:1dfee7208043 35 // frequency. See the printf() output for details.
hudakz 19:bf3ae4c3635d 36 uint32_t adcInputBuffer[SAMPLE_BUFFER_LENGTH];
AjK 12:1dfee7208043 37 memset(adcInputBuffer, 0, sizeof(adcInputBuffer));
hudakz 19:bf3ae4c3635d 38
AjK 12:1dfee7208043 39 // We use the ADC irq to trigger DMA and the manual says
AjK 12:1dfee7208043 40 // that in this case the NVIC for ADC must be disabled.
AjK 12:1dfee7208043 41 NVIC_DisableIRQ(ADC_IRQn);
hudakz 19:bf3ae4c3635d 42
AjK 12:1dfee7208043 43 // Power up the ADC and set PCLK
hudakz 19:bf3ae4c3635d 44 LPC_SC->PCONP |= (1UL << 12);
hudakz 19:bf3ae4c3635d 45 LPC_SC->PCLKSEL0 &= ~(3UL << 24); // PCLK = CCLK/4 96M/4 = 24MHz
hudakz 19:bf3ae4c3635d 46
AjK 12:1dfee7208043 47 // Enable the ADC, 12MHz, ADC0.0 & .1
hudakz 19:bf3ae4c3635d 48 LPC_ADC->ADCR = (1UL << 21) | (1UL << 8) | (3UL << 0);
hudakz 19:bf3ae4c3635d 49
AjK 12:1dfee7208043 50 // Set the pin functions to ADC
hudakz 19:bf3ae4c3635d 51 LPC_PINCON->PINSEL1 &= ~(3UL << 14); /* P0.23, Mbed p15. */
hudakz 19:bf3ae4c3635d 52 LPC_PINCON->PINSEL1 |= (1UL << 14);
hudakz 19:bf3ae4c3635d 53 LPC_PINCON->PINSEL1 &= ~(3UL << 16); /* P0.24, Mbed p16. */
hudakz 19:bf3ae4c3635d 54 LPC_PINCON->PINSEL1 |= (1UL << 16);
hudakz 19:bf3ae4c3635d 55
AjK 12:1dfee7208043 56 // Setup the serial port to print out results.
hudakz 19:bf3ae4c3635d 57 printf("ADC with DMA example\n");
hudakz 19:bf3ae4c3635d 58 printf("====================\n");
hudakz 19:bf3ae4c3635d 59
AjK 12:1dfee7208043 60 // Prepare an ADC configuration.
hudakz 19:bf3ae4c3635d 61 MODDMA_Config* conf = new MODDMA_Config;
hudakz 19:bf3ae4c3635d 62 conf->channelNum(MODDMA::Channel_0);
hudakz 19:bf3ae4c3635d 63 conf->srcMemAddr(0);
hudakz 19:bf3ae4c3635d 64 conf->dstMemAddr((uint32_t) adcInputBuffer);
hudakz 19:bf3ae4c3635d 65 conf->transferSize(SAMPLE_BUFFER_LENGTH);
hudakz 19:bf3ae4c3635d 66 conf->transferType(MODDMA::p2m);
hudakz 19:bf3ae4c3635d 67 conf->transferWidth(MODDMA::word);
hudakz 19:bf3ae4c3635d 68 conf->srcConn(MODDMA::ADC);
hudakz 19:bf3ae4c3635d 69 conf->dstConn(0);
hudakz 19:bf3ae4c3635d 70 conf->dmaLLI(0);
hudakz 19:bf3ae4c3635d 71 conf->attach_tc(&TC0_callback);
hudakz 19:bf3ae4c3635d 72 conf->attach_err(&ERR0_callback);
hudakz 19:bf3ae4c3635d 73
AjK 12:1dfee7208043 74 // Prepare configuration.
hudakz 19:bf3ae4c3635d 75 dma.Setup(conf);
hudakz 19:bf3ae4c3635d 76
AjK 12:1dfee7208043 77 // Enable configuration.
hudakz 19:bf3ae4c3635d 78 dma.Enable(conf);
hudakz 19:bf3ae4c3635d 79
AjK 12:1dfee7208043 80 // Enable ADC irq flag (to DMA).
AjK 12:1dfee7208043 81 // Note, don't set the individual flags,
AjK 12:1dfee7208043 82 // just set the global flag.
AjK 12:1dfee7208043 83 LPC_ADC->ADINTEN = 0x100;
AjK 12:1dfee7208043 84
AjK 12:1dfee7208043 85 // Enable burst mode on inputs 0 and 1.
hudakz 19:bf3ae4c3635d 86 LPC_ADC->ADCR |= (1UL << 16);
hudakz 19:bf3ae4c3635d 87
AjK 12:1dfee7208043 88 while (1) {
hudakz 19:bf3ae4c3635d 89
AjK 12:1dfee7208043 90 // When transfer complete do this block.
AjK 12:1dfee7208043 91 if (dmaTransferComplete) {
hudakz 19:bf3ae4c3635d 92 delete conf; // No memory leaks, delete the configuration.
AjK 12:1dfee7208043 93 dmaTransferComplete = false;
AjK 12:1dfee7208043 94 for (int i = 0; i < SAMPLE_BUFFER_LENGTH; i++) {
hudakz 19:bf3ae4c3635d 95 int channel = (adcInputBuffer[i] >> 24) & 0x7;
hudakz 19:bf3ae4c3635d 96 int iVal = (adcInputBuffer[i] >> 4) & 0xFFF;
hudakz 19:bf3ae4c3635d 97 double fVal = 3.3 * (double)((double)iVal) / ((double)0x1000); // scale to 0v to 3.3v
hudakz 19:bf3ae4c3635d 98
hudakz 19:bf3ae4c3635d 99 printf("Array index %02d : ADC input channel %d = 0x%03x %01.3f volts\n", i, channel, iVal, fVal);
AjK 12:1dfee7208043 100 }
AjK 12:1dfee7208043 101 }
hudakz 19:bf3ae4c3635d 102
AjK 12:1dfee7208043 103 // Just flash LED1 for something to do.
AjK 12:1dfee7208043 104 led1 = !led1;
hudakz 19:bf3ae4c3635d 105 ThisThread::sleep_for(250ms);
AjK 12:1dfee7208043 106 }
AjK 12:1dfee7208043 107 }
AjK 12:1dfee7208043 108
AjK 12:1dfee7208043 109 // Configuration callback on TC
hudakz 19:bf3ae4c3635d 110 void TC0_callback(void)
hudakz 19:bf3ae4c3635d 111 {
hudakz 19:bf3ae4c3635d 112 MODDMA_Config* config = dma.getConfig();
hudakz 19:bf3ae4c3635d 113
AjK 12:1dfee7208043 114 // Disbale burst mode and switch off the IRQ flag.
AjK 12:1dfee7208043 115 LPC_ADC->ADCR &= ~(1UL << 16);
hudakz 19:bf3ae4c3635d 116 LPC_ADC->ADINTEN = 0;
hudakz 19:bf3ae4c3635d 117
AjK 12:1dfee7208043 118 // Finish the DMA cycle by shutting down the channel.
hudakz 19:bf3ae4c3635d 119 dma.haltAndWaitChannelComplete((MODDMA::CHANNELS) config->channelNum());
hudakz 19:bf3ae4c3635d 120 dma.Disable((MODDMA::CHANNELS) config->channelNum());
hudakz 19:bf3ae4c3635d 121
AjK 12:1dfee7208043 122 // Tell main() while(1) loop to print the results.
hudakz 19:bf3ae4c3635d 123 dmaTransferComplete = true;
hudakz 19:bf3ae4c3635d 124
AjK 12:1dfee7208043 125 // Switch on LED2 to show transfer complete.
hudakz 19:bf3ae4c3635d 126 led2 = 1;
hudakz 19:bf3ae4c3635d 127
AjK 12:1dfee7208043 128 // Clear DMA IRQ flags.
hudakz 19:bf3ae4c3635d 129 if (dma.irqType() == MODDMA::TcIrq)
hudakz 19:bf3ae4c3635d 130 dma.clearTcIrq();
hudakz 19:bf3ae4c3635d 131 if (dma.irqType() == MODDMA::ErrIrq)
hudakz 19:bf3ae4c3635d 132 dma.clearErrIrq();
AjK 12:1dfee7208043 133 }
AjK 12:1dfee7208043 134
AjK 12:1dfee7208043 135 // Configuration callback on Error
hudakz 19:bf3ae4c3635d 136 void ERR0_callback(void)
hudakz 19:bf3ae4c3635d 137 {
AjK 12:1dfee7208043 138 // Switch off burst conversions.
AjK 12:1dfee7208043 139 LPC_ADC->ADCR |= ~(1UL << 16);
AjK 12:1dfee7208043 140 LPC_ADC->ADINTEN = 0;
AjK 12:1dfee7208043 141 error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem");
AjK 12:1dfee7208043 142 }