mirror of
https://github.com/apache/nuttx.git
synced 2026-06-02 17:48:54 +08:00
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:
committed by
Alan Carvalho de Assis
parent
e9a94859bc
commit
bfc15a6295
@@ -29,11 +29,56 @@
|
|||||||
|
|
||||||
#include <arch/io.h>
|
#include <arch/io.h>
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
|
#include <nuttx/clock.h>
|
||||||
|
|
||||||
#include "chip.h"
|
#include "chip.h"
|
||||||
#include "clock/clock.h"
|
#include "clock/clock.h"
|
||||||
#include "z80_internal.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
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -108,29 +153,30 @@ void up_timer_initialize(void)
|
|||||||
* In continuous mode:
|
* In continuous mode:
|
||||||
*
|
*
|
||||||
* timer_period = reload_value x clock_divider / system_clock_frequency
|
* timer_period = reload_value x clock_divider / system_clock_frequency
|
||||||
|
*
|
||||||
* or
|
* or
|
||||||
|
*
|
||||||
* reload_value = (timer_period * system_clock_frequency) / clock_divider
|
* reload_value = (timer_period * system_clock_frequency) / clock_divider
|
||||||
|
* = system_clock_frequency / DENOMINATOR
|
||||||
|
*
|
||||||
|
* Where:
|
||||||
|
*
|
||||||
|
* DENOMINATOR = clock_divider / timer_period
|
||||||
*
|
*
|
||||||
* eZ80F91:
|
* eZ80F91:
|
||||||
* For timer_period=10mS, and clock_divider=16, that would yield:
|
* 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
|
||||||
* reload_value = system_clock_frequency / 1600
|
* result in a reload value of 31,250.
|
||||||
*
|
|
||||||
* For a system timer of 50,000,000, that would result in a reload value
|
|
||||||
* of 31,250.
|
|
||||||
*
|
*
|
||||||
* eZ80F92:
|
* eZ80F92:
|
||||||
* For timer_period=10mS, and clock_divider=4, that would yield:
|
* 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
|
||||||
* reload_value = system_clock_frequency / 400
|
* result in a reload value of 50,000.
|
||||||
*
|
|
||||||
* For a system timer of 20,000,000, * divider of 4, that would result
|
|
||||||
* in a reload value of 50,000.
|
|
||||||
*
|
*
|
||||||
* NOTE: The system clock frequency value is defined in the board.h file
|
* 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_RRH, (uint8_t)(reload >> 8));
|
||||||
outp(EZ80_TMR0_RRL, (uint8_t)(reload));
|
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_TIMEN: Bit 0: The programmable reload timer is enabled
|
||||||
* EZ80_TMRCTL_RLD: Bit 1: Force reload
|
* EZ80_TMRCTL_RLD: Bit 1: Force reload
|
||||||
* EZ80_TMRCTL_TIMCONT: Bit 2: The timer operates in CONTINUOUS mode.
|
* 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 |
|
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 */
|
/* Enable timer end-of-count interrupts */
|
||||||
|
|
||||||
@@ -171,13 +217,13 @@ void up_timer_initialize(void)
|
|||||||
defined(CONFIG_ARCH_CHIP_EZ80F93)
|
defined(CONFIG_ARCH_CHIP_EZ80F93)
|
||||||
/* EZ80_TMRCTL_TIMEN: Bit 0: Programmable reload timer enabled.
|
/* EZ80_TMRCTL_TIMEN: Bit 0: Programmable reload timer enabled.
|
||||||
* EZ80_TMRCTL_RSTEN: Bit 1: Reload and start function 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_TIMCONT: Bit 4: Continuous mode
|
||||||
* EZ80_TMRCTL_EN: Bit 6: Enable timer interrupt requests
|
* EZ80_TMRCTL_EN: Bit 6: Enable timer interrupt requests
|
||||||
*/
|
*/
|
||||||
|
|
||||||
outp(EZ80_TMR0_CTL, (EZ80_TMRCTL_TIMEN | EZ80_TMRCTL_RSTEN |
|
outp(EZ80_TMR0_CTL, (EZ80_TMRCTL_TIMEN | EZ80_TMRCTL_RSTEN |
|
||||||
EZ80_TMRCLKDIV_4 | EZ80_TMRCTL_TIMCONT |
|
EZ80_TMRCLKDIV | EZ80_TMRCTL_TIMCONT |
|
||||||
EZ80_TMRCTL_EN));
|
EZ80_TMRCTL_EN));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -101,9 +101,9 @@
|
|||||||
#define EZ80_TMRCTL_TIMCONT 0x10 /* Bit 4: Continuous mode */
|
#define EZ80_TMRCTL_TIMCONT 0x10 /* Bit 4: Continuous mode */
|
||||||
#define EZ80_TMRCTL_CLKDIV 0x18 /* Bits 2-3: Timer input clock divider */
|
#define EZ80_TMRCTL_CLKDIV 0x18 /* Bits 2-3: Timer input clock divider */
|
||||||
# define EZ80_TMRCLKDIV_4 0x00 /* 00: 4 */
|
# define EZ80_TMRCLKDIV_4 0x00 /* 00: 4 */
|
||||||
# define EZ80_TMRCLKDIV_16 0x08 /* 01: 16 */
|
# define EZ80_TMRCLKDIV_16 0x04 /* 01: 16 */
|
||||||
# define EZ80_TMRCLKDIV_64 0x10 /* 10: 64 */
|
# define EZ80_TMRCLKDIV_64 0x08 /* 10: 64 */
|
||||||
# define EZ80_TMRCLKDIV_256 0x18 /* 11: 256 */
|
# define EZ80_TMRCLKDIV_256 0x0c /* 11: 256 */
|
||||||
#define EZ80_TMRCTL_RSTEN 0x02 /* Bit 1: Reload and start function enabled */
|
#define EZ80_TMRCTL_RSTEN 0x02 /* Bit 1: Reload and start function enabled */
|
||||||
#define EZ80_TMRCTL_TIMEN 0x01 /* Bit 0: Programmable reload timer enabled */
|
#define EZ80_TMRCTL_TIMEN 0x01 /* Bit 0: Programmable reload timer enabled */
|
||||||
|
|
||||||
|
|||||||
@@ -317,6 +317,31 @@ Configuration Subdirectories
|
|||||||
|
|
||||||
The boot loader source is located at boards/z20x/src/w25_main.c.
|
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:
|
NOTES:
|
||||||
|
|
||||||
1. A large UART1 Rx buffer (4Kb), a slow UART1 BAUD (2400), and a very
|
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
|
Things worth trying: 4800 BAUD, smaller Rx buffer, large Rx FIFO
|
||||||
trigger level.
|
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?)
|
||||||
@@ -287,6 +287,7 @@ static int w25_read_binary(FAR struct prog_header_s *hdr)
|
|||||||
fd = open(W25_CHARDEV, O_RDONLY);
|
fd = open(W25_CHARDEV, O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
|
ret = -get_errno();
|
||||||
return ret;
|
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;
|
FAR const uint8_t *src = (FAR const uint8_t *)PROGSTART;
|
||||||
uint32_t crc = 0;
|
uint32_t crc = 0;
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
|
/* Loop for each byte in the binary image */
|
||||||
|
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
uint8_t val = *src++;
|
uint8_t val = *src++;
|
||||||
crc ^= (uint32_t)val << 16;
|
crc ^= (uint32_t)val << 16;
|
||||||
|
|
||||||
|
/* Loop for each bit in each byte */
|
||||||
|
|
||||||
for (j = 0; j < 8; j++)
|
for (j = 0; j < 8; j++)
|
||||||
{
|
{
|
||||||
crc <<= 1;
|
crc <<= 1;
|
||||||
@@ -548,7 +553,7 @@ static int w25_wait_keypress(FAR char *keyset, int nseconds)
|
|||||||
{
|
{
|
||||||
char tmpch;
|
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 (; ; )
|
for (; ; )
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user