Ejemplo n.º 1
0
// Set the frequency (in Hz)
DueTimer DueTimer::setFrequency(long frequency){
	Timer t = Timers[timer];
    uint32_t rc = VARIANT_MCK/128/frequency; //128 because we selected TIMER_CLOCK4 above
    TC_SetRA(t.tc, t.channel, rc/2); //50% high, 50% low
    TC_SetRC(t.tc, t.channel, rc);
    TC_Start(t.tc, t.channel);
    t.tc->TC_CHANNEL[t.channel].TC_IER=TC_IER_CPCS;
    t.tc->TC_CHANNEL[t.channel].TC_IDR=~TC_IER_CPCS;
	return *this;
}
Ejemplo n.º 2
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.º 3
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.º 4
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.º 5
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);
}