From bfc15a6295de95f77fbadcc11cd324fed27ed6e6 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 11 Mar 2020 13:28:33 -0600 Subject: [PATCH] z20x: Fixes related to W25 boot configurations. arch/z80/src/ez80/ez80_timerisr.c: Correct a mismatch between the programmed reload value and the timer input clock frequency. arch/z80/src/ez80/ez80f92.h: Correct error in timer input clock divider: Bits 2-3, not bits 3-4. boards/z80/ez80/z20x/src/w25_main.c: Correct an uninitialized return value; private function was not declard static. --- arch/z80/src/ez80/ez80_timerisr.c | 80 +++++++++++++++++++++++------ arch/z80/src/ez80/ez80f92.h | 6 +-- boards/z80/ez80/z20x/README.txt | 30 +++++++++++ boards/z80/ez80/z20x/src/w25_main.c | 9 +++- 4 files changed, 103 insertions(+), 22 deletions(-) diff --git a/arch/z80/src/ez80/ez80_timerisr.c b/arch/z80/src/ez80/ez80_timerisr.c index 12be388ba8e..830fc7a8ab2 100644 --- a/arch/z80/src/ez80/ez80_timerisr.c +++ b/arch/z80/src/ez80/ez80_timerisr.c @@ -29,11 +29,56 @@ #include #include +#include #include "chip.h" #include "clock/clock.h" #include "z80_internal.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select a clock divider. Choices are 4, 16, 64, or 256 */ + +#define CLOCK_DIVIDER 16 + +/* Given that: + * + * reload_value = (timer_period * system_clock_frequency) / clock_divider + * = system_clock_frequency / DENOMINATOR + * + * Where: + * + * DENOMINATOR = clock_divider / timer_period + * + * The system timer period is given by CONFIG_USEC_PER_TICK which is usually + * 10,000 corresponding to 100Hz. + * + * + * DENOMINATOR = clock_divider / CONFIG_USEC_PER_TICK / USEC_PER_SEC + * = (USEC_PER_SEC * clock_divider) / CONFIG_USEC_PER_TICK + * + * So for the usual value of CONFIG_USEC_PER_TICK (10,000) and a divider of + * 16, the DENOMINATOR would be 1,600 + */ + +#define DENOMINATOR ((USEC_PER_SEC * CLOCK_DIVIDER) / CONFIG_USEC_PER_TICK) + +/* Pick clock divider register setting */ + +#if CLOCK_DIVIDER == 4 +# define EZ80_TMRCLKDIV EZ80_TMRCLKDIV_4 +#elif CLOCK_DIVIDER == 16 +# define EZ80_TMRCLKDIV EZ80_TMRCLKDIV_16 +#elif CLOCK_DIVIDER == 64 +# define EZ80_TMRCLKDIV EZ80_TMRCLKDIV_64 +#elif CLOCK_DIVIDER == 256 +# define EZ80_TMRCLKDIV EZ80_TMRCLKDIV_256 +#else +# error Invalid clock divider +#endif + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -108,29 +153,30 @@ void up_timer_initialize(void) * In continuous mode: * * timer_period = reload_value x clock_divider / system_clock_frequency + * * or + * * reload_value = (timer_period * system_clock_frequency) / clock_divider + * = system_clock_frequency / DENOMINATOR + * + * Where: + * + * DENOMINATOR = clock_divider / timer_period * * eZ80F91: - * For timer_period=10mS, and clock_divider=16, that would yield: - * - * reload_value = system_clock_frequency / 1600 - * - * For a system timer of 50,000,000, that would result in a reload value - * of 31,250. + * For timer_period=10mS, and clock_divider=16, that would yield a + * DENOMINATOR of 1600. For a system timer of 50,000,000, that would + * result in a reload value of 31,250. * * eZ80F92: - * For timer_period=10mS, and clock_divider=4, that would yield: - * - * reload_value = system_clock_frequency / 400 - * - * For a system timer of 20,000,000, * divider of 4, that would result - * in a reload value of 50,000. + * For timer_period=10mS, and clock_divider=4, that would yield a + * DENOMINATOR of 1600. For a system timer of 20,000,000, that would + * result in a reload value of 50,000. * * NOTE: The system clock frequency value is defined in the board.h file */ - reload = (uint16_t)(ez80_systemclock / 1600); + reload = (uint16_t)(ez80_systemclock / DENOMINATOR); outp(EZ80_TMR0_RRH, (uint8_t)(reload >> 8)); outp(EZ80_TMR0_RRL, (uint8_t)(reload)); @@ -157,11 +203,11 @@ void up_timer_initialize(void) /* EZ80_TMRCTL_TIMEN: Bit 0: The programmable reload timer is enabled * EZ80_TMRCTL_RLD: Bit 1: Force reload * EZ80_TMRCTL_TIMCONT: Bit 2: The timer operates in CONTINUOUS mode. - * EZ80_TMRCLKDIV_16: Bits 3-4: System clock divider = 16 + * EZ80_TMRCLKDIV: Bits 2-3: Timer input clock divider */ outp(EZ80_TMR0_CTL, (EZ80_TMRCTL_TIMEN | EZ80_TMRCTL_RLD | - EZ80_TMRCTL_TIMCONT | EZ80_TMRCLKDIV_16)); + EZ80_TMRCTL_TIMCONT | EZ80_TMRCLKDIV)); /* Enable timer end-of-count interrupts */ @@ -171,13 +217,13 @@ void up_timer_initialize(void) defined(CONFIG_ARCH_CHIP_EZ80F93) /* EZ80_TMRCTL_TIMEN: Bit 0: Programmable reload timer enabled. * EZ80_TMRCTL_RSTEN: Bit 1: Reload and start function enabled. - * EZ80_TMRCLKDIV_4: Bits 2-3: Timer input clock divided by 4 (5Mhz) + * EZ80_TMRCLKDIV: Bits 2-3: Timer input clock divider * EZ80_TMRCTL_TIMCONT: Bit 4: Continuous mode * EZ80_TMRCTL_EN: Bit 6: Enable timer interrupt requests */ outp(EZ80_TMR0_CTL, (EZ80_TMRCTL_TIMEN | EZ80_TMRCTL_RSTEN | - EZ80_TMRCLKDIV_4 | EZ80_TMRCTL_TIMCONT | + EZ80_TMRCLKDIV | EZ80_TMRCTL_TIMCONT | EZ80_TMRCTL_EN)); #endif diff --git a/arch/z80/src/ez80/ez80f92.h b/arch/z80/src/ez80/ez80f92.h index d64b8e0ca72..aca178fcaca 100644 --- a/arch/z80/src/ez80/ez80f92.h +++ b/arch/z80/src/ez80/ez80f92.h @@ -101,9 +101,9 @@ #define EZ80_TMRCTL_TIMCONT 0x10 /* Bit 4: Continuous mode */ #define EZ80_TMRCTL_CLKDIV 0x18 /* Bits 2-3: Timer input clock divider */ # define EZ80_TMRCLKDIV_4 0x00 /* 00: 4 */ -# define EZ80_TMRCLKDIV_16 0x08 /* 01: 16 */ -# define EZ80_TMRCLKDIV_64 0x10 /* 10: 64 */ -# define EZ80_TMRCLKDIV_256 0x18 /* 11: 256 */ +# define EZ80_TMRCLKDIV_16 0x04 /* 01: 16 */ +# define EZ80_TMRCLKDIV_64 0x08 /* 10: 64 */ +# define EZ80_TMRCLKDIV_256 0x0c /* 11: 256 */ #define EZ80_TMRCTL_RSTEN 0x02 /* Bit 1: Reload and start function enabled */ #define EZ80_TMRCTL_TIMEN 0x01 /* Bit 0: Programmable reload timer enabled */ diff --git a/boards/z80/ez80/z20x/README.txt b/boards/z80/ez80/z20x/README.txt index bab4a57dc7b..d65f0cb3065 100644 --- a/boards/z80/ez80/z20x/README.txt +++ b/boards/z80/ez80/z20x/README.txt @@ -317,6 +317,31 @@ Configuration Subdirectories The boot loader source is located at boards/z20x/src/w25_main.c. + When starting, you may see one of two things, depending upon whether or + not there is a valid, bootable image in the W25 FLASH partition: + + 1. If there is a bootable image in FLASH, you should see something like: + + Verifying 203125 bytes in the W25 Serial FLASH + Successfully verified 203125 bytes in the W25 Serial FLASH + [L]oad [B]oot + ......... + + The program will wait up to 5 seconds for you to provide a response: + B to load the program program from the W25 and start it, or L to + download a new program from serial and write it to FLASH. + + If nothing is pressed in within the 5 second delay, the program will + continue to boot the program just as though B were pressed. + + If L is pressed, then you should see the same dialog as for the case + where there is no valid binary image in FLASH. + + 2. If there is no valid program in FLASH (or if L is pressed), you will + be asked to : + + Send HEX file now. + NOTES: 1. A large UART1 Rx buffer (4Kb), a slow UART1 BAUD (2400), and a very @@ -346,3 +371,8 @@ Configuration Subdirectories Things worth trying: 4800 BAUD, smaller Rx buffer, large Rx FIFO trigger level. + + 2. Booting large programs from the serial FLASH is unbearably slow; + you will think that the system is simply not booting at all. There + is probably some bug contributing to this probably (maybe the timer + interrupt rate?) \ No newline at end of file diff --git a/boards/z80/ez80/z20x/src/w25_main.c b/boards/z80/ez80/z20x/src/w25_main.c index 01c8efac023..7a7767830aa 100644 --- a/boards/z80/ez80/z20x/src/w25_main.c +++ b/boards/z80/ez80/z20x/src/w25_main.c @@ -287,6 +287,7 @@ static int w25_read_binary(FAR struct prog_header_s *hdr) fd = open(W25_CHARDEV, O_RDONLY); if (fd < 0) { + ret = -get_errno(); return ret; } @@ -342,18 +343,22 @@ errout: * ****************************************************************************/ -uint24_t w25_crc24(uint32_t len) +static uint24_t w25_crc24(uint32_t len) { FAR const uint8_t *src = (FAR const uint8_t *)PROGSTART; uint32_t crc = 0; int i; int j; + /* Loop for each byte in the binary image */ + for (i = 0; i < len; i++) { uint8_t val = *src++; crc ^= (uint32_t)val << 16; + /* Loop for each bit in each byte */ + for (j = 0; j < 8; j++) { crc <<= 1; @@ -548,7 +553,7 @@ static int w25_wait_keypress(FAR char *keyset, int nseconds) { char tmpch; - /* Read handling retries. We get out of this loop if a key is press*/ + /* Read handling retries. We get out of this loop if a key is press. */ for (; ; ) {