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:
parent
953a1fafae
commit
1c83406fd1
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user