Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
DMAFuncGen.cpp@0:337ad0fe7734, 2013-12-29 (annotated)
- Committer:
- Mischa
- Date:
- Sun Dec 29 01:00:30 2013 +0000
- Revision:
- 0:337ad0fe7734
First version.
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| Mischa | 0:337ad0fe7734 | 1 | #include "assert.h" |
| Mischa | 0:337ad0fe7734 | 2 | #include "DMAFuncGen.h" |
| Mischa | 0:337ad0fe7734 | 3 | |
| Mischa | 0:337ad0fe7734 | 4 | //DigitalOut led1(LED1); |
| Mischa | 0:337ad0fe7734 | 5 | |
| Mischa | 0:337ad0fe7734 | 6 | DMAFuncGen::DMAFuncGen(MODDMA& dma, MODDMA::CHANNELS channel) : dma(dma) { |
| Mischa | 0:337ad0fe7734 | 7 | conf.channelNum( channel ); |
| Mischa | 0:337ad0fe7734 | 8 | buffer_size = 0; |
| Mischa | 0:337ad0fe7734 | 9 | buffer = NULL; |
| Mischa | 0:337ad0fe7734 | 10 | } |
| Mischa | 0:337ad0fe7734 | 11 | |
| Mischa | 0:337ad0fe7734 | 12 | #define DAC_POWER_MODE (0 << 16) // DAC output power mode. |
| Mischa | 0:337ad0fe7734 | 13 | |
| Mischa | 0:337ad0fe7734 | 14 | uint16_t DMAFuncGen::operator[](const uint16_t idx) { |
| Mischa | 0:337ad0fe7734 | 15 | assert(buffer!=NULL); |
| Mischa | 0:337ad0fe7734 | 16 | assert(idx<buffer_size); |
| Mischa | 0:337ad0fe7734 | 17 | return buffer[idx] & 0xFFC0; |
| Mischa | 0:337ad0fe7734 | 18 | } |
| Mischa | 0:337ad0fe7734 | 19 | |
| Mischa | 0:337ad0fe7734 | 20 | void DMAFuncGen::set(int idx, uint16_t x) { |
| Mischa | 0:337ad0fe7734 | 21 | // V = (x>>6) × ((VrefP - VrefN)/1024) + VrefN; VrefN = 0V; VrefP = 3.3V; |
| Mischa | 0:337ad0fe7734 | 22 | buffer[idx] = DAC_POWER_MODE | (x & 0xFFC0); |
| Mischa | 0:337ad0fe7734 | 23 | } |
| Mischa | 0:337ad0fe7734 | 24 | |
| Mischa | 0:337ad0fe7734 | 25 | void DMAFuncGen::Connect() { |
| Mischa | 0:337ad0fe7734 | 26 | // Connect DAC to pin |
| Mischa | 0:337ad0fe7734 | 27 | LPC_PINCON->PINSEL1 &= ~(3UL <<20); |
| Mischa | 0:337ad0fe7734 | 28 | LPC_PINCON->PINSEL1 |= 2UL <<20; //AOUT |
| Mischa | 0:337ad0fe7734 | 29 | LPC_PINCON->PINMODE1 &= ~(3UL <<20); |
| Mischa | 0:337ad0fe7734 | 30 | LPC_PINCON->PINMODE1 |= (2UL <<20); // neither pull-up nor pull-down |
| Mischa | 0:337ad0fe7734 | 31 | LPC_PINCON->PINMODE_OD0 &= ~(1UL <<26); // normal (not open drain) mode |
| Mischa | 0:337ad0fe7734 | 32 | } |
| Mischa | 0:337ad0fe7734 | 33 | |
| Mischa | 0:337ad0fe7734 | 34 | void DMAFuncGen::Disconnect() { |
| Mischa | 0:337ad0fe7734 | 35 | LPC_PINCON->PINSEL1 &= ~(3UL <<20); |
| Mischa | 0:337ad0fe7734 | 36 | LPC_PINCON->PINSEL1 |= 1UL <<20; //AD0.3, input |
| Mischa | 0:337ad0fe7734 | 37 | LPC_PINCON->PINMODE1 &= ~(3UL <<20); |
| Mischa | 0:337ad0fe7734 | 38 | LPC_PINCON->PINMODE1 |= (2UL <<20); // neither pull-up nor pull-down |
| Mischa | 0:337ad0fe7734 | 39 | LPC_PINCON->PINMODE_OD0 &= ~(1UL <<26); // normal (not open drain) mode |
| Mischa | 0:337ad0fe7734 | 40 | } |
| Mischa | 0:337ad0fe7734 | 41 | |
| Mischa | 0:337ad0fe7734 | 42 | void DMAFuncGen::Setup(void) { |
| Mischa | 0:337ad0fe7734 | 43 | // Prepare the GPDMA system. |
| Mischa | 0:337ad0fe7734 | 44 | lli.srcAddr( (uint32_t) buffer ); |
| Mischa | 0:337ad0fe7734 | 45 | lli.dstAddr( (uint32_t) &LPC_DAC->DACR ); |
| Mischa | 0:337ad0fe7734 | 46 | lli.nextLLI( (uint32_t) &lli); |
| Mischa | 0:337ad0fe7734 | 47 | lli.control( dma.CxControl_TransferSize(buffer_size) |
| Mischa | 0:337ad0fe7734 | 48 | | dma.CxControl_SBSize((uint32_t)MODDMA::_1) |
| Mischa | 0:337ad0fe7734 | 49 | | dma.CxControl_DBSize((uint32_t)MODDMA::_1) |
| Mischa | 0:337ad0fe7734 | 50 | | dma.CxControl_SWidth((uint32_t)MODDMA::word) |
| Mischa | 0:337ad0fe7734 | 51 | | dma.CxControl_DWidth((uint32_t)MODDMA::word) |
| Mischa | 0:337ad0fe7734 | 52 | | dma.CxControl_SI() |
| Mischa | 0:337ad0fe7734 | 53 | | dma.CxControl_I() ); |
| Mischa | 0:337ad0fe7734 | 54 | |
| Mischa | 0:337ad0fe7734 | 55 | conf.srcMemAddr ( (uint32_t) buffer ) |
| Mischa | 0:337ad0fe7734 | 56 | ->dstMemAddr ( MODDMA::DAC ) // unnecessary? |
| Mischa | 0:337ad0fe7734 | 57 | ->transferSize ( buffer_size ) |
| Mischa | 0:337ad0fe7734 | 58 | ->transferType ( MODDMA::m2p ) |
| Mischa | 0:337ad0fe7734 | 59 | ->dstConn ( MODDMA::DAC ) |
| Mischa | 0:337ad0fe7734 | 60 | ->dmaLLI ( (uint32_t) &lli ) |
| Mischa | 0:337ad0fe7734 | 61 | ->attach_tc ( this, &DMAFuncGen::TC_callback ) |
| Mischa | 0:337ad0fe7734 | 62 | ->attach_err ( this, &DMAFuncGen::ERR_callback ); |
| Mischa | 0:337ad0fe7734 | 63 | |
| Mischa | 0:337ad0fe7734 | 64 | // Setup dma. |
| Mischa | 0:337ad0fe7734 | 65 | if (!dma.Setup( &conf )) { |
| Mischa | 0:337ad0fe7734 | 66 | error("Unexpected error during DMA.Setup(conf)"); |
| Mischa | 0:337ad0fe7734 | 67 | } |
| Mischa | 0:337ad0fe7734 | 68 | } |
| Mischa | 0:337ad0fe7734 | 69 | |
| Mischa | 0:337ad0fe7734 | 70 | float DMAFuncGen::Frequency() { |
| Mischa | 0:337ad0fe7734 | 71 | float f; |
| Mischa | 0:337ad0fe7734 | 72 | f=SystemCoreClock; |
| Mischa | 0:337ad0fe7734 | 73 | const int divisors[4] = {4,1,2,8}; |
| Mischa | 0:337ad0fe7734 | 74 | f/=divisors[((LPC_SC->PCLKSEL0) >> 22) & 0x03]; |
| Mischa | 0:337ad0fe7734 | 75 | f/=buffer_size; |
| Mischa | 0:337ad0fe7734 | 76 | f/=LPC_DAC->DACCNTVAL; |
| Mischa | 0:337ad0fe7734 | 77 | return f; |
| Mischa | 0:337ad0fe7734 | 78 | } |
| Mischa | 0:337ad0fe7734 | 79 | |
| Mischa | 0:337ad0fe7734 | 80 | void DMAFuncGen::SetFrequency(float f) { |
| Mischa | 0:337ad0fe7734 | 81 | // Set the transfer frequency. |
| Mischa | 0:337ad0fe7734 | 82 | float cntval; |
| Mischa | 0:337ad0fe7734 | 83 | cntval = SystemCoreClock/(f*buffer_size); |
| Mischa | 0:337ad0fe7734 | 84 | const int PCLK_DAC[4] = {1,2,0,3}; |
| Mischa | 0:337ad0fe7734 | 85 | int i=0; |
| Mischa | 0:337ad0fe7734 | 86 | int divisor=1; |
| Mischa | 0:337ad0fe7734 | 87 | while (((cntval/divisor)>65535) && (i<4)) {divisor*=2; i++; } |
| Mischa | 0:337ad0fe7734 | 88 | if (i==4) { divisor=8; i=3; } |
| Mischa | 0:337ad0fe7734 | 89 | LPC_SC->PCLKSEL0 &= ~(3UL<<22); |
| Mischa | 0:337ad0fe7734 | 90 | LPC_SC->PCLKSEL0 |= ((uint32_t) PCLK_DAC[i])<<22; |
| Mischa | 0:337ad0fe7734 | 91 | LPC_DAC->DACCNTVAL = cntval/divisor; |
| Mischa | 0:337ad0fe7734 | 92 | } |
| Mischa | 0:337ad0fe7734 | 93 | |
| Mischa | 0:337ad0fe7734 | 94 | void DMAFuncGen::Start() { |
| Mischa | 0:337ad0fe7734 | 95 | dma.Enable( &conf ); |
| Mischa | 0:337ad0fe7734 | 96 | |
| Mischa | 0:337ad0fe7734 | 97 | // Enable DMA, and TC interrupt |
| Mischa | 0:337ad0fe7734 | 98 | LPC_DAC->DACCTRL = 3UL<<2; // DMA_ENA set, DMA_CNT set |
| Mischa | 0:337ad0fe7734 | 99 | } |
| Mischa | 0:337ad0fe7734 | 100 | |
| Mischa | 0:337ad0fe7734 | 101 | void DMAFuncGen::Stop() { |
| Mischa | 0:337ad0fe7734 | 102 | dma.haltAndWaitChannelComplete( (MODDMA::CHANNELS) conf.channelNum() ); |
| Mischa | 0:337ad0fe7734 | 103 | LPC_DAC->DACCTRL = 0UL<<2; |
| Mischa | 0:337ad0fe7734 | 104 | } |
| Mischa | 0:337ad0fe7734 | 105 | |
| Mischa | 0:337ad0fe7734 | 106 | // Configuration callback on TC |
| Mischa | 0:337ad0fe7734 | 107 | void DMAFuncGen::TC_callback(void) { |
| Mischa | 0:337ad0fe7734 | 108 | |
| Mischa | 0:337ad0fe7734 | 109 | // Just show sending buffer complete. |
| Mischa | 0:337ad0fe7734 | 110 | // led1 = !led1; |
| Mischa | 0:337ad0fe7734 | 111 | |
| Mischa | 0:337ad0fe7734 | 112 | // Clear DMA IRQ flags. |
| Mischa | 0:337ad0fe7734 | 113 | if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); |
| Mischa | 0:337ad0fe7734 | 114 | } |
| Mischa | 0:337ad0fe7734 | 115 | |
| Mischa | 0:337ad0fe7734 | 116 | // Configuration callback on Error |
| Mischa | 0:337ad0fe7734 | 117 | void DMAFuncGen::ERR_callback(void) { |
| Mischa | 0:337ad0fe7734 | 118 | error("Unexpected error - DMA error callback."); |
| Mischa | 0:337ad0fe7734 | 119 | } |
| Mischa | 0:337ad0fe7734 | 120 |