#ifdef __USB_COMM__ #include "sys_api_cdc_comm.h" #include "app_factory_cdc_comm.h" #include "hal_bootmode.h" #include "hwtimer_list.h" #include "pmu.h" #ifdef CHIP_HAS_USB #include "usb_cdc.h" #endif #define TIMEOUT_INFINITE ((uint32_t)-1) const unsigned int default_recv_timeout_short = MS_TO_TICKS(500); const unsigned int default_recv_timeout_idle = TIMEOUT_INFINITE; // MS_TO_TICKS(10 * 60 * 1000); const unsigned int default_recv_timeout_4k_data = MS_TO_TICKS(500); const unsigned int default_send_timeout = MS_TO_TICKS(500); static uint32_t send_timeout; static uint32_t recv_timeout; static volatile bool cancel_xfer = false; static uint32_t xfer_err_time = 0; static uint32_t xfer_err_cnt = 0; static HWTIMER_ID xfer_timer; static const struct USB_SERIAL_CFG_T cdc_cfg = { .mode = USB_SERIAL_API_NONBLOCKING, }; void reset_transport(void) { cancel_xfer = false; if (xfer_timer) { hwtimer_stop(xfer_timer); } else { xfer_timer = hwtimer_alloc(NULL, NULL); } usb_serial_flush_recv_buffer(); usb_serial_init_xfer(); set_recv_timeout(default_recv_timeout_short); set_send_timeout(default_send_timeout); } void set_recv_timeout(unsigned int timeout) { recv_timeout = timeout; } void set_send_timeout(unsigned int timeout) { send_timeout = timeout; } static void usb_send_timeout(void *param) { usb_serial_cancel_send(); } static void usb_send_timer_start(void) { if (send_timeout == TIMEOUT_INFINITE) { return; } if (xfer_timer) { hwtimer_update_then_start(xfer_timer, usb_send_timeout, NULL, send_timeout); } } static void usb_send_timer_stop(void) { if (xfer_timer) { hwtimer_stop(xfer_timer); } } static int usb_send_data(const unsigned char *buf, size_t len) { int ret; usb_send_timer_start(); ret = usb_serial_send(buf, len); usb_send_timer_stop(); return ret; } int send_data(const unsigned char *buf, size_t len) { if (cancel_xfer) { return -1; } return usb_send_data(buf, len); } static void usb_recv_timeout(void *param) { usb_serial_cancel_recv(); } static void usb_recv_timer_start(void) { if (recv_timeout == TIMEOUT_INFINITE) { return; } if (xfer_timer) { hwtimer_update_then_start(xfer_timer, usb_recv_timeout, NULL, recv_timeout); } } static void usb_recv_timer_stop(void) { if (xfer_timer) { hwtimer_stop(xfer_timer); } } static int usb_recv_data(unsigned char *buf, size_t len, size_t *rlen) { int ret; usb_recv_timer_start(); ret = usb_serial_recv(buf, len); usb_recv_timer_stop(); if (ret == 0) { *rlen = len; } return ret; } int recv_data_ex(unsigned char *buf, size_t len, size_t expect, size_t *rlen) { if (cancel_xfer) { return -1; } return usb_recv_data(buf, expect, rlen); } static int usb_handle_error(void) { int ret; TRACE(0, "****** Send break ******"); // Send break signal, to tell the peer to reset the connection ret = usb_serial_send_break(); if (ret) { TRACE(1, "Sending break failed: %d", ret); } return ret; } int handle_error(void) { int ret = 0; uint32_t err_time; hal_sys_timer_delay(MS_TO_TICKS(50)); if (!cancel_xfer) { ret = usb_handle_error(); } err_time = hal_sys_timer_get(); if (xfer_err_cnt == 0 || err_time - xfer_err_time > MS_TO_TICKS(5000)) { xfer_err_cnt = 0; xfer_err_time = err_time; } xfer_err_cnt++; if (xfer_err_cnt < 3) { hal_sys_timer_delay(MS_TO_TICKS(100)); } else if (xfer_err_cnt < 5) { hal_sys_timer_delay(MS_TO_TICKS(500)); } else { hal_sys_timer_delay(MS_TO_TICKS(2000)); } return ret; } static int usb_cancel_input(void) { return usb_serial_flush_recv_buffer(); } int cancel_input(void) { return usb_cancel_input(); } void system_reboot(void) { hal_sys_timer_delay(MS_TO_TICKS(10)); hal_cmu_sys_reboot(); } void system_shutdown(void) { #if 0 if (dld_transport == TRANSPORT_USB) { // Avoid PC usb serial driver hanging usb_serial_close(); } #endif hal_sys_timer_delay(MS_TO_TICKS(10)); pmu_shutdown(); } void system_set_bootmode(unsigned int bootmode) { bootmode &= ~(HAL_SW_BOOTMODE_READ_ENABLED | HAL_SW_BOOTMODE_WRITE_ENABLED); hal_sw_bootmode_set(bootmode); } void system_clear_bootmode(unsigned int bootmode) { bootmode &= ~(HAL_SW_BOOTMODE_READ_ENABLED | HAL_SW_BOOTMODE_WRITE_ENABLED); hal_sw_bootmode_clear(bootmode); } unsigned int system_get_bootmode(void) { return hal_sw_bootmode_get(); } #endif