Esempio n. 1
0
void ADC_init(ADC_name_t adc_name, ADC_prescaler_t prescaler, ADC_refference_t refference, ADC_conv_mode_t mode, ADC_freerun_t freerun, ADC_sweep_t sweep)
{		
	ADC_t * ADCx;	///< Wskaźnik na odpowiedni ADC
	
	if(adc_name == ADC_A)
		ADCx = &ADCA;
	else 
		ADCx = &ADCB;
		
		
	ADCx->PRESCALER = prescaler;		//ustawienie preskalera
	
	if(refference == ADC_REF_INT1V)		//ustawienie napięcia referencyjnego
	{
		ADCx->REFCTRL = ADC_REF_INT1V | 
						ADC_CH_MUXINT_BANDGAP_gc;	//ustaw napięcie referencyjnego 1V i włącz BANDGAP dla wewnętrznego źródła 1V
	}
	else 
		ADCx->REFCTRL = refference;
		
	ADCx_refsource_mV[ADC_A] = ADCA_ref_source_val_mV;	
	ADCx_refsource_mV[ADC_B] = ADCB_ref_source_val_mV;
	
	
	if(freerun == ADC_FREERUN_ENABLE)		//ustawienie trybu freerun
		ADCx->CTRLB |= ADC_FREERUN_bm;
	else
		ADCx->CTRLB &= ~ADC_FREERUN_bm;
		
		
	if(mode == ADC_MODE_SIGNED)				//ustawienie trybu pomiaru
	{
		ADCx->CTRLB |= ADC_CONMODE_bm;		
		ADCx_resolution[adc_name] = 2048;	//dla trybu signed rozdzielczosć wynosi 2048
		ADCx_delta_mV[adc_name] = 0;
	}
	else 
	{
		ADCx->CTRLB &= ~ADC_CONMODE_bm;
		ADCx_resolution[adc_name] = 4096;							//dla trybu unsigned rozdzielczosc 4096
		ADCx_delta_mV[adc_name] = ADCx_refsource_mV[adc_name]*0,05;	//delta dla unsigned wynosi 5% napięcia referencyjnego (dokumentacja)
	}
	
	ADCx->EVCTRL = sweep;					//włączenie triggera dla wybranych kanałów  ADC (dla freerun)
	
	ADCA.CALL = ReadCalibrationByte(PRODSIGNATURES_ADCACAL0);	//czytanie z flasha i zapisywanie do rejestru bajtów kalibracyjnych 
	ADCA.CALH = ReadCalibrationByte(PRODSIGNATURES_ADCACAL1);
	
	ADCB.CALL = ReadCalibrationByte(PRODSIGNATURES_ADCACAL0);	
	ADCB.CALH = ReadCalibrationByte(PRODSIGNATURES_ADCACAL1);
	
		
}
Esempio n. 2
0
/*
 * Switch to 32MHz clock
 */
void switch_to_32MHz_clock(void)
{
    DFLLRC32M.CALA = ReadCalibrationByte(PROD_SIGNATURES_START + RCOSC32MA_offset); // Load calibration value for 32M RC Oscillator
    DFLLRC32M.CALB = ReadCalibrationByte(PROD_SIGNATURES_START + RCOSC32M_offset);  // Load calibration value for 32M RC Oscillator
    OSC.CTRL |= OSC_RC32MEN_bm;                                                     // Enable 32MHz oscillator
    while((OSC.STATUS & OSC_RC32MRDY_bm) == 0);                                     // Wait for stable oscillator
    CCP = CCP_IOREG_gc;                                                             // Inform process we change a protected register
    CLK.CTRL = CLK_SCLKSEL_RC32M_gc;                                                // Switch to 32MHz    
    OSC.CTRL &= (~OSC_RC2MEN_bm);                                                   // Disable the default 2Mhz oscillator    
    OSC.XOSCCTRL = OSC_XOSCSEL_32KHz_gc;                                            // Choose 32kHz external crystal
    OSC.CTRL |= OSC_XOSCEN_bm;                                                      // Enable external oscillator
    while((OSC.STATUS & OSC_XOSCRDY_bm) == 0);                                      // Wait for stable 32kHz clock
    OSC.DFLLCTRL = OSC_RC32MCREF_XOSC32K_gc;                                        // Select the 32kHz clock as calibration ref for our 32M
    DFLLRC32M.CTRL = DFLL_ENABLE_bm;                                                // Enable DFLL for RC32M
}
Esempio n. 3
0
/*
 * Initialize the DAC
 */
void init_dac(void)
{
    dacdprintf_P(PSTR("-----------------------\r\n"));
    dacdprintf_P(PSTR("DAC init\r\n\r\n"));
    
    DACB.CH0GAINCAL = ReadCalibrationByte(PROD_SIGNATURES_START + DACB0GAINCAL_offset);     // Set correct calibration values
    DACB.CH0OFFSETCAL = ReadCalibrationByte(PROD_SIGNATURES_START + DACB0OFFCAL_offset);    // Set correct calibration values
    DACB.CH1GAINCAL = ReadCalibrationByte(PROD_SIGNATURES_START + DACB1GAINCAL_offset);     // Set correct calibration values
    DACB.CH1OFFSETCAL = ReadCalibrationByte(PROD_SIGNATURES_START + DACB1OFFCAL_offset);    // Set correct calibration values
    disable_vbias_dac();                                                                    // Disable VBIAS output
    disable_opampin_dac();                                                                  // Disable OPAMPIN output
    DACB.CTRLA = DAC_ENABLE_bm;                                                             // Enable DAC
    DACB.CTRLB = DAC_CHSEL_DUAL_gc;                                                         // Enable both channels
    DACB.CTRLC = DAC_REFSEL_AREFB_gc;                                                       // Use external VREF (1.24V)
    
    dacdprintf_P(PSTR("DAC initialized\r\n"));
}
Esempio n. 4
0
void calibrate_ADC(void) {
	ADCA.CALL = ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, ADCACAL0) );
	ADCA.CALH = ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, ADCACAL1) );
}
Esempio n. 5
0
void adc_init(void) {
	
	// ADC Clock was disabled initially in sysclk_init()
	// Must re-activate the ADC clock before configuring its registers (we're using ADCA)
	PR.PRPA &= ~0x02; // Clear ADC bit in Power Reduction Port A Register
	
	// Calibration values are stored at production time
	// Load stored bytes into the calibration registers
	// First NVM read is junk and must be thrown away
	ADCA.CALL = ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, ADCACAL0) );
	ADCA.CALH = ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, ADCACAL1) );
	ADCA.CALL = ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, ADCACAL0) );
	ADCA.CALH = ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, ADCACAL1) );

	//////////////////////////////////////////////////////////////////////
	//ADCA.CH0.CTRL
	//     7        6       5        4        3        2       1       0
	// | START  |   -   |   -   |         GAIN[2:0]        | INPUTMODE[1:0] |
	//     0        0       0        0        0        0       0       0
	// Place ADC channel in single-ended mode
	// Gain set to 1
	ADCA.CH0.CTRL = ADC_CH_INPUTMODE0_bm; // 0x01
	//////////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////////////////
	//ADCA.CH0.MUXCTRL
	//     7        6       5        4        3        2       1       0
	// |   -    |           MUXPOS[3:0]             |     MUXNEG[2:0]     |
	//     0        0       0        0        0        0       0       0
	// Connect potentiometer (PB1) to positive input
	// MUXNEG bits are ignored in single-ended mode
	ADCA.CH0.MUXCTRL = ADC_CH_MUXINT0_bm; // 0x08
	//////////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////////////////
	//ADCA.CTRLA
	//     7        6       5         4         3         2       1        0
	// |   -   | CURRLIMIT[1:0] | CONVMODE | FREERUN | RESOLUTION[1:0] |   -   |
	//     0        0       0         0         0         0       0        0
	// Apply no limit to ADC sample rate
	// Put ADC in signed mode
	// Disable Free-run mode (single conversion upon trigger)
	// Resolution set to 12-bit, right justified (11-bit effective in signed mode)
	ADCA.CTRLA = ADC_CONMODE_bm; // 0x10
	//////////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////////////////
	//ADCA.PRESCALER
	//     7       6       5       4       3       2       1       0
	// |   -   |   -   |   -   |   -   |       |     PRESCALER[2:0]    |
	//     0       0       0       0       0       0       0       0
	// The ADC runs off of the CPU_per clock
	// In sys_clk_init() the internal 2MHz RC osc was used to source a 16 MHz PLL
	// The PLL is then divided using Prescalers A, B, and C setting CPU_per to 8 MHz
	// According to AVR1300, the ADC clock should run in the range 100 kHz ~ approx 1.4 MHz
	// Set ADC clock to 125kHz:  CPU_per/64    =>    8MHz/64 = 125kHz
	ADCA.PRESCALER = ADC_PRESCALER2_bm; // 0x04
	//////////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////////////////
	//ADCA.REFCTRL
	//     7       6       5       4       3       2        1         0
	// |   -   |      REFSEL[2:0]      |   -   |   -   | BANDGAP | TEMPREF |
	//     0       0       0       0       0       0        0         0
	// Set Vref to Vcc/1.6.  This gives 3.3/1.6 = approx 2.06V
	// With effectively 11-bit resolution, this means each LSB 
	// will represent approximately 1 mV.
	ADCA.REFCTRL = ADC_REFSEL0_bm; // 0x10
	//////////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////////////////
	//ADCA.EVCTRL
	//     7       6       5       4       3       2       1       0
	// |   -   |   -   |   -   |   EVSEL[1:0]  |      EVACT[2:0]       |
	//     0       0       0       0       0       0       0       0
	// Not implementing Event System so ensure EVCTRL is reading zeros
	ADCA.EVCTRL = 0x00;
	//////////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////////////////
	//ADCA.INTFLAGS
	//     7       6       5       4       3       2       1       0
	// |   -   |   -   |   -   |   -   |   -   |   -   |   -   | CH0IF |
	//     0       0       0       0       0       0       0       0
	// Ensure the ADC complete flag is cleared (by writing a '1' to it)
	ADCA.INTFLAGS = ADC_CH0IF_bm; // 0x01
	//////////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////////////////
	//ADCA.CH0.INTCTRL
	//     7       6       5       4        3       2       1       0
	// |   -   |   -   |   -   |   -   |  INTMODE[1:0]  |  INTLVL[1:0]  |
	//     0       0       0       0        0       0       0       0
	// Configure interrupt on conversion complete with high priority
	ADCA.CH0.INTCTRL = ADC_CH_INTLVL1_bm | ADC_CH_INTLVL0_bm; // 0x03
	//////////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////////////////
	//ADCA.CTRLA
	//     7       6       5       4       3         2        1        0
	// |   -   |   -   |   -   |   -   |   -   | CH0START | FLUSH | ENABLE |
	//     0       0       0       0       0         0        0        0
	// Enable ADC, module B
	ADCA.CTRLA = ADC_ENABLE_bm; // 0x01
	//////////////////////////////////////////////////////////////////////
}
Esempio n. 6
0
void adcInit()
{
	
	ADCA.CALL = ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, ADCACAL0) );
	ADCA.CALH = ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, ADCACAL1) );

	ADCA.CTRLB = 
						ADC_CURRLIMIT_NO_gc		|
						ADC_CONMODE_bm			|	//enable signed mode
						ADC_FREERUN_bm			|
						ADC_RESOLUTION_12BIT_gc	;
					
	ADCA.REFCTRL =		ADC_REFSEL_VCC_gc;			//utilize the vref of vcc/1.6 = 2.0625 V
	
	ADCA.PRESCALER =	ADC_PRESCALER_DIV512_gc;		
	
	//set all the adc channels to be single ended inputs	
	ADCA.CH0.CTRL =		ADC_CH_INPUTMODE_SINGLEENDED_gc;
	ADCA.CH1.CTRL =		ADC_CH_INPUTMODE_SINGLEENDED_gc;
	ADCA.CH2.CTRL =		ADC_CH_INPUTMODE_SINGLEENDED_gc;
	ADCA.CH3.CTRL =		ADC_CH_INPUTMODE_SINGLEENDED_gc;
	
	//analog channels 0-3 will correlate to the analog pins 0-3 on port A
	ADCA.CH0.MUXCTRL =	ADC_CH_MUXPOS_PIN0_gc;
	ADCA.CH1.MUXCTRL =	ADC_CH_MUXPOS_PIN1_gc;
	ADCA.CH2.MUXCTRL =	ADC_CH_MUXPOS_PIN2_gc;
	ADCA.CH3.MUXCTRL =	ADC_CH_MUXPOS_PIN3_gc;
	
	//initialize conversion complete interrupts on all ADCA channel inputs
	ADCA.CH0.INTCTRL =	ADC_CH_INTMODE_COMPLETE_gc | ADC_CH_INTLVL_LO_gc;	
	ADCA.CH1.INTCTRL =	ADC_CH_INTMODE_COMPLETE_gc | ADC_CH_INTLVL_LO_gc;
	ADCA.CH2.INTCTRL =	ADC_CH_INTMODE_COMPLETE_gc | ADC_CH_INTLVL_LO_gc;
	ADCA.CH3.INTCTRL =	ADC_CH_INTMODE_COMPLETE_gc | ADC_CH_INTLVL_LO_gc;
	
	ADCA.EVCTRL =		ADC_SWEEP_0123_gc;
	
	//enable ADCA, and start conversions on all channels
	ADCA.CTRLA =		ADC_ENABLE_bm	|
						ADC_CH0START_bm	|
						ADC_CH1START_bm	|
						ADC_CH2START_bm	|
						ADC_CH3START_bm	;

	ADCB.CALL = ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, ADCBCAL0) );
	ADCB.CALH = ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, ADCBCAL1) );
	
	ADCB.CTRLB =
						ADC_CURRLIMIT_NO_gc		|
						ADC_CONMODE_bm			|	//enable signed mode
						ADC_FREERUN_bm			|
						ADC_RESOLUTION_12BIT_gc	;
	
	ADCB.REFCTRL =		ADC_REFSEL_VCC_gc;			//utilize the vref of vcc/1.6 = 2.0625 V
	
	ADCB.PRESCALER =	ADC_PRESCALER_DIV512_gc;		
	
	//set all the adc channels to be single ended inputs
	ADCB.CH0.CTRL =		ADC_CH_INPUTMODE_SINGLEENDED_gc;
	ADCB.CH1.CTRL =		ADC_CH_INPUTMODE_SINGLEENDED_gc;
	ADCB.CH2.CTRL =		ADC_CH_INPUTMODE_SINGLEENDED_gc;
	ADCB.CH3.CTRL =		ADC_CH_INPUTMODE_SINGLEENDED_gc;
	
	//analog channels 0-3 will correlate to the analog pins 4-7 on port A
	ADCB.CH0.MUXCTRL =	ADC_CH_MUXPOS_PIN12_gc;
	ADCB.CH1.MUXCTRL =	ADC_CH_MUXPOS_PIN13_gc;
	ADCB.CH2.MUXCTRL =	ADC_CH_MUXPOS_PIN14_gc;
	ADCB.CH3.MUXCTRL =	ADC_CH_MUXPOS_PIN15_gc;
	
	//initialize conversion complete interrupts on all ADCA channel inputs
	ADCB.CH0.INTCTRL =	ADC_CH_INTMODE_COMPLETE_gc | ADC_CH_INTLVL_LO_gc;
	ADCB.CH1.INTCTRL =	ADC_CH_INTMODE_COMPLETE_gc | ADC_CH_INTLVL_LO_gc;
	ADCB.CH2.INTCTRL =	ADC_CH_INTMODE_COMPLETE_gc | ADC_CH_INTLVL_LO_gc;
	ADCB.CH3.INTCTRL =	ADC_CH_INTMODE_COMPLETE_gc | ADC_CH_INTLVL_LO_gc;
	
	ADCB.EVCTRL =		ADC_SWEEP_0123_gc;
	
	//enable ADCB
	ADCB.CTRLA =		ADC_ENABLE_bm	|
						ADC_CH0START_bm	|
						ADC_CH1START_bm	|
						ADC_CH2START_bm	|
						ADC_CH3START_bm	;

	PMIC.CTRL |= PMIC_LOLVLEN_bm | PMIC_RREN_bm;
}