/*
		This example shows how to configure TCC0 for basic timer operation.

		The timer will run at the main clock frequency (32MHz) so we need
		to do a bit of math to derive the number of clock cycles to arrive
		at the desired microsecond time out.
 */
void startTimer(uint16_t microseconds)
{
    uint32_t cycles;

    // There are 31.25 nano seconds per clock cycle.
    // So we multiply the micro seconds by the clock period to determine
    // the number of clock cycles to achieve the microsecond timeout.
    // That number of cycles becomes our TOP value.
    // We will use 32 nano seconds to preclude floating point arithmetic.
    cycles = 32*microseconds;

    // Set period/TOP value.
    TCC0.CCA = cycles;

    // Set the CNT to 0.
    TC_SetCount(&TCC0, 0);

    /* Enable Input "Capture or Compare" channel A. */
    TC0_EnableCCChannels( &TCC0, TC0_CCAEN_bm );

    // Select clock source and start the timer.
    TC0_ConfigClockSource( &TCC0, TC_CLKSEL_DIV1_gc );

    // Enable CCA interrupt.
    TC0_SetCCAIntLevel( &TCC0, TC_CCAINTLVL_LO_gc );
    PMIC.CTRL |= PMIC_LOLVLEN_bm;
}
Exemple #2
0
void setup_Timer(){
	//16 ms
	TC0_ConfigClockSource( &TCC0, TC_CLKSEL_DIV8_gc );
	//TC0_ConfigClockSource( &TCC0, TC_CLKSEL_DIV1024_gc );
	TC_SetPeriod( &TCC0, 0xFA00 );	//Es el periodo o TOP Value para que se active la interrupción. (Equivale a 16ms)
	//TC_SetPeriod( &TCC0, 0x7A12 );
	
}
Exemple #3
0
/*
 * Setup timer 1 compare match A to generate a tick interrupt.
 */
static void prvSetupTimerInterrupt(void) {
    //Use TCC0 as a tick counter. If this is to be changed, change ISR as well
    TC0_t * tickTimer = &TCC0;
    //select the clock source and pre-scale by 64
    TC0_ConfigClockSource(tickTimer, TC_CLKSEL_DIV64_gc);
    //set period of counter
    tickTimer->PER = configCPU_CLOCK_HZ / configTICK_RATE_HZ / 64 - 1;

    //enable interrupt and set low level
    TC0_SetOverflowIntLevel(tickTimer, TC_OVFINTLVL_LO_gc);
    //enable low level interrupts
    PMIC_EnableLowLevel();
}
Exemple #4
0
// This function initializes the PWMs
void Init_PWM( void )
{

// Set PWM outputs
	MOTOR_OUTPUT.DIRSET = 0x03;										// PD0/PD1 set as outputs

// Configure timer
	TC0_ConfigWGM(&MOTOR_TIMER, TC_WGMODE_SS_gc);
	TC0_EnableCCChannels(&MOTOR_TIMER, TC0_CCAEN_bm|TC0_CCBEN_bm);
	TC_SetCompareA(&MOTOR_TIMER, 0);
	TC_SetCompareB(&MOTOR_TIMER, 0);
	TC_SetPeriod(&MOTOR_TIMER, MAX_PWM);
	TC0_ConfigClockSource(&MOTOR_TIMER, TC_CLKSEL_DIV1_gc);			// 32MHz
}
Exemple #5
0
/** \brief Initializes the library timer 0 or 1 based on given timer parameter.
 *
 * Sets up the given timer for use with this library. This involves setting the
 * clock prescaler and mode, but the period and overflow interrupt enable are
 * left to the SM_move() and ISR for the corresponding timer.
 *
 * This function also handles mapping the appropriate speed ramp to the
 *
 * \param[in] motor The motor to initialize the timer for
 * \param[in] timer The timer to initialize (TIMER0 or TIMER1) */
static void SM_timer_init(SM_t *motor, SM_timer_t timer) {
   /* 32M/256 == 125K Hz*/
   if (timer == SM_TIMER_NEEDLE) {
      TC0_ConfigWGM(&TIMER_NEEDLE, TC_WGMODE_NORMAL_gc);
      TC0_ConfigClockSource(&TIMER_NEEDLE, TC_CLKSEL_DIV256_gc);
      needle_motor = motor;
   }
   else {
      TC1_ConfigWGM(&TIMER_RING, TC_WGMODE_NORMAL_gc);
      TC1_ConfigClockSource(&TIMER_RING, TC_CLKSEL_DIV256_gc);
      ring_motor = motor;
   }

   motor->timer = timer;
}
Exemple #6
0
// Configures PWM output on compare a b and c for single slope pwm, with hires, and clk source as sys clk
void configPWM (volatile TC0_t * tc, HIRES_t * hires, uint16_t period) {
	TC_SetPeriod (tc, period );
	TC0_ConfigWGM (tc, TC_WGMODE_NORMAL_gc ); // set to single slope pwm generation mode
	TC0_EnableCCChannels (tc, TC0_CCAEN_bm); // enable compare A
	TC0_EnableCCChannels (tc, TC0_CCBEN_bm); // enable compare B
	TC0_EnableCCChannels (tc, TC0_CCCEN_bm); // enable compare C
	TC0_EnableCCChannels (tc, TC0_CCDEN_bm); // enable compare D

	//~ TC0_SetCCAIntLevel (tc, TC_CCAINTLVL_HI_gc);
	TC0_SetCCBIntLevel (tc, TC_CCBINTLVL_LO_gc);
	//~ TC0_SetCCCIntLevel (tc, TC_CCCINTLVL_HI_gc);
	//~ TC0_SetCCDIntLevel (tc, TC_CCDINTLVL_HI_gc);

	TC0_SetOverflowIntLevel (tc, TC_OVFINTLVL_LO_gc);
	
	PMIC.CTRL |= PMIC_HILVLEN_bm;

	TC0_ConfigClockSource (tc, TC_CLKSEL_DIV1_gc);
	HIRES_Enable (hires, HIRES_HREN_TC0_gc);
}
Exemple #7
0
void battery_init()
{
	PORTD.DIRSET = PIN4_bm | PIN5_bm | PIN6_bm; // battery level indicator
	PORTD.OUT = 0x00;

	PORTC.DIRSET = PIN7_bm; // signal to stop the boost converters
	PORTC.OUTSET = PIN7_bm; // start with the converters stopped to avoid power
	                        // surges on the battery. When the voltage recovers
	                        // the converters will be enabled again
	PORTC.DIRCLR = PIN6_bm; // input V_USB_CHG

	PORTE.DIRCLR = PIN3_bm; // input CHG_STAT

	// update once for each second (1Hz)
	TC_SetPeriod(&TCE0, 31250);
	TC0_ConfigClockSource(&TCE0, TC_CLKSEL_DIV256_gc);
	TC0_ConfigWGM(&TCE0, TC_WGMODE_NORMAL_gc);
	TC0_EnableCCChannels(&TCE0, TC0_CCAEN_bm);
	TC0_SetCCAIntLevel(&TCE0, TC_CCAINTLVL_LO_gc);
}
Exemple #8
0
int main( void )
{
  
	/* To toggle a LED, set pin 0  as output and high so the LED is default off. */

	LEDPORT.OUTSET = PIN0_bm; 
	LEDPORT.DIRSET = PIN0_bm;

	//Add code here that sets the timer compare value for channel A
	//ie. CCA register for the TCC0
	


	/* We need to start the counter with correct prescaling, 
	* and make it count to a specific TOP value, as we did in task1.
	* To do this we use the driver functions supplied in TC_driver.c, study the source
	* file to see how the timer is configured */

	TC_SetPeriod(&TCC0, 0xFFFF);
	TC0_ConfigClockSource(&TCC0, TC_CLKSEL_DIV64_gc); 


	/* This code turn on the LED on compare match, and turn the LED off on timer overflow */

	while(1)
	{

		if((TCC0.INTFLAGS & TC0_OVFIF_bm) != 0)
		{
			TCC0.INTFLAGS = TC0_OVFIF_bm;      // Clear the TC_OVFIF by writing a logical 1 to the flag
			LEDPORT.OUTSET = PIN0_bm;            // Turn off LED
		}
  
		if((TCC0.INTFLAGS & TC0_CCAIF_bm) !=0)
		{
			TCC0.INTFLAGS = TC0_CCAIF_bm;      //Clear the TC_CCAIF by writing a logical 1 to the flag
			TCC0.CCABUF += 0x1000;            //Update the CCABUF register with a new value to change the LED on time.
			LEDPORT.OUTCLR = PIN0_bm;            //Turn on LED
		}
	}
}
void TCE0_init()
{
  
 /* Select a Waveform Genreation mode and the CC channels to use*/

  TC0_ConfigWGM( &TCE0, TC_WGMODE_SS_gc );
  TC0_EnableCCChannels( &TCE0, TC0_CCAEN_bm); // only CCA is used
  TC_SetPeriod( &TCE0, 60000);


  /* The corresponding port pins MUST be output for the Waveform to be visible */
  
  PORTE.DIRSET = 0xFF;
  PORTE.OUTSET = 0xFF; //set port high to switch LEDs off, take INVEN into account
  
  
  /* To have inverted ouput on some pins we set the corresponding INVEN bit for the pin*/
  
  
  TC0_ConfigClockSource(&TCE0, TC_CLKSEL_DIV1_gc);

}
Exemple #10
0
void configDelayTimer (volatile TC0_t * tc) {
	TC_SetPeriod (tc, (uint16_t)65535); // set tc period
	TC0_ConfigWGM (tc, TC_WGMODE_NORMAL_gc); // normal timer countermode
	TC0_ConfigClockSource (tc, TC_CLKSEL_DIV1024_gc);
}
int main( void )
{

    /* To change the duty cycle for the PWM for the LED control, use a variable to increase/decrease the
    * CCx registers once for each period */

    int16_t pwm_delta = 300;

    // Add code to select a Single Slope PWM as Waveform Generation mode. 
    // This is done by setting the WGM bits,in the CTRLB register for the TC.



    /* Add code to enable the CC channels we wish to use. Each channel must be separately enabled
    * by setting the corresponding CCxEN bits in the CTRLB register for the TC.
    * Code for enabling CCA is already added, but add code to enable CCB, CCC and CCD */

    TCE0.CTRLB |= TC0_CCAEN_bm;

    //Insert code to enable CC for the other channels, B, C and D.




    /* The corresponding port pins MUST be ouput for the Waveform to be visible
    * on the pin. For TCE0 the corresponding port is PORTE, and pin 0 to 3 for
    * CC channel A to D */

    PORTE.DIRSET = 0x0F;

    /* Note how the inverted signal is always controlled from the Port pin configuration in XMEGA
    * This can be used with all other peripherals connected to the pin to have inverted output.
    * Below is example code on how you can set inverted ouput on a pin using the Pin Control Register*/

    //PORTE.PIN0CTRL &= ~PORT_INVEN_bm;

    /* Set a compare value for each compare channel, just as in task2.
    * The compare value decide the PWM duty cycle for the waveform.
    * 
    * Code for CC channel A is added, add code for channel B, C, and D
    * with the compare value 3000 */

    TC_SetCompareA(&TCE0, 3000);

    //Insert function calls to set the other compare values

	

    /* Using the TC_driver we set the Period and 
    * start the timer with no prescaling */

    TC_SetPeriod(&TCE0, 60000);
    TC0_ConfigClockSource(&TCE0, TC_CLKSEL_DIV1_gc);

    while(1)
    {
        /* The code check if the overflow flag is set,
         * if so it clears the flag and sets a new duty cycle for all
         * CC channels */

        /* Check if overflow flag (OVFIF) is set,
         * clear flag and set a new duty cycle
         */
        if(TC_GetOverflowFlag(&TCE0) != 0) 
        {
            TC_ClearOverflowFlag(&TCE0);      //Clear the IF by writing a logical 1 to the flag

            if(TCE0.CCA >= 59000)
            {		                        //Some "random" values above 0 and below TOP is selected
                pwm_delta = -300;            //for the PWM changes, and make the LED look ok.
            }
            else if(TCE0.CCA <= 5000)
            {
                pwm_delta = +300;
            }

            TCE0.CCABUF += pwm_delta;             //Change the compare value to change duty cycle
            TCE0.CCBBUF += pwm_delta;
            TCE0.CCCBUF += pwm_delta;
            TCE0.CCDBUF += pwm_delta;

        }

    }
    }
Exemple #12
0
// This function initializes system tick
void Init_SysTick( void )
{
	TC_SetPeriod(&TCF0, 124);										// 125 ticks at 31.25KHz = 4ms periods
	TC0_ConfigClockSource(&TCF0, TC_CLKSEL_DIV1024_gc);				// 32MHz/1024=31.25KHz
	TC0_SetOverflowIntLevel(&TCF0, TC_OVFINTLVL_LO_gc);				// Enable interrupts for overflow
}
Exemple #13
0
//-----------------------------------------------------------------------------
// functions
//-----------------------------------------------------------------------------
void adc_init(void) {
/*
	Note: port_init() must be run before this function, so that the inputs are
	set correctly.
	
	We are using both ADCs. So everything will be set up for ADCA && ADCB.
*/

// Load the production calibration data into each ADC.
// This data was taken by Atmel and is stored in the micro.
// This function takes care of the whole process for you.
	ADC_CalibrationValues_Load(&ADCA);
	ADC_CalibrationValues_Load(&ADCB);
	
// Set the mode of operation for each ADC
// Signed operation mode is required for the differential configuration.
	ADC_ConvMode_and_Resolution_Config(&ADCA,signed_y,ADC_RESOLUTION_12BIT_gc);
	ADC_ConvMode_and_Resolution_Config(&ADCB,signed_y,ADC_RESOLUTION_12BIT_gc);
	
// Set ADC clocks
// 32MHz / 128 = 250KHz
// I currently have no explanation for this choice
// Atmel documentation states that you need to stay within the recommended
// ADC frequencies, but I cannot find the specific numbers.
	ADC_Prescaler_Config(&ADCA, ADC_PRESCALER_DIV128_gc);
	ADC_Prescaler_Config(&ADCB, ADC_PRESCALER_DIV128_gc);
	
// Select reference to be external reference on PIN0 for A and B
	ADC_Reference_Config(&ADCA, ADC_REFSEL_AREFA_gc);
	ADC_Reference_Config(&ADCB, ADC_REFSEL_AREFB_gc);

// Setup all channels to have differential input and 1X gain
	ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH0,ADC_CH_INPUTMODE_DIFF_gc,
	                                  ADC_CH_GAIN_1X_gc); // V1
	ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH1,ADC_CH_INPUTMODE_DIFF_gc,
	                                  ADC_CH_GAIN_1X_gc); // V2
	ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH2,ADC_CH_INPUTMODE_DIFF_gc,
	                                  ADC_CH_GAIN_1X_gc); // reference
									  
	ADC_Ch_InputMode_and_Gain_Config(&ADCB.CH0,ADC_CH_INPUTMODE_DIFF_gc,
	                                  ADC_CH_GAIN_1X_gc); // I1
	ADC_Ch_InputMode_and_Gain_Config(&ADCB.CH1,ADC_CH_INPUTMODE_DIFF_gc,
	                                  ADC_CH_GAIN_1X_gc); // I2
	ADC_Ch_InputMode_and_Gain_Config(&ADCB.CH2,ADC_CH_INPUTMODE_DIFF_gc,
	                                  ADC_CH_GAIN_1X_gc); // reference								  									 								  

// Select the input pins for each ADC.
/*
	See AnodV2.1.sch eagle file:
	V1 - A1
	V2 - A2
	I1 - B1
	I2 - B2
	Ref - A0,A3,B0,B3
*/
	ADC_Ch_InputMux_Config(&ADCA.CH0, ADC_CH_MUXPOS_PIN1_gc, \
									  ADC_CH_MUXNEG_PIN3_gc); // V1
	ADC_Ch_InputMux_Config(&ADCA.CH1, ADC_CH_MUXPOS_PIN2_gc, \
									  ADC_CH_MUXNEG_PIN3_gc); // V2
	ADC_Ch_InputMux_Config(&ADCA.CH2, ADC_CH_MUXPOS_PIN3_gc, \
									  ADC_CH_MUXNEG_PIN3_gc); // Offset calib
			
	ADC_Ch_InputMux_Config(&ADCB.CH0, ADC_CH_MUXPOS_PIN1_gc, \
									  ADC_CH_MUXNEG_PIN3_gc); // V1
	ADC_Ch_InputMux_Config(&ADCB.CH1, ADC_CH_MUXPOS_PIN2_gc, 
									  ADC_CH_MUXNEG_PIN3_gc); // V2
	ADC_Ch_InputMux_Config(&ADCB.CH2, ADC_CH_MUXPOS_PIN3_gc,
									  ADC_CH_MUXNEG_PIN3_gc); // Offset calib

// Configure the ADCA.CH2 interrupt.
// This will trip once a reading on channel 2 has been completely resolved.
// I am assuming the chan 0 and 1 of both ADCs will have their results completed
// when chan 2 is done. This is based from the Xmega A manual (sect 25)									  
	ADC_Ch_Interrupts_Config(&ADCA.CH1, ADC_CH_INTMODE_COMPLETE_gc, \
									    ADC_CH_INTLVL_LO_gc);

//Enable ADCs
	ADC_Enable(&ADCA);
	ADC_Enable(&ADCB);								

// Wait until common mode voltage is stable so tha bypass transients are not passed.
// What is the difference between the 32 and 8 MHz versions, 
// and which one do I want?
	ADC_Wait_32MHz(&ADCA);
	ADC_Wait_32MHz(&ADCB);									  

// The TCD0 timer will periodically trigger an event that will  create an event
// on channel 0. (Xmega A manual sect 6)
	eflags.setEventSource = EVSYS_SetEventSource(0, EVSYS_CHMUX_TCD0_OVF_gc);
	TC0_ConfigClockSource(&TCD0, TC_CLKSEL_DIV8_gc);
	TCD0.PER = 200; // 1/f = 1/(32MHz/DIVx/PER) --- 200---50us---20KHz

// This is moved to the adc_test() fun. May want to enable it here later.
	// enable timer overflow int and set priority to low.
	//TCD0.INTCTRLA = TC_OVFINTLVL_LO_gc; 

// An event on eventChan 0 will trigger a sweep of chan 0,1 in ADCA && ADCB.
// I do not know what would happen if an event happened on eventChan 1,2,3.
	ADC_Events_Config(&ADCA, ADC_EVSEL_0123_gc, ADC_EVACT_SWEEP_gc);	
	ADC_Events_Config(&ADCB, ADC_EVSEL_0123_gc, ADC_EVACT_SWEEP_gc);
	ADC_SweepChannels_Config(&ADCA, ADC_SWEEP_01_gc);
	ADC_SweepChannels_Config(&ADCB, ADC_SWEEP_01_gc);
	
	
// Calibration routine for the ADCs
// Find offset with two pins shorted together.
// Steve also found the offset for the current with 0 current flowing into them,
// but did not do an equivalent for voltage. I will leave this out for now.
	offset_A = ADC_Offset_Get_Signed(&ADCA, &(ADCA.CH2), true);
	offset_B = ADC_Offset_Get_Signed(&ADCB, &(ADCB.CH2), true);
}