diff --git a/32blit-stm32/Src/32blit.cpp b/32blit-stm32/Src/32blit.cpp index c7a52838f..27f13a398 100644 --- a/32blit-stm32/Src/32blit.cpp +++ b/32blit-stm32/Src/32blit.cpp @@ -14,6 +14,7 @@ #include "multiplayer.hpp" #include "power.hpp" +#include "CDCCommandStream.h" #include "tim.h" #include "rng.h" #include "fatfs.h" @@ -30,6 +31,7 @@ using namespace blit; extern USBD_HandleTypeDef hUsbDeviceHS; extern USBManager g_usbManager; +extern CDCCommandStream g_commandStream; FATFS filesystem; extern Disk_drvTypeDef disk; @@ -81,19 +83,27 @@ static void init_api_shared() { api.message_received = nullptr; api.i2c_completed = nullptr; + + // take CDC back + g_commandStream.SetParsingEnabled(true); } bool g_bConsumerConnected = true; -void blit_debug(const char *message) { - if(g_usbManager.GetType() == USBManager::usbtCDC) - { + +static bool set_raw_cdc_enabled(bool enabled) { + g_commandStream.SetParsingEnabled(!enabled); + return true; +} + +static void cdc_write(const uint8_t *data, uint16_t len) { + if(g_usbManager.GetType() == USBManager::usbtCDC) { // The mad STM CDC implementation relies on a USB packet being received to set TxState // Also calls to CDC_Transmit_HS do not buffer the data so we have to rely on TxState before sending new data. // So if there is no consumer running at the other end we will hang, so we need to check for this if(g_bConsumerConnected) { uint32_t tickstart = HAL_GetTick(); - while(g_bConsumerConnected && CDC_Transmit_HS((uint8_t *)message, strlen(message)) == USBD_BUSY) + while(g_bConsumerConnected && CDC_Transmit_HS((uint8_t *)data, len) == USBD_BUSY) g_bConsumerConnected = !(HAL_GetTick() > (tickstart + 2)); } else @@ -104,6 +114,14 @@ void blit_debug(const char *message) { } } +static uint16_t cdc_read(uint8_t *data, uint16_t len) { + return g_commandStream.Read(data, len); +} + +void blit_debug(const char *message) { + cdc_write((uint8_t *)message, strlen(message)); +} + void blit_exit(bool is_error) { if(is_error) blit_reset_with_error(); // likely an abort @@ -394,6 +412,10 @@ void blit_init() { blit::api.i2c_send = i2c::user_send; blit::api.i2c_receive = i2c::user_receive; + blit::api.set_raw_cdc_enabled = set_raw_cdc_enabled; + blit::api.cdc_write = cdc_write; + blit::api.cdc_read = cdc_read; + display::init(); multiplayer::init(); diff --git a/32blit/engine/api_private.hpp b/32blit/engine/api_private.hpp index 25efda5d8..fa6dd0348 100644 --- a/32blit/engine/api_private.hpp +++ b/32blit/engine/api_private.hpp @@ -123,6 +123,11 @@ namespace blit { bool (*i2c_send)(uint8_t address, uint8_t reg, const uint8_t *data, uint16_t len); bool (*i2c_receive)(uint8_t address, uint8_t reg, uint8_t *data, uint16_t len); void (*i2c_completed)(uint8_t address, uint8_t reg, const uint8_t *data, uint16_t len); // callback when done + + // raw cdc + bool (*set_raw_cdc_enabled)(bool enabled); + void (*cdc_write)(const uint8_t *data, uint16_t len); + uint16_t (*cdc_read)(uint8_t *data, uint16_t len); }; #pragma pack(pop)