M firmware/include/usb_device_cdc.h => firmware/include/usb_device_cdc.h +7 -2
@@ 96,7 96,8 @@ typedef struct {
} usb_cdc_call_management_functional_decriptor_t;
_Static_assert(sizeof(usb_cdc_call_management_functional_decriptor_t) == 5, "Size check");
-typedef void (*cdc_receive_callback_t)(usb_device_t* device, uint16_t count);
+typedef uint16_t (*cdc_receive_callback_t)(usb_device_t* device, uint8_t* data, uint16_t count);
+typedef uint8_t* (*cdc_receive_location_callback_t)(usb_device_t* device, uint16_t count);
/* typedef enum { */
/* CDC_STATE_NONE, */
@@ 116,7 117,8 @@ typedef struct {
uint8_t functional_descriptors_count;
usb_cdc_functional_descriptor_header_t** functional_descriptors;
- cdc_receive_callback_t callback;
+ cdc_receive_callback_t receive_callback;
+ cdc_receive_location_callback_t receive_location_callback;
// Internal state.
queue_t* rx_buffer;
@@ 143,6 145,9 @@ void cdc_acm_configure(usb_device_t *device, uint16_t rx_queue_size);
void cdc_data_set_receive_callback(usb_device_t *device,
cdc_receive_callback_t callback);
+void cdc_data_set_receive_location_callback(usb_device_t *device,
+ cdc_receive_location_callback_t callback);
+
int32_t cdc_data_send_blocking(usb_device_t *device, uint8_t *data, uint16_t size);
int32_t cdc_data_send(usb_device_t* device, uint8_t* data, uint16_t size);
M firmware/src/main.c => firmware/src/main.c +74 -17
@@ 21,6 21,8 @@ pin_t wkup;
pin_t led1;
exti_t exti_wkup;
+uint8_t* global_framebuffer;
+
void init_fmc(fmc_t *fmc)
{
@@ 239,7 241,7 @@ usb_device_t* init_usb()
void *usb_dev = usb_device_init(USB_OTG_HS1, &USB_CLASS_CDC_ACM,
0x1234, 0x1111, u"Frantisek Bohacek",
u"Display", 1, NULL);
- cdc_acm_configure(usb_dev, 512 * 8); // 8 full packets maximum
+ cdc_acm_configure(usb_dev, 512 * 8); // 8 full packets maximum size
usb_device_setup(usb_dev);
return usb_dev;
@@ 450,6 452,9 @@ pixel_rgb888_t* init_display(display_t* display, fmc_t* fmc)
void app_loop(usb_device_t* usb_dev, display_t* display, pixel_rgb888_t* framebuffer);
+uint16_t cdc_receive_callback(usb_device_t* device, uint8_t* data, uint16_t count);
+uint8_t* cdc_receive_location_callback(usb_device_t* device, uint16_t count);
+
void main()
{
fmc_t fmc;
@@ 490,21 495,70 @@ void main()
app_loop(usb_dev, &display, framebuffer);
}
+bool image_command_handling = false;
+bool image_command_handled = false;
+uint8_t* framebuffer_ptr;
+uint32_t read_count;
+#define TOTAL_PIXEL_BYTES DISPLAY_WIDTH * DISPLAY_HEIGHT * 3
+
+uint16_t cdc_receive_callback(usb_device_t *device, uint8_t *data,
+ uint16_t count) {
+
+ if (!image_command_handling && data[0] == 'i') {
+ framebuffer_ptr = global_framebuffer;
+ read_count = 0;
+ image_command_handling = true;
+
+ for (uint16_t i = 0; i < count - 1; i++) {
+ framebuffer_ptr[i] = data[i + 1];
+ }
+ framebuffer_ptr += count - 1;
+ read_count += count - 1;
+ return count;
+ }
+
+ return 0;
+}
+
+uint8_t* cdc_receive_location_callback(usb_device_t *device, uint16_t count) {
+ if (!image_command_handling) {
+ return NULL;
+ }
+
+ uint8_t* ptr = framebuffer_ptr;
+ framebuffer_ptr += count;
+ read_count += count;
+
+ if (read_count >= TOTAL_PIXEL_BYTES) {
+ image_command_handling = false;
+ image_command_handled = true;
+ }
+
+ return framebuffer_ptr;
+}
+
void app_loop(usb_device_t* usb_dev, display_t* display, pixel_rgb888_t* framebuffer)
{
- uint8_t data[1024];
+ global_framebuffer = (uint8_t*)framebuffer;
+
+ cdc_data_set_receive_callback(usb_dev, cdc_receive_callback);
+ cdc_data_set_receive_location_callback(usb_dev, cdc_receive_location_callback);
+
+ uint8_t data[16];
bool handling_cmd = false;
uint8_t cmd;
uint32_t pos = 0;
- uint32_t max_size = 1;
display_refresh(display);
while (1) {
- uint16_t received = cdc_data_receive(usb_dev, data, max_size);
+ uint16_t received = cdc_data_receive(usb_dev, data, 1);
- max_size = 1;
+ if (image_command_handled) {
+ display_refresh(display);
+ image_command_handled = false;
+ }
if (received == 0) {
continue;
@@ 563,24 617,27 @@ void app_loop(usb_device_t* usb_dev, display_t* display, pixel_rgb888_t* framebu
}
display_refresh(display);
break;
- case 'i':
- handling_cmd = true;
- max_size = 1024;
+ case 'i': {
+ uint8_t* framebuffer_ptr = (uint8_t*)framebuffer;
+ uint32_t bytes = DISPLAY_WIDTH * DISPLAY_HEIGHT * 3;
- for (uint16_t i = 0; i < received; i++) {
- if (pos > 0) {
- ((uint8_t *)framebuffer)[pos - 1] = data[i];
+ pos = 0;
+
+ while (pos < bytes) {
+ uint32_t max = bytes - pos;
+ if (max > 65535) {
+ max = 65535;
}
- pos++;
- }
- if (pos >= DISPLAY_WIDTH * DISPLAY_HEIGHT * 3) {
- handling_cmd = false;
- display_refresh(display);
- max_size = 1;
+ uint16_t received = cdc_data_receive(usb_dev, framebuffer_ptr, max);
+ pos += received;
+ framebuffer_ptr += received;
}
+
+ display_refresh(display);
break;
}
+ }
}
}
M firmware/src/usb_device_cdc.c => firmware/src/usb_device_cdc.c +23 -3
@@ 585,14 585,28 @@ void usb_device_cdc_enable_endpoint_maybe(usb_device_t* device, usb_device_cdc_t
void usb_device_cdc_received_data_callback(usb_device_t *device, packet_info_t *packet) {
usb_device_cdc_t* cdc = (usb_device_cdc_t*)device->class;
- uint8_t data[4*MAX_PACKET_SIZE];
+ uint8_t data[2*MAX_PACKET_SIZE];
uint16_t len = packet->byte_count;
volatile uint32_t* fifo = &device->fifos[packet->endpoint_num].data[0];
if (packet->packet_status == PACKET_OUT_DATA_PACKET_RCVD) {
- // TODO: could be optimized until pointer has to wrap
+ if (cdc->receive_location_callback != NULL) {
+ uint8_t* receive_location = cdc->receive_location_callback(device, len);
+ if (receive_location != NULL) {
+ usb_generic_read(receive_location, len, fifo);
+ return;
+ }
+ }
+
usb_generic_read(data, len, fifo);
+
+ if (cdc->receive_callback != NULL) {
+ uint16_t app_read = cdc->receive_callback(device, data, len);
+ len -= app_read;
+ }
+
+ // TODO: could be optimized until pointer has to wrap
if (queue_space(cdc->rx_buffer) < len) {
cdc->lost_data += len - queue_space(cdc->rx_buffer);
}
@@ 624,7 638,13 @@ void usb_device_cdc_nyet_callback(usb_device_t *device, uint8_t endpoint) {
void cdc_data_set_receive_callback(usb_device_t *device,
cdc_receive_callback_t callback) {
usb_device_cdc_t* cdc = (usb_device_cdc_t*)device->class;
- cdc->callback = callback;
+ cdc->receive_callback = callback;
+}
+
+void cdc_data_set_receive_location_callback(usb_device_t *device,
+ cdc_receive_location_callback_t callback) {
+ usb_device_cdc_t* cdc = (usb_device_cdc_t*)device->class;
+ cdc->receive_location_callback = callback;
}
int32_t cdc_data_send_blocking(usb_device_t *device, uint8_t *data, uint16_t size) {