more work, trying to figure out performance issue
diff --git a/32blit-stm32/Inc/core-debug.hpp b/32blit-stm32/Inc/core-debug.hpp
index 11677a9..c210e5b 100644
--- a/32blit-stm32/Inc/core-debug.hpp
+++ b/32blit-stm32/Inc/core-debug.hpp
@@ -7,5 +7,6 @@
 

   extern std::vector<std::string> messages;

   extern void debug(const char *p);

+  extern void debug(const std::string &s);

   extern void render();

 }
\ No newline at end of file
diff --git a/32blit-stm32/Inc/usb-cdc.hpp b/32blit-stm32/Inc/usb-cdc.hpp
index b06d625..77a103f 100644
--- a/32blit-stm32/Inc/usb-cdc.hpp
+++ b/32blit-stm32/Inc/usb-cdc.hpp
@@ -7,9 +7,14 @@
 

   typedef bool (*CommandHandler)(char *data, uint32_t length);

 

-  extern std::map<std::string, CommandHandler> handlers;

+  struct Packet {

+    char data[64];

+    uint8_t length = 0;

+  };

 

-  void reset_rx_buffer();

+  extern std::map<std::string, CommandHandler> handlers;

+  

+  void init();

   void data_received(uint32_t length);  

   void parse_command();

   void register_command_handler(std::string command, CommandHandler handler);    

diff --git a/32blit-stm32/Src/32blit.c b/32blit-stm32/Src/32blit.c
index 7cc2294..b66a19a 100644
--- a/32blit-stm32/Src/32blit.c
+++ b/32blit-stm32/Src/32blit.c
@@ -8,7 +8,7 @@
 #include "display.hpp"

 #include "gpio.hpp"

 #include "file.hpp"

-

+#include "usb-cdc.hpp"

 

 #include "adc.h"

 #include "tim.h"

@@ -21,6 +21,7 @@
 #include "quadspi.h"

 #include "usbd_core.h"

 

+

 #include "32blit.hpp"

 #include "graphics/color.hpp"

 

@@ -77,6 +78,7 @@
 void render_yield() {

   if(display::needs_render) {

     blit::render(blit::now());

+    debug::render();

     display::enable_vblank_interrupt();

   }

 }

@@ -166,9 +168,8 @@
 

     blit_enable_amp();

 

-  display::init();

-  

-  blit::init();

+    display::init();

+    blit::init();

 

 }

 

diff --git a/32blit-stm32/Src/core-debug.cpp b/32blit-stm32/Src/core-debug.cpp
index 7501c92..fb33a3b 100644
--- a/32blit-stm32/Src/core-debug.cpp
+++ b/32blit-stm32/Src/core-debug.cpp
@@ -9,6 +9,10 @@
 

   std::vector<std::string> messages;

 

+  void debug(const std::string &s) {

+    debug(s.c_str());

+  }

+

   void debug(const char *p) {

     std::string message = p;

 

diff --git a/32blit-stm32/Src/main.c b/32blit-stm32/Src/main.c
index 1c7c622..fbd8d6f 100644
--- a/32blit-stm32/Src/main.c
+++ b/32blit-stm32/Src/main.c
@@ -117,6 +117,7 @@
   /* Initialize all configured peripherals */

   gpio::init();

   sound::init();

+  cdc::init();

 

   //MX_GPIO_Init();

 

diff --git a/32blit-stm32/Src/usb-cdc.cpp b/32blit-stm32/Src/usb-cdc.cpp
index 323b04c..edfec89 100644
--- a/32blit-stm32/Src/usb-cdc.cpp
+++ b/32blit-stm32/Src/usb-cdc.cpp
@@ -6,6 +6,8 @@
 

 #include <cstring>

 #include <string>

+#include <stdint.h>

+#include <queue>

 

 extern USBD_HandleTypeDef hUsbDeviceHS;

 

@@ -13,49 +15,95 @@
 

   std::map<std::string, CommandHandler> handlers;

 

-  struct {

-    char data[64];

-    uint32_t length = 0;

-  } rx_buffer;

+  // declare storage for packets buffer

+  constexpr uint32_t MAX_PARSE_PACKETS = 16;

+  Packet packets[MAX_PARSE_PACKETS];

+  std::vector<Packet*> free_packets;

+

+  Packet *rx_packet = nullptr;

+  std::queue<Packet*> parse_queue;

+  

+  void request_new_packet();

+

+  void init() {

+    debug::debug("CDC INIT");

+    

+    // push the packet buffers into the free packets collection

+    for(uint32_t i = 0; i < MAX_PARSE_PACKETS; i++) {

+      free_packets.push_back(&packets[i]);

+    }

+

+    //request_new_packet();

+  }

+  

+  void request_new_packet() {    

+    // if we have space to receive more packets then return false

+//    std::string m = "FREE ";

+    //m += std::to_string(free_packets.size());

+    //debug::debug(m);

+

+    if(rx_packet == nullptr && free_packets.size() > 0) {

+      rx_packet = free_packets.back();

+      free_packets.pop_back();

+

+      USBD_CDC_SetRxBuffer(&hUsbDeviceHS, rx_packet->data);

+      USBD_CDC_ReceivePacket(&hUsbDeviceHS); 

+    }

+  }

+

+  void data_received(uint32_t length) {      

+    // take a copy of the newly received packet into the parse queue

+    rx_packet->length = length;

+    parse_queue.push(rx_packet);

+

+    // request a new packet of data

+    rx_packet = nullptr;

+    request_new_packet();

+  }

 

   // register a function to handle a new USB serial command

   void register_command_handler(std::string command, CommandHandler handler) {

     handlers[command] = handler;

   }

 

-  void data_received(uint32_t length) {

-    rx_buffer.length = length;

-  }

-

-  // stores the length of the current rx buffer and swaps to the other buffer if

-  // it is free for use returning a pointer to the data member (or null if not free)

-  void reset_rx_buffer() {      

-    rx_buffer.length = 0;

-

-    USBD_CDC_SetRxBuffer(&hUsbDeviceHS, rx_buffer.data);

-    USBD_CDC_ReceivePacket(&hUsbDeviceHS);

-  }

-

   // check for the incoming command identifier and matches it to the 

   // appropriate handler, then streams all incoming data directly to

   // the handler until the command processing is complete

   void parse_command() {

+    static uint32_t parse_wait_ms = 1000;

+    static uint32_t last_parse_time_ms = blit::now();

     static CommandHandler handler = nullptr;

     

-    if(rx_buffer.length > 0) {   

-     // debug::debug(std::to_string(rx_buffer.length).c_str());

-      uint32_t s = blit::now();

+    uint32_t time_ms = blit::now();

+    if(time_ms - last_parse_time_ms < parse_wait_ms) {

+      return;

+    }

+

+    last_parse_time_ms = time_ms;

+

+    std::string m = "PARSE ";

+    m += "QUEUE: ";

+    m += std::to_string(parse_queue.size());

+    m += " - FREE: ";

+    m += std::to_string(free_packets.size());

+    debug::debug(m);

+

+    while(parse_queue.size() > 0) {

+      // fetch the oldest packet from the queue

+      Packet *packet = parse_queue.front();

+      parse_queue.pop();

+      

       if(!handler) {                

         // if no handler assigned yet then we're waiting for the command

         // search through the handler list to see if we have a matching one

         for(auto c : handlers) {

-          if(strcmp(c.first.c_str(), rx_buffer.data) == 0) {

+          if(strcmp(c.first.c_str(), packet->data) == 0) {

             // found the command so assign the handler and call it with the

             // first packet of data

             handler = c.second;

-            uint32_t command_length = strlen(rx_buffer.data) + 1;

+            uint32_t command_length = strlen(packet->data) + 1;

 

-            bool done = handler(rx_buffer.data + command_length, rx_buffer.length - command_length);

+            bool done = handler(packet->data + command_length, packet->length - command_length);

 

             if(done) {

               handler = nullptr;

@@ -65,14 +113,16 @@
       } else {

         // the command handle must return true when it has finished processing

         // the entire command (even if this is across multiple packets)

-        bool done = handler(rx_buffer.data, rx_buffer.length);

+        bool done = handler(packet->data, packet->length);

 

         if(done) {

           handler = nullptr;

         }

-      }

+      }  

 

-      reset_rx_buffer();

-    }    

+      free_packets.push_back(packet);      

+    }

+

+    request_new_packet();

   }

 }
\ No newline at end of file
diff --git a/32blit-stm32/Src/usbd_cdc_if.c b/32blit-stm32/Src/usbd_cdc_if.c
index e7a8189..a20c2c4 100644
--- a/32blit-stm32/Src/usbd_cdc_if.c
+++ b/32blit-stm32/Src/usbd_cdc_if.c
@@ -161,10 +161,8 @@
   /* USER CODE BEGIN 8 */

   /* Set Application Buffers */

   USBD_CDC_SetTxBuffer(&hUsbDeviceHS, UserTxBufferHS, 0);

-  //USBD_CDC_SetRxBuffer(&hUsbDeviceHS, g_commandStream.GetFifoWriteBuffer());

-  //USBD_CDC_SetRxBuffer(&hUsbDeviceHS, cdc::swap_buffers(0));

+  //USBD_CDC_SetRxBuffer(&hUsbDeviceHS, g_commandStream.GetFifoWriteBuffer());  

 

-  cdc::reset_rx_buffer();

   return (USBD_OK);

   /* USER CODE END 8 */

 }

@@ -277,8 +275,11 @@
 	// release the old write buffer for reading and set length

 //	g_commandStream.ReleaseFifoWriteBuffer(*Len);

 

-

   cdc::data_received(*Len);

+	  //USBD_CDC_SetRxBuffer(&hUsbDeviceHS, pBuffer);

+		

+  

+

   

   //g_commandStream.ReleaseFifoWriteBuffer(*Len);^M