mirror of
https://github.com/polhenarejos/pico-rng.git
synced 2026-06-07 18:43:34 +02:00
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:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
build
|
build
|
||||||
|
.vscode
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)))
|
||||||
|
|||||||
Reference in New Issue
Block a user