Updated firware to contain only 1 endpoint. Created a global data buffer to hold the ADC EP1 IN data. This increased performance from 7.5 KBps to 150+ KBps.

This commit is contained in:
Mickey Malone
2021-02-10 07:26:40 -06:00
parent b1eb887656
commit 55de2de8c7
4 changed files with 56 additions and 98 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
build build
.vscode

View File

@@ -32,11 +32,9 @@
#define usb_hw_clear hw_clear_alias(usb_hw) #define usb_hw_clear hw_clear_alias(usb_hw)
// Function prototypes for our device specific endpoint handlers defined // Function prototypes for our device specific endpoint handlers defined
// later on
void ep0_in_handler(uint8_t *buf, uint16_t len); void ep0_in_handler(uint8_t *buf, uint16_t len);
void ep0_out_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 ep1_in_handler(uint8_t *buf, uint16_t len);
void ep2_in_handler(uint8_t *buf, uint16_t len);
// Global device address // Global device address
static bool should_set_address = false; static bool should_set_address = false;
@@ -46,6 +44,9 @@ static volatile bool configured = false;
// Global data buffer for EP0 // Global data buffer for EP0
static uint8_t ep0_buf[64]; static uint8_t ep0_buf[64];
// Global data buffer for EP1
static uint8_t ep1_buf[64];
// Struct defining the device configuration // Struct defining the device configuration
static struct usb_device_configuration dev_config = { static struct usb_device_configuration dev_config = {
.device_descriptor = &device_descriptor, .device_descriptor = &device_descriptor,
@@ -71,21 +72,12 @@ static struct usb_device_configuration dev_config = {
.data_buffer = &usb_dpram->ep0_buf_a[0], .data_buffer = &usb_dpram->ep0_buf_a[0],
}, },
{ {
.descriptor = &ep1_out, .descriptor = &ep1_in,
.handler = &ep1_out_handler, .handler = &ep1_in_handler,
// EP1 starts at offset 0 for endpoint control .endpoint_control = &usb_dpram->ep_ctrl[0].in,
.endpoint_control = &usb_dpram->ep_ctrl[0].out, .buffer_control = &usb_dpram->ep_buf_ctrl[1].in,
.buffer_control = &usb_dpram->ep_buf_ctrl[1].out,
// First free EPX buffer // First free EPX buffer
.data_buffer = &usb_dpram->epx_data[0 * 64], .data_buffer = &usb_dpram->epx_data[0],
},
{
.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],
} }
} }
}; };
@@ -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) { 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) { * @brief Get random data using the onboard pico ADC.
uint16_t new_buf[40]; *
uint16_t adc_result; * @param buf the buffer to store the random data in
uint8_t size; * @param len the length of the random data in bytes
int i; */
void get_random_data(char *buf, uint16_t len) {
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) {
uint16_t adc_result; uint16_t adc_result;
uint8_t size; uint8_t size;
int i; int i;
@@ -591,28 +556,37 @@ void get_random_data(char *buffer, uint16_t len) {
size = 64; size = 64;
} }
memset(buffer, 0, len); memset(buf, 0, len);
for(i = 1; i <= len; i=i+1) for(i = 1; i <= len; i=i+1)
{ {
adc_result = adc_read(); adc_result = adc_read();
memcpy(&buffer[i-1], (void*)&adc_result, 2); memcpy(&buf[i-1], (void*)&adc_result, 2);
} }
gpio_put(25, 0); gpio_put(25, 0);
} }
void ep2_in_handler(uint8_t *buf, uint16_t len) { /**
printf("Sent %d bytes to host\n", len); * @brief EP1 in transfer complete. Prime the EP1 in buffer
// Get ready to rx again from host * 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]; printf("Sent %d bytes to host\n", len);
get_random_data(buffer, 64);
//usb_start_transfer(usb_get_endpoint_configuration(EP1_OUT_ADDR), NULL, 64); // Prime the EP1 IN buffer for the next transfer
struct usb_endpoint_configuration *ep = usb_get_endpoint_configuration(EP2_IN_ADDR); get_random_data(ep1_buf, 64);
usb_start_transfer(ep, buffer, 64); usb_start_transfer(usb_get_endpoint_configuration(EP1_IN_ADDR), ep1_buf, 64);
} }
/**
* @brief This is where it all begins
*/
int main(void) { int main(void) {
// Enable uart debug messages
stdio_init_all(); stdio_init_all();
// Builtin GPIO // Builtin GPIO
@@ -632,12 +606,9 @@ int main(void) {
tight_loop_contents(); tight_loop_contents();
} }
char buffer[64]; // Populate the TX buffer
get_random_data(ep1_buf, 64);
// Get ready to tx usb_start_transfer(usb_get_endpoint_configuration(EP1_IN_ADDR), ep1_buf, 64);
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);
// Everything is interrupt driven so just loop here // Everything is interrupt driven so just loop here
while (1) { while (1) {

View File

@@ -38,8 +38,7 @@ struct usb_device_configuration {
#define EP0_IN_ADDR (USB_DIR_IN | 0) #define EP0_IN_ADDR (USB_DIR_IN | 0)
#define EP0_OUT_ADDR (USB_DIR_OUT | 0) #define EP0_OUT_ADDR (USB_DIR_OUT | 0)
#define EP1_OUT_ADDR (USB_DIR_OUT | 1) #define EP1_IN_ADDR (USB_DIR_IN | 1)
#define EP2_IN_ADDR (USB_DIR_IN | 2)
// EP0 IN and OUT // EP0 IN and OUT
static const struct usb_endpoint_descriptor ep0_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, .bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = 0, .bInterfaceNumber = 0,
.bAlternateSetting = 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. .bInterfaceClass = 0xef, // Miscellaneous device. See https://www.usb.org/defined-class-codes.
.bInterfaceSubClass = 0, .bInterfaceSubClass = 0,
.bInterfaceProtocol = 0, .bInterfaceProtocol = 0,
.iInterface = 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), .bLength = sizeof(struct usb_endpoint_descriptor),
.bDescriptorType = USB_DT_ENDPOINT, .bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = EP1_OUT_ADDR, // EP number 1, OUT from host (rx to device) .bEndpointAddress = EP1_IN_ADDR, // EP number 1, IN from host (tx from 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)
.bmAttributes = USB_TRANSFER_TYPE_BULK, .bmAttributes = USB_TRANSFER_TYPE_BULK,
.wMaxPacketSize = 64, .wMaxPacketSize = 64,
.bInterval = 0 .bInterval = 0
@@ -113,8 +103,7 @@ static const struct usb_configuration_descriptor config_descriptor = {
.bDescriptorType = USB_DT_CONFIG, .bDescriptorType = USB_DT_CONFIG,
.wTotalLength = (sizeof(config_descriptor) + .wTotalLength = (sizeof(config_descriptor) +
sizeof(interface_descriptor) + sizeof(interface_descriptor) +
sizeof(ep1_out) + sizeof(ep1_in)),
sizeof(ep2_in)),
.bNumInterfaces = 1, .bNumInterfaces = 1,
.bConfigurationValue = 1, // Configuration 1 .bConfigurationValue = 1, // Configuration 1
.iConfiguration = 0, // No string .iConfiguration = 0, // No string

View File

@@ -21,11 +21,8 @@ cfg = rng.get_active_configuration()
# Get the only interface of our device # Get the only interface of our device
intf = cfg.interfaces()[0] intf = cfg.interfaces()[0]
# Get the endpoints # Get the endpoint
endpts = intf.endpoints() endpt = intf.endpoints()[0]
# Get the IN or Host RCV Device TX endpoint
endpts_in = endpts[0] if endpts[0].bEndpointAddress == usb.util.ENDPOINT_IN else endpts[1]
# Time tracking for bits/s # Time tracking for bits/s
count = 0 count = 0
@@ -34,11 +31,11 @@ start_time = (int(time.time()) - 1)
if args.performance: if args.performance:
while True: while True:
try: try:
from_device = endpts_in.read(endpts_in.wMaxPacketSize, 500) from_device = endpt.read(endpt.wMaxPacketSize, 500)
count = count+1 count = count+1
print(":".join("{:02x}".format(b) for b in from_device), end="") 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 )) print(" KBps {0:.2f}".format((int((count * 64) / (int(time.time()) - start_time))) / 1024 ))
except KeyboardInterrupt: except KeyboardInterrupt:
exit(0) exit(0)
else: 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)))