/** * \brief Initialize the DACC controller * \param pDACC Pointer to an DACC instance. * \param idDACC identifier of DAC peripheral * \param trgEn trigger mode, free running mode or external Hardware trigger * \param word transfer size,word or half word * \param trgSel hardware trigger selection * \param sleepMode sleep mode selection * \param mck value of MCK in Hz * \param refresh refresh period * \param user_sel user channel selection ,0 or 1 * \param tag_mode tag for channel number * \param startup value of the start up time (in DACCClock) (see datasheet) */ extern void DACC_Initialize( Dacc* pDACC, uint8_t idDACC, uint8_t trgEn, uint8_t trgSel, uint8_t word, uint8_t sleepMode, uint32_t mck, uint8_t refresh, /* refresh period */ uint8_t user_sel, /* user channel selection */ uint32_t tag_mode, /* using tag for channel number */ uint32_t startup ) { /* Stop warning */ mck = mck; /* Enable peripheral clock*/ PMC->PMC_PCER0 = 1 << idDACC; /* Reset the controller */ DACC_SoftReset(pDACC); /* Write to the MR register */ DACC_CfgModeReg( pDACC, ( trgEn & DACC_MR_TRGEN) | DACC_MR_TRGSEL(trgSel) | ( word & DACC_MR_WORD) | ( sleepMode & DACC_MR_SLEEP) | DACC_MR_REFRESH(refresh) | ( user_sel & DACC_MR_USER_SEL_Msk) | ( tag_mode & DACC_MR_TAG) | ( startup & DACC_MR_STARTUP_Msk)); }
/** * \brief Enable trigger and set the trigger source. * * \param p_dacc Pointer to a DACC instance. * \param ul_trigger Trigger source number. * * \return \ref DACC_RC_OK for OK. */ uint32_t dacc_set_trigger(Dacc *p_dacc, uint32_t ul_trigger) { uint32_t mr = p_dacc->DACC_MR & (~(DACC_MR_TRGSEL_Msk)); #if (SAM3N_SERIES) p_dacc->DACC_MR = mr | DACC_MR_TRGEN | ((ul_trigger << DACC_MR_TRGSEL_Pos) & DACC_MR_TRGSEL_Msk); #else p_dacc->DACC_MR = mr | DACC_MR_TRGEN_EN | DACC_MR_TRGSEL(ul_trigger); #endif return DACC_RC_OK; }
uint32_t tag_mode, /* using tag for channel number */ uint32_t startup ) { assert( 1024*refresh*1000/(mck>>1) < 20 ) ; /* Enable peripheral clock*/ PMC->PMC_PCER0 = 1 << idDACC; /* Reset the controller */ DACC_SoftReset(pDACC); /* Write to the MR register */ DACC_CfgModeReg( pDACC, ( (trgEn<<0) & DACC_MR_TRGEN) | DACC_MR_TRGSEL(trgSel) | ( (word<<4) & DACC_MR_WORD) | ( (sleepMode<<5) & DACC_MR_SLEEP) | DACC_MR_REFRESH(refresh) | ( (user_sel<<DACC_MR_USER_SEL_Pos)& DACC_MR_USER_SEL_Msk) | ( (tag_mode<<20) & DACC_MR_TAG) | ( (startup<<DACC_MR_STARTUP_Pos) & DACC_MR_STARTUP_Msk)); } /** * Set the Conversion Data * \param pDACC Pointer to an Dacc instance. * \param dwData date to be converted. */ extern void DACC_SetConversionData( Dacc* pDACC, uint32_t dwData )
void CIO::start() { if (m_started) return; #if defined(__SAM3X8E__) if (ADC->ADC_ISR & ADC_ISR_EOC_Chan) // Ensure there was an End-of-Conversion and we read the ISR reg io.interrupt(); // Set up the ADC NVIC_EnableIRQ(ADC_IRQn); // Enable ADC interrupt vector ADC->ADC_IDR = 0xFFFFFFFF; // Disable interrupts ADC->ADC_IER = ADC_CHER_Chan; // Enable End-Of-Conv interrupt ADC->ADC_CHDR = 0xFFFF; // Disable all channels ADC->ADC_CHER = ADC_CHER_Chan; // Enable just one channel ADC->ADC_CGR = 0x15555555; // All gains set to x1 ADC->ADC_COR = 0x00000000; // All offsets off ADC->ADC_MR = (ADC->ADC_MR & 0xFFFFFFF0) | (1 << 1) | ADC_MR_TRGEN; // 1 = trig source TIO from TC0 #if defined(EXTERNAL_OSC) // Set up the external clock input on PA4 = AI5 REG_PIOA_ODR = 0x10; // Set pin as input REG_PIOA_PDR = 0x10; // Disable PIO A bit 4 REG_PIOA_ABSR &= ~0x10; // Select A peripheral = TCLK1 Input #endif // Set up the timer pmc_enable_periph_clk(TC_INTERFACE_ID + 0*3+0) ; // Clock the TC0 channel 0 TcChannel* t = &(TC0->TC_CHANNEL)[0]; // Pointer to TC0 registers for its channel 0 t->TC_CCR = TC_CCR_CLKDIS; // Disable internal clocking while setup regs t->TC_IDR = 0xFFFFFFFF; // Disable interrupts t->TC_SR; // Read int status reg to clear pending #if defined(EXTERNAL_OSC) t->TC_CMR = TC_CMR_TCCLKS_XC1 | // Use XC1 = TCLK1 external clock #else t->TC_CMR = TC_CMR_TCCLKS_TIMER_CLOCK1 | // Use TCLK1 (prescale by 2, = 42MHz) #endif TC_CMR_WAVE | // Waveform mode TC_CMR_WAVSEL_UP_RC | // Count-up PWM using RC as threshold TC_CMR_EEVT_XC0 | // Set external events from XC0 (this setup TIOB as output) TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_CLEAR | TC_CMR_BCPB_CLEAR | TC_CMR_BCPC_CLEAR; #if defined(EXTERNAL_OSC) t->TC_RC = EXTERNAL_OSC / 24000; // Counter resets on RC, so sets period in terms of the external clock t->TC_RA = EXTERNAL_OSC / 48000; // Roughly square wave #else t->TC_RC = 1750; // Counter resets on RC, so sets period in terms of 42MHz internal clock t->TC_RA = 880; // Roughly square wave #endif t->TC_CMR = (t->TC_CMR & 0xFFF0FFFF) | TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_SET; // Set clear and set from RA and RC compares t->TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG ; // re-enable local clocking and switch to hardware trigger source. // Set up the DAC pmc_enable_periph_clk(DACC_INTERFACE_ID); // Start clocking DAC DACC->DACC_CR = DACC_CR_SWRST; // Reset DAC DACC->DACC_MR = DACC_MR_TRGEN_EN | DACC_MR_TRGSEL(1) | // Trigger 1 = TIO output of TC0 DACC_MR_USER_SEL_Chan | // Select channel (24 << DACC_MR_STARTUP_Pos); // 24 = 1536 cycles which I think is in range 23..45us since DAC clock = 42MHz DACC->DACC_IDR = 0xFFFFFFFF; // No interrupts DACC->DACC_CHER = DACC_CHER_Chan; // Enable channel digitalWrite(PIN_PTT, m_pttInvert ? HIGH : LOW); digitalWrite(PIN_COSLED, LOW); digitalWrite(PIN_LED, HIGH); #elif defined(__MBED__) m_ticker.attach(&ADC_Handler, 1.0 / 24000.0); m_pinPTT.write(m_pttInvert ? 1 : 0); m_pinCOSLED.write(0); m_pinLED.write(1); #endif m_count = 0U; m_started = true; setMode(); }