[SOLVED] Minimum delay between reset and Atmega328P code execution time

I'm trying to use an ATmega328P in an environment where it will be in control of 3 digital lines that are directly connected to and read by another (host) CPU. The host CPU initially polls the lines approximately 1mS after the system reset signal ends. I have applied all the speed tricks that I know (which isn't saying much given my very limited experience with microcontrollers), but it appears that the soonest I can get the 328 to begin to control the lines after reset is 68mS. I can see these lines going active at this time on an oscilloscope.

I programmed the 328 using ArduinoISP to eliminate the bootloader delay.

I have dug into the core files to see how some of the Arduino commands such as pinMode and digitalWrite are handled and have written my code to manipulate the registers directly to speed things up, but I still can't seem to get past that 68mS startup duration.

Just in case it is relavent, I'm using Arduino 0022.

void setup()
{

  byte Oldsreg = SREG;                      // copy state of status register
  cli();                                    // disable interrupts
  DDRD = B00000000;                         // set all PORTD pins as inputs
  DDRC |= B00000111;                        // set PORTC pins 0, 1, and 2 as outputs
  SREG = Oldsreg;                           // restore interrupts

  PORTC |= B00000001;                       // write D14 / A0 HIGH
  PORTC |= B00000010;                       // write D15 / A1 HIGH
  PORTC |= B00000100;                       // write D16 / A2 HIGH

}

void loop()  // repeat writing LOW's and HIGH's for testing purposes
{

  PORTC &= B11111110;                       // write D14 / A0 LOW
  PORTC &= B11111101;                       // write D15 / A1 LOW
  PORTC &= B11111011;                       // write D16 / A2 LOW

  PORTC |= B00000001;                       // write D14 / A0 HIGH
  PORTC |= B00000010;                       // write D15 / A1 HIGH
  PORTC |= B00000100;                       // write D16 / A2 HIGH

Can't
PORTC |= B00000001; // write D14 / A0 HIGH
PORTC |= B00000010; // write D15 / A1 HIGH
PORTC |= B00000100; // write D16 / A2 HIGH
be condensed with
PORTC |= B00000111;

It can, but I wrote them separately at first so I could measure the time between each pin's state change, and never got around to merging them.

Depending on your fuse settings the default is for the chip to take 65 mS + 14 clock cycles to start after power-up.

http://www.engbedded.com/fusecalc

That doesn't quite give you 68 mS (closer to 66 mS) but that would explain a lot of it.

main, which calls init, probably uses a couple of mS on top of that.

You might make your own main, and do your own initialization.

You could change the fuse settings but you need to be aware of the time it takes the oscillator to spool up. I'm no expert on that part, but that is where I would be looking.

See the datasheet section "Clock Startup Sequence"; startup time is 65ms PLUS some number of clock ticks (16k in the default config. It says "typical" reset times will be 69ms.)

You could change the fuse settings but you need to be aware of the time it takes the oscillator to spool up.

Crystals are the slowest to start. If you use a resonator, the startup delay might be decreasable. If you use the internal clock or an external oscillator, you can decrease even further. Some of the delay is supposedly to make sure that the power supply reaches full voltage, so if you're using the brownout detector, have a stable supply, and know that you're using reset on a system that is already fully powered, you should be in pretty good shape.

Ah I see the fuse calculator left out a K. So it isn't 16 clock cycles but 16000 clock cycles. Well that will make a difference. :slight_smile:

Kind of sounds like Apple Desktop Bus, am I close?

but anyway yes you need to change fuse settings (which has the potential to brick your chip from low voltage programming so dont go into it blind) so the startup delay is shorter than what you require (while letting everything else in the system settle like clock sources and power)

By "system reset signal ends", do you mean that the whole operation already has power and is waiting for the reset signal to end?
It may be that you can have the atmega328P boot and get it's clock happy and go through whatever it needs to go through before the main system reset signal ends. Then have the Atmega poll the system reset line (whatever it might be) and wait till it changes state.

If the brown-out detector is enabled, then the datasheet seems to permit removing the power-stabilisation delay (normally approx 65ms). And with a ceramic resonator the clock-stabilisation delay can be shortened to 1k cycles (normally 16k cycles). So if the power is stable during reset, in theory you'd only have to wait ~63us (at 16MHz).

Usually Arduinos have the BOD set to 2.7V. If running at 16MHz without the power-stabilisation delay it may be wise to increase this to 4.3V.

The host system already has a pretty robust brown-out watchdog circuit that generates the system reset signal. The reset gets held on power-up until about 1/2 second after the 5V power stabilizes nicely, which ought to give the oscillator way more than enough time to stabilize. So I doubt there would be any issues with setting the fuses to get the ATmega328 going right away after reset.

So I just tried setting the fuses for 1K + 14 +0mS, and now the startup time between reset and outputs doing their thing has dropped to less than 150uS. Working great now!

A big thank you to everyone who answered! :grin: