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
Dave