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.
This commit is contained in:
Gregory Nutt 2020-03-11 13:28:33 -06:00 committed by Alan Carvalho de Assis
parent e9a94859bc
commit bfc15a6295
4 changed files with 103 additions and 22 deletions

View File

@ -29,11 +29,56 @@
#include <arch/io.h>
#include <nuttx/arch.h>
#include <nuttx/clock.h>
#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

View File

@ -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 */

View File

@ -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?)

View File

@ -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 (; ; )
{