diff --git a/.gitignore b/.gitignore index 378eac2..5acb669 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ build +.vscode diff --git a/firmware/pico_rng.c b/firmware/pico_rng.c index bf68bd7..0c13090 100644 --- a/firmware/pico_rng.c +++ b/firmware/pico_rng.c @@ -32,11 +32,9 @@ #define usb_hw_clear hw_clear_alias(usb_hw) // Function prototypes for our device specific endpoint handlers defined -// later on void ep0_in_handler(uint8_t *buf, uint16_t len); void ep0_out_handler(uint8_t *buf, uint16_t len); -void ep1_out_handler(uint8_t *buf, uint16_t len); -void ep2_in_handler(uint8_t *buf, uint16_t len); +void ep1_in_handler(uint8_t *buf, uint16_t len); // Global device address static bool should_set_address = false; @@ -46,6 +44,9 @@ static volatile bool configured = false; // Global data buffer for EP0 static uint8_t ep0_buf[64]; +// Global data buffer for EP1 +static uint8_t ep1_buf[64]; + // Struct defining the device configuration static struct usb_device_configuration dev_config = { .device_descriptor = &device_descriptor, @@ -71,21 +72,12 @@ static struct usb_device_configuration dev_config = { .data_buffer = &usb_dpram->ep0_buf_a[0], }, { - .descriptor = &ep1_out, - .handler = &ep1_out_handler, - // EP1 starts at offset 0 for endpoint control - .endpoint_control = &usb_dpram->ep_ctrl[0].out, - .buffer_control = &usb_dpram->ep_buf_ctrl[1].out, + .descriptor = &ep1_in, + .handler = &ep1_in_handler, + .endpoint_control = &usb_dpram->ep_ctrl[0].in, + .buffer_control = &usb_dpram->ep_buf_ctrl[1].in, // First free EPX buffer - .data_buffer = &usb_dpram->epx_data[0 * 64], - }, - { - .descriptor = &ep2_in, - .handler = &ep2_in_handler, - .endpoint_control = &usb_dpram->ep_ctrl[1].in, - .buffer_control = &usb_dpram->ep_buf_ctrl[2].in, - // Second free EPX buffer - .data_buffer = &usb_dpram->epx_data[1 * 64], + .data_buffer = &usb_dpram->epx_data[0], } } }; @@ -534,51 +526,24 @@ void ep0_in_handler(uint8_t *buf, uint16_t len) { } } +/** + * @brief EP0 out transfer complete. + * + * @param buf the data that was received + * @param len the length that was received + */ void ep0_out_handler(uint8_t *buf, uint16_t len) { - ; + // Nothing to see here + return; } -// Device specific functions -void ep1_out_handler(uint8_t *buf, uint16_t len) { - uint16_t new_buf[40]; - uint16_t adc_result; - uint8_t size; - int i; - - printf("RX %d bytes from host %d \n", len, *buf); - - gpio_put(25, 1); - - if(len != 1) - { - //TODO handle length error - size = 64; - } - else - { - size = *buf; - if(size == 0 || size > 64) - { - //TODO handle requested size error - size = 64; - } - } - - memset(new_buf, 0, 40); - for(i = 1; i < (size / 2) + 4; i++) - { - adc_result = adc_read(); - memcpy(&new_buf[i-1], (void*)&adc_result, sizeof(uint16_t)); - } - - gpio_put(25, 0); - - // Send random data back to the host - struct usb_endpoint_configuration *ep = usb_get_endpoint_configuration(EP2_IN_ADDR); - usb_start_transfer(ep, (char*)new_buf, size); -} - -void get_random_data(char *buffer, uint16_t len) { +/** + * @brief Get random data using the onboard pico ADC. + * + * @param buf the buffer to store the random data in + * @param len the length of the random data in bytes + */ +void get_random_data(char *buf, uint16_t len) { uint16_t adc_result; uint8_t size; int i; @@ -591,28 +556,37 @@ void get_random_data(char *buffer, uint16_t len) { size = 64; } - memset(buffer, 0, len); + memset(buf, 0, len); for(i = 1; i <= len; i=i+1) { adc_result = adc_read(); - memcpy(&buffer[i-1], (void*)&adc_result, 2); + memcpy(&buf[i-1], (void*)&adc_result, 2); } gpio_put(25, 0); } -void ep2_in_handler(uint8_t *buf, uint16_t len) { - printf("Sent %d bytes to host\n", len); - // Get ready to rx again from host +/** + * @brief EP1 in transfer complete. Prime the EP1 in buffer + * with more random data. + * + * @param buf the data that was sent + * @param len the length that was sent + */ +void ep1_in_handler(uint8_t *buf, uint16_t len) { - char buffer[64]; - get_random_data(buffer, 64); - //usb_start_transfer(usb_get_endpoint_configuration(EP1_OUT_ADDR), NULL, 64); - struct usb_endpoint_configuration *ep = usb_get_endpoint_configuration(EP2_IN_ADDR); - usb_start_transfer(ep, buffer, 64); + printf("Sent %d bytes to host\n", len); + + // Prime the EP1 IN buffer for the next transfer + get_random_data(ep1_buf, 64); + usb_start_transfer(usb_get_endpoint_configuration(EP1_IN_ADDR), ep1_buf, 64); } +/** + * @brief This is where it all begins + */ int main(void) { + // Enable uart debug messages stdio_init_all(); // Builtin GPIO @@ -632,12 +606,9 @@ int main(void) { tight_loop_contents(); } - char buffer[64]; - - // Get ready to tx - get_random_data(buffer, 64); - usb_start_transfer(usb_get_endpoint_configuration(EP2_IN_ADDR), buffer, 64); - //usb_start_transfer(usb_get_endpoint_configuration(EP1_OUT_ADDR), NULL, 64); + // Populate the TX buffer + get_random_data(ep1_buf, 64); + usb_start_transfer(usb_get_endpoint_configuration(EP1_IN_ADDR), ep1_buf, 64); // Everything is interrupt driven so just loop here while (1) { diff --git a/firmware/pico_rng.h b/firmware/pico_rng.h index 807f859..9d69055 100644 --- a/firmware/pico_rng.h +++ b/firmware/pico_rng.h @@ -38,8 +38,7 @@ struct usb_device_configuration { #define EP0_IN_ADDR (USB_DIR_IN | 0) #define EP0_OUT_ADDR (USB_DIR_OUT | 0) -#define EP1_OUT_ADDR (USB_DIR_OUT | 1) -#define EP2_IN_ADDR (USB_DIR_IN | 2) +#define EP1_IN_ADDR (USB_DIR_IN | 1) // EP0 IN and OUT static const struct usb_endpoint_descriptor ep0_out = { @@ -83,26 +82,17 @@ static const struct usb_interface_descriptor interface_descriptor = { .bDescriptorType = USB_DT_INTERFACE, .bInterfaceNumber = 0, .bAlternateSetting = 0, - .bNumEndpoints = 2, // Interface has 2 endpoints + .bNumEndpoints = 1, // Interface has 1 endpoint .bInterfaceClass = 0xef, // Miscellaneous device. See https://www.usb.org/defined-class-codes. .bInterfaceSubClass = 0, .bInterfaceProtocol = 0, .iInterface = 0 }; -static const struct usb_endpoint_descriptor ep1_out = { +static const struct usb_endpoint_descriptor ep1_in = { .bLength = sizeof(struct usb_endpoint_descriptor), .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP1_OUT_ADDR, // EP number 1, OUT from host (rx to device) - .bmAttributes = USB_TRANSFER_TYPE_BULK, - .wMaxPacketSize = 64, - .bInterval = 0 -}; - -static const struct usb_endpoint_descriptor ep2_in = { - .bLength = sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP2_IN_ADDR, // EP number 2, IN from host (tx from device) + .bEndpointAddress = EP1_IN_ADDR, // EP number 1, IN from host (tx from device) .bmAttributes = USB_TRANSFER_TYPE_BULK, .wMaxPacketSize = 64, .bInterval = 0 @@ -113,8 +103,7 @@ static const struct usb_configuration_descriptor config_descriptor = { .bDescriptorType = USB_DT_CONFIG, .wTotalLength = (sizeof(config_descriptor) + sizeof(interface_descriptor) + - sizeof(ep1_out) + - sizeof(ep2_in)), + sizeof(ep1_in)), .bNumInterfaces = 1, .bConfigurationValue = 1, // Configuration 1 .iConfiguration = 0, // No string diff --git a/firmware/pico_rng_test.py b/firmware/pico_rng_test.py index 0e17f69..2960e8e 100755 --- a/firmware/pico_rng_test.py +++ b/firmware/pico_rng_test.py @@ -21,11 +21,8 @@ cfg = rng.get_active_configuration() # Get the only interface of our device intf = cfg.interfaces()[0] -# Get the endpoints -endpts = intf.endpoints() - -# Get the IN or Host RCV Device TX endpoint -endpts_in = endpts[0] if endpts[0].bEndpointAddress == usb.util.ENDPOINT_IN else endpts[1] +# Get the endpoint +endpt = intf.endpoints()[0] # Time tracking for bits/s count = 0 @@ -34,11 +31,11 @@ start_time = (int(time.time()) - 1) if args.performance: while True: try: - from_device = endpts_in.read(endpts_in.wMaxPacketSize, 500) + from_device = endpt.read(endpt.wMaxPacketSize, 500) count = count+1 print(":".join("{:02x}".format(b) for b in from_device), end="") print(" KBps {0:.2f}".format((int((count * 64) / (int(time.time()) - start_time))) / 1024 )) except KeyboardInterrupt: exit(0) else: - print(":".join("{:02x}".format(b) for b in endpts_in.read(endpts_in.wMaxPacketSize, 500))) + print(":".join("{:02x}".format(b) for b in endpt.read(endpt.wMaxPacketSize, 500)))