static void usb_control_send_chunk(usbd_device *usbd_dev) { if (usbd_dev->desc->bMaxPacketSize0 < usbd_dev->control_state.ctrl_len) { /* Data stage, normal transmission */ usbd_ep_write_packet(usbd_dev, 0, usbd_dev->control_state.ctrl_buf, usbd_dev->desc->bMaxPacketSize0); usbd_dev->control_state.state = DATA_IN; usbd_dev->control_state.ctrl_buf += usbd_dev->desc->bMaxPacketSize0; usbd_dev->control_state.ctrl_len -= usbd_dev->desc->bMaxPacketSize0; } else { /* Data stage, end of transmission */ usbd_ep_write_packet(usbd_dev, 0, usbd_dev->control_state.ctrl_buf, usbd_dev->control_state.ctrl_len); usbd_dev->control_state.state = usbd_dev->control_state.needs_zlp ? DATA_IN : LAST_DATA_IN; usbd_dev->control_state.needs_zlp = false; usbd_dev->control_state.ctrl_len = 0; usbd_dev->control_state.ctrl_buf = NULL; } }
void gdb_if_putchar(unsigned char c, int flush) { buffer_in[count_in++] = c; if(flush || (count_in == CDCACM_PACKET_SIZE)) { /* Refuse to send if USB isn't configured, and * don't bother if nobody's listening */ if((cdcacm_get_config() != 1) || !cdcacm_get_dtr()) { count_in = 0; return; } while(usbd_ep_write_packet(usbdev, CDCACM_GDB_ENDPOINT, buffer_in, count_in) <= 0); if (flush && (count_in == CDCACM_PACKET_SIZE)) { /* We need to send an empty packet for some hosts * to accept this as a complete transfer. */ /* libopencm3 needs a change for us to confirm when * that transfer is complete, so we just send a packet * containing a null byte for now. */ while (usbd_ep_write_packet(usbdev, CDCACM_GDB_ENDPOINT, "\0", 1) <= 0); } count_in = 0; } }
static void my_usb_print_int(usbd_device *usbd_dev, int16_t value) { int8_t i = 0; uint16_t len = 0; char buffer[64]; if (value < 0) { buffer[0] = '-'; len++; value = value * -1; } i = 3; while (i >= 0) { buffer[len + i] = "0123456789"[value % 10]; value /= 10; i--; } len += 4; buffer[len++] = '\r'; buffer[len++] = '\n'; usbd_ep_write_packet(usbd_dev,0x82, buffer, len); }
void dma1_channel1_isr(void) { //usbd_ep_write_packet(usb_device,0x82,&(x[0]), 4); //usbd_ep_write_packet(usb_device,0x82, &(adc_samples[0]), 64); //gpio_port_write(GPIOE, 0xA500); /* if (state == 0){ state = 20; TIM3_SMCR |= TIM_SMCR_SMS_TM; } */ if ( dma_get_interrupt_flag(DMA1, 1, DMA_TCIF) != 0 ) { state = 0; gpio_port_write(GPIOE, 0xA500); dma_clear_interrupt_flags(DMA1, 1, DMA_TCIF); //gpio_port_write(GPIOE, 0xFF00); //usbd_ep_write_packet(usb_device,0x82,&(x[0]), 4); //((uint32_t *) adc_samples)[0] = ADC1_CR; //((uint32_t *) adc_samples)[1] = ADC1_ISR; //((uint32_t *) adc_samples)[2] = DMA1_CCR1; usbd_ep_write_packet(usb_device,0x82, (uint8_t *) &(adc_samples[0]), 62); // ((uint32_t *) x)[0] = DMA1_CCR1; //usbd_ep_write_packet(usb_device,0x82, x, 4); // reset DMA so we're ready to transmit again } }
bool cdc_send_data(const uint8_t* data, size_t len) { if (!cmp_usb_configured()) { return false; } uint16_t sent = usbd_ep_write_packet(cdc_usbd_dev, ENDP_CDC_DATA_IN, (const void*)data, (uint16_t)len); return (sent != 0); }
static void usb_control_send_chunk(void) { if (_usbd_device.desc->bMaxPacketSize0 < control_state.ctrl_len) { /* Data stage, normal transmission */ usbd_ep_write_packet(0, control_state.ctrl_buf, _usbd_device.desc->bMaxPacketSize0); control_state.state = DATA_IN; control_state.ctrl_buf += _usbd_device.desc->bMaxPacketSize0; control_state.ctrl_len -= _usbd_device.desc->bMaxPacketSize0; } else { /* Data stage, end of transmission */ usbd_ep_write_packet(0, control_state.ctrl_buf, control_state.ctrl_len); control_state.state = LAST_DATA_IN; control_state.ctrl_len = 0; control_state.ctrl_buf = NULL; } }
/* * Read a character from the UART RX and stuff it in a software FIFO. * Allowed to read from FIFO out pointer, but not write to it. * Allowed to write to FIFO in pointer. */ void USBUART_ISR(void) { int flush = uart_is_interrupt_source(USBUART, UART_INT_RT); while (!uart_is_rx_fifo_empty(USBUART)) { char c = uart_recv(USBUART); /* If the next increment of rx_in would put it at the same point * as rx_out, the FIFO is considered full. */ if (((buf_rx_in + 1) % FIFO_SIZE) != buf_rx_out) { /* insert into FIFO */ buf_rx[buf_rx_in++] = c; /* wrap out pointer */ if (buf_rx_in >= FIFO_SIZE) { buf_rx_in = 0; } } else { flush = 1; } } if (flush) { /* forcibly empty fifo if no USB endpoint */ if (cdcacm_get_config() != 1) { buf_rx_out = buf_rx_in; return; } uint8_t packet_buf[CDCACM_PACKET_SIZE]; uint8_t packet_size = 0; uint8_t buf_out = buf_rx_out; /* copy from uart FIFO into local usb packet buffer */ while (buf_rx_in != buf_out && packet_size < CDCACM_PACKET_SIZE) { packet_buf[packet_size++] = buf_rx[buf_out++]; /* wrap out pointer */ if (buf_out >= FIFO_SIZE) { buf_out = 0; } } /* advance fifo out pointer by amount written */ buf_rx_out += usbd_ep_write_packet(usbdev, CDCACM_UART_ENDPOINT, packet_buf, packet_size); buf_rx_out %= FIFO_SIZE; } }
static void tmc_data_rx_cb(usbd_device *usbd_dev, uint8_t ep) { uint8_t buf[64]; (void) ep; int len = usbd_ep_read_packet(usbd_dev, 0x01, buf, 64); /* TODO We actually need a state machine to handle >= than single transfer*/ struct usb_tmc_bulk_header *bhin = (struct usb_tmc_bulk_header *)buf; switch (bhin->MsgID) { case USB_TMC_MSGID_OUT_DEV_DEP_MSG_OUT: printf("dev dep out btag: %d\n", bhin->bTag); /* umm, what? should just drop the packet I guess?*/ #if 0 if (bhin->bTag != ~(bhin->bTagInverse)) { printf("ignoring invalid: bTag != bTagInverse?!!"); return; } #endif /* Could also assert that reserved is zero, but let's forgive things */ if (bhin->command_specific.dev_dep_msg_out.transferSize > 64) { printf("transfer > 1 packet! (UNHANDLED)\n"); return; } if (bhin->command_specific.dev_dep_msg_out.bmTransferAttributes & USB_TMC_BULK_HEADER_BMTRANSFER_ATTRIB_EOM) { /* exit state machine here */ printf("single frame packet :)\n"); } scpi_glue_input(&buf[sizeof(struct usb_tmc_bulk_header)], bhin->command_specific.dev_dep_msg_out.transferSize, true); case USB_TMC_MSGID_OUT_REQUEST_DEV_DEP_MSG_IN: /* WILL need state machiens here too I guess :( */ printf("req_dev_dep_in for max %" PRIu32 " bytes, btag: %d\n", bhin->command_specific.req_dev_dep_msg_in.transferSize, bhin->bTag); if (bhin->command_specific.req_dev_dep_msg_in.bmTransferAttributes & USB_TMC_BULK_HEADER_BMTRANSFER_ATTRIB_TERMCHAR) { printf("FAIL! requested term char!\n"); return; /* TODO reply error? */ } bhin->MsgID = USB_TMC_MSGID_IN_DEV_DEP_MSG_IN; bhin->command_specific.dev_dep_msg_in.transferSize = output_buffer_idx; /* only support short stuff now! */ bhin->command_specific.dev_dep_msg_in.bmTransferAttributes = USB_TMC_BULK_HEADER_BMTRANSFER_ATTRIB_EOM; memcpy(&buf[sizeof(struct usb_tmc_bulk_header) + 1], output_buffer, output_buffer_idx); usbd_ep_write_packet(tmc_dev, 0x82, buf, sizeof(struct usb_tmc_bulk_header) + output_buffer_idx); output_buffer_idx = 0; return; case USB_TMC_MSGID_OUT_VENDOR_SPECIFIC_OUT: printf("vendor_out (UNHANDLED)\n"); return; case USB_TMC_MSGID_OUT_REQUEST_VENDOR_SPECIFIC_IN: printf("req_vendor_in (UNHANDLED)\n"); return; } }
/* Handle sending a report to the host */ static void hid_interrupt_in(usbd_device *usbd_dev, uint8_t ep) { if (hid_report_in_callback != NULL) { uint8_t buf[USB_HID_MAX_PACKET_SIZE]; uint16_t len = 0; hid_report_in_callback(buf, &len); if (len > 0) { usbd_ep_write_packet(usbd_dev, ep, (const void*)buf, len); } } }
static void __cdcacm_data_rx_cb(usbd_device *usbd_dev, uint8_t ep) { (void)ep; char buf[64]; int len = usbd_ep_read_packet(usbd_dev, 0x01, buf, 64); if (len) { while (usbd_ep_write_packet(usbd_dev, 0x82, buf, len) == 0); } gpio_toggle(GPIOC, GPIO5); }
void gdb_if_putchar(unsigned char c, int flush) { buffer_in[count_in++] = c; if(flush || (count_in == CDCACM_PACKET_SIZE)) { /* Refuse to send if USB isn't configured, and * don't bother if nobody's listening */ if((cdcacm_get_config() != 1) || !cdcacm_get_dtr()) { count_in = 0; return; } while(usbd_ep_write_packet(usbdev, CDCACM_GDB_ENDPOINT, buffer_in, count_in) <= 0); count_in = 0; } }
static void cdcacm_data_rx_cb(u8 ep) { (void)ep; char buf[64]; int len = usbd_ep_read_packet(0x01, buf, 64); if (len) { rotate_letters(buf, (unsigned int)len); while (usbd_ep_write_packet(0x82, buf, len) == 0) ; } /* flash the LEDs so we know we're doing something */ gpio_toggle(GPIOD, GPIO12 | GPIO13 | GPIO14 | GPIO15); }
void dma1_channel1_isr(void) { //usbd_ep_write_packet(usb_device,0x82,&(x[0]), 4); //usbd_ep_write_packet(usb_device,0x82, &(adc_samples[0]), 64); //gpio_port_write(GPIOE, 0xA500); if ( dma_get_interrupt_flag(DMA1, 1, DMA_TCIF) != 0 ) { dma_clear_interrupt_flags(DMA1, 1, DMA_TCIF); gpio_port_write(GPIOE, 0xFF00); //usbd_ep_write_packet(usb_device,0x82,&(x[0]), 4); usbd_ep_write_packet(usb_device,0x82, (uint8_t *) &(adc_samples[0]), 62); // ((uint32_t *) x)[0] = DMA1_CCR1; //usbd_ep_write_packet(usb_device,0x82, x, 4); // reset DMA so we're ready to transmit again } }
void _usbd_control_out(usbd_device *usbd_dev, uint8_t ea) { (void)ea; switch (usbd_dev->control_state.state) { case DATA_OUT: if (usb_control_recv_chunk(usbd_dev) < 0) { break; } if ((usbd_dev->control_state.req.wLength - usbd_dev->control_state.ctrl_len) <= usbd_dev->desc->bMaxPacketSize0) { usbd_dev->control_state.state = LAST_DATA_OUT; } break; case LAST_DATA_OUT: if (usb_control_recv_chunk(usbd_dev) < 0) { break; } /* * We have now received the full data payload. * Invoke callback to process. */ if (usb_control_request_dispatch(usbd_dev, &(usbd_dev->control_state.req))) { /* Got to status stage on success. */ usbd_ep_write_packet(usbd_dev, 0, NULL, 0); usbd_dev->control_state.state = STATUS_IN; } else { stall_transaction(usbd_dev); } break; case STATUS_OUT: usbd_ep_read_packet(usbd_dev, 0, NULL, 0); usbd_dev->control_state.state = IDLE; if (usbd_dev->control_state.complete) { usbd_dev->control_state.complete(usbd_dev, &(usbd_dev->control_state.req)); } usbd_dev->control_state.complete = NULL; break; default: stall_transaction(usbd_dev); } }
/* Handle commands and read requests. */ static void usb_control_setup_read(struct usb_setup_data *req) { control_state.ctrl_buf = _usbd_device.ctrl_buf; control_state.ctrl_len = req->wLength; if (usb_control_request_dispatch(req)) { if (control_state.ctrl_len) { /* Go to data out stage if handled. */ usb_control_send_chunk(); } else { /* Go to status stage if handled. */ usbd_ep_write_packet(0, NULL, 0); control_state.state = STATUS_IN; } } else { /* Stall endpoint on failure. */ usbd_ep_stall_set(0, 1); } }
/* Handle commands and read requests. */ static void usb_control_setup_read(usbd_device *usbd_dev, struct usb_setup_data *req) { usbd_dev->control_state.ctrl_buf = usbd_dev->ctrl_buf; usbd_dev->control_state.ctrl_len = req->wLength; if (usb_control_request_dispatch(usbd_dev, req)) { if (usbd_dev->control_state.ctrl_len) { /* Go to data out stage if handled. */ usb_control_send_chunk(usbd_dev); } else { /* Go to status stage if handled. */ usbd_ep_write_packet(usbd_dev, 0, NULL, 0); usbd_dev->control_state.state = STATUS_IN; } } else { /* Stall endpoint on failure. */ stall_transaction(usbd_dev); } }
void trace_buf_push(void) { size_t len; if (buf_rx_in == buf_rx_out) { return; } else if (buf_rx_in > buf_rx_out) { len = buf_rx_in - buf_rx_out; } else { len = FIFO_SIZE - buf_rx_out; } if (len > 64) { len = 64; } if (usbd_ep_write_packet(usbdev, 0x85, (uint8_t *)&buf_rx[buf_rx_out], len) == len) { buf_rx_out += len; buf_rx_out %= FIFO_SIZE; } }
/* * Runs deferred processing for usb uart rx, draining RX FIFO by sending * characters to host PC via CDCACM. Allowed to read from FIFO in pointer, * but not write to it. Allowed to write to FIFO out pointer. */ static void usbuart_run(void) { /* forcibly empty fifo if no USB endpoint */ if (cdcacm_get_config() != 1) { buf_rx_out = buf_rx_in; } /* if fifo empty, nothing further to do */ if (buf_rx_in == buf_rx_out) { /* turn off LED, disable IRQ */ timer_disable_irq(USBUSART_TIM, TIM_DIER_UIE); gpio_clear(LED_PORT_UART, LED_UART); } else { uint8_t packet_buf[CDCACM_PACKET_SIZE]; uint8_t packet_size = 0; uint8_t buf_out = buf_rx_out; /* copy from uart FIFO into local usb packet buffer */ while (buf_rx_in != buf_out && packet_size < CDCACM_PACKET_SIZE) { packet_buf[packet_size++] = buf_rx[buf_out++]; /* wrap out pointer */ if (buf_out >= FIFO_SIZE) { buf_out = 0; } } /* advance fifo out pointer by amount written */ buf_rx_out += usbd_ep_write_packet(usbdev, CDCACM_UART_ENDPOINT, packet_buf, packet_size); buf_rx_out %= FIFO_SIZE; } }
void _usbd_control_out(u8 ea) { (void)ea; switch (control_state.state) { case DATA_OUT: if (usb_control_recv_chunk() < 0) break; if ((control_state.req.wLength - control_state.ctrl_len) <= _usbd_device.desc->bMaxPacketSize0) control_state.state = LAST_DATA_OUT; break; case LAST_DATA_OUT: if (usb_control_recv_chunk() < 0) break; /* * We have now received the full data payload. * Invoke callback to process. */ if (usb_control_request_dispatch(&control_state.req)) { /* Got to status stage on success. */ usbd_ep_write_packet(0, NULL, 0); control_state.state = STATUS_IN; } else { usbd_ep_stall_set(0, 1); } break; case STATUS_OUT: usbd_ep_read_packet(0, NULL, 0); control_state.state = IDLE; if (control_state.complete) control_state.complete(&control_state.req); control_state.complete = NULL; break; default: usbd_ep_stall_set(0, 1); } }
bool vcdc_app_update(void) { bool active = false; while (packet_len < USB_VCDC_MAX_PACKET_SIZE && !vcdc_tx_buffer_empty()) { packet_buffer[packet_len] = vcdc_tx_buffer_get(); packet_len++; } if (packet_len > 0 && cmp_usb_configured()) { uint16_t sent = usbd_ep_write_packet(vcdc_usbd_dev, ENDP_VCDC_DATA_IN, (const void*)packet_buffer, packet_len); if (sent != 0) { packet_len = 0; active = true; if (vcdc_tx_callback != NULL) { vcdc_tx_callback(); } } } return active; }
u16 usbmanager_send_packet(u8 addr, const void *buf, u16 len) { if (tx_ep_sizes[addr & 0x7F] < len) { len = tx_ep_sizes[addr & 0x7F]; } return usbd_ep_write_packet(usbd_dev, addr, buf, len); }
bool hid_send_report(const uint8_t* report, size_t len) { uint16_t sent = usbd_ep_write_packet(hid_usbd_dev, ENDP_HID_REPORT_IN, (const void*)report, (uint16_t)len); return (sent != 0); }