boards/z80/ez80/z20x: W25 Bootler is Code Complete

Code Complete but still things to be verify before I can claim Functionality Complete.
This commit is contained in:
Gregory Nutt 2020-03-07 18:46:22 -06:00 committed by Xiang Xiao
parent 953a1fafae
commit 1c83406fd1

View File

@ -108,12 +108,14 @@ static int w25_read_hex(FAR uint24_t *len)
return ret;
}
/* Wrap stdin as an IN stream that can get the HEX data over the serial port */
/* Wrap stdin as an IN stream that can get the HEX data over the serial
* port.
*/
lib_rawinstream(&rawinstream, 0);
/* Wrap the memory area used to hold the program as a seek-able OUT stream in
* which we can buffer the binary data.
/* Wrap the memory area used to hold the program as a seek-able OUT stream
* in which we can buffer the binary data.
*/
lib_memsostream(&memoutstream, (FAR char *)PROGSTART, PROGSIZE);
@ -217,7 +219,8 @@ static int w25_write_binary(FAR const struct prog_header_s *hdr)
goto errout;
}
printf("Writing %lu bytes to the W25 Serial FLASH\n", (unsigned long)hdr->len);
printf("Writing %lu bytes to the W25 Serial FLASH\n",
(unsigned long)hdr->len);
ret = w25_write(fd, (FAR const void *)PROGSTART, hdr->len);
if (ret < 0)
@ -411,6 +414,205 @@ static int w25_read_verify(void)
return OK;
}
/****************************************************************************
* Name: w25_write_program
*
* Description:
* Read the HEX program from serial and write to FLASH.
*
****************************************************************************/
static int w25_write_program(void)
{
struct prog_header_s hdr;
int ret;
/* Read the HEX data into RAM */
memset(&hdr, 0, sizeof(struct prog_header_s));
hdr.magic = PROG_MAGIC;
ret = w25_read_hex(&hdr.len);
if (ret < 0)
{
fprintf(stderr, "ERROR: Failed to load HEX: %d\n", ret);
return ret;
}
/* Calculate a CRC24 checksum */
hdr.crc = w25_crc24(hdr.len);
/* The HEX file load was successful, write the data to FLASH */
ret = w25_write_binary(&hdr);
if (ret < 0)
{
fprintf(stderr, "ERROR: Failed to write to W25: %d\n", ret);
return ret;
}
/* Now verify that the image in memory and the image in FLASH are
* truly the same.
*/
ret = w25_read_verify();
if (ret < 0)
{
fprintf(stderr, "ERROR: Failed to verify program: %d\n", ret);
}
return ret;
}
/****************************************************************************
* Name: w25_boot_program
*
* Description:
* Load the program binary from FLASH and execute it
*
****************************************************************************/
static int w25_boot_program(void)
{
int ret;
/* Load the program into memory and verify it. */
ret = w25_read_verify();
if (ret < 0)
{
fprintf(stderr, "ERROR: Failed to verify program: %d\n", ret);
return ret;
}
/* Start the successfully loaded program */
SRAM_ENTRY();
return ret;
}
/****************************************************************************
* Name: w25_wait_keypress
*
* Description:
* Wait the specified number of seconds on or until one of the specified
* keys is pressed.
*
****************************************************************************/
static int w25_wait_keypress(FAR char *keyset, int nseconds)
{
char ch = '\0';
ssize_t nread;
int ret;
int fd;
int i;
int j;
/* Open stdin read-only, nonblocking */
fd = open(0, O_WRONLY | O_NONBLOCK);
if (fd < 0)
{
ret = -get_errno();
fprintf(stderr, "ERROR: Failed to open stdin: %d\n", ret);
return ret;
}
/* Loop for the requested number of seconds */
for (i = 0; i < nseconds; i++)
{
/* Check for input every 50 milliseconds */
for (j = 0; j < 20; j++)
{
char tmpch;
/* Read handling retries. We get out of this loop if a key is press*/
for (; ; )
{
/* Read one character */
nread = read(fd, &tmpch, 1);
/* Check for errors */
if (nread < 0)
{
int errcode = get_errno();
/* If is not an error if a signal occurred or if there is
* no key pressed.
*/
if (errcode == EAGAIN)
{
/* If no key is pressed, then break out of this inner
* loop, delay, and read again.
*/
break;
}
/* If we were awakened by a signal, then loop and read
* again immediately.
*/
if (errcode != EINTR)
{
/* Punt on all other errors */
fprintf(stderr, "ERROR: Read from stdin failed: %d\n",
errcode);
return -errcode;
}
}
else if (nread != 1)
{
/* This should never happen */
fprintf(stderr, "ERROR: Bad read size: %d\n", (int)nread);
return -EIO;
}
/* A key was pressed. Is it one we care about? */
else if (strchr(keyset, tmpch) != NULL)
{
/* Yes, return the key */
ch = tmpch;
goto errout;
}
else
{
/* No... delay and try again */
break;
}
}
/* Delay 50 Milliseconds */
usleep(50 * 1000);
/* Output a dot to stdout every 200 milliseconds */
if ((j & 3) == 3)
{
putchar('.');
}
}
}
errout:
close(fd);
return ch;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -433,7 +635,6 @@ static int w25_read_verify(void)
int w25_main(int argc, char *argv)
{
struct prog_header_s hdr;
int ret;
#ifndef CONFIG_BOARD_LATE_INITIALIZE
@ -451,40 +652,25 @@ int w25_main(int argc, char *argv)
for (; ; )
{
/* Read the HEX data into RAM */
/* Wait up to 5 seconds for (L)oad or (B) keys. */
memset(&hdr, 0, sizeof(struct prog_header_s));
hdr.magic = PROG_MAGIC;
ret = w25_read_hex(&hdr.len);
ret = w25_wait_keypress("LB", 5);
if (ret < 0)
{
fprintf(stderr, "ERROR: Failed to load HEX: %d\n", ret);
return EXIT_FAILURE;
}
/* Calculate a CRC24 checksum */
hdr.crc = w25_crc24(hdr.len);
/* The HEX file load was successful, write the data to FLASH */
ret = w25_write_binary(&hdr);
if (ret < 0)
else if (ret == 'L')
{
fprintf(stderr, "ERROR: Failed to write to W25: %d\n", ret);
return EXIT_FAILURE;
ret = w25_write_program();
}
else /* if (ret == 'B' || ret == '\0') */
{
ret = w25_boot_program();
}
/* Now verify that the image in memory and the image in FLASH are
* truly the same.
*/
ret = w25_read_verify();
if (ret < 0)
{
fprintf(stderr, "ERROR: Failed to verify program: %d\n", ret);
return EXIT_FAILURE;
fprintf(stderr, "ERROR: Operation failed: %d\n", ret);
}
}