void usb_vcp_receive(const char *buf, uint32_t len) { if (dev_is_enabled) { for (int i = 0; i < len; i++) { // catch special interrupt character if (buf[i] == interrupt_char) { // raise exception when interrupts are finished pendsv_nlr_jump(mp_const_vcp_interrupt); interrupt_char = VCP_CHAR_NONE; continue; } rx_buf[rx_buf_in++] = buf[i]; if (rx_buf_in >= sizeof(rx_buf)) { rx_buf_in = 0; } if (rx_buf_in == rx_buf_out) { rx_buf_out = rx_buf_in + 1; if (rx_buf_out >= sizeof(rx_buf)) { rx_buf_out = 0; } } } } }
/** * @brief CDC_Itf_DataRx * Data received over USB OUT endpoint is processed here. * @param Buf: Buffer of data received * @param Len: Number of data received (in bytes) * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL * @note The buffer we are passed here is just UserRxBuffer, so we are * free to modify it. */ static int8_t CDC_Itf_Receive(uint8_t* Buf, uint32_t *Len) { #if 0 // this sends the data over the UART using DMA HAL_UART_Transmit_DMA(&UartHandle, Buf, *Len); #endif // TODO improve this function to implement a circular buffer // if we have processed all the characters, reset the buffer counters if (UserRxBufCur > 0 && UserRxBufCur >= UserRxBufLen) { memmove(UserRxBuffer, UserRxBuffer + UserRxBufLen, *Len); UserRxBufCur = 0; UserRxBufLen = 0; } uint32_t delta_len; if (user_interrupt_char == -1) { // no special interrupt character delta_len = *Len; } else { // filter out special interrupt character from the buffer bool char_found = false; uint8_t *dest = Buf; uint8_t *src = Buf; uint8_t *buf_top = Buf + *Len; for (; src < buf_top; src++) { if (*src == user_interrupt_char) { char_found = true; // raise exception when interrupts are finished pendsv_nlr_jump(user_interrupt_data); } else { if (char_found) { *dest = *src; } dest++; } } // length of remaining characters delta_len = dest - Buf; } if (UserRxBufLen + delta_len + CDC_DATA_FS_MAX_PACKET_SIZE > APP_RX_DATA_SIZE) { // if we keep this data then the buffer can overflow on the next USB rx // so we don't increment the length, and throw this data away } else { // data fits, leaving room for another CDC_DATA_FS_OUT_PACKET_SIZE UserRxBufLen += delta_len; } // initiate next USB packet transfer, to append to existing data in buffer USBD_CDC_SetRxBuffer(&hUSBDDevice, UserRxBuffer + UserRxBufLen); USBD_CDC_ReceivePacket(&hUSBDDevice); return USBD_OK; }
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; } }