4

I am attempting to interface a OV7670 camera to an arduino Due. (I am fairly new to this although have been programming for many years).

I need to generate a clock signal for the camera at a minimum of 8Mhz - I realise using the pre-scalers I can only get an approximation but I am cool with that.

I finally got a nice steady 3mhz signal from the sketch below (note that the irq routine for TC6 is not used and will be removed very soon (as soon as I get home).

I think I have a conceptial problem with the timers because as I am initialising RA and RC to 1 and telling via TC_Configure to toggle the line, and because I am using CLOCK1 (42 Mhz), I believe with those values of RA and RC I should be getting a 21'ish MHZ signal.

Ie RA starts at zero. First CLOCK1 tick. (at second/48,000,000) interval. RA Goes to 1 COmpares to RC Because they are equal, resets RA to 0 and toggles TIOA6 Next Clock1 tick occurs.....

As I said I am only getting a 3Mhz signal.

void TC6_Handler()
{
        TC_GetStatus(TC2, 0);

}

void startTimer(Tc *tc, uint32_t channel, IRQn_Type irq) {
        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_CLOCK1|
               TC_CMR_ACPA_TOGGLE );  // RC compare TOGGLES TIOA);

        TC_SetRA(tc, channel, 1); //50% high, 50% low
        TC_SetRC(tc, channel, 1);


        PIO_Configure(PIOC,
                   PIO_PERIPH_B,
                   PIO_PC25B_TIOA6,
                   PIO_DEFAULT);

       TC_Start(tc, channel);

}

void setup(){

        startTimer(TC2, 0, TC6_IRQn);
}

void loop(){
}
  • FWIW, I checked the ATMEL timer doc (again) and confirmed for a 8mhz'ish signal, RC should be set to 5.xxx (call it six) and RA should be set to 3 (50% duty cycle). Needless to say, this did not give me a 8Mhz signal. In that there is a very faint possibility that I have damaged the ARM (accidently put 5v on it a while back and Wire is a bit falky (but wire1 is good), is there any chance anyone with a Due and a logic analyser could run the sketch and tell me what signal you are getting on TIOA6? – Triumph Rider Aug 26 '14 at 21:22
1

the code below should give you a 8.4MHz signal on digital pin 7 of the due. I have used it to generate a 4.2MHz clock (by setting REG_PWM_CPRD6 = 20; and REG_PWM_CDTY6 = 10; but I think it should work for a 8.4MHz clock also.

I have been using this to provide a 4.2MHz clock signal instead of using a crystal oscillator for an ADE7913 and can confirm it is working well in that application. I have taken this from the arduino forum here.

#include <Arduino.h>

const unsigned long serialPeriodMillis = 2000;
unsigned long previousMillis = 0;

void setup()
{
  int32_t mask_PWM_pin = digitalPinToBitMask(7);
  REG_PMC_PCER1 = 1 << 4;                         // activate clock for PWM controller
  REG_PIOC_PDR |= mask_PWM_pin;                   // activate peripheral functions for pin (disables all PIO functionality)
  REG_PIOC_ABSR |= mask_PWM_pin;                  // choose peripheral option B
  REG_PWM_CLK = 0;                                // choose clock rate, 0 -> full MCLK as reference 84MHz
  REG_PWM_CMR6 = 0 << 9;                          // select clock and polarity for PWM channel (pin7) -> (CPOL = 0)
  REG_PWM_CPRD6 = 10;                             // initialize PWM period -> T = value/84MHz (value: up to 16bit), value=10 -> 8.4MHz
  REG_PWM_CDTY6 = 5;                              // initialize duty cycle, REG_PWM_CPRD6 / value = duty cycle, for 10/5 = 50%
  REG_PWM_ENA = 1 << 6;                           // enable PWM on PWM channel (pin 7 = PWML6)

  Serial.begin(115200);
  Serial.println("Serial on");
}

void loop()
{
  if (millis() - previousMillis > serialPeriodMillis) {
    Serial.println("TIC");
    previousMillis = millis();
  }
}
  • p.s. obviously you don't need the serial stuff, I've just put that in there to check that the code isn't hanging. – kabdulla Jul 1 '16 at 7:52
1

Example from Khalid Abdulla is correct, but I used 10.5 MHz for my ov7670 camera:

int32_t mask_PWM_pin = digitalPinToBitMask(7);
REG_PMC_PCER1 = 1<<4;               // activate clock for PWM controller
REG_PIOC_PDR |= mask_PWM_pin;  // activate peripheral functions for pin (disables all PIO functionality)
REG_PIOC_ABSR |= mask_PWM_pin; // choose peripheral option B    
REG_PWM_CLK = 0;                     // choose clock rate, 0 -> full MCLK as reference 84MHz
REG_PWM_CMR6 = 0<<9;             // select clock and polarity for PWM channel (pin7) -> (CPOL = 0)
REG_PWM_CPRD6 = 8;                // initialize PWM period -> T = value/84MHz (value: up to 16bit), value=8 -> 10.5MHz
REG_PWM_CDTY6 = 4;                // initialize duty cycle, REG_PWM_CPRD6 / value = duty cycle, for 8/4 = 50%
REG_PWM_ENA = 1<<6;               // enable PWM on PWM channel (pin 7 = PWML6)

My results: Arduino Due and OV7670

0

1) Timer counts close to zero are useless... i.e. they work same, as if count = 0; (I ran Due timers with TIMER_CLOCK_2 i.e. MCK/8 or 10.5MHz many times)

2) Select a reasonable pre-scalar depending on output frequency you need such that RC count will be a bit more. Here 42 MHz (TIMER_CLOCK_1) means you need a count of RC = 5 approximately (with RA = RC/2 for 50% duty ratio) for 8 MHz. When RA closes to RC we get output of half frequency i.e. close to 4 MHz.

I think here better option is to use master clock itself i.e. 84 MHz, then RC = 10 (approximately)(with RA = RC/2 for 50% duty ratio). Master clock can be selected using TIMER_CLOCK_5 (I am not sure..please check in the data sheet).

May be Arduino Due (with its clock and using timers) is not good option to generate pulses at that higher frequency (you can't execute other routines in just 10 clock cycles!) . If no additional processing is needed, why not go for a pulse generating IC....just my opinion :-)

  • Thanks for that - am checking (It seems timer5 is not the system clock). Using 3/6 on Timer 2 gives me a mixed wave of up to 6Mhz. (Also using UPDOWN_RC. 2/4 gives me a sloppy wave consisting of a 2Mhz, a bit of 6 and a bit of 4. Seems however you are right that low numbers give very inconsistent results. I agree that an external clock may be the way to go - but I am not beaten yet :-) Many thanks for responding. Stan – Triumph Rider Aug 27 '14 at 10:13
  • Thanks to all who responded and advised. Have ordered external clock generator (Adafruit). (Have also confirmed with the answers etc that I am not going nuts..... Stan – Triumph Rider Aug 28 '14 at 0:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.