Ejemplo n.º 1
0
void vInitialiseTimerForIntQueueTest( void )
{
const uint32_t ulDivider = 128UL, ulTCCLKS = 3UL;

	/* Enable the TC clocks. */
	PMC->PMC_PCER0 = 1 << ID_TC0;
	PMC->PMC_PCER0 = 1 << ID_TC1;

	/* Configure TC0 channel 0 for a tmrTIMER_0_FREQUENCY frequency and trigger
	on RC compare. */
	TC_Configure( TC0, tmrTC0_CHANNEL_0, ulTCCLKS | TC_CMR_CPCTRG );
	TC0->TC_CHANNEL[ tmrTC0_CHANNEL_0 ].TC_RC = BOARD_MCK / ( tmrTIMER_0_FREQUENCY * ulDivider );
	TC0->TC_CHANNEL[ tmrTC0_CHANNEL_0 ].TC_IER = TC_IER_CPCS;

	/* Configure TC0 channel 1 for a tmrTIMER_1_FREQUENCY frequency and trigger
	on RC compare. */
	TC_Configure( TC0, tmrTC0_CHANNEL_1, ulTCCLKS | TC_CMR_CPCTRG );
	TC0->TC_CHANNEL[ tmrTC0_CHANNEL_1 ].TC_RC = BOARD_MCK / ( tmrTIMER_1_FREQUENCY * ulDivider );
	TC0->TC_CHANNEL[ tmrTC0_CHANNEL_1 ].TC_IER = TC_IER_CPCS;

	/* Configure TC1 channel 0 tmrTIMER_2_FREQUENCY frequency and trigger on
	RC compare. */
	TC_Configure( TC1, tmrTC1_CHANNEL_0, ulTCCLKS | TC_CMR_CPCTRG );
	TC1->TC_CHANNEL[ tmrTC1_CHANNEL_0 ].TC_RC = BOARD_MCK / ( tmrTIMER_2_FREQUENCY * ulDivider );
	TC1->TC_CHANNEL[ tmrTC1_CHANNEL_0 ].TC_IER = TC_IER_CPCS;

	/* Enable interrupts and start the timers. */
	IRQ_ConfigureIT( ID_TC0, tmrLOWER_PRIORITY, prvTC0_Handler );
	IRQ_ConfigureIT( ID_TC1, tmrHIGHER_PRIORITY, prvTC1_Handler );
	IRQ_EnableIT( ID_TC0 );
	IRQ_EnableIT( ID_TC1 );
	TC_Start( TC0, tmrTC0_CHANNEL_0 );
	TC_Start( TC0, tmrTC0_CHANNEL_1 );
	TC_Start( TC1, tmrTC1_CHANNEL_0 );
}
Ejemplo n.º 2
0
int platform_init()
{
  int i;
   
  // Enable the peripherals we use in the PMC
  PMC_EnablePeripheral( AT91C_ID_US0 );  
  PMC_EnablePeripheral( AT91C_ID_US1 );
  PMC_EnablePeripheral( AT91C_ID_PIOA );
  PMC_EnablePeripheral( AT91C_ID_PIOB );
  PMC_EnablePeripheral( AT91C_ID_TC0 );
  PMC_EnablePeripheral( AT91C_ID_TC1 );
  PMC_EnablePeripheral( AT91C_ID_TC2 );
  PMC_EnablePeripheral( AT91C_ID_PWMC );  
  
  // Configure the timers
  AT91C_BASE_TCB->TCB_BMR = 0x15;
  for( i = 0; i < 3; i ++ )
    TC_Configure( ( AT91S_TC* )timer_base[ i ], AT91C_TC_CLKS_TIMER_DIV5_CLOCK | AT91C_TC_WAVE );
        
  // PWM setup (only the clocks are set at this point)
  PWMC_ConfigureClocks( BOARD_MCK, BOARD_MCK, BOARD_MCK );
  PWMC_ConfigureChannel( 0, AT91C_PWMC_CPRE_MCKA, 0, 0 );
  PWMC_ConfigureChannel( 1, AT91C_PWMC_CPRE_MCKA, 0, 0 );  
  PWMC_ConfigureChannel( 2, AT91C_PWMC_CPRE_MCKB, 0, 0 );
  PWMC_ConfigureChannel( 3, AT91C_PWMC_CPRE_MCKB, 0, 0 );    
  for( i = 0; i < 4; i ++ )
  {
    PWMC_EnableChannel( i );
    PWMC_EnableChannelIt( i );
  }

  cmn_platform_init();
  
#if VTMR_NUM_TIMERS > 0
  // Virtual timer initialization
  TC_Configure( AT91C_BASE_TC2, AT91C_TC_CLKS_TIMER_DIV5_CLOCK | AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO );
  AT91C_BASE_TC2->TC_RC = ( BOARD_MCK / 1024 ) / VTMR_FREQ_HZ;
  AIC_DisableIT( AT91C_ID_TC2 );
  AIC_ConfigureIT( AT91C_ID_TC2, 0, ISR_Tc2 );
  AT91C_BASE_TC2->TC_IER = AT91C_TC_CPCS;
  AIC_EnableIT( AT91C_ID_TC2 );  
  TC_Start( AT91C_BASE_TC2 );
#endif  

  // Initialize the system timer
  cmn_systimer_set_base_freq( BOARD_MCK / 16 );
  cmn_systimer_set_interrupt_period_us( SYSTIMER_US_PER_INTERRUPT );
  platform_systimer_init();
    
  return PLATFORM_OK;
} 
Ejemplo n.º 3
0
void vInitialiseTimerForIntQueueTest( void )
{
const uint32_t ulDivider = 128UL, ulTCCLKS = 3UL;

	/* Enable the TC clocks. */
	PMC_EnablePeripheral( ID_TC0 );
	PMC_EnablePeripheral( ID_TC1 );

	/* Configure TC0 channel 0 for a tmrTIMER_0_FREQUENCY frequency and trigger
	on RC compare.  This is part of the IntQTimer test. */
	TC_Configure( TC0, tmrTC0_CHANNEL_0, ulTCCLKS | TC_CMR_CPCTRG );
	TC0->TC_CHANNEL[ tmrTC0_CHANNEL_0 ].TC_RC = ( BOARD_MCK / 2 ) / ( tmrTIMER_0_FREQUENCY * ulDivider );
	TC0->TC_CHANNEL[ tmrTC0_CHANNEL_0 ].TC_IER = TC_IER_CPCS;

	/* Configure TC0 channel 1 for a tmrTIMER_1_FREQUENCY frequency and trigger
	on RC compare.  This is part of the IntQTimer test. */
	TC_Configure( TC0, tmrTC0_CHANNEL_1, ulTCCLKS | TC_CMR_CPCTRG );
	TC0->TC_CHANNEL[ tmrTC0_CHANNEL_1 ].TC_RC = ( BOARD_MCK / 2 ) / ( tmrTIMER_1_FREQUENCY * ulDivider );
	TC0->TC_CHANNEL[ tmrTC0_CHANNEL_1 ].TC_IER = TC_IER_CPCS;

	/* Configure TC1 channel 0 tmrTIMER_2_FREQUENCY frequency and trigger on
	RC compare.  This is the very high frequency timer. */
	TC_Configure( TC1, tmrTC1_CHANNEL_0, ulTCCLKS | TC_CMR_CPCTRG );
	TC1->TC_CHANNEL[ tmrTC1_CHANNEL_0 ].TC_RC = BOARD_MCK / ( tmrTIMER_2_FREQUENCY * ulDivider );
	TC1->TC_CHANNEL[ tmrTC1_CHANNEL_0 ].TC_IER = TC_IER_CPCS;

	/* First setup TC0 interrupt, in which two channels are used. */
    AIC->AIC_SSR = ID_TC0;

	/* Ensure the interrupt is disabled before setting mode and handler. */
    AIC->AIC_IDCR = AIC_IDCR_INTD;
    AIC->AIC_SMR  = AIC_SMR_SRCTYPE_EXT_POSITIVE_EDGE |  tmrLOWER_PRIORITY;
    AIC->AIC_SVR = ( uint32_t ) prvTC0_Handler;

	/* Start with the interrupt clear. */
    AIC->AIC_ICCR = AIC_ICCR_INTCLR;

	/* Do the same for TC1 - which is the high frequency timer. */
    AIC->AIC_SSR = ID_TC1;
    AIC->AIC_IDCR = AIC_IDCR_INTD;
    AIC->AIC_SMR  = AIC_SMR_SRCTYPE_EXT_POSITIVE_EDGE | tmrHIGHER_PRIORITY;
    AIC->AIC_SVR = ( uint32_t ) prvTC1_Handler;
    AIC->AIC_ICCR = AIC_ICCR_INTCLR;

	/* Finally enable the interrupts and start the timers. */
	AIC_EnableIT( ID_TC0 );
	AIC_EnableIT( ID_TC1 );
	TC_Start( TC0, tmrTC0_CHANNEL_0 );
	TC_Start( TC0, tmrTC0_CHANNEL_1 );
	TC_Start( TC1, tmrTC1_CHANNEL_0 );
}
Ejemplo n.º 4
0
void tone(uint32_t ulPin, uint32_t frequency, int32_t duration)
{
		const uint32_t rc = VARIANT_MCK / 256 / frequency; 
		tone_pin = ulPin;
		toggle_count = 0;  // strange  wipe out previous duration
		if (duration > 0 ) toggle_count = 2 * frequency * duration / 1000;
		 else toggle_count = -1;

		if (!TCChanEnabled) {
 			pmc_set_writeprotect(false);
			pmc_enable_periph_clk((uint32_t)TONE_IRQ);
			TC_Configure(chTC, chNo,
				TC_CMR_TCCLKS_TIMER_CLOCK4 |
				TC_CMR_WAVE |         // Waveform mode
				TC_CMR_WAVSEL_UP_RC ); // Counter running up and reset when equals to RC
	
			chTC->TC_CHANNEL[chNo].TC_IER=TC_IER_CPCS;  // RC compare interrupt
			chTC->TC_CHANNEL[chNo].TC_IDR=~TC_IER_CPCS;
			 NVIC_EnableIRQ(TONE_IRQ);
                         TCChanEnabled = 1;
		}
		if (!pinEnabled[ulPin]) {
			pinMode(ulPin, OUTPUT);
			pinEnabled[ulPin] = 1;
		}
		TC_Stop(chTC, chNo);
                TC_SetRC(chTC, chNo, rc);    // set frequency
		TC_Start(chTC, chNo);
}
Ejemplo n.º 5
0
// Constructor
DueTimer::DueTimer(int _timer){
	timer = _timer;

	// Initialize timer
	Timer t = Timers[timer];
	pmc_set_writeprotect(false);
	pmc_enable_periph_clk((uint32_t)Timers[timer].irq);
    TC_Configure(t.tc, t.channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4);
}
Ejemplo n.º 6
0
void Platform::InitialiseInterrupts()
{
  pmc_set_writeprotect(false);
  pmc_enable_periph_clk((uint32_t)TC3_IRQn);
  TC_Configure(TC1, 0, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4);
  TC1->TC_CHANNEL[0].TC_IER=TC_IER_CPCS;
  TC1->TC_CHANNEL[0].TC_IDR=~TC_IER_CPCS;
  SetInterrupt(STANDBY_INTERRUPT_RATE);
}
Ejemplo n.º 7
0
// Helper: set timer clock
static u32 platform_timer_set_clock( unsigned id, u32 clock )
{
  unsigned i, mini = 0;
  
  for( i = 0; i < 5; i ++ )
    if( ABSDIFF( clock, BOARD_MCK / clkdivs[ i ] ) < ABSDIFF( clock, BOARD_MCK / clkdivs[ mini ] ) )
      mini = i;
  TC_Configure( ( AT91S_TC* )timer_base[ id ], mini | AT91C_TC_WAVE );  
  return BOARD_MCK / clkdivs[ mini ];
}
Ejemplo n.º 8
0
DueTimer& DueTimer::setFrequency(double frequency){
	/*
		Set the timer frequency (in Hz)
	*/

	// Prevent negative frequencies
	if(frequency <= 0) { frequency = 1; }

	// Remember the frequency — see below how the exact frequency is reported instead
	//_frequency[timer] = frequency;

	// Get current timer configuration
	Timer t = Timers[timer];

	uint32_t rc = 0;
	uint8_t clock;

	// Tell the Power Management Controller to disable 
	// the write protection of the (Timer/Counter) registers:
	pmc_set_writeprotect(false);

	// Enable clock for the timer
	pmc_enable_periph_clk((uint32_t)t.irq);

	// Find the best clock for the wanted frequency
	clock = bestClock(frequency, rc);

	switch (clock) {
	  case TC_CMR_TCCLKS_TIMER_CLOCK1:
	    _frequency[timer] = (double)VARIANT_MCK / 2.0 / (double)rc;
	    break;
	  case TC_CMR_TCCLKS_TIMER_CLOCK2:
	    _frequency[timer] = (double)VARIANT_MCK / 8.0 / (double)rc;
	    break;
	  case TC_CMR_TCCLKS_TIMER_CLOCK3:
	    _frequency[timer] = (double)VARIANT_MCK / 32.0 / (double)rc;
	    break;
	  default: // TC_CMR_TCCLKS_TIMER_CLOCK4
	    _frequency[timer] = (double)VARIANT_MCK / 128.0 / (double)rc;
	    break;
	}

	// Set up the Timer in waveform mode which creates a PWM
	// in UP mode with automatic trigger on RC Compare
	// and sets it up with the determined internal clock as clock input.
	TC_Configure(t.tc, t.channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | clock);
	// Reset counter and fire interrupt when RC value is matched:
	TC_SetRC(t.tc, t.channel, rc);
	// Enable the RC Compare Interrupt...
	t.tc->TC_CHANNEL[t.channel].TC_IER=TC_IER_CPCS;
	// ... and disable all others.
	t.tc->TC_CHANNEL[t.channel].TC_IDR=~TC_IER_CPCS;

	return *this;
}
Ejemplo n.º 9
0
void TimerInit()
{
	PMC_EnablePeripheral(AT91C_ID_TC0);				// enable the Timer Counter from PMC
	TC_Configure(AT91C_BASE_TC0, AT91C_TC_CPCTRG);	// Configure TC-0 with RC compare trig.
	AT91C_BASE_TC0->TC_RC = 24000;					// Interrupt every 0.001s
	TC_Start(AT91C_BASE_TC0);							// start the timer
	
	AIC_ConfigureIT(AT91C_ID_TC0, AT91C_AIC_PRIOR_LOWEST, ISR_TC0);
	AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS;
	AIC_EnableIT(AT91C_ID_TC0);
}
Ejemplo n.º 10
0
void startTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency) {
	pmc_set_writeprotect(false);
	pmc_enable_periph_clk((uint32_t)irq);
	TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4);
	uint32_t rc = VARIANT_MCK/128/frequency; //128 because we selected TIMER_CLOCK4 above
	tc->TC_CHANNEL[channel].TC_RA = rc/2;
	tc->TC_CHANNEL[channel].TC_RC = rc;
	TC_Start(tc, channel);
	tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;
	tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;
	NVIC_EnableIRQ(irq);
}
Ejemplo n.º 11
0
void vInitialiseTimerForIntQueueTest( void )
{
    const uint32_t ulDivider = 128UL, ulTCCLKS = 3UL;

    /* Enable the TC clocks. */
    PMC_EnablePeripheral( ID_TC0 );
    PMC_EnablePeripheral( ID_TC1 );

    /* Configure TC0 channel 0 for a tmrTIMER_0_FREQUENCY frequency and trigger
    on RC compare.  This is part of the IntQTimer test. */
    TC_Configure( TC0, tmrTC0_CHANNEL_0, ulTCCLKS | TC_CMR_CPCTRG );
    TC0->TC_CHANNEL[ tmrTC0_CHANNEL_0 ].TC_RC = ( configCPU_CLOCK_HZ / 2 ) / ( tmrTIMER_0_FREQUENCY * ulDivider );
    TC0->TC_CHANNEL[ tmrTC0_CHANNEL_0 ].TC_IER = TC_IER_CPCS;

    /* Configure TC0 channel 1 for a tmrTIMER_1_FREQUENCY frequency and trigger
    on RC compare.  This is part of the IntQTimer test. */
    TC_Configure( TC0, tmrTC0_CHANNEL_1, ulTCCLKS | TC_CMR_CPCTRG );
    TC0->TC_CHANNEL[ tmrTC0_CHANNEL_1 ].TC_RC = ( configCPU_CLOCK_HZ / 2 ) / ( tmrTIMER_1_FREQUENCY * ulDivider );
    TC0->TC_CHANNEL[ tmrTC0_CHANNEL_1 ].TC_IER = TC_IER_CPCS;

    /* Configure and enable TC0 interrupt on RC compare. */
    NVIC_SetPriority( TC0_IRQn, tmrLOWER_PRIORITY );
    NVIC_ClearPendingIRQ( TC0_IRQn );
    NVIC_EnableIRQ( TC0_IRQn );

    /* Configure TC1 channel 0 tmrTIMER_2_FREQUENCY frequency and trigger on
    RC compare.  This is the very high frequency timer. */
    TC_Configure( TC1, tmrTC1_CHANNEL_0, ulTCCLKS | TC_CMR_CPCTRG );
    TC1->TC_CHANNEL[ tmrTC1_CHANNEL_0 ].TC_RC = ( configCPU_CLOCK_HZ / 2 ) / ( tmrTIMER_2_FREQUENCY * ulDivider );
    TC1->TC_CHANNEL[ tmrTC1_CHANNEL_0 ].TC_IER = TC_IER_CPCS;

    /* Configure and enable TC1 interrupt on RC compare */
//	NVIC_SetPriority( TC1_IRQn, tmrHIGHER_PRIORITY );
//    NVIC_ClearPendingIRQ( TC1_IRQn );
//    NVIC_EnableIRQ( TC1_IRQn );

    TC_Start( TC0, tmrTC0_CHANNEL_0 );
    TC_Start( TC0, tmrTC0_CHANNEL_1 );
//	TC_Start( TC1, tmrTC1_CHANNEL_0 );
}
Ejemplo n.º 12
0
/**
 *  \brief TC0 configuration
 *
 * Configures Timer Counter 0 (TC0) to generate an interrupt every second.
 *
 */
static void ConfigureTc0( void )
{

    /* Enable TC0 peripheral clock*/
    PMC_EnablePeripheral( ID_TC0 ) ;

    /* Configure TC for a 1s (= 1Hz) tick*/
    TC_Configure(TC0,0, 0x4 | TC_CMR0_ACPC_SET | TC_CMR0_WAVE
            | TC_CMR0_ACPA_CLEAR | (0x2 << 13));

    /* 50% duty ,1s frequency*/
    TC0->TC_CHANNEL[0].TC_RA = SAMPLING_PERIOD/2;
    TC0->TC_CHANNEL[0].TC_RC = SAMPLING_PERIOD;
}
Ejemplo n.º 13
0
/**
 * Configure TC0 to generate an interrupt every 4ms
 */
static void ConfigureTc0(void)
{
    uint32_t div, tcclks;

    /* Enable TC0 peripheral */
    PMC_EnablePeripheral(ID_TC0);
    /* Configure TC0 for 250Hz frequency and trigger on RC compare */
    TC_FindMckDivisor(250, BOARD_MCK, &div, &tcclks, BOARD_MCK);
    TC_Configure(TC0, 0, tcclks | TC_CMR_CPCTRG);
    TC0->TC_CHANNEL[0].TC_RC = (BOARD_MCK / div) / 250;
    /* Configure and enable interrupt on RC compare */
    NVIC_EnableIRQ(TC0_IRQn);
    TC0->TC_CHANNEL[0].TC_IER = TC_IER_CPCS;
    /* Start TC as event timer */
    TC_Start(TC0, 0);
}
Ejemplo n.º 14
0
static void _ConfigureTc0( void )
{
    /* Enable TC0 peripheral clock*/
    PMC_EnablePeripheral( ID_TC0 ) ;

    /* Configure TC for a 1s (= 1Hz) tick*/
    TC_Configure( TC0, 0, 0x4 | TC_CMR_CPCTRG ) ;

    TC0->TC_CHANNEL[0].TC_RC = 32768 ;

    /* Configure interrupt on RC compare*/
    TC0->TC_CHANNEL[0].TC_IER = TC_SR_CPCS ;

    NVIC_EnableIRQ( TC0_IRQn ) ;

}
Ejemplo n.º 15
0
void BaseDMD::begin()
{
  beginNoTimer(); // Do any generic setup

  NVIC_DisableIRQ(TC7_IRQn);
  register_running_dmd(this);
  pmc_set_writeprotect(false);
  pmc_enable_periph_clk(TC7_IRQn);
  // Timer 7 is TC2, channel 1
  TC_Configure(TC2, 1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4); // counter up, /128 divisor
  TC_SetRC(TC2, 1, 2500); // approx 4ms at /128 divisor
  TC2->TC_CHANNEL[1].TC_IER=TC_IER_CPCS;

  NVIC_ClearPendingIRQ(TC7_IRQn);
  NVIC_EnableIRQ(TC7_IRQn);
  TC_Start(TC2, 1);
}
Ejemplo n.º 16
0
static void _initISR(Tc *tc, uint32_t channel, uint32_t id, IRQn_Type irqn) {
  pmc_enable_periph_clk(id);
  TC_Configure(tc, channel,
    TC_CMR_TCCLKS_TIMER_CLOCK3 | // MCK/32
    TC_CMR_WAVE |                // Waveform mode
    TC_CMR_WAVSEL_UP_RC );       // Counter running up and reset when equals to RC

  /* 84MHz, MCK/32, for 1.5ms: 3937 */
  TC_SetRA(tc, channel, 2625); // 1ms

  /* Configure and enable interrupt */
  NVIC_EnableIRQ(irqn);
  // TC_IER_CPAS: RA Compare
  tc->TC_CHANNEL[channel].TC_IER = TC_IER_CPAS;

  // Enables the timer clock and performs a software reset to start the counting
  TC_Start(tc, channel);
}
Ejemplo n.º 17
0
/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBPortTimersInit( USHORT usTim1Timerout50us )
{
#if MB_TIMER_DEBUG == 1
    PIO_Configure( xTimerDebugPins, PIO_LISTSIZE( xTimerDebugPins ) );
#endif
    NVIC_DisableIRQ( TCXIRQ );

    PMC_EnablePeripheral( ID_TC0 );
    TC_Configure( TCX, 0, TC_CMRX_WAVE | TC_CMRX_TCCLKS_TIMER_DIV4_CLOCK | TC_CMRX_WAVESEL_UP_RC | TC_CMRX_CPCSTOP );
    TCX->TC_CHANNEL[TCCHANNEL].TC_RA = ( MB_TIMER_TICKS * usTim1Timerout50us ) / ( MB_50US_TICKS );
    TCX->TC_CHANNEL[TCCHANNEL].TC_RC = ( MB_TIMER_TICKS * usTim1Timerout50us ) / ( MB_50US_TICKS );

    NVIC_ClearPendingIRQ( TCXIRQ );
    NVIC_SetPriority( TCXIRQ, 0xF << 4 );
    NVIC_EnableIRQ( TCXIRQ );

    return TRUE;
}
Ejemplo n.º 18
0
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
  Tc *tc = TimerConfig[timer_num].pTimerRegs;
  IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
  uint32_t channel = TimerConfig[timer_num].channel;

  pmc_set_writeprotect(false);
  pmc_enable_periph_clk((uint32_t)irq);
  NVIC_SetPriority(irq, TimerConfig [timer_num].priority);

  TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1);

  TC_SetRC(tc, channel, VARIANT_MCK / 2 / frequency);
  TC_Start(tc, channel);

  // enable interrupt on RC compare
  tc->TC_CHANNEL[channel].TC_IER = TC_IER_CPCS;

  NVIC_EnableIRQ(irq);
}
Ejemplo n.º 19
0
/*------------------------------------------------------------------------------
Name:           startTimer
parameters:     tc - timer counter
                channel - timer channel
                irq - isr request
                frequency - frequency of inetrrupts
description:    initializes timer for periodic interrupt generation
------------------------------------------------------------------------------*/
void BldcControl::configureTimerInterrupt(Tc *tc,
                                          uint32_t channel,
                                          IRQn_Type irq,
                                          uint32_t frequency)
{
        pmc_set_writeprotect(false);
        pmc_enable_periph_clk((uint32_t)irq);
        TC_Configure(tc,
                     channel,
                     TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC |
                        TC_CMR_TCCLKS_TIMER_CLOCK4);
        uint32_t rc = VARIANT_MCK/128/frequency; //128 because we selected
                                                 //TIMER_CLOCK4 above
        TC_SetRA(tc, channel, rc/2); //50% high, 50% low
        TC_SetRC(tc, channel, rc);
        TC_Start(tc, channel);
        tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;
        tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;
        NVIC_EnableIRQ(irq);
}
Ejemplo n.º 20
0
//--------------------------------------------------
// Init Timer 1 for Soft PWM (Hotend 1 & 2)
//--------------------------------------------------
void ConfigureTc_1(void)
{

	// Enable peripheral clock
	AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_TC1;
	unsigned int freq=10000; 
	// Configure TC for a 10 kHz frequency and trigger on RC compare
	//TC_FindMckDivisor(freq, BOARD_MCK, &div, &tcclks);
	TC_Configure(AT91C_BASE_TC1, 3 | AT91C_TC_CPCTRG);
	AT91C_BASE_TC1->TC_RB = 3;
	AT91C_BASE_TC1->TC_RC = (BOARD_MCK / 128) / freq; // timerFreq / desiredFreq

	// Configure and enable interrupt on RC compare
	//IRQ_ConfigureIT(AT91C_ID_TC1, 2, TC1_IrqHandler);
	AT91C_BASE_TC1->TC_IER = AT91C_TC_CPCS | AT91C_TC_CPBS;
	IRQ_EnableIT(AT91C_ID_TC1);

	// Start the counter if LED is enabled.
	TC_Start(AT91C_BASE_TC1);

}
Ejemplo n.º 21
0
Archivo: main.c Proyecto: gstroe/Arm
/**
 *  Configure Timer Counter 0 to generate an interrupt every 250ms.
 */
static void _ConfigureTc(void)
{
	uint32_t div;
	uint32_t tcclks;

	/** Enable peripheral clock. */
	PMC_EnablePeripheral(ID_TC0);
	/** Configure TC for a 4Hz frequency and trigger on RC compare. */
	TC_FindMckDivisor(4, BOARD_MCK, &div, &tcclks, BOARD_MCK);

	TC_Configure(TC0, 0, tcclks | TC_CMR_CPCTRG);
	TC0->TC_CHANNEL[0].TC_RC = (BOARD_MCK / div) / 4;

	/* Configure and enable interrupt on RC compare */
	NVIC_ClearPendingIRQ(TC0_IRQn);
	NVIC_EnableIRQ(TC0_IRQn);

	TC0->TC_CHANNEL[0].TC_IER = TC_IER_CPCS;

	/** Start the counter */
	TC_Start(TC0, 0);
}
Ejemplo n.º 22
0
static void _ConfigureTc0( uint32_t freq )
{
    /* Enable TC0 peripheral clock*/
    PMC_EnablePeripheral( ID_TC0 ) ;

    /*
	 	CLK SRC: MCK/2, 64MHz/2 = 32MHz.
	 	RC Compare trigger, RC Compare resets the counter and starts the counter clock.
	 */
    TC_Configure( TC0, 0, TC_CMR_TCCLKS_TIMER_CLOCK1 | TC_CMR_CPCTRG ) ;

    TC0->TC_CHANNEL[0].TC_RC = 32*100 ;

    /* Configure interrupt on RC compare*/
    TC0->TC_CHANNEL[0].TC_IER = TC_SR_CPCS ;

    NVIC_DisableIRQ( TC0_IRQn ) ;
    NVIC_ClearPendingIRQ( TC0_IRQn ) ;
    NVIC_SetPriority( TC0_IRQn, 0 ) ;
    NVIC_EnableIRQ( TC0_IRQn ) ;

}
Ejemplo n.º 23
0
int platform_init()
{
  int i;
   
  unsigned int mode = AT91C_US_USMODE_NORMAL | AT91C_US_CLKS_CLOCK | AT91C_US_CHRL_8_BITS | 
      AT91C_US_PAR_NONE | AT91C_US_NBSTOP_1_BIT | AT91C_US_CHMODE_NORMAL;
      
  // Enable the peripherals we use in the PMC
  PMC_EnablePeripheral(AT91C_ID_US0);  
  PMC_EnablePeripheral(AT91C_ID_US1);
  PMC_EnablePeripheral(AT91C_ID_PIOA);
  PMC_EnablePeripheral(AT91C_ID_PIOB);
  PMC_EnablePeripheral(AT91C_ID_TC0);
  PMC_EnablePeripheral(AT91C_ID_TC1);
  PMC_EnablePeripheral(AT91C_ID_TC2);
 
  // Configure pins
  PIO_Configure(platform_uart_pins[ 0 ], PIO_LISTSIZE(platform_uart_pins[ 0 ]));
    
  // Configure the USART in the desired mode @115200 bauds
  USART_Configure(AT91C_BASE_US0, mode, 115200, BOARD_MCK);
  
  // Enable receiver & transmitter
  USART_SetTransmitterEnabled(AT91C_BASE_US0, 1);
  USART_SetReceiverEnabled(AT91C_BASE_US0, 1);  
  
  // Configure the timers
  AT91C_BASE_TCB->TCB_BMR = 7;
  for( i = 0; i < 3; i ++ )
    TC_Configure( ( AT91S_TC* )timer_base[ i ], AT91C_TC_CLKS_TIMER_DIV5_CLOCK | AT91C_TC_WAVE );
  
  // Set the send/recv functions                          
  std_set_send_func( uart_send );
  std_set_get_func( uart_recv );
    
  return PLATFORM_OK;
} 
Ejemplo n.º 24
0
/**
 * Initialize for timing operation
 */
void sys_init_timing(void)
{
    uint32_t div;
    uint32_t tcclks;

    /* Clear tick value */
    dwClockTick = 0;

    /* Enable peripheral clock. */
    PMC_EnablePeripheral( ID_TC0 ) ;

    /* Configure TC for a CLOCK_CONF_SECOND frequency. */
    TC_FindMckDivisor( CLOCK_CONF_SECOND, BOARD_MCK, &div, &tcclks, BOARD_MCK );
    TC_Configure( TC0, 0, tcclks | TC_CMR_CPCTRG );
    TC0->TC_CHANNEL[0].TC_RC = BOARD_MCK / (CLOCK_CONF_SECOND * div);

     /* Configure and enable interrupt on RC compare */    
    NVIC_ClearPendingIRQ(TC0_IRQn);
    NVIC_EnableIRQ(TC0_IRQn);
    
    TC0->TC_CHANNEL[ 0 ].TC_IER = TC_IER_CPCS ;
    /* Start timer */
    TC_Start( TC0, 0 );
}
Ejemplo n.º 25
0
// Set up all timer interrupts
void HAL::setupTimer() {
  uint32_t     tc_count, tc_clock;

  pmc_set_writeprotect(false);

  // set 3 bits for interrupt group priority, 1 bits for sub-priority
  //NVIC_SetPriorityGrouping(4);

#if USE_ADVANCE
  // Timer for extruder control
  pmc_enable_periph_clk(EXTRUDER_TIMER_IRQ);  // enable power to timer
  //NVIC_SetPriority((IRQn_Type)EXTRUDER_TIMER_IRQ, NVIC_EncodePriority(4, 4, 1));
  NVIC_SetPriority((IRQn_Type)EXTRUDER_TIMER_IRQ, 6);

  // count up to value in RC register using given clock
  TC_Configure(EXTRUDER_TIMER, EXTRUDER_TIMER_CHANNEL, TC_CMR_WAVSEL_UP_RC | TC_CMR_WAVE | TC_CMR_TCCLKS_TIMER_CLOCK3);

  TC_SetRC(EXTRUDER_TIMER, EXTRUDER_TIMER_CHANNEL, (F_CPU_TRUE / 32) / EXTRUDER_CLOCK_FREQ); // set frequency 43 for 60000Hz
  TC_Start(EXTRUDER_TIMER, EXTRUDER_TIMER_CHANNEL);           // start timer running

  // enable RC compare interrupt
  EXTRUDER_TIMER->TC_CHANNEL[EXTRUDER_TIMER_CHANNEL].TC_IER = TC_IER_CPCS;
  // clear the "disable RC compare" interrupt
  EXTRUDER_TIMER->TC_CHANNEL[EXTRUDER_TIMER_CHANNEL].TC_IDR = ~TC_IER_CPCS;

  // allow interrupts on timer
  NVIC_EnableIRQ((IRQn_Type)EXTRUDER_TIMER_IRQ);
#endif
  // Regular interrupts for heater control etc
  pmc_enable_periph_clk(PWM_TIMER_IRQ);
  //NVIC_SetPriority((IRQn_Type)PWM_TIMER_IRQ, NVIC_EncodePriority(4, 6, 0));
  NVIC_SetPriority((IRQn_Type)PWM_TIMER_IRQ, 15);

  TC_FindMckDivisor(PWM_CLOCK_FREQ, F_CPU_TRUE, &tc_count, &tc_clock, F_CPU_TRUE);
  TC_Configure(PWM_TIMER, PWM_TIMER_CHANNEL, TC_CMR_WAVSEL_UP_RC | TC_CMR_WAVE | tc_clock);

  TC_SetRC(PWM_TIMER, PWM_TIMER_CHANNEL, (F_CPU_TRUE / tc_count) / PWM_CLOCK_FREQ);
  TC_Start(PWM_TIMER, PWM_TIMER_CHANNEL);

  PWM_TIMER->TC_CHANNEL[PWM_TIMER_CHANNEL].TC_IER = TC_IER_CPCS;
  PWM_TIMER->TC_CHANNEL[PWM_TIMER_CHANNEL].TC_IDR = ~TC_IER_CPCS;
  NVIC_EnableIRQ((IRQn_Type)PWM_TIMER_IRQ);

  // Timer for stepper motor control
  pmc_enable_periph_clk(TIMER1_TIMER_IRQ );
  //NVIC_SetPriority((IRQn_Type)TIMER1_TIMER_IRQ, NVIC_EncodePriority(4, 7, 1)); // highest priority - no surprises here wanted
  NVIC_SetPriority((IRQn_Type)TIMER1_TIMER_IRQ,2); // highest priority - no surprises here wanted

  TC_Configure(TIMER1_TIMER, TIMER1_TIMER_CHANNEL, TC_CMR_WAVSEL_UP_RC |
               TC_CMR_WAVE | TC_CMR_TCCLKS_TIMER_CLOCK1);

  TC_SetRC(TIMER1_TIMER, TIMER1_TIMER_CHANNEL, (F_CPU_TRUE / TIMER1_PRESCALE) / TIMER1_CLOCK_FREQ);
  TC_Start(TIMER1_TIMER, TIMER1_TIMER_CHANNEL);

  TIMER1_TIMER->TC_CHANNEL[TIMER1_TIMER_CHANNEL].TC_IER = TC_IER_CPCS;
  TIMER1_TIMER->TC_CHANNEL[TIMER1_TIMER_CHANNEL].TC_IDR = ~TC_IER_CPCS;
  NVIC_EnableIRQ((IRQn_Type)TIMER1_TIMER_IRQ);

  // Servo control
#if FEATURE_SERVO
#if SERVO0_PIN > -1
  SET_OUTPUT(SERVO0_PIN);
  WRITE(SERVO0_PIN, LOW);
#endif
#if SERVO1_PIN > -1
  SET_OUTPUT(SERVO1_PIN);
  WRITE(SERVO1_PIN, LOW);
#endif
#if SERVO2_PIN > -1
  SET_OUTPUT(SERVO2_PIN);
  WRITE(SERVO2_PIN, LOW);
#endif
#if SERVO3_PIN > -1
  SET_OUTPUT(SERVO3_PIN);
  WRITE(SERVO3_PIN, LOW);
#endif
  pmc_enable_periph_clk(SERVO_TIMER_IRQ );
  //NVIC_SetPriority((IRQn_Type)SERVO_TIMER_IRQ, NVIC_EncodePriority(4, 5, 0));
  NVIC_SetPriority((IRQn_Type)SERVO_TIMER_IRQ,4);

  TC_Configure(SERVO_TIMER, SERVO_TIMER_CHANNEL, TC_CMR_WAVSEL_UP_RC |
               TC_CMR_WAVE | TC_CMR_TCCLKS_TIMER_CLOCK1);

  TC_SetRC(SERVO_TIMER, SERVO_TIMER_CHANNEL, (F_CPU_TRUE / SERVO_PRESCALE) / SERVO_CLOCK_FREQ);
  TC_Start(SERVO_TIMER, SERVO_TIMER_CHANNEL);

  SERVO_TIMER->TC_CHANNEL[SERVO_TIMER_CHANNEL].TC_IER = TC_IER_CPCS;
  SERVO_TIMER->TC_CHANNEL[SERVO_TIMER_CHANNEL].TC_IDR = ~TC_IER_CPCS;
  NVIC_EnableIRQ((IRQn_Type)SERVO_TIMER_IRQ);
#endif
}
Ejemplo n.º 26
0
static int8_t toneBegin(uint8_t _pin)
{
  int8_t _timer = -1;

  // if we're already using the pin, the timer should be configured.  
  for (int i = 0; i < AVAILABLE_TONE_PINS; i++) {
    if (tone_pins[i] == _pin) {
      return pgm_read_byte(tone_pin_to_timer_PGM + i);
    }
  }
  
  // search for an unused timer.
  for (int i = 0; i < AVAILABLE_TONE_PINS; i++) {
    if (tone_pins[i] == 255) {
      tone_pins[i] = _pin;
      _timer = pgm_read_byte(tone_pin_to_timer_PGM + i);
      break;
    }
  }
  
  if (_timer != -1)
  {
    // Set timer specific stuff
    // All timers in CTC mode
    // 8 bit timers will require changing prescalar values,
    // whereas 16 bit timers are set to either ck/1 or ck/64 prescalar
    switch (_timer)
    {
      #if defined(TCCR0A) && defined(TCCR0B)
      case 0:
        // 8 bit timer
        TCCR0A = 0;
        TCCR0B = 0;
        bitWrite(TCCR0A, WGM01, 1);
        bitWrite(TCCR0B, CS00, 1);
        timer0_pin_port = portOutputRegister(digitalPinToPort(_pin));
        timer0_pin_mask = digitalPinToBitMask(_pin);
        break;
      #endif

      #if defined(TCCR1A) && defined(TCCR1B) && defined(WGM12)
      case 1:
        // 16 bit timer
        TCCR1A = 0;
        TCCR1B = 0;
        bitWrite(TCCR1B, WGM12, 1);
        bitWrite(TCCR1B, CS10, 1);
        timer1_pin_port = portOutputRegister(digitalPinToPort(_pin));
        timer1_pin_mask = digitalPinToBitMask(_pin);
        break;
      #endif

      #if defined(TCCR2A) && defined(TCCR2B)
      case 2:
        // 8 bit timer
        TCCR2A = 0;
        TCCR2B = 0;
        bitWrite(TCCR2A, WGM21, 1);
        bitWrite(TCCR2B, CS20, 1);
        timer2_pin_port = portOutputRegister(digitalPinToPort(_pin));
        timer2_pin_mask = digitalPinToBitMask(_pin);
        break;
      #endif

      #if defined(TCCR3A) && defined(TCCR3B) &&  defined(TIMSK3)
      case 3:
        // 16 bit timer
        TCCR3A = 0;
        TCCR3B = 0;
        bitWrite(TCCR3B, WGM32, 1);
        bitWrite(TCCR3B, CS30, 1);
        timer3_pin_port = portOutputRegister(digitalPinToPort(_pin));
        timer3_pin_mask = digitalPinToBitMask(_pin);
        break;
      #endif

      #if defined(TCCR4A) && defined(TCCR4B) &&  defined(TIMSK4)
      case 4:
        // 16 bit timer
        TCCR4A = 0;
        TCCR4B = 0;
        #if defined(WGM42)
          bitWrite(TCCR4B, WGM42, 1);
        #elif defined(CS43)
          #warning this may not be correct
          // atmega32u4
          bitWrite(TCCR4B, CS43, 1);
        #endif
        bitWrite(TCCR4B, CS40, 1);
        timer4_pin_port = portOutputRegister(digitalPinToPort(_pin));
        timer4_pin_mask = digitalPinToBitMask(_pin);
        break;
      #endif

      #if defined(TCCR5A) && defined(TCCR5B) &&  defined(TIMSK5)
      case 5:
        // 16 bit timer
        TCCR5A = 0;
        TCCR5B = 0;
        bitWrite(TCCR5B, WGM52, 1);
        bitWrite(TCCR5B, CS50, 1);
        timer5_pin_port = portOutputRegister(digitalPinToPort(_pin));
        timer5_pin_mask = digitalPinToBitMask(_pin);
        break;
      #endif

      #if defined(TC0) && defined(TC1) &&  defined(TC2)
      case 6:
        // 16 bit timer
        pmc_set_writeprotect(false);
        pmc_enable_periph_clk((uint32_t)TC3_IRQn);

        TC_Configure(TC1, 0,
            TC_CMR_TCCLKS_TIMER_CLOCK4 |
            TC_CMR_WAVE |          // Waveform mode
            TC_CMR_WAVSEL_UP_RC ); // Counter running up and reset when equals to RC

        TC1->TC_CHANNEL[0].TC_IER=TC_IER_CPCS;  // RC compare interrupt
        TC1->TC_CHANNEL[0].TC_IDR=~TC_IER_CPCS;
        NVIC_EnableIRQ(TC3_IRQn);
        timer6_pin_port = portOutputRegister(digitalPinToPort(_pin));
        timer6_pin_mask = digitalPinToBitMask(_pin);
        break;
      #endif
    }
  }

  return _timer;
}
Ejemplo n.º 27
0
/**
 * Configure the TC0 and DACC for audio output.
 * \param sampleRate Audio sample rate.
 * \param nbChannels Number of audio channels.
 * \param mck        MCK frequence.
 */
static void ConfigureAudioPlay(uint32_t sampleRate,
                               uint8_t nbChannels,
                               uint32_t mck)
{
    uint32_t div = 2;
    uint32_t tcclks = TC_CMR_TCCLKS_TIMER_CLOCK1;
    uint32_t freq = sampleRate * nbChannels;
    double   ra, rc;

    /* Enable TC0 Peripheral */
    PMC_EnablePeripheral(ID_TC0);
    {
        uint32_t divs[5] = {2, 8, 32, 128,BOARD_MCK / 32768};
        uint8_t i = 0;
        divs[4] = mck/32768;
        /* Minimize DIV & Maxmize RC for better waveform */
        while(freq < ((mck / divs[i]) / 65536)) {
            ++ i;
            if (i == 5) {
                TRACE_FATAL("Cann't find TC0 divisor!\n\r");
            }
        }
        div = divs[i];
        tcclks = i;
    }
    /* Configure TC for tioa output: 48M -> 48K*2 */
    TC_Configure(TC0,0, tcclks /*MCK/2*/
                 | TC_CMR_ACPC_SET
                 | TC_CMR_WAVE
                 | TC_CMR_ACPA_CLEAR
                 | TC_CMR_CPCTRG);
    /* 50% duty ,freq frequency*/
    ra = (((double)mck/div)/(freq*2) + 0.5 );
    rc = (((double)mck/div)/(freq)   + 0.99);
    TC0->TC_CHANNEL[0].TC_RA = (uint32_t)ra;
    TC0->TC_CHANNEL[0].TC_RC = (uint32_t)ra*2;
    defaultRA = (uint32_t)ra;

    printf("-I- MCK %dKHz, Div %d(%x), RA: %d*.01(%x), RC: %d*.01(%x)\n\r",
           (int)mck/1000, (int)div, (unsigned int)div,
           (int)(ra*100), (int)ra, (int)(rc*100), (int)rc);

    /* Initialize DACC with HW as trigger */
    DACC_Initialize( DACC, ID_DACC,
                     1,
                     1,
                     0, /* DACC_MR_WORD_HALF */
                     0,
                     BOARD_MCK,
                     8,
                     CHANNEL_R,
                     1,
                     16);
    /* channel number is in the first 4 significant bits*/
    DACC->DACC_MR |= DACC_MR_TAG;
    /* disable PDC for DAC */
    DACC->DACC_PTCR = DACC_PTCR_TXTDIS;
    /* Mute */
    AudioPlayEnable(0);
    /* Enable DACC ISR */
    NVIC_EnableIRQ(DACC_IRQn);
}
Ejemplo n.º 28
0
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);
}
Ejemplo n.º 29
0
void ADCSampler::begin(unsigned int samplingRate)
{
  this->sampleingRate = sampleingRate;
  // Turning devices Timer on.
  pmc_enable_periph_clk(ID_TC0); 


  // Configure timer
  TC_Configure(TC0, 0, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_SET | TC_CMR_ASWTRG_CLEAR | TC_CMR_TCCLKS_TIMER_CLOCK1);

  // It is good to have the timer 0 on PIN2, good for Debugging 
  //int result = PIO_Configure( PIOB, PIO_PERIPH_B, PIO_PB25B_TIOA0, PIO_DEFAULT);

  // Configure ADC pin A7
  //  the below code is taken from adc_init(ADC, SystemCoreClock, ADC_FREQ_MAX, ADC_STARTUP_FAST);

  ADC->ADC_CR = ADC_CR_SWRST;                            // Reset the controller.
  ADC->ADC_MR = 0;                                       // Reset Mode Register.
  ADC->ADC_PTCR = (ADC_PTCR_RXTDIS | ADC_PTCR_TXTDIS);   // Reset PDC transfer.
  ADC->ADC_MR |= ADC_MR_PRESCAL(3);                      // ADC clock = MSCK/((PRESCAL+1)*2), 13 -> 750000 Sps
  ADC->ADC_MR |= ADC_MR_STARTUP_SUT0;                    // What is this by the way?
  ADC->ADC_MR |= ADC_MR_TRACKTIM(15);
  ADC->ADC_MR |= ADC_MR_TRANSFER(1);
  ADC->ADC_MR |= ADC_MR_TRGEN_EN;                         // Hardware trigger selected by TRGSEL field is enabled. Включен аппаратный триггер, выбранный по полю TRGSEL.
  ADC->ADC_MR |= ADC_MR_TRGSEL_ADC_TRIG1;                 // selecting TIOA0 as trigger.
  ADC->ADC_MR |= ADC_MR_LOWRES_BITS_12;                   // brief (ADC_MR) 12-bit resolution 
  //ADC->ADC_ACR |= ADC_ACR_TSON;                         // Включить датчик температуры    
 
  ADC->ADC_CHER = ADC_CHANNELS;                           // Записать контролируемые входа
  ADC->ADC_CHDR = ADC_CHANNELS_DIS;                       // Отключить не используемые входа
  ADC->ADC_EMR = ADC_EMR_CMPMODE_IN                       // Генерирует событие, когда преобразованные данные пересекают окно сравнения.
	//  | ADC_EMR_CMPSEL(4)                               // Compare channel 4 = A3
	  | ADC_EMR_CMPALL                                    // Compare ALL channel
	  | ADC_EMR_CMPFILTER(0);                             // Количество последовательных событий сравнения, необходимых для повышения флага = CMPFILTER + 1
														  // При запрограммированном значении 0 флаг увеличивается, как только происходит событие.

  ADC->ADC_CWR = ADC_CWR_LOWTHRES(_compare_Low) | ADC_CWR_HIGHTHRES(_compare_High); // Установить высокий и низкий порог компаратора АЦП

  //ADC->ADC_SEQR1 = 0x01234567;                            // использовать A0 до A7 в порядке в массив
  //ADC->ADC_SEQR2 = 0x00dcba00;                            // использовать для А8 А11 следующие действия по порядку в массив  

  /* Interupts */
  ADC->ADC_IDR = ~ADC_IDR_ENDRX;                        // сбросить регистры прерывания по готовности данных.
  ADC->ADC_IDR = ~ADC_IDR_COMPE;                        // сбросить регистры копаратора.
  ADC->ADC_IER =  ADC_IER_ENDRX;                        // Включить прерывание по готовности данных.
 // ADC->ADC_IER =  ADC_IER_COMPE;                        // Прерывание по совпадению сравнения компаратором
  ADC->ADC_ISR = ~ADC_ISR_COMPE;                        // ADC Interrupt Status Register Обнулить ошибку сравнения с момента последнего чтения ADC_ISR.
  /* Waiting for ENDRX as end of the transfer is set
    when the current DMA transfer is done (RCR = 0), i.e. it doesn't include the
    next DMA transfer.

    If we trigger on RXBUFF This flag is set if there is no more DMA transfer in
    progress (RCR = RNCR = 0). Hence we may miss samples.

	Ожидание окончания ENDRX в конце передачи
	когда выполняется текущая передача DMA (RCR = 0), то есть она не включает следующая передача DMA.
    Если мы запускаем RXBUFF, этот флаг устанавливается, если больше нет передачи DMA в прогресс (RCR = RNCR = 0). 
	Следовательно, мы можем пропустить образцы.
  */

  
  unsigned int cycles = 42000000 / samplingRate;

  /*  timing of ADC */
  TC_SetRC(TC0, 0, cycles);                             // TIOA0 goes HIGH on RC.
  TC_SetRA(TC0, 0, cycles / 2);                         // TIOA0 goes LOW  on RA.

  // We have to reinitalise just in case the Sampler is stopped and restarted...
  // Мы должны приступить к реинициализировать на случай, если Sampler остановлен и перезапущен ...
  dataReady = false;
  dataHigh = false;                       // Признак срабатывания компаратора
  adcDMAIndex = 0;
  adcTransferIndex = 0;
  for (int i = 0; i < NUMBER_OF_BUFFERS; i++)
  {
    memset((void *)adcBuffer[i], 0, BUFFER_SIZE);
  }

  ADC->ADC_RPR  = (unsigned long) adcBuffer[adcDMAIndex];         // DMA buffer
  ADC->ADC_RCR  = (unsigned int)  BUFFER_SIZE;                    // ADC works in half-word mode.
  ADC->ADC_RNPR = (unsigned long) adcBuffer[(adcDMAIndex + 1)];   // next DMA buffer
  ADC->ADC_RNCR = (unsigned int)  BUFFER_SIZE;

  // Enable interrupts
  NVIC_SetPriorityGrouping(NVIC_PriorityGroup_1);
  NVIC_DisableIRQ(ADC_IRQn);
  NVIC_ClearPendingIRQ(ADC_IRQn);  
  NVIC_SetPriority(ADC_IRQn, 6);  
  NVIC_EnableIRQ(ADC_IRQn);
  ADC->ADC_PTCR  =  ADC_PTCR_RXTEN;                               // Enable receiving data.
  ADC->ADC_CR   |=  ADC_CR_START;                                 // start waiting for trigger.

  // Start timer
  TC0->TC_CHANNEL[0].TC_SR;
  TC0->TC_CHANNEL[0].TC_CCR = TC_CCR_CLKEN;
  TC_Start(TC0, 0);
}