Mischa Megens / DMAFuncGen

Dependents:   DACDMAfuncgenlib

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DMAFuncGen.cpp Source File

DMAFuncGen.cpp

00001 #include "assert.h"
00002 #include "DMAFuncGen.h"
00003 
00004 //DigitalOut led1(LED1);
00005 
00006 DMAFuncGen::DMAFuncGen(MODDMA& dma, MODDMA::CHANNELS channel) : dma(dma) {
00007     conf.channelNum( channel );
00008     buffer_size = 0;
00009     buffer = NULL;
00010 }
00011 
00012 #define DAC_POWER_MODE  (0 << 16)  // DAC output power mode.
00013 
00014 uint16_t DMAFuncGen::operator[](const uint16_t idx) {
00015     assert(buffer!=NULL);
00016     assert(idx<buffer_size);
00017     return buffer[idx] & 0xFFC0;
00018 }
00019 
00020 void DMAFuncGen::set(int idx, uint16_t x) {
00021     // V = (x>>6) × ((VrefP - VrefN)/1024) + VrefN; VrefN = 0V; VrefP = 3.3V;
00022     buffer[idx] = DAC_POWER_MODE | (x & 0xFFC0);
00023 }
00024 
00025 void DMAFuncGen::Connect() {
00026     // Connect DAC to pin
00027     LPC_PINCON->PINSEL1 &= ~(3UL <<20);
00028     LPC_PINCON->PINSEL1 |= 2UL <<20; //AOUT
00029     LPC_PINCON->PINMODE1 &= ~(3UL <<20);
00030     LPC_PINCON->PINMODE1 |= (2UL <<20);  // neither pull-up nor pull-down
00031     LPC_PINCON->PINMODE_OD0 &= ~(1UL <<26);  // normal (not open drain) mode
00032 }
00033  
00034 void DMAFuncGen::Disconnect() {
00035     LPC_PINCON->PINSEL1 &= ~(3UL <<20);
00036     LPC_PINCON->PINSEL1 |= 1UL <<20; //AD0.3, input
00037     LPC_PINCON->PINMODE1 &= ~(3UL <<20);
00038     LPC_PINCON->PINMODE1 |= (2UL <<20);  // neither pull-up nor pull-down
00039     LPC_PINCON->PINMODE_OD0 &= ~(1UL <<26);  // normal (not open drain) mode
00040 }
00041 
00042 void DMAFuncGen::Setup(void) {
00043     // Prepare the GPDMA system.
00044     lli.srcAddr( (uint32_t) buffer );
00045     lli.dstAddr( (uint32_t) &LPC_DAC->DACR );
00046     lli.nextLLI( (uint32_t) &lli);
00047     lli.control( dma.CxControl_TransferSize(buffer_size)
00048                | dma.CxControl_SBSize((uint32_t)MODDMA::_1) 
00049                | dma.CxControl_DBSize((uint32_t)MODDMA::_1) 
00050                | dma.CxControl_SWidth((uint32_t)MODDMA::word) 
00051                | dma.CxControl_DWidth((uint32_t)MODDMA::word) 
00052                | dma.CxControl_SI() 
00053                | dma.CxControl_I() );
00054 
00055     conf.srcMemAddr  ( (uint32_t) buffer )
00056       ->dstMemAddr   ( MODDMA::DAC )  // unnecessary?
00057       ->transferSize ( buffer_size )
00058       ->transferType ( MODDMA::m2p )
00059       ->dstConn      ( MODDMA::DAC )
00060       ->dmaLLI       ( (uint32_t) &lli )
00061       ->attach_tc    ( this, &DMAFuncGen::TC_callback ) 
00062       ->attach_err   ( this, &DMAFuncGen::ERR_callback );
00063 
00064     // Setup dma.
00065     if (!dma.Setup( &conf )) {
00066         error("Unexpected error during DMA.Setup(conf)");
00067     }
00068 }        
00069 
00070 float DMAFuncGen::Frequency() {
00071     float f;
00072     f=SystemCoreClock;
00073     const int divisors[4] = {4,1,2,8};
00074     f/=divisors[((LPC_SC->PCLKSEL0) >> 22) & 0x03];
00075     f/=buffer_size;
00076     f/=LPC_DAC->DACCNTVAL;
00077     return f;
00078 }
00079 
00080 void DMAFuncGen::SetFrequency(float f) {
00081     // Set the transfer frequency.
00082     float cntval;
00083     cntval = SystemCoreClock/(f*buffer_size);
00084     const int PCLK_DAC[4] = {1,2,0,3}; 
00085     int i=0;
00086     int divisor=1;
00087     while (((cntval/divisor)>65535) && (i<4)) {divisor*=2; i++; }
00088     if (i==4) { divisor=8; i=3; }
00089     LPC_SC->PCLKSEL0 &= ~(3UL<<22);
00090     LPC_SC->PCLKSEL0 |=  ((uint32_t) PCLK_DAC[i])<<22;
00091     LPC_DAC->DACCNTVAL = cntval/divisor;
00092 }
00093 
00094 void DMAFuncGen::Start() {
00095     dma.Enable( &conf );
00096     
00097     // Enable DMA, and TC interrupt
00098     LPC_DAC->DACCTRL = 3UL<<2; // DMA_ENA set, DMA_CNT set
00099 }
00100 
00101 void DMAFuncGen::Stop() {
00102     dma.haltAndWaitChannelComplete( (MODDMA::CHANNELS) conf.channelNum() );
00103     LPC_DAC->DACCTRL = 0UL<<2;
00104 }
00105 
00106 // Configuration callback on TC
00107 void DMAFuncGen::TC_callback(void) {
00108     
00109     // Just show sending buffer complete.
00110     // led1 = !led1; 
00111 
00112     // Clear DMA IRQ flags.
00113     if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); 
00114 }
00115 
00116 // Configuration callback on Error
00117 void DMAFuncGen::ERR_callback(void) {
00118     error("Unexpected error - DMA error callback.");
00119 }
00120