void __attribute__((noreturn)) serial_ctrl_task(struct vcom * vcom) { struct serial_dev * serial = vcom->serial; struct usb_cdc_class * cdc = vcom->cdc; struct usb_cdc_state prev_state; struct usb_cdc_state state; DCC_LOG1(LOG_TRACE, "[%d] started.", thinkos_thread_self()); usb_cdc_state_get(cdc, &prev_state); while (1) { DCC_LOG1(LOG_INFO, "[%d] usb_cdc_ctl_wait() sleep!", thinkos_thread_self()); usb_cdc_ctl_wait(cdc, 0); DCC_LOG1(LOG_INFO, "[%d] wakeup!", thinkos_thread_self()); usb_cdc_state_get(cdc, &state); if (state.flags != prev_state.flags) { if (state.suspended) { DCC_LOG1(LOG_TRACE, "[%d] suspending...", thinkos_thread_self()); } else { if (prev_state.suspended) { DCC_LOG1(LOG_TRACE, "[%d] wakeup from suspended!", thinkos_thread_self()); } } prev_state.flags = state.flags; } if (state.ctrl.dtr != prev_state.ctrl.dtr) { vcom->ser_stat.dsr = state.ctrl.dtr; usb_cdc_status_set(cdc, &vcom->ser_stat); prev_state.ctrl = state.ctrl; } if ((state.cfg.baudrate != prev_state.cfg.baudrate) || (state.cfg.databits != prev_state.cfg.databits) || (state.cfg.parity != prev_state.cfg.parity) || (state.cfg.stopbits != prev_state.cfg.stopbits)) { serial_rx_disable(serial); DCC_LOG1(LOG_TRACE, "baudrate=%d", state.cfg.baudrate); DCC_LOG1(LOG_TRACE, "databits=%d", state.cfg.databits); DCC_LOG1(LOG_TRACE, "parity=%d", state.cfg.parity); DCC_LOG1(LOG_TRACE, "stopbits=%d", state.cfg.stopbits); if (state.cfg.baudrate == 921600) { vcom->mode = VCOM_MODE_SERVICE; DCC_LOG(LOG_TRACE, "magic config!"); } else { vcom->mode = VCOM_MODE_CONVERTER; serial_config_set(serial, &state.cfg); prev_state.cfg = state.cfg; // serial_enable(serial); serial_rx_enable(serial); } } } }
int ymodem_send(const char * port, int fcnt, char * pathname[]) { struct serial_config cfg = { .baudrate = 115200, .databits = 8, .parity = 0, .stopbits = 1, .flowctrl = 0 }; struct serial_dev * ser; struct xmodem_send * sy; uint8_t buf[512]; int ret; int i; printf("-- serial port: '%s'\n", port); fflush(stdout); DBG(DBG_TRACE, "1. win_serial_open() ..."); if ((ser = win_serial_open(port)) == NULL) { return 1; } DBG(DBG_TRACE, "2. xmodem_send_alloc() ..."); if ((sy = xmodem_send_alloc()) == NULL) { return 1; } DBG(DBG_TRACE, "3. serial_config_set() ..."); serial_config_set(ser, &cfg); xmodem_send_open(sy, ser, MODE_YMODEM); for (i = 0; i < fcnt; ++i) { unsigned int fsize; unsigned int rem; char * fname; FILE * f; int len; if ((f = fopen(pathname[i], "rb")) == NULL) { fprintf(stderr, "ERROR: %s: open(): %s.\n", __func__, strerror(errno)); return -1; } fname = basename(pathname[i]); fseek(f, 0, SEEK_END); fsize = ftell(f); fseek(f, 0, SEEK_SET); rem = fsize; if ((ret = xmodem_send_start(sy, fname, fsize)) < 0) { fprintf(stderr, "ERROR: %s: xmodem_send_start().\n", __func__); return ret; } while (rem) { if ((len = fread(buf, 1, sizeof(buf), f)) <= 0) { fprintf(stderr, "ERROR: %s: fread(): %s.\n", __func__, strerror(errno)); fclose(f); return len; } if ((ret = xmodem_send_loop(sy, buf, len)) < 0) { DBG(DBG_WARNING, "xmodem_send_loop() failed!"); fclose(f); return ret; } rem -= len; } if ((ret = xmodem_send_eot(sy)) < 0) { DBG(DBG_WARNING, "xmodem_send_eot() failed!"); fclose(f); return ret; } fclose(f); } if ((ret = xmodem_send_close(sy)) < 0) { DBG(DBG_WARNING, "xmodem_send_close() failed!"); return ret; } return 0; } int ymodem_recv(const char * port) { struct serial_config cfg = { .baudrate = 115200, .databits = 8, .parity = 0, .stopbits = 1, .flowctrl = 0 }; struct serial_dev * ser; struct xmodem_recv * ry; uint8_t buf[512]; FILE * f = NULL; int ret; printf("-- serial port: '%s'\n", port); fflush(stdout); DBG(DBG_TRACE, "1. win_serial_open() ..."); if ((ser = win_serial_open(port)) == NULL) { return 1; } DBG(DBG_TRACE, "2. xmodem_recv_alloc() ..."); if ((ry = xmodem_recv_alloc()) == NULL) { return 1; } DBG(DBG_TRACE, "3. serial_config_set() ..."); serial_config_set(ser, &cfg); DBG(DBG_TRACE, "4. xmodem_recv_init() ..."); xmodem_recv_init(ry, ser, FCS_CRC, MODE_YMODEM); DBG(DBG_TRACE, "5. xmodem_recv_loop() ..."); while ((ret = xmodem_recv_loop(ry, buf, sizeof(buf))) >= 0) { int len; DBG(DBG_INFO, "xmodem_recv_loop() ret = %d.", ret); len = ret; if (len == 0) { if (ry->fsize == 0) { printf("End of transfer\n"); fflush(stdout); break; } printf("-- file='%s' size=%d\n", ry->fname, ry->fsize); fflush(stdout); if (f != NULL) fclose(f); if ((f = fopen(ry->fname, "wb")) == NULL) { fprintf(stderr, "ERROR: %s: open(): %s.\n", __func__, strerror(errno)); return -1; } } else { // printf(" - data=%d\n", len); // fflush(stdout); if ((ret = fwrite(buf, len, 1, f)) != 1) { fprintf(stderr, "ERROR: %s: fwrite(): %s.\n", __func__, strerror(errno)); fclose(f); return ret; } } } if (f != NULL) fclose(f); DBG(DBG_TRACE, "xmodem_recv_loop() ret = %d.", ret); return ret; } /* ------------------------------------------------------------------------- * Application startup * ------------------------------------------------------------------------- */ #define APP_NAME "ymodem_test" #define VERSION_MAJOR 3 #define VERSION_MINOR 0 static char * progname; static void show_usage(void) { fprintf(stderr, "Usage: %s [OPTION...]\n", progname); fprintf(stderr, " -h \tShow this help message\n"); fprintf(stderr, " -v \tShow version\n"); fprintf(stderr, " -p PORT \tSet comm PORT\n"); fprintf(stderr, " -d \tEnable DAV/RPC protocol over stdout/stdin\n"); fprintf(stderr, "\n"); } static void show_version(void) { fprintf(stderr, "%s %d.%d\n", APP_NAME, VERSION_MAJOR, VERSION_MINOR); }
void vcom_service_input(struct vcom * vcom, uint8_t buf[], int len) { usb_cdc_class_t * cdc = vcom->cdc; struct serial_config cfg; int i; int c; if (vcom->mode == VCOM_MODE_SERVICE) { usb_printf(cdc, "\r\n\r\n"); usb_printf(cdc, "--- U2S-485 %d.%d -------------\r\n\r\n", FW_VERSION_MAJOR, FW_VERSION_MINOR); usb_printf(cdc, "--- Service mode ...\r\n\r\n"); vcom->mode = VCOM_MODE_INTERACTIVE; } for (i = 0; i < len; ++i) { c = buf[i]; (void)c; switch (c) { case 'q': usb_printf(cdc, " - Converter mode...\r\n"); vcom->mode = VCOM_MODE_CONVERTER; break; case 'T': usb_printf(cdc, " - SDU trace mode...\r\n"); vcom->mode = VCOM_MODE_SDU_TRACE; sdu_trace_init(cdc); break; case 't': usb_printf(cdc, " - Interactive mode...\r\n"); vcom->mode = VCOM_MODE_INTERACTIVE; break; case 'F': if (vcom->mode == VCOM_MODE_INTERACTIVE) { usb_printf(cdc, " - Firmware update...\r\n"); usb_xflash(0, 32 * 1024); } break; case '1': cfg.baudrate = 9600; cfg.databits = 8; cfg.parity = 0; cfg.stopbits = 1; serial_rx_disable(vcom->serial); serial_config_set(vcom->serial, &cfg); serial_rx_enable(vcom->serial); usb_printf(cdc, " - 9600 8N1\r\n"); break; case '2': cfg.baudrate = 19200; cfg.databits = 8; cfg.parity = 0; cfg.stopbits = 1; serial_rx_disable(vcom->serial); serial_config_set(vcom->serial, &cfg); serial_rx_enable(vcom->serial); usb_printf(cdc, " - 19200 8N1\r\n"); break; case '3': cfg.baudrate = 38400; cfg.databits = 8; cfg.parity = 0; cfg.stopbits = 1; serial_rx_disable(vcom->serial); serial_config_set(vcom->serial, &cfg); serial_rx_enable(vcom->serial); usb_printf(cdc, " - 38400 8N1\r\n"); break; case '4': cfg.baudrate = 57600; cfg.databits = 8; cfg.parity = 0; cfg.stopbits = 1; serial_rx_disable(vcom->serial); serial_config_set(vcom->serial, &cfg); serial_rx_enable(vcom->serial); usb_printf(cdc, " - 57600 8N1\r\n"); break; case '5': cfg.baudrate = 115200; cfg.databits = 8; cfg.parity = 0; cfg.stopbits = 1; serial_rx_disable(vcom->serial); serial_config_set(vcom->serial, &cfg); serial_rx_enable(vcom->serial); usb_printf(cdc, " - 115200 8N1\r\n"); break; case 'U': sdu_trace_show_supv(true); usb_printf(cdc, " - Show supervisory...\r\n"); break; case 'u': sdu_trace_show_supv(false); usb_printf(cdc, " - Don't show supervisory...\r\n"); break; case 'P': sdu_trace_show_pkt(true); usb_printf(cdc, " - Show packets...\r\n"); break; case 'p': sdu_trace_show_pkt(false); usb_printf(cdc, " - Don't show packets...\r\n"); break; case 'A': sdu_trace_time_abs(true); usb_printf(cdc, " - Absolute timestamps...\r\n"); break; case 'a': sdu_trace_time_abs(false); usb_printf(cdc, " - Relative timestamps...\r\n"); break; case 'v': usb_printf(cdc, "\r\n"); usb_printf(cdc, "0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDEF" "0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDEF"); usb_printf(cdc, "\r\n"); usb_printf(cdc, "0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDEF" "0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDEF"); usb_printf(cdc, "\r\n"); usb_printf(cdc, "0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDEF" "0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDEF"); /* usb_printf(cdc, "\r\n" "1. The qick brown fox jumps over the lazy dog.\r\n" "2. THE QICK BROWN FOX JUMPS OVER THE LAZY DOG.\r\n"); usb_printf(cdc, "3. The qick brown fox jumps over the lazy dog.\r\n" "4. THE QICK BROWN FOX JUMPS OVER THE LAZY DOG.\r\n"); usb_printf(cdc, "5. The qick brown fox jumps over the lazy dog.\r\n"); usb_printf(cdc, "6. THE QICK BROWN FOX JUMPS OVER THE LAZY DOG.\r\n"); */ break; default: show_menu(cdc); } } }