void config_dacc(void){ sysclk_enable_peripheral_clock(ID_DACC); /* Reset DACC registers */ dacc_reset(DACC); /* Half-Word transfer mode */ dacc_set_transfer_mode(DACC, 0); /* Timing: * startup - 0x10 (17 clocks) * internal trigger clock - 0x60 (96 clocks) */ dacc_set_timing(DACC, 0x10, 0x60); /*External trigger mode disabled. DACC in free running mode.*/ dacc_disable_trigger(DACC); /* Enable DAC */ dacc_enable(DACC); while((dacc_get_interrupt_status(DACC) & DACC_ISR_TXRDY) != DACC_ISR_TXRDY); dacc_write_conversion_data(DACC, 0); }
/** * \brief Start DAC ouput. * Initialize DAC, set clock and timing, and set DAC to given mode. */ static void start_dac(void) { sysclk_enable_peripheral_clock(DACC); /* Reset DACC registers */ dacc_reset(DACC); /* Half word transfer mode */ dacc_set_transfer_mode(DACC, 0); /* Timing: * startup - 0x10 (17 clocks) * internal trigger clock - 0x60 (96 clocks) */ dacc_set_timing(DACC, 0x10, 0x60); /* Enable DAC */ dacc_enable(DACC); /* The DAC is 10-bit resolution, so output voltage should be * (3300 * 255) / ((1 << 10) - 1) = 823mv */ dacc_write_conversion_data(DACC, 0xFF); }
void configure_DAC() { /************************************************************************/ /* DAC */ /************************************************************************/ /* Enable clock for DACC */ sysclk_enable_peripheral_clock(DACC_ID); /* Reset DACC registers */ dacc_reset(DACC_BASE); /* Half word transfer mode */ dacc_set_transfer_mode(DACC_BASE, 0); /* selects channel */ dacc_set_channel_selection(DACC_BASE, DACC_CHANNEL); /* Enable output channel DACC_CHANNEL */ dacc_enable_channel(DACC_BASE, DACC_CHANNEL); /* Set up analog current */ dacc_set_analog_control(DACC_BASE, DACC_ANALOG_CONTROL); }
/** * Initialize the DAC as event user. */ static void init_dacc(void) { /* Enable clock for DACC */ sysclk_enable_peripheral_clock(DACC); /* Reset DACC registers */ dacc_reset(DACC); /* Half word transfer mode */ dacc_set_transfer_mode(DACC, 0); /* * Timing: * startup - 0x10 (17 clocks) * internal trigger clock - 0x60 (96 clocks) */ dacc_set_timing(DACC, 0x10, 0x60); /* Enable event trigger (0: external trigger, 1: peripheral event) */ dacc_set_trigger(DACC, 1); /* Enable DAC */ dacc_enable(DACC); }
/** * \brief ACC example application entry point. * * \return Unused (ANSI-C compatibility). */ int main(void) { uint32_t uc_key; int16_t s_volt = 0; uint32_t ul_value = 0; volatile uint32_t ul_status = 0x0; int32_t l_volt_dac0 = 0; /* Initialize the system */ sysclk_init(); board_init(); /* Initialize debug console */ configure_console(); /* Output example information */ puts(STRING_HEADER); /* Initialize DACC */ /* Enable clock for DACC */ pmc_enable_periph_clk(ID_DACC); /* Reset DACC registers */ dacc_reset(DACC); /* External trigger mode disabled. DACC in free running mode. */ dacc_disable_trigger(DACC, DACC_CHANNEL_0); /* Half word transfer mode */ dacc_set_transfer_mode(DACC, 0); #if (SAM3S) || (SAM3XA) /* Power save: * sleep mode - 0 (disabled) * fast wakeup - 0 (disabled) */ dacc_set_power_save(DACC, 0, 0); #endif /* Enable output channel DACC_CHANNEL */ dacc_enable_channel(DACC, DACC_CHANNEL_0); /* Setup analog current */ dacc_set_analog_control(DACC, DACC_ANALOG_CONTROL); /* Set DAC0 output at ADVREF/2. The DAC formula is: * * (5/6 * VOLT_REF) - (1/6 * VOLT_REF) volt - (1/6 * VOLT_REF) * ----------------------------------- = -------------------------- * MAX_DIGITAL digit * * Here, digit = MAX_DIGITAL/2 */ dacc_write_conversion_data(DACC, MAX_DIGITAL / 2, DACC_CHANNEL_0); l_volt_dac0 = (MAX_DIGITAL / 2) * (2 * VOLT_REF / 3) / MAX_DIGITAL + VOLT_REF / 6; /* Enable clock for AFEC */ afec_enable(AFEC0); struct afec_config afec_cfg; afec_get_config_defaults(&afec_cfg); /* Initialize AFEC */ afec_init(AFEC0, &afec_cfg); struct afec_ch_config afec_ch_cfg; afec_ch_get_config_defaults(&afec_ch_cfg); afec_ch_cfg.gain = AFEC_GAINVALUE_0; afec_ch_set_config(AFEC0, AFEC_CHANNEL_POTENTIOMETER, &afec_ch_cfg); /* * Because the internal ADC offset is 0x200, it should cancel it and shift * down to 0. */ afec_channel_set_analog_offset(AFEC0, AFEC_CHANNEL_POTENTIOMETER, 0x200); afec_set_trigger(AFEC0, AFEC_TRIG_SW); /* Enable channel for potentiometer. */ afec_channel_enable(AFEC0, AFEC_CHANNEL_POTENTIOMETER); /* Enable clock for ACC */ pmc_enable_periph_clk(ID_ACC); /* Initialize ACC */ acc_init(ACC, ACC_MR_SELPLUS_AFE0_AD0, ACC_MR_SELMINUS_DAC0, ACC_MR_EDGETYP_ANY, ACC_MR_INV_DIS); /* Enable ACC interrupt */ NVIC_EnableIRQ(ACC_IRQn); /* Enable */ acc_enable_interrupt(ACC); dsplay_menu(); while (1) { while (usart_read(CONSOLE_UART, &uc_key)) { } printf("input: %c\r\n", uc_key); switch (uc_key) { case 's': case 'S': printf("Input DAC0 output voltage (%d~%d mv): ", (VOLT_REF / 6), (VOLT_REF * 5 / 6)); s_volt = get_input_voltage(); puts("\r"); if (s_volt > 0) { l_volt_dac0 = s_volt; /* The DAC formula is: * * (5/6 * VOLT_REF) - (1/6 * VOLT_REF) volt - (1/6 * VOLT_REF) * ----------------------------------- = -------------------------- * MAX_DIGITAL digit * */ ul_value = ((s_volt - (VOLT_REF / 6)) * (MAX_DIGITAL * 6) / 4) / VOLT_REF; dacc_write_conversion_data(DACC, ul_value, DACC_CHANNEL_0); puts("-I- Set ok\r"); } else { puts("-I- Input voltage is invalid\r"); } break; case 'v': case 'V': /* Start conversion */ afec_start_software_conversion(AFEC0); ul_status = afec_get_interrupt_status(AFEC0); while ((ul_status & AFEC_ISR_EOC0) != AFEC_ISR_EOC0) { ul_status = afec_get_interrupt_status(AFEC0); } /* Conversion is done */ ul_value = afec_channel_get_value(AFEC0, AFEC_CHANNEL_POTENTIOMETER); /* * Convert AFEC sample data to voltage value: * voltage value = (sample data / max. resolution) * reference voltage */ s_volt = (ul_value * VOLT_REF) / MAX_DIGITAL; printf("-I- Voltage on potentiometer(AD0) is %d mv\n\r", s_volt); printf("-I- Voltage on DAC0 is %ld mv \n\r", (long)l_volt_dac0); break; case 'm': case 'M': dsplay_menu(); break; } } }
/** * \brief Start ADC sample. * Initialize ADC, set clock and timing, and set ADC to given mode. */ static void start_adc(void) { struct adc_config adc_cfg = { /* System clock division factor is 16 */ .prescal = ADC_PRESCAL_DIV16, /* The APB clock is used */ .clksel = ADC_CLKSEL_APBCLK, /* Max speed is 150K */ .speed = ADC_SPEED_150K, /* ADC Reference voltage is 0.625*VCC */ .refsel = ADC_REFSEL_1, /* Enables the Startup time */ .start_up = CONFIG_ADC_STARTUP }; struct adc_seq_config adc_seq_cfg = { /* Select Vref for shift cycle */ .zoomrange = ADC_ZOOMRANGE_0, /* Pad Ground */ .muxneg = ADC_MUXNEG_1, /* DAC internal */ .muxpos = ADC_MUXPOS_3, /* Enables the internal voltage sources */ .internal = ADC_INTERNAL_3, /* Disables the ADC gain error reduction */ .gcomp = ADC_GCOMP_DIS, /* Disables the HWLA mode */ .hwla = ADC_HWLA_DIS, /* 12-bits resolution */ .res = ADC_RES_12_BIT, /* Enables the single-ended mode */ .bipolar = ADC_BIPOLAR_SINGLEENDED }; struct adc_ch_config adc_ch_cfg = { .seq_cfg = &adc_seq_cfg, /* Internal Timer Max Counter */ .internal_timer_max_count = 60, /* Window monitor mode is off */ .window_mode = 0, .low_threshold = 0, .high_threshold = 0, }; if(adc_init(&g_adc_inst, ADCIFE, &adc_cfg) != STATUS_OK) { puts("-F- ADC Init Fail!\n\r"); while(1); } if(adc_enable(&g_adc_inst) != STATUS_OK) { puts("-F- ADC Enable Fail!\n\r"); while(1); } if (g_adc_test_mode.uc_pdc_en) { adc_disable_interrupt(&g_adc_inst, ADC_SEQ_SEOC); adc_pdca_set_config(&g_adc_pdca_cfg); pdca_channel_set_callback(CONFIG_ADC_PDCA_RX_CHANNEL, pdca_transfer_done, PDCA_0_IRQn, 1, PDCA_IER_TRC); } else { pdca_channel_disable_interrupt(CONFIG_ADC_PDCA_RX_CHANNEL, PDCA_IDR_TRC); pdca_channel_disable_interrupt(CONFIG_ADC_PDCA_TX_CHANNEL, PDCA_IDR_TRC); adc_ch_set_config(&g_adc_inst, &adc_ch_cfg); adc_set_callback(&g_adc_inst, ADC_SEQ_SEOC, adcife_read_conv_result, ADCIFE_IRQn, 1); } /* Configure trigger mode and start convention. */ switch (g_adc_test_mode.uc_trigger_mode) { case TRIGGER_MODE_SOFTWARE: adc_configure_trigger(&g_adc_inst, ADC_TRIG_SW); break; case TRIGGER_MODE_CON: adc_configure_trigger(&g_adc_inst, ADC_TRIG_CON); break; case TRIGGER_MODE_ITIMER: adc_configure_trigger(&g_adc_inst, ADC_TRIG_INTL_TIMER); adc_configure_itimer_period(&g_adc_inst, adc_ch_cfg.internal_timer_max_count); adc_start_itimer(&g_adc_inst); break; default: break; } if (g_adc_test_mode.uc_gain_en) { adc_configure_gain(&g_adc_inst, ADC_GAIN_2X); } else { adc_configure_gain(&g_adc_inst, ADC_GAIN_1X); } } /** * \brief Start DAC ouput. * Initialize DAC, set clock and timing, and set DAC to given mode. */ static void start_dac(void) { sysclk_enable_peripheral_clock(DACC); /* Reset DACC registers */ dacc_reset(DACC); /* Half word transfer mode */ dacc_set_transfer_mode(DACC, 0); /* Timing: * startup - 0x10 (17 clocks) * internal trigger clock - 0x60 (96 clocks) */ dacc_set_timing(DACC, 0x10, 0x60); /* Enable DAC */ dacc_enable(DACC); /* The DAC is 10-bit resolution, so output voltage should be * (3300 * 255) / ((1 << 10) - 1) = 823mv */ dacc_write_conversion_data(DACC, 0xFF); }
void DACClass::begin(uint32_t period) { // Enable clock for DAC pmc_enable_periph_clk(dacId); dacc_reset(dac); // Set transfer mode to double word dacc_set_transfer_mode(dac, 1); // Power save: // sleep mode - 0 (disabled) // fast wakeup - 0 (disabled) dacc_set_power_save(dac, 0, 0); // DAC refresh/startup timings: // refresh - 0x08 (1024*8 dacc clocks) // max speed mode - 0 (disabled) // startup time - 0x10 (1024 dacc clocks) dacc_set_timing(dac, 0x08, 0, DACC_MR_STARTUP_1024); // Flexible channel selection with tags dacc_enable_flexible_selection(dac); // Set up analog current dacc_set_analog_control(dac, DACC_ACR_IBCTLCH0(0x02) | DACC_ACR_IBCTLCH1(0x02) | DACC_ACR_IBCTLDACCORE(0x01)); // Enable output channels dacc_enable_channel(dac, 0); dacc_enable_channel(dac, 1); // Configure Timer Counter to trigger DAC // -------------------------------------- pmc_enable_periph_clk(ID_TC1); TC_Configure(TC0, 1, TC_CMR_TCCLKS_TIMER_CLOCK2 | // Clock at MCR/8 TC_CMR_WAVE | // Waveform mode TC_CMR_WAVSEL_UP_RC | // Counter running up and reset when equals to RC TC_CMR_ACPA_SET | TC_CMR_ACPC_CLEAR); const uint32_t TC = period / 8; TC_SetRA(TC0, 1, TC / 2); TC_SetRC(TC0, 1, TC); TC_Start(TC0, 1); // Configure clock source for DAC (2 = TC0 Output Chan. 1) dacc_set_trigger(dac, 2); // Configure pins PIO_Configure(g_APinDescription[DAC0].pPort, g_APinDescription[DAC0].ulPinType, g_APinDescription[DAC0].ulPin, g_APinDescription[DAC0].ulPinConfiguration); PIO_Configure(g_APinDescription[DAC1].pPort, g_APinDescription[DAC1].ulPinType, g_APinDescription[DAC1].ulPin, g_APinDescription[DAC1].ulPinConfiguration); // Enable interrupt controller for DAC dacc_disable_interrupt(dac, 0xFFFFFFFF); NVIC_DisableIRQ(isrId); NVIC_ClearPendingIRQ(isrId); NVIC_SetPriority(isrId, 0); NVIC_EnableIRQ(isrId); }
/** * \brief DAC Sinewave application entry point. * * \return Unused (ANSI-C compatibility). */ int main(void) { uint8_t uc_key; uint32_t ul_freq, ul_amp; /* Initialize the system */ sysclk_init(); board_init(); /* Initialize debug console */ configure_console(); /* Output example information */ puts(STRING_HEADER); /* Enable clock for DACC */ #if SAM4L sysclk_enable_peripheral_clock(DACC_BASE); #else sysclk_enable_peripheral_clock(DACC_ID); #endif /* Reset DACC registers */ dacc_reset(DACC_BASE); /* Half word transfer mode */ dacc_set_transfer_mode(DACC_BASE, 0); /* Initialize timing, amplitude and frequency */ #if (SAM3N) || (SAM4L) /* Timing: * startup - 0x10 (17 clocks) * internal trigger clock - 0x60 (96 clocks) */ dacc_set_timing(DACC_BASE, 0x10, 0x60); /* Enable DAC */ dacc_enable(DACC_BASE); #else /* Power save: * sleep mode - 0 (disabled) * fast wakeup - 0 (disabled) */ dacc_set_power_save(DACC_BASE, 0, 0); /* Timing: * refresh - 0x08 (1024*8 dacc clocks) * max speed mode - 0 (disabled) * startup time - 0x10 (1024 dacc clocks) */ dacc_set_timing(DACC_BASE, 0x08, 0, 0x10); /* Disable TAG and select output channel DACC_CHANNEL */ dacc_set_channel_selection(DACC_BASE, DACC_CHANNEL); /* Enable output channel DACC_CHANNEL */ dacc_enable_channel(DACC_BASE, DACC_CHANNEL); /* Set up analog current */ dacc_set_analog_control(DACC_BASE, DACC_ANALOG_CONTROL); #endif /* (SAM3N) */ g_l_amplitude = MAX_AMPLITUDE / 2; g_ul_frequency = DEFAULT_FREQUENCY; SysTick_Config(sysclk_get_cpu_hz() / (g_ul_frequency * SAMPLES)); /* Main menu */ display_menu(); while (1) { usart_serial_getchar((Usart *)CONSOLE_UART, &uc_key); switch (uc_key) { case '0': puts("Frequency:"); ul_freq = get_input_value(MIN_FREQUENCY, MAX_FREQUENCY); puts("\r"); if (ul_freq != VAL_INVALID) { printf("Set frequency to : %luHz\n\r", (unsigned long)ul_freq); SysTick_Config(sysclk_get_cpu_hz() / (ul_freq * SAMPLES)); g_ul_frequency = ul_freq; } break; case '1': puts("Amplitude:"); ul_amp = get_input_value(MIN_AMPLITUDE, MAX_AMPLITUDE); puts("\r"); if (ul_amp != VAL_INVALID) { printf("Set amplitude to : %lu\n\r", (unsigned long)ul_amp); g_l_amplitude = ul_amp; } break; case 'i': case 'I': printf("-I- Frequency : %lu Hz Amplitude : %ld\n\r", (unsigned long)g_ul_frequency, (long)g_l_amplitude); break; case 'w': case 'W': printf("-I- Switch wave to : %s\n\r", g_uc_wave_sel ? "SINE" : "Full Amplitude SQUARE"); g_uc_wave_sel = (g_uc_wave_sel + 1) & 1; break; case 'm': case 'M': display_menu(); break; } puts("Press \'m\' or \'M\' to display the main menu again!\r"); } }
/** * \brief ACC example application entry point. * * \return Unused (ANSI-C compatibility). */ int main(void) { uint8_t uc_key; int16_t s_volt = 0; uint32_t ul_value = 0; volatile uint32_t ul_status = 0x0; int32_t l_volt_dac0 = 0; /* Initialize the system */ sysclk_init(); board_init(); /* Initialize debug console */ configure_console(); /* Output example information */ puts(STRING_HEADER); /* Initialize DACC */ /* Enable clock for DACC */ pmc_enable_periph_clk(ID_DACC); /* Reset DACC registers */ dacc_reset(DACC); /* External trigger mode disabled. DACC in free running mode. */ dacc_disable_trigger(DACC); /* Half word transfer mode */ dacc_set_transfer_mode(DACC, 0); /* Power save: * sleep mode - 0 (disabled) * fast wake-up - 0 (disabled) */ dacc_set_power_save(DACC, 0, 0); /* Timing: * refresh - 0x08 (1024*8 dacc clocks) * max speed mode - 0 (disabled) * startup time - 0xf (960 dacc clocks) */ dacc_set_timing(DACC, 0x08, 0, 0xf); /* Disable TAG and select output channel DACC_CHANNEL */ dacc_set_channel_selection(DACC, DACC_CHANNEL_0); /* Enable output channel DACC_CHANNEL */ dacc_enable_channel(DACC, DACC_CHANNEL_0); /* Setup analog current */ dacc_set_analog_control(DACC, DACC_ANALOG_CONTROL); /* Set DAC0 output at ADVREF/2. The DAC formula is: * * (5/6 * VOLT_REF) - (1/6 * VOLT_REF) volt - (1/6 * VOLT_REF) * ----------------------------------- = -------------------------- * MAX_DIGITAL digit * * Here, digit = MAX_DIGITAL/2 */ dacc_write_conversion_data(DACC, MAX_DIGITAL / 2); l_volt_dac0 = (MAX_DIGITAL / 2) * (2 * VOLT_REF / 3) / MAX_DIGITAL + VOLT_REF / 6; /* Initialize ADC */ /* Enable clock for ADC */ pmc_enable_periph_clk(ID_ADC); /* * Formula: ADCClock = MCK / ( (PRESCAL+1) * 2 ) * For example, MCK = 64MHZ, PRESCAL = 4, then: * ADCClock = 64 / ((4+1) * 2) = 6.4MHz; */ adc_init(ADC, sysclk_get_cpu_hz(), ADC_CLOCK, ADC_STARTUP_TIME_SETTING); /* Formula: * Startup Time = startup value / ADCClock * Transfer Time = (TRANSFER * 2 + 3) / ADCClock * Tracking Time = (TRACKTIM + 1) / ADCClock * Settling Time = settling value / ADCClock * For example, ADC clock = 6MHz (166.7 ns) * Startup time = 512 / 6MHz = 85.3 us * Transfer Time = (1 * 2 + 3) / 6MHz = 833.3 ns * Tracking Time = (0 + 1) / 6MHz = 166.7 ns * Settling Time = 3 / 6MHz = 500 ns */ /* Set ADC timing */ adc_configure_timing(ADC, ADC_TRACK_SETTING, ADC_SETTLING_TIME_3, ADC_TRANSFER_SETTING); /* Channel 5 has to be compared */ adc_enable_channel(ADC, ADC_CHANNEL_5); //! [acc_enable_clock] /** Enable clock for ACC */ pmc_enable_periph_clk(ID_ACC); //! [acc_enable_clock] //! [acc_init] /** Initialize ACC */ acc_init(ACC, ACC_MR_SELPLUS_AD5, ACC_MR_SELMINUS_DAC0, ACC_MR_EDGETYP_ANY, ACC_MR_INV_DIS); //! [acc_init] //! [acc_irq_enable] /** Enable ACC interrupt */ NVIC_EnableIRQ(ACC_IRQn); /** Enable */ acc_enable_interrupt(ACC); //! [acc_irq_enable] dsplay_menu(); while (1) { while (uart_read(CONSOLE_UART, &uc_key)) { } printf("input: %c\r\n", uc_key); switch (uc_key) { case 's': case 'S': printf("Input DAC0 output voltage (%d~%d mv): ", (VOLT_REF / 6), (VOLT_REF * 5 / 6)); s_volt = get_input_voltage(); puts("\r"); if (s_volt > 0) { l_volt_dac0 = s_volt; /* The DAC formula is: * * (5/6 * VOLT_REF) - (1/6 * VOLT_REF) volt - (1/6 * VOLT_REF) * ----------------------------------- = -------------------------- * MAX_DIGITAL digit * */ ul_value = ((s_volt - (VOLT_REF / 6)) * (MAX_DIGITAL * 6) / 4) / VOLT_REF; dacc_write_conversion_data(DACC, ul_value); puts("-I- Set ok\r"); } else { puts("-I- Input voltage is invalid\r"); } break; case 'v': case 'V': /* Start conversion */ adc_start(ADC); ul_status = adc_get_status(ADC); while ((ul_status & ADC_ISR_EOC5) != ADC_ISR_EOC5) { ul_status = adc_get_status(ADC); } /* Conversion is done */ ul_value = adc_get_channel_value(ADC, ADC_CHANNEL_5); /* * Convert ADC sample data to voltage value: * voltage value = (sample data / max. resolution) * reference voltage */ s_volt = (ul_value * VOLT_REF) / MAX_DIGITAL; printf("-I- Voltage on potentiometer(AD5) is %d mv\n\r", s_volt); printf("-I- Voltage on DAC0 is %ld mv \n\r", (long)l_volt_dac0); break; case 'm': case 'M': dsplay_menu(); break; } } }