Go Down

Topic: TC0[0]+ADC and TC2[2]+VirtualWire don't work concurrently (Read 507 times) previous topic - next topic

dxdy

I've been trying to run RF communication (carried out by VirtualWire) and ADC triggered by a (intern) timer @40kHz within the same project, but the two things just won't run concurrently.

For RF, I use the VirtualWire lib with some modifications for DUE grabbed on this forum. I modified the code to get the VW to "listen" on the clock TC2 channel 2 rather than TC0 channel 0. Here is the setup code:
Code: [Select]

   void vw_setup(uint16_t speed) //2000
    {
uint16_t nticks; // number of prescaled ticks needed
uint8_t prescaler; // Bit values for CS0[2:0]

Tc *tc = TC2;
uint32_t channel = 2;
IRQn_Type irq = TC8_IRQn;
uint32_t frequency = speed*8;
pmc_set_writeprotect(false);
pmc_enable_periph_clk((uint32_t)irq);
tc->TC_CHANNEL[channel].TC_CCR = TC_CCR_CLKDIS ;
TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1);

        uint32_t rc = VARIANT_MCK/2/frequency;
TC_SetRA(tc, channel, rc/2); //50% high, 50% low
TC_SetRC(tc, channel, rc);
tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;
tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;
NVIC_ClearPendingIRQ(irq);
NVIC_EnableIRQ(irq);
TC_Start(tc, channel);
pinMode(vw_tx_pin, OUTPUT);
pinMode(vw_rx_pin, INPUT);
pinMode(vw_ptt_pin, OUTPUT);
digitalWrite(vw_ptt_pin, vw_ptt_inverted);
    }


Then the ADC interrupts are set to occur REC_SAMPLE_RATE=40000 times/s
Code: [Select]

   void set_adc_frequency()
{
    pmc_enable_periph_clk (ID_TC0) ;  // start up TC0 Channel 0
    TcChannel * t = &(TC0->TC_CHANNEL)[0] ;  // create a pointer to TC0, Chan 0
   
    t->TC_CCR = TC_CCR_CLKDIS ;  // disable internal clocking while setup regs
    t->TC_IDR = 0xFFFFFFFF ;     // disable interrupts
    t->TC_SR ;                   // read int status reg to clear pending
 
     t->TC_CMR = TC_CMR_TCCLKS_TIMER_CLOCK1 |   // set timer clock at 42 MHz
TC_CMR_WAVE |                  // waveform mode
TC_CMR_WAVSEL_UP_RC;           // count-up PWM using RegisterC as threshold to reset
   
    int cycle = 42000000/REC_SAMPLE_RATE;  // 42 MHz/desired frequency, yields the counter used by registers
    t->TC_RC =  cycle ;         // RegisterC counts at the specificed cycle speed (ticks high each cycle)
    t->TC_RA =  cycle/2 ;       // RegisterA counts twice as fast as RC,
    t->TC_CMR = (t->TC_CMR & 0xFFF0FFFF) |   
TC_CMR_ACPC_SET |            // RC set compare on TIOA, creating a new clock from RC and RA cycle times
TC_CMR_ACPA_CLEAR ;          // RA clear on TIOA.
 
    t->TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG ;  // re-enable local clocking and switch to hardware trigger source.
}


And finally, the ADC is configured to be triggered by the timer from set_adc_frequency():
Code: [Select]

void adc0_setup ()
{
    adc_disable_all_channel(ADC); // disable all ADC channels (less noise)
    eAnalogReference(DEFAULT);    // set ADC reference voltage to the 3.3V default on the Due
    NVIC_EnableIRQ (ADC_IRQn) ;   // enable ADC interrupt vector
    ADC->ADC_IDR = 0xFFFFFFFF ;   // disable interrupts
    ADC->ADC_IER = 0x80 ;         // enable AD7 End-Of-Conv interrupt (Arduino pin A0), used to check for completed conversions
    ADC->ADC_CHER = 0x80 ;        // enable channel A0 (AD7) 
    ADC->ADC_CGR = 0 ;            // Set all gains to 1
 
    ADC->ADC_COR = 0x00000000 ;             // All offsets off
    ADC->ADC_MR = ADC_MR_ANACH |            // allow for different analog settings on each channel (if desired)
ADC_MR_LOWRES_BITS_12 |   // enforce 12 bit capture
ADC_MR_FREERUN_OFF |      // turn off freerun to force wait for trigger
ADC_MR_TRGEN |            // enable external trigger mode for ADC
ADC_MR_TRGSEL_ADC_TRIG1 ; // ADC_TRIG1 = Use TIOA output from TC0 as the trigger
}


Both parts (RF communication and ADC) do work in exactly the same form when running separated, but I'm out of ideas on what I'm doing wrong when running them together.

UPDATE: The problem seems to be the last line of adc0_setup() where the trigger is set to ADC_MR_TRGSEL_ADC_TRIG1. Not sure how to interpret this fact, since, as has been said, ADC part works when running "standalone".

Go Up