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;
|
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);
|
lib_rawinstream(&rawinstream, 0);
|
||||||
|
|
||||||
/* Wrap the memory area used to hold the program as a seek-able OUT stream in
|
/* Wrap the memory area used to hold the program as a seek-able OUT stream
|
||||||
* which we can buffer the binary data.
|
* in which we can buffer the binary data.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
lib_memsostream(&memoutstream, (FAR char *)PROGSTART, PROGSIZE);
|
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;
|
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);
|
ret = w25_write(fd, (FAR const void *)PROGSTART, hdr->len);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -411,6 +414,205 @@ static int w25_read_verify(void)
|
|||||||
return OK;
|
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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -433,7 +635,6 @@ static int w25_read_verify(void)
|
|||||||
|
|
||||||
int w25_main(int argc, char *argv)
|
int w25_main(int argc, char *argv)
|
||||||
{
|
{
|
||||||
struct prog_header_s hdr;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
#ifndef CONFIG_BOARD_LATE_INITIALIZE
|
#ifndef CONFIG_BOARD_LATE_INITIALIZE
|
||||||
@ -451,40 +652,25 @@ int w25_main(int argc, char *argv)
|
|||||||
|
|
||||||
for (; ; )
|
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));
|
ret = w25_wait_keypress("LB", 5);
|
||||||
hdr.magic = PROG_MAGIC;
|
|
||||||
|
|
||||||
ret = w25_read_hex(&hdr.len);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ERROR: Failed to load HEX: %d\n", ret);
|
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
else if (ret == 'L')
|
||||||
/* 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);
|
ret = w25_write_program();
|
||||||
return EXIT_FAILURE;
|
}
|
||||||
|
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)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ERROR: Failed to verify program: %d\n", ret);
|
fprintf(stderr, "ERROR: Operation failed: %d\n", ret);
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user