Arduino UNO R3 SMD - wrong master clock?

So, I just bought 2 UNO R3 SMD’s from Sparkfun.

I started off writing some interrupt-based code (not the 1st time, I’m not quite that new), and it no workee.

So I got to looking at different things and decided that my interrupt was not being run correctly.

I “got back to basics” and wrote the following code:

#include <stdlib.h>
#include <stdio.h>

// These are the VGA outputs…
#define H_SYNC DDB0 // Happens at the beginning (or end, depending on how you look at it) of every line
#define V_SYNC DDB1 // Happens at the end (again, or beginning, depending on how you look at it) of every frame
#define RED_PIN DDB2 // Red port (all on, or all off - no in between)
#define GREEN_PIN DDB3 // Green port (all on, or all off - no in between)
#define BLUE_PIN DDB4 // Green port (all on, or all off - no in between)
#define OUT_REG PORTB // Using PORTC as out output register
#define OUT_DDR DDRB // Output register’s data direction register

void setup() {
// set up the output register
OUT_REG = 0x00; // Set outputs to zero, and ensure pull-ups are disabled on inputs
OUT_DDR = (1<<H_SYNC)|(1<<V_SYNC)|(1<<RED_PIN)|(1<<GREEN_PIN)|(1<<BLUE_PIN);
}

void loop() {

// get data from USB
// if (Serial.available() > 0) // iF THERE’S A BYTE AVAILABLE…
// Command = Serial.read();
// OUT_REG ++;
OUT_REG = ~OUT_REG;
}

This is the entirety of (uncommented) code…

I would (mot likely) expect this to generate an ~8MHz square wave. Instead, I see an ~533kHz square wave as shown in the attached “image.png”:

I’ve done a little bit of research, and best I can tell, the way to fix this is by recompiling and reburning the bootloader with the correct fuse settings (?)

Unfortunately, all the tutorials and info I can find point to things that don’t exist (or work) in my installation.

So, here’s my setup:
Windows 7 Pro, 64b
Arduino IDE v1.6.0

I have available:
Atmel AVR Studio for Windows
Atmel AVR ISP Mk II

Anyone got any clues?

No, I don’t have anything against linux, but my linux box is old enough to not support USB…

Update: I just did some more investigations. It would appear that my master clock is running at 4MHz, not 1.

The following code leads me to the O’scope screen seen in the attached image… That would be a 250ns delay between pin 0 toggling, and pin 1 toggling - I believe there should only be 1 clcok cycle between those two events…

void loop() {

// get data from USB
// if (Serial.available() > 0) // iF THERE’S A BYTE AVAILABLE…
// Command = Serial.read();
// OUT_REG ++;

OUT_REG ^= 0x01; // toggle pin 0
OUT_REG ^= 0x02; // then immediately toggle pin 1

// delayMicroseconds(1);
// OUT_REG = ~OUT_REG;
}

PS: including <avr/power.h> and then

void setup() {
// Set internal system clock prescaler to 1
// CLKPR = (1<<CLKPCE); // Enable prescaler change
// CLKPR &= (1<<CLKPCE); // set the clock prescaler select bits to 0
clock_prescale_set(clock_div_1);

}

Does not seem to have an effect

It takes more than 1 clock cycle to turn on (or off) a digital output.

Hey, yep. Thanks for the confirmation.

So, that says my instruction cycle is 250ns, when it should be ~62.5...

Now if I can just figure out how to fix that, I'll be golden...

Try this instead:

void loop(){ 
PIND = 0b00000001; // writing 1 to input register toggles the output pin
}

Frequency is then limited by the time to execute the loop() code

Try different ways:

void loop(){
while (1){ 
PIND = 0b00000001; // writing 1 to input register toggles the output pin
}
}
void loop(){
while (1){ 
PIND = 0b00000001; // writing 1 to input register toggles the output pin
PIND = 0b00000001; // writing 1 to input register toggles the output pin
PIND = 0b00000001; // writing 1 to input register toggles the output pin
PIND = 0b00000001; // writing 1 to input register toggles the output pin
PIND = 0b00000001; // writing 1 to input register toggles the output pin
PIND = 0b00000001; // writing 1 to input register toggles the output pin
PIND = 0b00000001; // writing 1 to input register toggles the output pin
PIND = 0b00000001; // writing 1 to input register toggles the output pin
}
}

Okay… I honestly don’t see the point, but you’ve been around these things longer… So I’ll go with it and maybe learn something… :wink:

void loop(){ 
PINB = 0b00000001; // writing 1 to input register toggles the output pin
}

Frequency is then limited by the time to execute the loop() code

Leads to the attached “image2.png” - no change from what I expected; that is, still at about 570kHz (which would be an overall 1.4MHz toggling rate)…

void loop(){
   while (1){ 
      PINB = 0b00000001; // writing 1 to input register toggles the output pin
   }
}

Leads to “image3.png.” Now, I do find this to be quite interesting. Now the pin is toggling at ~ a 4MHz rate… I would not have expected a while loop to be faster than the embedded loop - I honestly assumed it was the same thing. Amazing. But this still doesn’t get us over the “Why aint the toggle rate 8MHz?”

void loop(){
   while (1){ 
      PINB = 0b00000001; // writing 1 to input register toggles the output pin
      PINB = 0b00000001; // writing 1 to input register toggles the output pin
      PINB = 0b00000001; // writing 1 to input register toggles the output pin
      PINB = 0b00000001; // writing 1 to input register toggles the output pin
      PINB = 0b00000001; // writing 1 to input register toggles the output pin
      PINB = 0b00000001; // writing 1 to input register toggles the output pin
      PINB = 0b00000001; // writing 1 to input register toggles the output pin
      PINB = 0b00000001; // writing 1 to input register toggles the output pin
   }
}

So, (1) Thank you, I’ve learned something (although I’m not quite sure what). I tried the same exercise with xoring of the register, and it does, indeed, take about twice as long (most of my coding has been on PICs, and this would be a single instruction cycle action)…

So it would seem that I was incorrect, and my clock is running at 16MHz, then (??)… I guess my problem, then, is that my counting of clock cycles was way off from what I expected - I honestly expected that most instructions were single-cycle.

So, I’ve been disabused of that, now, so…

I guess I need to rethink my interrupts. How many clock cycles does it generally take to enter into, and return from an interrupt? I was assuming about 5 to 7…

A lot of instructions Are single cycle. Add the loop() code or while() code adds overhead. If you look the compiled assembly code, you can see the instructions adding up.

Nick Gammon has a good page on interrupts and their timing. The data sheet also discuss the needed steps. http://www.gammon.com.au/interrupts

CrossRoads: A lot of instructions Are single cycle. Add the loop() code or while() code adds overhead. If you look the compiled assembly code, you can see the instructions adding up.

Nick Gammon has a good page on interrupts and their timing. The data sheet also discuss the needed steps. http://www.gammon.com.au/interrupts

Thanks for the link, I'll take a look. I've done a fair number of AVR projects (mostly ATTiny), and never really had a problem, but I was running a lot simpler things at slower speeds. Here, I'm trying to generate VGA video, and so I need much quicker stuff. I had found that I was only able to generate my HSYNC at a rate that was too slow (needs to be ~28kHz).

Guess I'll try again, but I'm really hoping to not have to resort to assembly - that was one of the things that finally got me to move away from PICs - a good C compiler.

Lots of discussion here: http://forum.arduino.cc/index.php?topic=4324.0 All jumps and memory accesses are two cycles. Skips and rcall can be 3, long calls and return are 4. The pin-toggle code itself isn't going to be any faster in assembler; the compiler does as well as is possible.

You're not going to be able to write a VGA driver without at least LOOKING at the assembler produced...

How many clock cycles does it generally take to enter into, and return from an interrupt? I was assuming about 5 to 7..

Interrupt entry itself (and the return-from-interrupt instruction) are about 4 cycles (up to four clocks for the current instruction to complete, 4 cycles to process the interrupt itself.) The minimal C "prologue" adds about 8 more cycles of context saving (and 7 more for restore.) A "typical" C prologue will save more context than that; probably around 20 cycles for each, and significantly more if you call other C functions. There was recent discussion here: http://www.avrfreaks.net/forum/assembly-interrupt-questions

ISR optimization is one area where the C compiler isn't great. It will save/restore R0/R1 whether or not they are used, and the compiler will not specifically try to minimize register use just because it's an ISR.