// get the next character, or -1 if nothing received int usb_serial_getchar() { unsigned int i; int c; if ( !rx_packet ) { if ( !usb_configuration ) return -1; rx_packet = usb_rx( CDC_RX_ENDPOINT ); if ( !rx_packet ) return -1; } i = rx_packet->index; c = rx_packet->buf[i++]; if ( i >= rx_packet->len ) { usb_free( rx_packet ); rx_packet = NULL; } else { rx_packet->index = i; } return c; }
void usb_setup_control(void) { void *buf = ep0_buf[usb.ep_state[0].rx.pingpong]; usb.ep_state[0].rx.data01 = USB_DATA01_DATA0; usb.ep_state[0].tx.data01 = USB_DATA01_DATA1; usb_rx(&usb.ep_state[0].rx, buf, EP0_BUFSIZE, usb_handle_control, NULL); }
void fcBuffers::handleUSB() { /* * Look for incoming USB packets, and file them appropriately. * Our framebuffer and LUT buffers are arrays of references to USB packets * which we hold until a new packet arrives to replace them. */ bool handledAnyPackets = false; while (1) { usb_packet_t *packet = usb_rx(FC_OUT_ENDPOINT); if (!packet) { break; } handledAnyPackets = true; unsigned control = packet->buf[0]; unsigned type = control & TYPE_BITS; unsigned final = control & FINAL_BIT; unsigned index = control & INDEX_BITS; switch (type) { case TYPE_FRAMEBUFFER: fbNew->store(index, packet); if (final) { finalizeFramebuffer(); } break; case TYPE_LUT: lutNew.store(index, packet); if (final) { finalizeLUT(); } break; case TYPE_CONFIG: flags = packet->buf[1]; usb_free(packet); break; default: usb_free(packet); break; } } if (flags & CFLAG_NO_ACTIVITY_LED) { // LED under manual control digitalWrite(LED_BUILTIN, flags & CFLAG_LED_CONTROL); } else { // Use the built-in LED as a USB activity indicator. digitalWrite(LED_BUILTIN, handledAnyPackets); } }
void usb_setup_control(void) { void *buf = ep0_buf[usbd_pipe_state[USBD_PIPE_EP0_RX].pingpong]; usbd_pipe_state[USBD_PIPE_EP0_RX].data01 = USB_DATA01_DATA0; usbd_pipe_state[USBD_PIPE_EP0_TX].data01 = USB_DATA01_DATA1; usb_rx(&usbd_pipe_state[USBD_PIPE_EP0_RX], buf, EP0_BUFSIZE, usb_handle_control, NULL); }
ssize_t read(uint8_t *m, size_t s) { if (!usb_enabled) return -1; auto ret = usb_rx(m, s); rxed = rxed or !!ret; return ret; }
// peek at the next character, or -1 if nothing received int usb_serial_peekchar(void) { if (!rx_packet) { if (!usb_configuration) return -1; rx_packet = usb_rx(CDC_RX_ENDPOINT); if (!rx_packet) return -1; } if (!rx_packet) return -1; return rx_packet->buf[rx_packet->index]; }
static void usb_serial_receive(void) { if (!usb_configuration) return; if (rx_packet) return; while (1) { rx_packet = usb_rx(CDC_RX_ENDPOINT); if (rx_packet == NULL) return; if (rx_packet->len > 0) return; usb_free(rx_packet); rx_packet = NULL; } }
// discard any buffered input void usb_serial_flush_input(void) { usb_packet_t *rx; if (!usb_configuration) return; if (rx_packet) { usb_free(rx_packet); rx_packet = NULL; } while (1) { rx = usb_rx(CDC_RX_ENDPOINT); if (!rx) break; usb_free(rx); } }
int usb_rawhid_recv(void *buffer, uint32_t timeout) { usb_packet_t *rx_packet; uint32_t begin = millis(); while (1) { if (!usb_configuration) return -1; rx_packet = usb_rx(RAWHID_RX_ENDPOINT); if (rx_packet) break; if (millis() - begin > timeout || !timeout) return 0; yield(); } memcpy(buffer, rx_packet->buf, RAWHID_RX_SIZE); usb_free(rx_packet); return RAWHID_RX_SIZE; }
__noinline void usb_handle_control_status_cb(ep_callback_t cb, void *cbdata) { /* empty status transfer */ switch (usb.ctrl_dir) { case USB_CTRL_REQ_IN: usbd_pipe_state[USBD_PIPE_EP0_RX].data01 = USB_DATA01_DATA1; usb_rx(&usbd_pipe_state[USBD_PIPE_EP0_RX], NULL, 0, cb, cbdata); break; default: usbd_pipe_state[USBD_PIPE_EP0_TX].data01 = USB_DATA01_DATA1; usb_ep0_tx_cp(NULL, 0, 1 /* short packet */, cb, cbdata); break; } }
__noinline void usb_handle_control_status_cb(ep_callback_t cb) { /* empty status transfer */ switch (usb.ctrl_dir) { case USB_CTRL_REQ_IN: usbd_ep_state[0].rx.data01 = USB_DATA01_DATA1; usb_rx(&usbd_ep_state[0].rx, NULL, 0, cb, NULL); break; default: usbd_ep_state[0].tx.data01 = USB_DATA01_DATA1; usb_ep0_tx_cp(NULL, 0, 1 /* short packet */, cb, NULL); break; } }
void usb_handle_control_status(int fail) { if (fail) { usb_pipe_stall(&usb.ep_state[0].rx); usb_pipe_stall(&usb.ep_state[0].tx); return; } /* empty status transfer */ switch (usb.ctrl_dir) { case USB_CTRL_REQ_IN: usb.ep_state[0].rx.data01 = USB_DATA01_DATA1; usb_rx(&usb.ep_state[0].rx, NULL, 0, usb_handle_control_done, NULL); break; default: usb.ep_state[0].tx.data01 = USB_DATA01_DATA1; usb_ep0_tx_cp(NULL, 0, 1 /* short packet */, usb_handle_control_done, NULL); break; } }
// read a block of bytes to a buffer int usb_serial_read( void *buffer, uint32_t size ) { uint8_t *p = (uint8_t *)buffer; uint32_t qty, count=0; while ( size ) { if ( !usb_configuration ) break; if ( !rx_packet ) { rx: rx_packet = usb_rx(CDC_RX_ENDPOINT); if ( !rx_packet ) break; if ( rx_packet->len == 0 ) { usb_free(rx_packet); goto rx; } } qty = rx_packet->len - rx_packet->index; if ( qty > size ) qty = size; memcpy( p, rx_packet->buf + rx_packet->index, qty ); p += qty; count += qty; size -= qty; rx_packet->index += qty; if ( rx_packet->index >= rx_packet->len ) { usb_free( rx_packet ); rx_packet = NULL; } } return count; }
int usb_ep0_rx(void *buf, size_t len, ep_callback_t cb, void *cb_data) { return (usb_rx(&usbd_pipe_state[USBD_PIPE_EP0_RX], buf, len, cb, cb_data)); }
int usb_ep0_rx(void *buf, size_t len, ep_callback_t cb, void *cb_data) { return (usb_rx(&usb.ep_state[0].rx, buf, len, cb, cb_data)); }
void FlightSimClass::update(void) { uint8_t len, maxlen, type, *p, *end; union { uint8_t b[4]; long l; float f; } data; usb_packet_t *rx_packet; uint16_t id; while (1) { if (!usb_configuration) break; rx_packet = usb_rx(FLIGHTSIM_RX_ENDPOINT); if (!rx_packet) break; p = rx_packet->buf; end = p + 64; maxlen = 64; do { len = p[0]; if (len < 2 || len > maxlen) break; switch (p[1]) { case 0x02: // write data if (len < 10) break; id = p[2] | (p[3] << 8); type = p[4]; if (type == 1) { FlightSimInteger *item = FlightSimInteger::find(id); if (!item) break; #ifdef KINETISK data.l = *(long *)(p + 6); #else data.b[0] = p[6]; data.b[1] = p[7]; data.b[2] = p[8]; data.b[3] = p[9]; #endif item->update(data.l); } else if (type == 2) { FlightSimFloat *item = FlightSimFloat::find(id); if (!item) break; #ifdef KINETISK data.f = *(float *)(p + 6); #else data.b[0] = p[6]; data.b[1] = p[7]; data.b[2] = p[8]; data.b[3] = p[9]; #endif item->update(data.f); /// JB } else if (type == 3) { FlightSimEvent *item = FlightSimEvent::find(id); if (!item) break; #ifdef KINETISK data.l = *(long *)(p + 6); #else data.b[0] = p[6]; data.b[1] = p[7]; data.b[2] = p[8]; data.b[3] = p[9]; #endif item->update(data.f); } else if (type == 4) { FlightSimData *item = FlightSimData::find(id); if (!item) break; item->update(((char*)p)+6,len-6); /// JB End } break; case 0x03: // enable/disable if (len < 4) break; switch (p[2]) { case 1: request_id_messages = 1; /* no break */ case 2: enable(); frameCount++; break; case 3: disable(); } } p += len; maxlen -= len; } while (p < end); usb_free(rx_packet); } if (enabled && request_id_messages) { request_id_messages = 0; for (FlightSimCommand *p = FlightSimCommand::first; p; p = p->next) { p->identify(); } /// JB for (FlightSimEvent *p = FlightSimEvent::first; p; p = p->next) { p->identify(); } for (FlightSimData *p = FlightSimData::first; p; p=p->next) { p->identify(); } /// JB End for (FlightSimInteger *p = FlightSimInteger::first; p; p = p->next) { p->identify(); // TODO: send any dirty data } for (FlightSimFloat *p = FlightSimFloat::first; p; p = p->next) { p->identify(); // TODO: send any dirty data } } }
void cdc_read_more(struct cdc_ctx *ctx) { usb_rx(ctx->rx_pipe, ctx->inbuf, sizeof(ctx->inbuf), cdc_rx_done, ctx); }
int main(void) { uint8_t loops_ocr1a = 0; /* Cache for OCR1A when PWM is disabled */ uint16_t OCR1A_save; bool usb_initialized = 0; /* Is HV supply voltage reached? If not take bigger steps */ bool hv_reached = 0; setupHardware(); sei(); /* Enable interrupts */ while(1) { if(!usb_initialized) { /* Check if USB power is connected */ if (bit_is_set(PINB,4)) { /* USB initialization */ USB_Init(); CDC_Device_CreateStream(&VirtualSerial_CDC_Interface, &USBSerialStream); usb_initialized = 1; } } if (usb_connected) { /* Check mail */ usb_rx(); CDC_Device_USBTask(&VirtualSerial_CDC_Interface); USB_USBTask(); /* Send counter over usb and reset */ if (send_count && tx_flag) { tx_flag = 0; /* Print number of events and time of last event */ fprintf(&USBSerialStream, "c%3d,%3d\r\n", tx_count, tx_event_time); /* TODO: LCD */ } } /* HV supply feedback */ if( use_comparator ) { /* Check if output voltage is over threshold */ if (bit_is_set(ACSR, ACO)) { /* Not over 400V */ if ((loops_ocr1a % 10) == 0) { if (OCR1A < 100) { if (!hv_reached) { OCR1A += 15; } else { OCR1A += 1; } } if (OCR1A < 500) { if (!hv_reached) { OCR1A += 10; } else { OCR1A += 1; } } } } else if((loops_ocr1a == 100)) { /* Required voltage reached, decrease step size */ hv_reached = 1; /* Decrease OCR1A when after some time to avoid creeping upwards */ if (OCR1A > 2) { OCR1A--; } /* Reset loop counter */ loops_ocr1a = 0; } loops_ocr1a++; } if (buzzer_enabled && tick_pending) { bit_set(PORTC, 7); tick_pending = 0; } sleep1ms(); bit_clear(PORTC, 7); } }