diff options
Diffstat (limited to 'avr/main.c')
-rw-r--r-- | avr/main.c | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/avr/main.c b/avr/main.c new file mode 100644 index 0000000..5c4cd0c --- /dev/null +++ b/avr/main.c @@ -0,0 +1,212 @@ +/* + */ + + +#include "common.h" + +#include <util/delay.h> +//#include <avr/power.h> +//#include <avr/pgmspace.h> +#include <avr/interrupt.h> +//#include <util/atomic.h> +//#include <avr/sleep.h> +//#include <string.h> + +#include <util/delay.h> + +#include <stdlib.h> +#include <stdio.h> + + +#include "config.h" +#include "debug.h" +#include "z80-if.h" +#include "con-utils.h" +#include "serial.h" +#include "timer.h" +#include "cli.h" +#include "env.h" + +/*--------------------------------------------------------------------------*/ + +static uint8_t mcusr; + +static +void setup_avr(void) +{ + /* save and clear reset reason(s) */ + mcusr = MCUSR; + MCUSR = 0; + + /* WD */ + + /* CPU */ + + /* Disable JTAG Interface regardless of the JTAGEN fuse setting. */ + MCUCR = _BV(JTD); + MCUCR = _BV(JTD); + + /* disable unused periphels */ + PRR0 = _BV(PRTIM2) | _BV(PRTIM0) | _BV(PRADC); + PRR1 = _BV(PRTIM5) | _BV(PRTIM4) | _BV(PRTIM3) | + _BV(PRUSART3) | _BV(PRUSART2) | _BV(PRUSART1); + + /* disable analog comparator */ + ACSR = _BV(ACD); + /* Ports */ + + /* Clock */ + CLKPR = _BV(CLKPCE); + CLKPR = 0; + + /* Timer */ + + OCR1A = F_CPU / 8 / 1000 - 1; // Timer1: 1000Hz interval (OC1A) + TCCR1B = 0b00001010; + TIMSK1 = _BV(OCIE1A); // Enable TC1.oca interrupt +} + +static const FLASH char * const FLASH rreasons[] = { + FSTR("Power on"), + FSTR("External"), + FSTR("Brown out"), + FSTR("Watchdog"), + FSTR("JTAG"), + }; + +static +void print_reset_reason(void) +{ + uint8_t r = mcusr & 0x1f; + const FLASH char * const FLASH *p = rreasons; + + printf_P(PSTR("Reset reason(s): ")); + for ( ; r; p++, r >>= 1) { + if (r & 1) { + my_puts_P(*p); + if (r & ~1) + printf_P(PSTR(", ")); + } + } + printf_P(PSTR(".\n")); +} + + +/*******************************************************************************/ +/*******************************************************************************/ + +#define udelay(n) _delay_us(n) + + +/* Stored value of bootdelay, used by autoboot_command() */ +static int stored_bootdelay; + + +/*************************************************************************** + * Watch for 'delay' seconds for autoboot stop. + * returns: 0 - no key, allow autoboot + * 1 - got key, abort + */ + +static int abortboot(int bootdelay) +{ + int abort = 0; + uint32_t ts; + + if (bootdelay >= 0) + printf_P(PSTR("Hit any key to stop autoboot: %2d "), bootdelay); + +#if defined CONFIG_ZERO_BOOTDELAY_CHECK + /* + * Check if key already pressed + * Don't check if bootdelay < 0 + */ + if (bootdelay >= 0) { + if (tstc()) { /* we got a key press */ + (void) my_getchar(); /* consume input */ + my_puts_P(PSTR("\b\b\b 0")); + abort = 1; /* don't auto boot */ + } + } +#endif + + while ((bootdelay > 0) && (!abort)) { + --bootdelay; + /* delay 1000 ms */ + ts = get_timer(0); + do { + if (tstc()) { /* we got a key press */ + abort = 1; /* don't auto boot */ + bootdelay = 0; /* no more delay */ + break; + } + udelay(10000); + } while (!abort && get_timer(ts) < 1000); + + printf_P(PSTR("\b\b\b%2d "), bootdelay); + } + + putchar('\n'); + + return abort; +} + +static +const char *bootdelay_process(void) +{ + char *s; + int bootdelay; + + s = getenv("bootdelay"); + bootdelay = s ? atoi(s) : CONFIG_BOOTDELAY; + + + debug("### main_loop entered: bootdelay=%d\n\n", bootdelay); + _delay_ms(20); + + s = getenv("bootcmd"); + stored_bootdelay = bootdelay; + return s; +} + +static +void autoboot_command(const char *s) +{ + debug("### main_loop: bootcmd=\"%s\"\n", s ? s : PSTR("<UNDEFINED>")); + _delay_ms(20); + + if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay)) { + run_command_list(s, -1); + } +} + + +static +void main_loop(void) +{ + const char *s; + + s = bootdelay_process(); + autoboot_command(s); + cli_loop(); +} + +int main(void) +{ + setup_avr(); + z80_setup_bus(); + + serial_setup(); + sei(); + + debug("\n=========================< (RE)START DEBUG >=========================\n"); +#if DEBUG + print_reset_reason(); +#endif + + env_init(); + + printf_P(PSTR("\n(ATMEGA1281+HD64180)_stamp Tester\n")); + + main_loop(); +} |