~ruther/stm32h747i-disco-usb-image-viewer

4c34bf99a65daa0fbc7ed26e30c0587290a8b062 — Rutherther 4 months ago 76bfb76
fix: unicode strings
6 files changed, 31 insertions(+), 38 deletions(-)

M include/usb.h
M include/usb_device.h
M src/main.c
M src/usb.c
M src/usb_device.c
M src/usb_device_cdc.c
M include/usb.h => include/usb.h +1 -1
@@ 267,7 267,7 @@ typedef struct {

typedef struct {
  usb_descriptor_t header;
  uint8_t *bString;
  uint16_t *bString;
} usb_unicode_string_descriptor_t;

// NOTE: End of structs from usb specification here

M include/usb_device.h => include/usb_device.h +6 -4
@@ 3,6 3,8 @@
#include "generic.h"
#include "queue.h"

typedef uint16_t char16_t;

#ifndef USB_DEVICE_H
#define USB_DEVICE_H



@@ 85,8 87,8 @@ typedef struct {
 */
  struct usb_class_header_t *(*init)(usb_device_t *device,
                uint16_t id_vendor, uint16_t id_product,
                char *vendor_name, char *product_name,
                uint16_t serial_number, char* serial_name);
                char16_t *vendor_name, char16_t *product_name,
                uint16_t serial_number, char16_t* serial_name);

/**
 * @brief Configure the endpoint zero, and send configuration, including writing to the fifo.


@@ 290,8 292,8 @@ extern usb_device_t usb_devices[2];
 */
void *usb_device_init(usb_device_slot_t slot, usb_class_vtable_t *class,
                      uint16_t id_vendor, uint16_t id_product,
                      char *vendor_name, char *product_name,
                      uint16_t serial_number, char* serial_name);
                      char16_t *vendor_name, char16_t *product_name,
                      uint16_t serial_number, char16_t* serial_name);

/**
 * @brief Setup device endpoint 0

M src/main.c => src/main.c +2 -5
@@ 158,12 158,9 @@ void main()
  pin_into_input_highspeed(&otg_hs_overcurrent);

  // TODO: why can't I send string descriptors?
  /* void *usb_dev = usb_device_init(USB_OTG_HS1, &USB_CLASS_CDC_ACM, */
  /*                                 0x1234, 0x1111, "Frantisek Bohacek", */
  /*                                 "Display", 1, NULL); */
  void *usb_dev = usb_device_init(USB_OTG_HS1, &USB_CLASS_CDC_ACM,
                                  0x1234, 0x1111, NULL,
                                  NULL, 1, NULL);
                                  0x1234, 0x1111, u"Frantisek Bohacek",
                                  u"Display", 1, NULL);
  cdc_acm_configure(usb_dev, 512);
  usb_device_setup(usb_dev);


M src/usb.c => src/usb.c +1 -1
@@ 263,7 263,7 @@ task_result_t usb_send_unicode_string_descriptor(
  usb_generic_fill_fifo(endpoint, &data.bytes[0], 4, fifo_tx_target);

  if (string_descriptor->header.bLength > 4) {
    usb_generic_fill_fifo(endpoint, &string_descriptor->bString[2], string_descriptor->header.bLength - 4, fifo_tx_target);
    usb_generic_fill_fifo(endpoint, (uint8_t*)&string_descriptor->bString[1], string_descriptor->header.bLength - 4, fifo_tx_target);
  }

  /* endpoint->DIEPCTL |= USB_OTG_DIEPCTL_CNAK; */

M src/usb_device.c => src/usb_device.c +3 -12
@@ 14,8 14,8 @@ void* usb_periph_addresses[] =

void* usb_device_init(usb_device_slot_t slot, usb_class_vtable_t *class,
                      uint16_t id_vendor, uint16_t id_product,
                      char *vendor_name, char *product_name,
                      uint16_t serial_number, char* serial_name) {
                      char16_t *vendor_name, char16_t *product_name,
                      uint16_t serial_number, char16_t* serial_name) {
  usb_device_t* device = &usb_devices[slot];
  void* peripheral_address = usb_periph_addresses[slot];



@@ 71,10 71,6 @@ void usb_device_wait_for_handshake(void* device_ptr) {
void usb_device_setup(void* device_ptr) {
  RCC->AHB1ENR |= RCC_AHB1ENR_USB1OTGHSEN | RCC_AHB1ENR_USB1OTGHSULPIEN;

  volatile uint32_t dummy;
  dummy = RCC->AHB1ENR;
  dummy = RCC->AHB1ENR;

  NVIC_SetPriority(OTG_HS_IRQn, 2);
  NVIC_EnableIRQ(OTG_HS_IRQn);



@@ 163,7 159,7 @@ task_result_t usb_handle_setup_command(usb_device_t *device, usb_setup_command_t
      size = sizeof(usb_endpoint_status_t);
      endpoint_status.halt = 0;
      endpoint_status.reserved_zeros = 0;
      packet = (uint8_t*)&interface_status;
      packet = (uint8_t*)&endpoint_status;
    }
      break;
    }


@@ 420,7 416,6 @@ task_result_t usb_handle_setup(usb_device_t *device, usb_event_t event) {

void usb_handle_rxflvl_control_int(usb_device_t *device,
                                   packet_info_t *packet_info) {
  uint32_t dummy;
  uint8_t data[64];
  volatile uint32_t *fifo = device->fifos[0].data;



@@ 433,10 428,6 @@ void usb_handle_rxflvl_control_int(usb_device_t *device,
    usb_setup_command_t command;
    usb_generic_read((uint8_t*)&command, 8, fifo);

    if (command.wLength > 60000) {
      dummy = 0;
    }

    if (!queue_enqueue(device->setup.received_setup_commands, &command)) {
      // Got a problem, setup command lost!
      device->setup.detected_setup_errors++;

M src/usb_device_cdc.c => src/usb_device_cdc.c +18 -15
@@ 10,8 10,8 @@

usb_class_header_t* usb_device_cdc_init(usb_device_t *device,
                uint16_t id_vendor, uint16_t id_product,
                char *vendor_name, char *product_name,
                uint16_t serial_number, char* serial_name);
                char16_t *vendor_name, char16_t *product_name,
                uint16_t serial_number, char16_t* serial_name);

task_result_t usb_device_cdc_send_configuration(usb_device_t* device, usb_setup_command_t* cmd);
void usb_device_cdc_setup_endpoints(usb_device_t* device, uint8_t configuration);


@@ 51,10 51,17 @@ usb_class_vtable_t USB_CLASS_CDC_ACM = {
  .received_data_callback = usb_device_cdc_received_data_callback,
};

static inline size_t strlen16(register const char16_t * string) {
    if (!string) return 0;
    register size_t len = 0;
    while(string[len++]);
    return len;
}

usb_class_header_t *usb_device_cdc_init(usb_device_t *device, uint16_t id_vendor,
                          uint16_t id_product, char *vendor_name,
                          char *product_name, uint16_t serial_number,
                          char *serial_name) {
                          uint16_t id_product, char16_t *vendor_name,
                          char16_t *product_name, uint16_t serial_number,
                          char16_t *serial_name) {
  usb_class_header_t* class = (usb_class_header_t*)calloc(1, sizeof(usb_device_cdc_t));

  class->device_descriptor.idProduct = id_product;


@@ 86,21 93,21 @@ usb_class_header_t *usb_device_cdc_init(usb_device_t *device, uint16_t id_vendor

  if (vendor_name != NULL) {
    descriptor->header.bDescriptorType = DESCRIPTOR_STRING;
    descriptor->header.bLength = 4 + strlen(vendor_name);
    descriptor->bString = (uint8_t*)vendor_name;
    descriptor->header.bLength = 2 + strlen16(vendor_name) * sizeof(char16_t);
    descriptor->bString = (uint16_t*)vendor_name;

    descriptor++;
  }
  if (product_name != NULL) {
    descriptor->header.bDescriptorType = DESCRIPTOR_STRING;
    descriptor->header.bLength = 4 + strlen(product_name);
    descriptor->bString = (uint8_t*)product_name;
    descriptor->header.bLength = 2 + strlen16(product_name) * sizeof(char16_t);
    descriptor->bString = (uint16_t*)product_name;
    descriptor++;
  }
  if (serial_name != NULL) {
    descriptor->header.bDescriptorType = DESCRIPTOR_STRING;
    descriptor->header.bLength = 4 + strlen(serial_name);
    descriptor->bString = (uint8_t*)serial_name;
    descriptor->header.bLength = 2 + strlen16(serial_name) * sizeof(char16_t);
    descriptor->bString = (uint16_t*)serial_name;
    descriptor++;
  }



@@ 504,7 511,6 @@ task_result_t cdc_transmit(usb_device_t *device, uint8_t* data, uint16_t* size) 
}

void cdc_process_tx(usb_device_t *device, cdc_event_t event) {
  usb_device_cdc_t* cdc = (usb_device_cdc_t*)device->class;
  switch (event) {
  case CDC_TX_REQ:
    break;


@@ 633,8 639,6 @@ int32_t cdc_data_send(usb_device_t *device, uint8_t* data, uint16_t size) {
    size = strlen((char*)data);
  }

  usb_device_cdc_t* cdc = (usb_device_cdc_t*)device->class;

  task_result_t result = cdc_transmit(device, data, &size);

  // If would block, just send back nothing was sent


@@ 654,7 658,6 @@ uint16_t cdc_data_receive(usb_device_t *device, uint8_t* buffer,
  uint16_t size = max_size;

  for (uint16_t i = 0; i < max_size; i++) {
    uint8_t element;
    if (!queue_dequeue_safely(cdc->rx_buffer, buffer + i)) {
      size = i;
      break;

Do not follow this link