Sketch_Restart()

Thanks for the pointers, I now have read quite a bit more, and perhaps I understand some more.

I understand the comments from others in the past - that a software reset() is not really a good thing to seek out...

But given the sorts of things that I want to ask my poor micro controller to do (tack my model boat, and get the sails on the right side pulling, and head a certain direction, ...)
And that I want that to be done in combinations of interrupt code and other peoples PID code and etc...

I am sure that a fast - start from the very beggining() - method is worth having ;).

All that said, what I understand is required is:

Set all the device registers to the initial states documented in the datasheet

Set the cpu registers to zero

jmp 0

#ifdef simple_reset
void (*sketchRestaRt)(void) = 0x0000; 
#else
#include <avr/io.h>
void sketchRestart(void)
{
  noInterrupts() ; // no interrupts while adjusting register values.
  
  // SET ALL DOCUMENTED REGISTERS TO THEIR POWER ON VALUES.
  
  MCUSR = 0  ; // no reset source
  WDTCSR = 0 ; // no watch dog resets
  EICRA = 0 ; // no external interrupts
  EIMSK = 0 ; // external interrupt mask cleared
  EIFR = 0 ; // external interrupt flag register - no pending interrupts
  PCICR = 0 ; // pin change interrupt control register
  PCIFR = 0 ; // pin change inetrrupt flag register
  PCMSK2 = 0 ; // pin change mask register 2
  PCMSK1 = 0 ; // pin change mask register 1
  PCMSK0 = 0 ; // pin change mask register 0
  
  // port B
  DDRB = 0 ;
  PORTB = 0 ;
  // PINB not defined.
  
  // port C
  DDRC = 0 ;
  PORTC = 0 ;
  // PINC not defined
  
  // port D
  DDRD = 0 ;
  PORTD = 0 ;
  // PIND not defined
  
  // timer prescalers (timer 0 and 1)
  GTCCR = 0 ;
  
  // Timer - 0
  TCCR0A = 0 ;
  TCCR0B = 0 ;
  TCNT0 = 0 ;
  OCR0A = 0 ;
  OCR0B = 0 ;
  TIFR0 = 0 ;
  TIMSK0 = 0 ;
  
  // Timer - 1
  TCCR1A = 0 ;
  TCCR1B = 0 ;
  TCCR1C = 0 ;
  TCNT1 = 0 ; // 16 bit
  OCR1A = 0 ; // 16 bit
  OCR1B = 0 ; // 16 bit
  ICR1 = 0 ; // 16 bit
  TIFR1 = 0 ;
  TIMSK1 = 0 ;
  
  // Timer - 2
  TCCR2A = 0 ;
  TCCR2B = 0 ;
  TCNT2 = 0 ;
  OCR2A = 0 ;
  OCR2B = 0 ;
  TIFR2 = 0 ;
  TIMSK2 = 0 ;
  
  // Assynchronous Status Register (timer 2 stuff)
  ASSR = 0 ;
  
  // SPI
  SPCR = 0 ;
  SPSR = 0 ;
  // SPDR undefined on restart
  
  // usart0
  UDR0 = 0 ;
  UCSR0A = 0 ; // UDRE0 bit is read only, and 1 according the restart normal logic
                        // can not change a read-only bit :(
  UCSR0B = 0 ;
  UCSR0C = _BV(UCSZ01) | _BV(UCSZ00) ; // reset values are these bits.
  UBRR0L = 0 ;
  UBRR0H = 0 ;
  
  // two wire interface
  TWBR = 0 ;
  TWCR = 0 ;
  TWSR = 0 ;
  
  TWDR = 0xff ; // this write might not suceed. Is only writeable when TWI is not shifting a byte.
                // maybe should disable twi as early as possible, so more chance this instruction works.
                // could need to delay for >1 milliSec for byte to be sent.
                // I do not use TWI (yet) so can perhaps ignore this.

                
  TWAR = ~(_BV(TWGCE)) ; // all bits except TWGCE set.
  TWAMR = 0 ;
  
  // analog comparator
  ADCSRB = 0 ;
  ACSR = 0 ;
  DIDR1 = 0 ;
  
  // ADC
  ADMUX = 0 ;
  ADCSRA = 0 ;
  ADCSRB = 0 ;
  DIDR0 = 0 ;
  
 // ADCL = 0 ;  // read only and the output of a conversion, not really a problem if not 0 on restart.
 // ADCH = 0 ;  // read only
 
  // debugWire - not accessible outside debugWire
  // DWDR = 0 ;  // might be prohibited from setting this.
  
  
  // flash access control
  SPMCSR = 0 ;
  
  // clear registers - still to do

  interrupts() ;
  
  asm volatile ("jmp 0") ;
}
#endif

Ok... i haven't cleared the cpu registers yet - and there are IO registers that are read only with
values defined at startup - so sketchRestart() is never going to be a 100% reset,
but all the periperals that I care about are done/ for a 168 or a 368.

It sort of works, except that the output of the first print is corrupted after the reset.

I am guessing that the hardware serial code is assuming some control value has been set in the boot loader.

That will be a problem for tomorrow.

And then the register clear.

And then the same stuff for a Mega 1280.

Maybe I am optimistic... but I think that then we will have a sketchReset() that is fast and reliable :sunglasses:

Dave