Jared's DAC Code
Dependencies: mbed
Fork of Chemical_Sensor_DMA by
Sample/dma.cpp
- Committer:
- baxterja
- Date:
- 2015-10-29
- Revision:
- 2:3771b3195c7b
- Child:
- 3:a85b742be262
File content as of revision 2:3771b3195c7b:
/** * Setup triggering for DMA2 and PortC */ #include "dma.h" DigitalOut toggle_dma0(LED_RED); DigitalOut toggle_dma1(LED_BLUE); DigitalOut toggle_dma2(LED_GREEN); Serial debug3(USBTX,USBRX); //#define TOTAL_SAMPLES 30000 //#define FILENAME_SIZE 26 // this matches what is defined in DistanceFirmware's main.cpp int len = TOTAL_SAMPLES; uint16_t sample_array0[TOTAL_SAMPLES]; uint16_t sample_array1[TOTAL_SAMPLES]; uint16_t angle_array[TOTAL_SAMPLES+FILENAME_SIZE]; bool dma_done = false; bool dma_half_done = false; /* DMA0 and DMA1 are triggered by ADC0 and ADC1 (which are triggered * by the PDB). However, DMA2 is triggered directly by the PDB. This * is becuase DMA2 is reading FTM2, which cannot trigger the DMA. */ void dma_init() { toggle_dma0 = 1; toggle_dma1 = 1; toggle_dma2 = 1; // Enable clock for DMAMUX and DMA SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK; SIM_SCGC7 |= SIM_SCGC7_DMA_MASK; SIM_SCGC6 |= SIM_SCGC6_FTM2_MASK; // make sure clock is enabled for FTM2 // Enable DMA channels and select MUX to the correct source (see page 95 of user manual DMAMUX_CHCFG0 |= DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE(40); // ADC0 DMAMUX_CHCFG1 |= DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE(41); // ADC1 DMAMUX_CHCFG2 |= DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE(48); // Set trigger source to PDB (Don't set DMA Trig Enable because that is for the PIT) /* Source number Source module 40 ADC0 41 ADC1 48 PDB */ // Enable request signal for channel 0 DMA_ERQ = DMA_ERQ_ERQ0_MASK | DMA_ERQ_ERQ1_MASK | DMA_ERQ_ERQ2_MASK; // select round-robin arbitration priority DMA_CR |= DMA_CR_ERCA_MASK; // Set memory address for source and destination for DMA0, DMA1, and DMA2 DMA_TCD0_SADDR = (uint32_t) &ADC0_RB; DMA_TCD0_DADDR = (uint32_t) sample_array0; DMA_TCD1_SADDR = (uint32_t) &ADC1_RA; DMA_TCD1_DADDR = (uint32_t) sample_array1; DMA_TCD2_SADDR = (uint32_t) &FTM2_CNT; DMA_TCD2_DADDR = (uint32_t) angle_array; // Set an offset for source and destination address DMA_TCD0_SOFF = 0x00; // Source address offset of 2 bits per transaction DMA_TCD0_DOFF = 0x02; // Destination address offset of 1 bit per transaction DMA_TCD1_SOFF = 0x00; // Source address offset of 2 bits per transaction DMA_TCD1_DOFF = 0x02; // Destination address offset of 1 bit per transaction DMA_TCD2_SOFF = 0x00; // Source address offset of 2 bits per transaction DMA_TCD2_DOFF = 0x02; // Destination address offset of 1 bit per transaction // Set source and destination data transfer size DMA_TCD0_ATTR = DMA_ATTR_SSIZE(1) | DMA_ATTR_DSIZE(1); DMA_TCD1_ATTR = DMA_ATTR_SSIZE(1) | DMA_ATTR_DSIZE(1); DMA_TCD2_ATTR = DMA_ATTR_SSIZE(1) | DMA_ATTR_DSIZE(1); // Number of bytes to be transfered in each service request of the channel DMA_TCD0_NBYTES_MLNO = 0x02; DMA_TCD1_NBYTES_MLNO = 0x02; DMA_TCD2_NBYTES_MLNO = 0x02; // Current major iteration count DMA_TCD0_CITER_ELINKNO = DMA_CITER_ELINKNO_CITER(len); DMA_TCD0_BITER_ELINKNO = DMA_BITER_ELINKNO_BITER(len); DMA_TCD1_CITER_ELINKNO = DMA_CITER_ELINKNO_CITER(len); DMA_TCD1_BITER_ELINKNO = DMA_BITER_ELINKNO_BITER(len); DMA_TCD2_CITER_ELINKNO = DMA_CITER_ELINKNO_CITER(len); DMA_TCD2_BITER_ELINKNO = DMA_BITER_ELINKNO_BITER(len); // Adjustment value used to restore the source and destiny address to the initial value // After reading 'len' number of times, the DMA goes back to the beginning by subtracting len*2 from the address (going back to the original address) DMA_TCD0_SLAST = 0; // Source address adjustment DMA_TCD0_DLASTSGA = -len*2; // Destination address adjustment DMA_TCD1_SLAST = 0; // Source address adjustment DMA_TCD1_DLASTSGA = -len*2; // Destination address adjustment DMA_TCD2_SLAST = 0; // Source address adjustment DMA_TCD2_DLASTSGA = -len*2; // Destination address adjustment // Setup control and status register DMA_TCD0_CSR = 0; DMA_TCD1_CSR = 0; DMA_TCD2_CSR = 0; // enable interrupt call at end of major loop DMA_TCD0_CSR |= DMA_CSR_INTMAJOR_MASK | DMA_CSR_INTHALF_MASK; // add interrupt handlers to interrupt vector table NVIC_SetVector(DMA0_IRQn, (uint32_t)&DMA_IRQHandler); //enable interrupts NVIC_EnableIRQ(DMA0_IRQn); // dma_init takes 4.09us to run. } void dma_reset() { dma_done = false; dma_half_done = false; // clear all DMA interrupts DMA_CINT = DMA_CINT_CAIR_MASK; //enable interrupts NVIC_EnableIRQ(DMA0_IRQn); } /* The only DMA interrupt is from DMA0. The interrupts from DMA1 and DMA2 * are turned off because they all trigger at the same time. Actually * DMA2 triggers just before DMA0 and DMA1, but it's a negligible amount * of time. By the time the PDB is turned off, the ADCs will have already * been triggered. */ void DMA_IRQHandler() { DMA_CINT |= DMA_CINT_CINT(0); // clear interrupt flag //toggle_dma0 = 0; //debug3.printf("DMA "); if(!dma_half_done) { dma_half_done = true; //debug3.printf("half done\r\n"); return; } //PDB0_SC &= ~PDB_SC_PDBEN_MASK; // disable PDB //NVIC_DisableIRQ(DMA0_IRQn); // disable interrupt dma_done = true; //debug3.printf("done\r\n"); } /* * * * * * * * * * * * * * For Debugging Purposes * * * * * * * * * * * * * * * * * * * * */ void dma_print_registers() { debug3.printf("SADDR0: 0x%08x\r\n",DMA_TCD0_SADDR); debug3.printf("DADDR0: 0x%08x\r\n",DMA_TCD0_DADDR); debug3.printf("SADDR1: 0x%08x\r\n",DMA_TCD1_SADDR); debug3.printf("DADDR1: 0x%08x\r\n",DMA_TCD1_DADDR); debug3.printf("SADDR2: 0x%08x\r\n",DMA_TCD2_SADDR); debug3.printf("DADDR2: 0x%08x\r\n",DMA_TCD2_DADDR); debug3.printf("CITER0: 0x%08x\r\n",DMA_TCD0_CITER_ELINKNO); debug3.printf("BITER0: 0x%08x\r\n",DMA_TCD0_BITER_ELINKNO); debug3.printf("CITER1: 0x%08x\r\n",DMA_TCD1_CITER_ELINKNO); debug3.printf("BITER1: 0x%08x\r\n",DMA_TCD1_BITER_ELINKNO); debug3.printf("CITER2: 0x%08x\r\n",DMA_TCD2_CITER_ELINKNO); debug3.printf("BITER2: 0x%08x\r\n",DMA_TCD2_BITER_ELINKNO); debug3.printf("DMA_CR: %08x\r\n", DMA_CR); debug3.printf("DMA_ES: %08x\r\n", DMA_ES); debug3.printf("DMA_ERQ: %08x\r\n", DMA_ERQ); debug3.printf("DMA_EEI: %08x\r\n", DMA_EEI); debug3.printf("DMA_CEEI: %02x\r\n", DMA_CEEI); debug3.printf("DMA_SEEI: %02x\r\n", DMA_SEEI); debug3.printf("DMA_CERQ: %02x\r\n", DMA_CERQ); debug3.printf("DMA_SERQ: %02x\r\n", DMA_SERQ); debug3.printf("DMA_CDNE: %02x\r\n", DMA_CDNE); debug3.printf("DMA_SSRT: %02x\r\n", DMA_SSRT); debug3.printf("DMA_CERR: %02x\r\n", DMA_CERR); debug3.printf("DMA_CINT: %02x\r\n", DMA_CINT); debug3.printf("DMA_INT: %08x\r\n", DMA_INT); debug3.printf("DMA_ERR: %08x\r\n", DMA_ERR); debug3.printf("DMA_HRS: %08x\r\n", DMA_HRS); }