void mp_hal_set_interrupt_char(int c) { if (c != -1) { #if MICROPY_KBD_EXCEPTION mp_obj_exception_clear_traceback(MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception))); #else mp_obj_exception_clear_traceback(MP_STATE_PORT(mp_kbd_exception)); #endif } mp_interrupt_char = c; }
void mp_hal_set_interrupt_char(int c) { if (c != -1) { mp_obj_exception_clear_traceback(MP_STATE_PORT(mp_kbd_exception)); } extern int interrupt_char; interrupt_char = c; }
void usb_vcp_set_interrupt_char(int c) { if (dev_is_enabled) { if (c != VCP_CHAR_NONE) { mp_obj_exception_clear_traceback(mp_const_vcp_interrupt); } USBD_CDC_SetInterrupt(c, mp_const_vcp_interrupt); } }
void usb_vcp_set_interrupt_char(int c) { if (pyb_usb_flags & PYB_USB_FLAG_DEV_ENABLED) { if (c != -1) { mp_obj_exception_clear_traceback(MP_STATE_PORT(mp_const_vcp_interrupt)); } USBD_CDC_SetInterrupt(c, MP_STATE_PORT(mp_const_vcp_interrupt)); } }
STATIC void sighandler(int signum) { if (signum == SIGINT) { if (MP_STATE_VM(mp_pending_exception) == MP_STATE_VM(keyboard_interrupt_obj)) { // this is the second time we are called, so die straight away exit(1); } mp_obj_exception_clear_traceback(MP_STATE_VM(keyboard_interrupt_obj)); MP_STATE_VM(mp_pending_exception) = MP_STATE_VM(keyboard_interrupt_obj); } }
STATIC void sighandler(int signum) { if (signum == SIGINT) { #if MICROPY_ASYNC_KBD_INTR mp_obj_exception_clear_traceback(MP_STATE_VM(keyboard_interrupt_obj)); sigset_t mask; sigemptyset(&mask); // On entry to handler, its signal is blocked, and unblocked on // normal exit. As we instead perform longjmp, unblock it manually. sigprocmask(SIG_SETMASK, &mask, NULL); nlr_raise(MP_STATE_VM(keyboard_interrupt_obj)); #else if (MP_STATE_VM(mp_pending_exception) == MP_STATE_VM(keyboard_interrupt_obj)) { // this is the second time we are called, so die straight away exit(1); } mp_obj_exception_clear_traceback(MP_STATE_VM(keyboard_interrupt_obj)); MP_STATE_VM(mp_pending_exception) = MP_STATE_VM(keyboard_interrupt_obj); #endif } }
STATIC void sighandler(int signum) { if (signum == SIGINT) { mp_obj_exception_clear_traceback(MP_STATE_VM(keyboard_interrupt_obj)); MP_STATE_VM(mp_pending_exception) = MP_STATE_VM(keyboard_interrupt_obj); // disable our handler so next we really die struct sigaction sa; sa.sa_handler = SIG_DFL; sigemptyset(&sa.sa_mask); sigaction(SIGINT, &sa, NULL); } }
// Handler to be installed by SetConsoleCtrlHandler, currently used only to handle Ctrl-C. // This handler has to be installed just once (this has to be done elswhere in init code). // Previous versions of the mp_hal code would install a handler whenever Ctrl-C input is // allowed and remove the handler again when it is not. That is not necessary though (1), // and it might introduce problems (2) because console notifications are delivered to the // application in a seperate thread. // (1) mp_hal_set_interrupt_char effectively enables/disables processing of Ctrl-C via the // ENABLE_PROCESSED_INPUT flag so in raw mode console_sighandler won't be called. // (2) if mp_hal_set_interrupt_char would remove the handler while Ctrl-C was issued earlier, // the thread created for handling it might not be running yet so we'd miss the notification. BOOL WINAPI console_sighandler(DWORD evt) { if (evt == CTRL_C_EVENT) { if (MP_STATE_VM(mp_pending_exception) == MP_STATE_VM(keyboard_interrupt_obj)) { // this is the second time we are called, so die straight away exit(1); } mp_obj_exception_clear_traceback(MP_STATE_VM(keyboard_interrupt_obj)); MP_STATE_VM(mp_pending_exception) = MP_STATE_VM(keyboard_interrupt_obj); return TRUE; } return FALSE; }
void mp_hal_set_interrupt_char(int c) { if (c != -1) { mp_obj_exception_clear_traceback(MP_STATE_PORT(keyboard_interrupt_obj)); } interrupt_char = c; }
void mp_hal_set_interrupt_char(int c) { if (c != -1) { mp_obj_exception_clear_traceback(MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception))); } mp_interrupt_char = c; }
void usbdbg_control(void *buffer, uint8_t request, uint32_t length) { cmd = (enum usbdbg_cmd) request; switch (cmd) { case USBDBG_FW_VERSION: xfer_bytes = 0; xfer_length = length; break; case USBDBG_FRAME_SIZE: xfer_bytes = 0; xfer_length = length; break; case USBDBG_FRAME_DUMP: xfer_bytes = 0; xfer_length = length; break; case USBDBG_ARCH_STR: xfer_bytes = 0; xfer_length = length; break; case USBDBG_SCRIPT_EXEC: xfer_bytes = 0; xfer_length = length; vstr_reset(&script_buf); break; case USBDBG_SCRIPT_STOP: if (script_running) { // Set script running flag script_running = false; // Disable IDE IRQ (re-enabled by pyexec or main). usbdbg_set_irq_enabled(false); // interrupt running code by raising an exception mp_obj_exception_clear_traceback(mp_const_ide_interrupt); pendsv_nlr_jump(mp_const_ide_interrupt); } cmd = USBDBG_NONE; break; case USBDBG_SCRIPT_SAVE: /* save running script */ // TODO break; case USBDBG_SCRIPT_RUNNING: xfer_bytes = 0; xfer_length =length; break; case USBDBG_TEMPLATE_SAVE: case USBDBG_DESCRIPTOR_SAVE: /* save template */ xfer_bytes = 0; xfer_length =length; break; case USBDBG_ATTR_WRITE: { /* write sensor attribute */ int16_t attr= *((int16_t*)buffer); int16_t val = *((int16_t*)buffer+1); switch (attr) { case ATTR_CONTRAST: sensor_set_contrast(val); break; case ATTR_BRIGHTNESS: sensor_set_brightness(val); break; case ATTR_SATURATION: sensor_set_saturation(val); break; case ATTR_GAINCEILING: sensor_set_gainceiling(val); break; default: break; } cmd = USBDBG_NONE; break; } case USBDBG_SYS_RESET: NVIC_SystemReset(); break; case USBDBG_FB_ENABLE: { int16_t enable = *((int16_t*)buffer); JPEG_FB()->enabled = enable; if (enable == 0) { // When disabling framebuffer, the IDE might still be holding FB lock. // If the IDE is not the current lock owner, this operation is ignored. mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_IDE); } cmd = USBDBG_NONE; break; } case USBDBG_TX_BUF: case USBDBG_TX_BUF_LEN: xfer_bytes = 0; xfer_length = length; break; default: /* error */ cmd = USBDBG_NONE; break; } }
void usbdbg_data_out(void *buffer, int length) { switch (cmd) { case USBDBG_SCRIPT_EXEC: // check if GC is locked before allocating memory for vstr. If GC was locked // at least once before the script is fully uploaded xfer_bytes will be less // than the total length (xfer_length) and the script will Not be executed. if (!script_running && !gc_is_locked()) { vstr_add_strn(&script_buf, buffer, length); xfer_bytes += length; if (xfer_bytes == xfer_length) { // Set script ready flag script_ready = true; // Set script running flag script_running = true; // Disable IDE IRQ (re-enabled by pyexec or main). usbdbg_set_irq_enabled(false); // Clear interrupt traceback mp_obj_exception_clear_traceback(mp_const_ide_interrupt); // Interrupt running REPL // Note: setting pendsv explicitly here because the VM is probably // waiting in REPL and the soft interrupt flag will not be checked. pendsv_nlr_jump_hard(mp_const_ide_interrupt); } } break; case USBDBG_TEMPLATE_SAVE: { image_t image ={ .w = MAIN_FB()->w, .h = MAIN_FB()->h, .bpp = MAIN_FB()->bpp, .pixels = MAIN_FB()->pixels }; // null terminate the path length = (length == 64) ? 63:length; ((char*)buffer)[length] = 0; rectangle_t *roi = (rectangle_t*)buffer; char *path = (char*)buffer+sizeof(rectangle_t); imlib_save_image(&image, path, roi, 50); // raise a flash IRQ to flush image //NVIC->STIR = FLASH_IRQn; break; } case USBDBG_DESCRIPTOR_SAVE: { image_t image ={ .w = MAIN_FB()->w, .h = MAIN_FB()->h, .bpp = MAIN_FB()->bpp, .pixels = MAIN_FB()->pixels }; // null terminate the path length = (length == 64) ? 63:length; ((char*)buffer)[length] = 0; rectangle_t *roi = (rectangle_t*)buffer; char *path = (char*)buffer+sizeof(rectangle_t); py_image_descriptor_from_roi(&image, path, roi); break; } default: /* error */ break; } }
void usbdbg_data_out(void *buffer, int length) { switch (cmd) { case USBDBG_SCRIPT_EXEC: // check if GC is locked before allocating memory for vstr. If GC was locked // at least once before the script is fully uploaded xfer_bytes will be less // than the total length (xfer_length) and the script will Not be executed. if (usbdbg_get_irq_enabled() && !gc_is_locked()) { vstr_add_strn(&script_buf, buffer, length); xfer_bytes += length; if (xfer_bytes == xfer_length) { // Set script ready flag script_ready = 1; // Disable IDE IRQ (re-enabled by pyexec or main). usbdbg_set_irq_enabled(false); // interrupt running script/REPL mp_obj_exception_clear_traceback(mp_const_ide_interrupt); pendsv_nlr_jump_hard(mp_const_ide_interrupt); } } break; case USBDBG_TEMPLATE_SAVE: { image_t image ={ .w = fb->w, .h = fb->h, .bpp = fb->bpp, .pixels = fb->pixels }; // null terminate the path length = (length == 64) ? 63:length; ((char*)buffer)[length] = 0; rectangle_t *roi = (rectangle_t*)buffer; char *path = (char*)buffer+sizeof(rectangle_t); int res=imlib_save_image(&image, path, roi); if (res != FR_OK) { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, ffs_strerror(res))); } // raise a flash IRQ to flush image //NVIC->STIR = FLASH_IRQn; break; } case USBDBG_DESCRIPTOR_SAVE: { image_t image ={ .w = fb->w, .h = fb->h, .bpp = fb->bpp, .pixels = fb->pixels }; // null terminate the path length = (length == 64) ? 63:length; ((char*)buffer)[length] = 0; rectangle_t *roi = (rectangle_t*)buffer; char *path = (char*)buffer+sizeof(rectangle_t); py_image_descriptor_from_roi(&image, path, roi); break; } default: /* error */ break; } } void usbdbg_control(void *buffer, uint8_t request, uint32_t length) { cmd = (enum usbdbg_cmd) request; switch (cmd) { case USBDBG_FW_VERSION: xfer_bytes = 0; xfer_length = length; break; case USBDBG_FRAME_SIZE: xfer_bytes = 0; xfer_length = length; break; case USBDBG_FRAME_DUMP: xfer_bytes = 0; xfer_length = length; break; case USBDBG_FRAME_LOCK: xfer_bytes = 0; xfer_length = length; break; case USBDBG_FRAME_UPDATE: sensor_snapshot(NULL); cmd = USBDBG_NONE; break; case USBDBG_SCRIPT_EXEC: xfer_bytes = 0; xfer_length =length; vstr_reset(&script_buf); break; case USBDBG_SCRIPT_STOP: if (usbdbg_get_irq_enabled()) { // Disable IDE IRQ (re-enabled by pyexec or main). usbdbg_set_irq_enabled(false); // interrupt running code by raising an exception mp_obj_exception_clear_traceback(mp_const_ide_interrupt); pendsv_nlr_jump_hard(mp_const_ide_interrupt); } cmd = USBDBG_NONE; break; case USBDBG_SCRIPT_SAVE: /* save running script */ break; case USBDBG_TEMPLATE_SAVE: case USBDBG_DESCRIPTOR_SAVE: /* save template */ xfer_bytes = 0; xfer_length =length; break; case USBDBG_ATTR_WRITE: { /* write sensor attribute */ int16_t attr= *((int16_t*)buffer); int16_t val = *((int16_t*)buffer+1); switch (attr) { case ATTR_CONTRAST: sensor_set_contrast(val); break; case ATTR_BRIGHTNESS: sensor_set_brightness(val); break; case ATTR_SATURATION: sensor_set_saturation(val); break; case ATTR_GAINCEILING: sensor_set_gainceiling(val); break; default: break; } cmd = USBDBG_NONE; break; } case USBDBG_SYS_RESET: NVIC_SystemReset(); break; case USBDBG_BOOT: *((uint32_t *)0x20002000) = 0xDEADBEEF; NVIC_SystemReset(); break; case USBDBG_TX_BUF: case USBDBG_TX_BUF_LEN: xfer_bytes = 0; xfer_length = length; break; default: /* error */ cmd = USBDBG_NONE; break; } }
ide_dbg_status_t ide_dbg_dispatch_cmd(machine_uart_obj_t* uart, uint8_t* data) { uint32_t length; if(ide_dbg_cmd_len_count==0) { if( is_busy_sending ) // throw out data //TODO: maybe need queue data? return IDE_DBG_DISPATCH_STATUS_BUSY; length = xfer_length - xfer_bytes; if(length)//receive data from IDE { ide_dbg_receive_data(uart, data); ++xfer_bytes; return IDE_DBG_STATUS_OK; } if(*data == IDE_DBG_CMD_START_FLAG) ide_dbg_cmd_len_count = 1; } else { ide_dbg_cmd_buf[ide_dbg_cmd_len_count++] = *data; if(ide_dbg_cmd_len_count < 6) return IDE_DBG_DISPATCH_STATUS_WAIT; length = *( (uint32_t*)(ide_dbg_cmd_buf+2) ); cmd = ide_dbg_cmd_buf[1]; switch (cmd) { case USBDBG_FW_VERSION: xfer_bytes = 0; xfer_length = length; break; case USBDBG_FRAME_SIZE: xfer_bytes = 0; xfer_length = length; break; case USBDBG_FRAME_DUMP: xfer_bytes = 0; xfer_length = length; if(length) is_sending_jpeg = true; break; case USBDBG_ARCH_STR: xfer_bytes = 0; xfer_length = length; break; case USBDBG_SCRIPT_EXEC: xfer_bytes = 0; xfer_length = length; vstr_reset(&script_buf); break; case USBDBG_SCRIPT_STOP: if (script_running) { // Set script running flag script_running = false; // // Disable IDE IRQ (re-enabled by pyexec or main). // usbdbg_set_irq_enabled(false); // interrupt running code by raising an exception mp_obj_exception_clear_traceback(mp_const_ide_interrupt); // pendsv_nlr_jump_hard(mp_const_ide_interrupt); MP_STATE_VM(mp_pending_exception) = mp_const_ide_interrupt; //MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)); #if MICROPY_ENABLE_SCHEDULER if (MP_STATE_VM(sched_state) == MP_SCHED_IDLE) { MP_STATE_VM(sched_state) = MP_SCHED_PENDING; } #endif } cmd = USBDBG_NONE; break; case USBDBG_FILE_SAVE: xfer_bytes = 0; xfer_length = length; ide_file_save_status = 0; if(length) { ide_file_save_status = 1; ide_file_length = length; if( p_data_temp ) { free(p_data_temp); } p_data_temp = malloc( (length%4)? (length+4-(length%4)): length ); if(!p_data_temp) { xfer_length = 0; ide_file_length = 0; ide_file_save_status = 2; } } break; case USBDBG_FILE_SAVE_STATUS: xfer_bytes = 0; xfer_length = length; break; case USBDBG_SCRIPT_RUNNING: xfer_bytes = 0; xfer_length =length; break; case USBDBG_TEMPLATE_SAVE: case USBDBG_DESCRIPTOR_SAVE: /* save template */ xfer_bytes = 0; xfer_length =length; break; case USBDBG_ATTR_WRITE: { if(ide_dbg_cmd_len_count < 10) return IDE_DBG_DISPATCH_STATUS_WAIT; /* write sensor attribute */ int16_t attr = *( (int16_t*)(ide_dbg_cmd_buf+6) ); int16_t val = *( (int16_t*)(ide_dbg_cmd_buf+8) ); switch (attr) { case ATTR_CONTRAST: sensor_set_contrast(val); break; case ATTR_BRIGHTNESS: sensor_set_brightness(val); break; case ATTR_SATURATION: sensor_set_saturation(val); break; case ATTR_GAINCEILING: sensor_set_gainceiling(val); break; default: break; } cmd = USBDBG_NONE; break; } case USBDBG_SYS_RESET: sipeed_sys_reset(); break; case USBDBG_FB_ENABLE: { if(ide_dbg_cmd_len_count < 8) return IDE_DBG_DISPATCH_STATUS_WAIT; int16_t enable = *( (int16_t*)(ide_dbg_cmd_buf+6) ); JPEG_FB()->enabled = enable; if (enable == 0) { // When disabling framebuffer, the IDE might still be holding FB lock. // If the IDE is not the current lock owner, this operation is ignored. mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_IDE); } xfer_bytes = 0; xfer_length = length; cmd = USBDBG_NONE; break; } case USBDBG_TX_BUF: case USBDBG_TX_BUF_LEN: xfer_bytes = 0; xfer_length = length; break; default: /* error */ cmd = USBDBG_NONE; break; } ide_dbg_cmd_len_count = 0; // all cmd data received ok if(length && (cmd&0x80) ) // need send data to IDE { is_busy_sending = true; ide_dbg_ack_data(uart); // ack data } } }
ide_dbg_status_t ide_dbg_receive_data(machine_uart_obj_t* uart, uint8_t* data) { switch (cmd) { case USBDBG_SCRIPT_EXEC: // check if GC is locked before allocating memory for vstr. If GC was locked // at least once before the script is fully uploaded xfer_bytes will be less // than the total length (xfer_length) and the script will Not be executed. if (!script_running && !gc_is_locked()) { vstr_add_strn_00(&script_buf, data, 1); if (xfer_bytes+1 == xfer_length) { // Set script ready flag script_ready = true; // Set script running flag script_running = true; // Disable IDE IRQ (re-enabled by pyexec or main). // usbdbg_set_irq_enabled(false); // Clear interrupt traceback mp_obj_exception_clear_traceback(mp_const_ide_interrupt); // Interrupt running REPL // Note: setting pendsv explicitly here because the VM is probably // waiting in REPL and the soft interrupt flag will not be checked. // nlr_jump(mp_const_ide_interrupt); MP_STATE_VM(mp_pending_exception) = mp_const_ide_interrupt;//MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)); #if MICROPY_ENABLE_SCHEDULER if (MP_STATE_VM(sched_state) == MP_SCHED_IDLE) { MP_STATE_VM(sched_state) = MP_SCHED_PENDING; } #endif } } break; case USBDBG_FILE_SAVE: { p_data_temp[xfer_bytes] = *data; if (xfer_bytes+1 == xfer_length) { //save to FS ide_file_save_status = 5; mp_obj_exception_clear_traceback(mp_const_ide_interrupt); MP_STATE_VM(mp_pending_exception) = mp_const_ide_interrupt;//MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)); #if MICROPY_ENABLE_SCHEDULER if (MP_STATE_VM(sched_state) == MP_SCHED_IDLE) { MP_STATE_VM(sched_state) = MP_SCHED_PENDING; } #endif } break; } case USBDBG_TEMPLATE_SAVE: { //TODO: save image support // image_t image ={ // .w = MAIN_FB()->w, // .h = MAIN_FB()->h, // .bpp = MAIN_FB()->bpp, // .pixels = MAIN_FB()->pixels // }; // // null terminate the path // length = (length == 64) ? 63:length; // ((char*)buffer)[length] = 0; // rectangle_t *roi = (rectangle_t*)buffer; // char *path = (char*)buffer+sizeof(rectangle_t); // imlib_save_image(&image, path, roi, 50); // raise a flash IRQ to flush image //NVIC->STIR = FLASH_IRQn; break; } case USBDBG_DESCRIPTOR_SAVE: { //TODO: save descriptor support // image_t image ={ // .w = MAIN_FB()->w, // .h = MAIN_FB()->h, // .bpp = MAIN_FB()->bpp, // .pixels = MAIN_FB()->pixels // }; // // null terminate the path // length = (length == 64) ? 63:length; // ((char*)buffer)[length] = 0; // rectangle_t *roi = (rectangle_t*)buffer; // char *path = (char*)buffer+sizeof(rectangle_t); // py_image_descriptor_from_roi(&image, path, roi); break; } default: /* error */ break; } }