diff --git a/boards/z80/ez80/z20x/src/w25_main.c b/boards/z80/ez80/z20x/src/w25_main.c index 934b229d76..366d0068f3 100644 --- a/boards/z80/ez80/z20x/src/w25_main.c +++ b/boards/z80/ez80/z20x/src/w25_main.c @@ -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); } }