@@ 420,4 420,13 @@ task_result_t usb_send_unicode_string_descriptor(
     uint16_t max_size,
     volatile uint32_t *fifo_tx_target);
 
+task_result_t usb_send_unicode_string_descriptor(
+    USB_OTG_INEndpointTypeDef *endpoint,
+    usb_unicode_string_descriptor_t *string_descriptor,
+    uint16_t max_size,
+    volatile uint32_t *fifo_tx_target);
+
+void usb_flush_tx_fifo(USB_OTG_GlobalTypeDef* core, uint16_t fifo_num);
+void usb_flush_rx_fifo(USB_OTG_GlobalTypeDef* core);
+
 #endif // USB_H
 
  
@@ 1,5 1,6 @@
 #include "usb.h"
 #include "usb_device.h"
+#include "registers.h"
 #include <stm32h747xx.h>
 
 typedef union {
@@ 110,7 111,7 @@ task_result_t usb_generic_setup_in_endpoint(USB_OTG_INEndpointTypeDef *endpoint,
   } else { // just one packet, of zero length
     endpoint->DIEPTSIZ = (1 << USB_OTG_DIEPTSIZ_PKTCNT_Pos);
   }
-  endpoint->DIEPCTL = USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA;
+  endpoint->DIEPCTL |= USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA;
 
   return RES_OK;
 }
@@ 127,7 128,7 @@ task_result_t usb_generic_send(USB_OTG_INEndpointTypeDef *endpoint,
   usb_generic_fill_fifo(endpoint, data, size, fifo_tx_target);
 
   // After the fifo is filled...
-  endpoint->DIEPCTL = USB_OTG_DIEPCTL_CNAK;
+  endpoint->DIEPCTL |= USB_OTG_DIEPCTL_CNAK;
   return RES_OK;
 }
 
@@ 226,7 227,7 @@ task_result_t usb_send_string_descriptor_zero(USB_OTG_INEndpointTypeDef *endpoin
     usb_generic_fill_fifo(endpoint, (uint8_t*)&string_descriptor->wLANGID[1], string_descriptor->header.bLength - 4, fifo_tx_target);
   }
 
-  endpoint->DIEPCTL = USB_OTG_DIEPCTL_CNAK;
+  endpoint->DIEPCTL |= USB_OTG_DIEPCTL_CNAK;
 
   return RES_OK;
 }
@@ 259,7 260,7 @@ task_result_t usb_send_unicode_string_descriptor(
     usb_generic_fill_fifo(endpoint, &string_descriptor->bString[2], string_descriptor->header.bLength - 4, fifo_tx_target);
   }
 
-  endpoint->DIEPCTL = USB_OTG_DIEPCTL_CNAK;
+  endpoint->DIEPCTL |= USB_OTG_DIEPCTL_CNAK;
   return RES_OK;
 }
 
@@ 270,3 271,13 @@ bool usb_is_inendpoint_ready(USB_OTG_INEndpointTypeDef *endpoint) {
 bool usb_check_fifo_space(USB_OTG_INEndpointTypeDef *endpoint, uint16_t size) {
   return ((endpoint->DTXFSTS & (USB_OTG_DTXFSTS_INEPTFSAV_Msk)) >> USB_OTG_DTXFSTS_INEPTFSAV_Pos) >= (size + 3) / 4;
 }
+
+void usb_flush_tx_fifo(USB_OTG_GlobalTypeDef *core, uint16_t fifo_num) {
+  reg_write_bits_pos(&core->GRSTCTL, fifo_num, USB_OTG_GRSTCTL_TXFNUM_Pos, 0xF);
+  reg_write_bits_pos(&core->GRSTCTL, fifo_num, USB_OTG_GRSTCTL_TXFFLSH_Pos, 1);
+  while (reg_read_bits_pos(&core->GRSTCTL, USB_OTG_GRSTCTL_TXFFLSH_Pos, 1));
+}
+void usb_flush_rx_fifo(USB_OTG_GlobalTypeDef *core) {
+  reg_set_bits_pos(&core->GRSTCTL, USB_OTG_GRSTCTL_RXFFLSH_Pos, 1);
+  while (reg_read_bits_pos(&core->GRSTCTL, USB_OTG_GRSTCTL_TXFFLSH_Pos, 1));
+}