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