From 534e1dfcb2f6cdfa1cd62913045b832f2189b7aa Mon Sep 17 00:00:00 2001 From: Leo C Date: Thu, 14 Aug 2014 16:27:17 +0200 Subject: Add commands: loadf, go, reset restart --- avr/Tupfile | 8 +-- avr/bootc.c | 175 ------------------------------------------------------ avr/cmd_boot.c | 106 +++++++++++++++++++++++++++++++++ avr/command_tbl.c | 29 ++++++++- avr/env.c | 58 +++++++++++++----- avr/main.c | 175 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ avr/z180-serv.c | 28 --------- avr/z80-if.c | 9 +++ avr/z80-if.h | 2 + 9 files changed, 368 insertions(+), 222 deletions(-) delete mode 100644 avr/bootc.c create mode 100644 avr/cmd_boot.c create mode 100644 avr/main.c diff --git a/avr/Tupfile b/avr/Tupfile index 449b2a1..b7da73b 100644 --- a/avr/Tupfile +++ b/avr/Tupfile @@ -1,14 +1,14 @@ include_rules -PROG = stamp-bootc -SRC = bootc.c +PROG = stamp-test +SRC = main.c SRC += cli.c cli_readline.c command.c command_tbl.c -SRC += cmd_help.c cmd_echo.c cmd_mem.c +SRC += cmd_help.c cmd_echo.c cmd_mem.c cmd_boot.c SRC += env.c xmalloc.c SRC += timer.c con-utils.c serial.c SRC += background.c z180-serv.c z80-if.c -#SRC_Z = ../z180/hdrom.c +SRC_Z = ../z180/hdrom.c #TARGETS = $(PROG).elf diff --git a/avr/bootc.c b/avr/bootc.c deleted file mode 100644 index 6dbcdef..0000000 --- a/avr/bootc.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - */ - - -#include "common.h" - -#include -//#include -//#include -#include -//#include -//#include -//#include - -#include - -#include -#include - - -#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" - -/*--------------------------------------------------------------------------*/ - -void setup_avr(void) -{ - /* 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 -} - - - -/*******************************************************************************/ -/*******************************************************************************/ - -#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; -} - -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; -} - -void autoboot_command(const char *s) -{ - debug("### main_loop: bootcmd=\"%s\"\n", s ? s : PSTR("")); - _delay_ms(20); - - if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay)) { - run_command_list(s, -1); - } -} - - -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(); - - if (env_check() == 0) - set_default_env(); - env_init(); - - printf_P(PSTR("\n(ATMEGA1281+HD64180)_stamp Tester\n")); - - main_loop(); -} diff --git a/avr/cmd_boot.c b/avr/cmd_boot.c new file mode 100644 index 0000000..4fb9c2a --- /dev/null +++ b/avr/cmd_boot.c @@ -0,0 +1,106 @@ + +/* + * Misc boot support + */ +#include "common.h" +#include +#include + +#include "command.h" +#include "z80-if.h" + +/* ugly hack to get Z180 loadfile into flash memory */ +#define const const FLASH +#include "../z180/hdrom.h" +#undef const + + + +static void z80_load_mem(void) +{ + unsigned sec = 0; + uint32_t sec_base = hdrom_start; + + printf_P(PSTR("Loading Z180 memory... \n")); + + while (sec < hdrom_sections) { + printf_P(PSTR(" From: 0x%.5lX to: 0x%.5lX (%5li bytes)\n"), + hdrom_address[sec], + hdrom_address[sec]+hdrom_length_of_sections[sec] - 1, + hdrom_length_of_sections[sec]); + + z80_request_bus(); + z80_write_block((const FLASH unsigned char *) &hdrom[sec_base], /* src */ + hdrom_address[sec], /* dest */ + hdrom_length_of_sections[sec]); /* len */ + z80_release_bus(); + sec_base+=hdrom_length_of_sections[sec]; + sec++; + } +} + +int do_loadf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + (void) cmdtp; (void) flag; (void) argc; (void) argv; + + if (z80_runstate() != 0) { + printf_P(PSTR("## Can't load while CPU is running!\n")); + return 1; + } + + z80_load_mem(); + + return 0; +} + + +int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + uint32_t addr; + + (void) cmdtp; (void) flag; (void) argc; + + if (z80_runstate() != 0) { + printf_P(PSTR("## CPU allready running!\n")); + return 1; + } + + addr = strtoul(argv[1], NULL, 16); + + if (addr > (1UL<<16) - 1) { + printf_P(PSTR("## Startaddress 0x%05lx too high.\n" + " (Out of logical address space (0x00000-0x0ffff))\n"), + addr); + return 1; + } else if (addr != 0) { + printf_P(PSTR("## Starting application at " + "address != 0x0000 not implemented yet.\n")); + return 1; + } else { + printf_P(PSTR("## Starting application at 0x%05lX ...\n"), addr); + z80_release_bus(); + z80_reset(HIGH); + } + + return 0; +} + +int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + (void) cmdtp; (void) flag; (void) argc; (void) argv; + + printf_P(PSTR("## CPU now in reset state.\n")); + z80_reset(LOW); + + return 0; +} + +int do_restart(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + (void) cmdtp; (void) flag; (void) argc; (void) argv; + + z80_reset_pulse(); + + return 0; +} + diff --git a/avr/command_tbl.c b/avr/command_tbl.c index 78f7a24..2717a37 100644 --- a/avr/command_tbl.c +++ b/avr/command_tbl.c @@ -9,6 +9,9 @@ extern int do_help(cmd_tbl_t *, int, int, char * const []); extern int do_echo(cmd_tbl_t *, int, int, char * const []); extern int do_env_print(cmd_tbl_t *, int, int, char * const []); extern int do_env_set(cmd_tbl_t *, int, int, char * const []); +extern int do_loadf(cmd_tbl_t *, int, int, char * const []); +extern int do_go(cmd_tbl_t *, int, int, char * const []); +extern int do_restart(cmd_tbl_t *, int, int, char * const []); cmd_tbl_t cmd_tbl[] = { @@ -30,7 +33,7 @@ CMD_TBL_ITEM_COMPLETE( printenv, CONFIG_SYS_MAXARGS, 1, do_env_print, "print environment variables", "\n" - " - print [all] values of all environment variables\n" + " - print values of all environment variables\n" "printenv name ...\n" " - print value of environment variable 'name'", var_complete @@ -45,6 +48,30 @@ CMD_TBL_ITEM_COMPLETE( var_complete ), +CMD_TBL_ITEM( + loadf, 1, 0, do_loadf, + "load srec_cat prepared image from controller flash", + "" +), +CMD_TBL_ITEM( + go, 2, 0, do_go, + "start application at address 'addr'", + "addr\n" + " - start application at address 'addr'" +// "\n" +// " passing 'arg' as arguments" +), +CMD_TBL_ITEM( + reset, 1, 0, do_reset, + "Keep CPU in RESET state", + "" +), +CMD_TBL_ITEM( + restart, 1, 0, do_restart, + "Perform RESET of the CPU", + "" +), + CMD_TBL_ITEM( md, 3, 1, do_mem_md, "memory display", diff --git a/avr/env.c b/avr/env.c index 3488afc..48413f3 100644 --- a/avr/env.c +++ b/avr/env.c @@ -15,12 +15,23 @@ #define DELIM "\0" -#define ENV_SIZE CONFIG_ENV_SIZE-2 #define ENV_GET_VAL (1<<0) +/* + * Default Environment + */ +const FLASH char default_env[] = { + "bootdelay=" "3" DELIM + "bootcmd=" "reset; loadf; go $(startaddr)" DELIM + "baudrate=" "115200" DELIM + "startaddr=" "0" DELIM + DELIM +}; + + /* * Debugging * @@ -97,15 +108,7 @@ void dump_eep(const uint8_t *addr, int len) putchar('\n'); } - -const FLASH char default_env[] = { - "bootdelay=" "3" DELIM - "bootcmd=" "echo hallo" DELIM - "baudrate=" "115200" DELIM - DELIM -}; - - +#define ENV_SIZE CONFIG_ENV_SIZE-2 typedef struct environment_s { uint16_t crc; /* CRC16 over data bytes */ char data[ENV_SIZE]; /* Environment data */ @@ -470,7 +473,7 @@ int set_default_env(void) char buf[64]; uint16_t crc = 0xffff; uint16_t eep = CONFIG_ENV_OFFSET + offsetof(env_t, data); - unsigned int len = CONFIG_ENV_SIZE - offsetof(env_t, data); + unsigned int len = ENV_SIZE; unsigned int i, src = 0; char c = 0xff, c0 = c; #if 0 @@ -502,6 +505,10 @@ printf_P(PSTR("\n\n** set_default_env()\n")); src += sizeof(buf); eep += sizeof(buf); } + + eeprom_update_word( + (uint16_t *) CONFIG_ENV_OFFSET + offsetof(env_t, crc), + crc); #if 0 dump_eep(0, 128); #endif @@ -524,14 +531,15 @@ int env_check(void) crc = 0xffff; c = 0xff; for (i = offsetof(env_t, data); - !(c == 0 && c0 == 0) && i < CONFIG_ENV_SIZE; + !(c == 0 && c0 == 0) && i < ENV_SIZE; i++) { c0 = c; c = eeprom_read_byte((const uint8_t *) CONFIG_ENV_OFFSET + i); crc = crc16(crc, c); } - debug("** crc eep: 0x%.4x, crc new: 0x%.4x\n", stored_crc, crc); + debug_cond((crc != stored_crc), + "** crc eep: 0x%.4x, crc new: 0x%.4x\n", stored_crc, crc); return crc == stored_crc; } @@ -591,7 +599,28 @@ static int env_print(char *name) return len; } - +int env_print_ramsize(void) +{ + int size = 0; + uint8_t name_cnt = 0; + uint8_t val_cnt = 0; + + for (int i = 0 ; i < entrycount; i++) { + if ((env_list[i].flags & EF_N_EEP) == 0 && + (env_list[i].name.ram != NULL)) { + name_cnt++; + size += strlen(env_list[i].name.ram) + 3; + } + if ((env_list[i].flags & EF_V_EEP) == 0 && + (env_list[i].val.ram != NULL)) { + val_cnt++; + size += strlen(env_list[i].val.ram) + 3; + } + } + printf_P(PSTR("%d bytes RAM used for %u names and %u values\n"), + size, name_cnt, val_cnt); + return size; +} int do_env_print(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) @@ -608,6 +637,7 @@ int do_env_print(cmd_tbl_t *cmdtp, int flag, int argc, return 1; printf_P(PSTR("\nEnvironment size: %d/%d bytes\n"), rcode, ENV_SIZE); + env_print_ramsize(); return 0; } diff --git a/avr/main.c b/avr/main.c new file mode 100644 index 0000000..6dbcdef --- /dev/null +++ b/avr/main.c @@ -0,0 +1,175 @@ +/* + */ + + +#include "common.h" + +#include +//#include +//#include +#include +//#include +//#include +//#include + +#include + +#include +#include + + +#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" + +/*--------------------------------------------------------------------------*/ + +void setup_avr(void) +{ + /* 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 +} + + + +/*******************************************************************************/ +/*******************************************************************************/ + +#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; +} + +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; +} + +void autoboot_command(const char *s) +{ + debug("### main_loop: bootcmd=\"%s\"\n", s ? s : PSTR("")); + _delay_ms(20); + + if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay)) { + run_command_list(s, -1); + } +} + + +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(); + + if (env_check() == 0) + set_default_env(); + env_init(); + + printf_P(PSTR("\n(ATMEGA1281+HD64180)_stamp Tester\n")); + + main_loop(); +} diff --git a/avr/z180-serv.c b/avr/z180-serv.c index d28cb98..a4ff057 100644 --- a/avr/z180-serv.c +++ b/avr/z180-serv.c @@ -14,11 +14,6 @@ #include "z80-if.h" -/* ugly hack to get Z180 loadfile into flash memory */ -#define const const FLASH -#include "../z180/hdrom.h" -#undef const - /*--------------------------------------------------------------------------*/ @@ -274,29 +269,6 @@ void dump_mem(const FLASH uint8_t *addr, uint32_t len) /*--------------------------------------------------------------------------*/ -void z80_load_mem(void) -{ - unsigned sec = 0; - uint32_t sec_base = hdrom_start; - - DBG_P(1, "Loading z80 memory... \n"); - - while (sec < hdrom_sections) { - DBG_P(2, " From: 0x%.5lX to: 0x%.5lX (%5li bytes)\n", - hdrom_address[sec], - hdrom_address[sec]+hdrom_length_of_sections[sec] - 1, - hdrom_length_of_sections[sec]); - - z80_write_block((const FLASH unsigned char *) &hdrom[sec_base], /* src */ - hdrom_address[sec], /* dest */ - hdrom_length_of_sections[sec]); /* len */ - sec_base+=hdrom_length_of_sections[sec]; - sec++; - } -} - -/*--------------------------------------------------------------------------*/ - const FLASH uint8_t iniprog[] = { 0xAF, // xor a diff --git a/avr/z80-if.c b/avr/z80-if.c index 9ee9cb0..949de17 100644 --- a/avr/z80-if.c +++ b/avr/z80-if.c @@ -153,6 +153,10 @@ void z80_reset(level_t level) Stat &= ~S_Z180_RUNNING; } +int z80_stat_reset(void) +{ + return Z80_O_RST; +} void z80_reset_pulse(void) { @@ -162,6 +166,11 @@ void z80_reset_pulse(void) Stat |= S_Z180_RUNNING; } +int z80_runstate(void) +{ + return (Stat & S_Z180_RUNNING) != 0; +} + #if 0 int z80_stat_halt(void) { diff --git a/avr/z80-if.h b/avr/z80-if.h index ecb6712..a2617ce 100644 --- a/avr/z80-if.h +++ b/avr/z80-if.h @@ -9,6 +9,8 @@ void z80_release_bus(void); void z80_memset(uint32_t addr, uint8_t data, uint32_t length); void z80_reset(level_t level); void z80_reset_pulse(void); +int z80_stat_reset(void); +int z80_runstate(void); //void z80_busreq(level_t level); void z80_write_block(const FLASH uint8_t *src, uint32_t dest, uint32_t length); int z80_stat_halt(void); -- cgit v1.2.3