Fork of Andy Kirkham's MODDMA GPDMA Controller for Mbed OS 6
Read MODDMA for more info.
example2.h@20:01d0a680e45a, 22 months ago (annotated)
- 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?
User | Revision | Line number | New 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 | } |