FreeCalypso > hg > freecalypso-reveng
diff frbl/test/frbl2.c @ 324:43c92df87ac6
frbl2test: meat filled in
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 06 Mar 2020 00:30:18 +0000 |
parents | cefa700d1b8f |
children | 7df08926a4e7 |
line wrap: on
line diff
--- a/frbl/test/frbl2.c Thu Mar 05 22:05:01 2020 +0000 +++ b/frbl/test/frbl2.c Fri Mar 06 00:30:18 2020 +0000 @@ -1,12 +1,19 @@ #include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <sys/errno.h> +#include <ctype.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> +#include <termios.h> #include <unistd.h> #include "srecreader.h" +extern int errno; + extern char *target_ttydev; extern int target_fd; extern struct srecreader srimage; @@ -17,6 +24,16 @@ static unsigned codeimage_len; static uint32_t loadaddr; +static u_char beacon_cmd[3] = {0xAA, 0x01, 0xDD}; +static u_char fluid_baudrate_cmd[2] = {0x00, 0x07}; +static u_char fluid_version_cmd[1] = {'V'}; +static u_char fluid_chipquery_cmd[2] = {'Q', 'C'}; +static u_char fluid_download_cmd[7] = {'L'}; + +#define BEACON_INTERVAL 13 /* ms between beacons */ +#define INTERMEDIATE_TIMEOUT 500 /* ms to wait for responses */ +#define SERIAL_FLUSH_DELAY 200 /* also in ms */ + read_srec_image() { u_char *writep; @@ -111,8 +128,149 @@ return(0); } +static void +fill_download_cmd() +{ + unsigned nwords; + + nwords = codeimage_len >> 1; + fluid_download_cmd[1] = loadaddr >> 24; + fluid_download_cmd[2] = loadaddr >> 16; + fluid_download_cmd[3] = loadaddr >> 8; + fluid_download_cmd[4] = loadaddr; + fluid_download_cmd[5] = nwords >> 8; + fluid_download_cmd[6] = nwords; +} + +static int +expect_beacon_response(timeout) +{ + u_char buf; + fd_set fds; + struct timeval tv; + int cc; + + for (;;) { + FD_ZERO(&fds); + FD_SET(target_fd, &fds); + tv.tv_sec = 0; + tv.tv_usec = timeout * 1000; + cc = select(target_fd+1, &fds, NULL, NULL, &tv); + if (cc < 0) { + if (errno == EINTR) + continue; + perror("select"); + exit(1); + } + if (cc < 1) + return(0); + cc = read(target_fd, &buf, 1); + if (cc <= 0) { + perror("read after successful select"); + exit(1); + } + if (buf == 'H') + return(1); + } +} + +static +send_beacons() +{ + printf("Sending beacons to %s\n", target_ttydev); + do + write(target_fd, beacon_cmd, sizeof beacon_cmd); + while (!expect_beacon_response(BEACON_INTERVAL)); + return 0; +} + +static int +expect_add_response(buf, expect_bytes, timeout) + u_char *buf; +{ + fd_set fds; + struct timeval tv; + int pass, cc; + + for (pass = 0; pass < expect_bytes; ) { + FD_ZERO(&fds); + FD_SET(target_fd, &fds); + tv.tv_sec = 0; + tv.tv_usec = timeout * 1000; + cc = select(target_fd+1, &fds, NULL, NULL, &tv); + if (cc < 0) { + if (errno == EINTR) + continue; + perror("select"); + exit(1); + } + if (cc < 1) + return(-1); + cc = read(target_fd, buf + pass, expect_bytes - pass); + if (cc <= 0) { + perror("read after successful select"); + exit(1); + } + pass += cc; + } + return(0); +} + +perform_frbl2_protocol() +{ + u_char respbuf[4]; + static int zero = 0; + + ioctl(target_fd, FIONBIO, &zero); + send_beacons(); + printf("Got beacon response, attempting FLUID protocol\n"); + write(target_fd, fluid_baudrate_cmd, sizeof fluid_baudrate_cmd); + usleep(SERIAL_FLUSH_DELAY * 1000); + tcflush(target_fd, TCIFLUSH); + write(target_fd, fluid_version_cmd, sizeof fluid_version_cmd); + if (expect_add_response(respbuf, 1, INTERMEDIATE_TIMEOUT) < 0) { + fprintf(stderr, "no response to version query\n"); + exit(1); + } + if (!isdigit(respbuf[0])) { + fprintf(stderr, "bad response to version query: 0x%02X\n", + respbuf[0]); + exit(1); + } + printf("Version response: %d\n", respbuf[0] - '0'); + write(target_fd, fluid_chipquery_cmd, sizeof fluid_chipquery_cmd); + if (expect_add_response(respbuf, 4, INTERMEDIATE_TIMEOUT) < 0) { + fprintf(stderr, "no response to chip ID query\n"); + exit(1); + } + if (respbuf[2] || respbuf[3]) { + fprintf(stderr, + "bad response to chip ID query: %02X %02X %02X %02X\n", + respbuf[0], respbuf[1], respbuf[2], respbuf[3]); + exit(1); + } + printf("Chip ID response: %04X\n", (respbuf[1] << 8) | respbuf[0]); + printf("Sending download command\n"); + write(target_fd, fluid_download_cmd, sizeof fluid_download_cmd); + if (expect_add_response(respbuf, 1, INTERMEDIATE_TIMEOUT) < 0) { + fprintf(stderr, "no response to download command\n"); + exit(1); + } + if (respbuf[0] != 'R') { + fprintf(stderr, "bad response to download command: 0x%02X\n", + respbuf[0]); + exit(1); + } + if (write(target_fd, codeimage, codeimage_len) != codeimage_len) { + perror("write of download image bulk"); + exit(1); + } + printf("Code image sent!\n"); +} + frbl_test_main() { read_srec_image(); - /* remainder to be implemented */ + fill_download_cmd(); + perform_frbl2_protocol(); }