void usbdbg_data_in(void *buffer, int length) { switch (cmd) { case USBDBG_FW_VERSION: { uint32_t *ver_buf = buffer; ver_buf[0] = FIRMWARE_VERSION_MAJOR; ver_buf[1] = FIRMWARE_VERSION_MINOR; ver_buf[2] = FIRMWARE_VERSION_PATCH; cmd = USBDBG_NONE; break; } case USBDBG_TX_BUF_LEN: { uint32_t tx_buf_len = usbd_cdc_tx_buf_len(); memcpy(buffer, &tx_buf_len, sizeof(tx_buf_len)); cmd = USBDBG_NONE; break; } case USBDBG_TX_BUF: { uint8_t *tx_buf = usbd_cdc_tx_buf(length); memcpy(buffer, tx_buf, length); if (xfer_bytes == xfer_length) { cmd = USBDBG_NONE; } break; } case USBDBG_FRAME_SIZE: // Return 0 if FB is locked or not ready. ((uint32_t*)buffer)[0] = 0; // Try to lock FB. If header size == 0 frame is not ready if (mutex_try_lock(&JPEG_FB()->lock, MUTEX_TID_IDE)) { // If header size == 0 frame is not ready if (JPEG_FB()->size == 0) { // unlock FB mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_IDE); } else { // Return header w, h and size/bpp ((uint32_t*)buffer)[0] = JPEG_FB()->w; ((uint32_t*)buffer)[1] = JPEG_FB()->h; ((uint32_t*)buffer)[2] = JPEG_FB()->size; } } cmd = USBDBG_NONE; break; case USBDBG_FRAME_DUMP: if (xfer_bytes < xfer_length) { memcpy(buffer, JPEG_FB()->pixels+xfer_bytes, length); xfer_bytes += length; if (xfer_bytes == xfer_length) { cmd = USBDBG_NONE; JPEG_FB()->w = 0; JPEG_FB()->h = 0; JPEG_FB()->size = 0; mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_IDE); } } break; case USBDBG_ARCH_STR: { snprintf((char *) buffer, 64, "%s [%s:%08X%08X%08X]", OMV_ARCH_STR, OMV_BOARD_TYPE, *((unsigned int *) (OMV_UNIQUE_ID_ADDR + 8)), *((unsigned int *) (OMV_UNIQUE_ID_ADDR + 4)), *((unsigned int *) (OMV_UNIQUE_ID_ADDR + 0))); cmd = USBDBG_NONE; break; } case USBDBG_SCRIPT_RUNNING: { uint32_t *buf = buffer; buf[0] = (uint32_t) script_running; cmd = USBDBG_NONE; break; } default: /* error */ 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 } } }
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; } }
ide_dbg_status_t ide_dbg_ack_data(machine_uart_obj_t* uart) { uint32_t length = 0; ack_start: length = xfer_length - xfer_bytes; length = (length>IDE_DBG_MAX_PACKET) ? IDE_DBG_MAX_PACKET : length; if(length == 0) { if(cmd == USBDBG_NONE) is_busy_sending = false; return IDE_DBG_STATUS_OK; } switch (cmd) { case USBDBG_FW_VERSION: { ((uint32_t*)ide_dbg_cmd_buf)[0] = MICROPY_VERSION_MAJOR; ((uint32_t*)ide_dbg_cmd_buf)[1] = MICROPY_VERSION_MINOR; ((uint32_t*)ide_dbg_cmd_buf)[2] = MICROPY_VERSION_MICRO; cmd = USBDBG_NONE; break; } case USBDBG_TX_BUF_LEN: { *((uint32_t*)ide_dbg_cmd_buf) = Buffer_Size(&g_uart_send_buf_ide); cmd = USBDBG_NONE; break; } case USBDBG_TX_BUF: { Buffer_Gets(&g_uart_send_buf_ide, ide_dbg_cmd_buf, length); if (xfer_bytes+ length == xfer_length) { cmd = USBDBG_NONE; } break; } case USBDBG_FRAME_SIZE: { // Return 0 if FB is locked or not ready. ((uint32_t*)ide_dbg_cmd_buf)[0] = 0; // Try to lock FB. If header size == 0 frame is not ready if (mutex_try_lock(&(JPEG_FB()->lock), MUTEX_TID_IDE)) { // If header size == 0 frame is not ready if (JPEG_FB()->size == 0) { // unlock FB mutex_unlock(&(JPEG_FB()->lock), MUTEX_TID_IDE); } else { // Return header w, h and size/bpp ((uint32_t*)ide_dbg_cmd_buf)[0] = JPEG_FB()->w; ((uint32_t*)ide_dbg_cmd_buf)[1] = JPEG_FB()->h; ((uint32_t*)ide_dbg_cmd_buf)[2] = JPEG_FB()->size; } } } cmd = USBDBG_NONE; break; case USBDBG_FRAME_DUMP: if (xfer_bytes < xfer_length) { if(MICROPY_UARTHS_DEVICE == uart->uart_num) { temp_size = uarths_send_data(JPEG_FB()->pixels, xfer_length); } else if(UART_DEVICE_MAX > uart->uart_num) { // uart_configure(uart->uart_num, (size_t)uart->baudrate, (size_t)uart->bitwidth, uart->stop, uart->parity); temp_size= uart_send_data(uart->uart_num, JPEG_FB()->pixels, xfer_length); } cmd = USBDBG_NONE; xfer_bytes = xfer_length; JPEG_FB()->w = 0; JPEG_FB()->h = 0; JPEG_FB()->size = 0; mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_IDE); } break; case USBDBG_ARCH_STR: { snprintf((char *) ide_dbg_cmd_buf, IDE_DBG_MAX_PACKET, "%s [%s:%08X%08X%08X]", OMV_ARCH_STR, OMV_BOARD_TYPE,0,0,0);//TODO: UID cmd = USBDBG_NONE; break; } case USBDBG_SCRIPT_RUNNING: { *((uint32_t*)ide_dbg_cmd_buf) = script_running?1:0; cmd = USBDBG_NONE; break; } case USBDBG_FILE_SAVE_STATUS: { *((uint32_t*)ide_dbg_cmd_buf) = ide_file_save_status; cmd = USBDBG_NONE; break; } default: /* error */ break; } if(length && !is_sending_jpeg) { if(MICROPY_UARTHS_DEVICE == uart->uart_num) { temp_size = uarths_send_data(ide_dbg_cmd_buf, length); } else if(UART_DEVICE_MAX > uart->uart_num) temp_size= uart_send_data(uart->uart_num, ide_dbg_cmd_buf, length); xfer_bytes += length; if( xfer_bytes < xfer_length ) goto ack_start; } if(cmd == USBDBG_NONE) { is_sending_jpeg = false; is_busy_sending = false; } }