diff --git a/firmware/src/protocol.c b/firmware/src/protocol.c index a6902d1..f80e0cb 100644 --- a/firmware/src/protocol.c +++ b/firmware/src/protocol.c @@ -14,7 +14,7 @@ LOG_MODULE_REGISTER(protocol, LOG_LEVEL_DBG); #define PROTOCOL_STACK_SIZE 2048 #define PROTOCOL_PRIORITY 5 -#define BUFFER_SIZE 512 +#define BUFFER_SIZE 4096 static uint8_t buffer[BUFFER_SIZE]; static volatile uint32_t rx_index = 0; @@ -25,6 +25,7 @@ static protocol_cmd_t current_command = CMD_INVALID; void send_ok() { const char *response = "OK\n"; + LOG_DBG("Sending response: %s", response); usb_write_buffer((const uint8_t *)response, strlen(response)); } @@ -32,6 +33,7 @@ void send_error(int32_t error_code) { char response[32]; snprintf(response, sizeof(response), "ERR %d\n", error_code); + LOG_DBG("Sending response: %s", response); usb_write_buffer((const uint8_t *)response, strlen(response)); } @@ -81,6 +83,7 @@ int put_binary_file(const char *filename, ssize_t filesize, uint32_t expected_cr ssize_t bytes_written = 0; uint32_t running_crc32 = 0; uint32_t retry_count = 0; + size_t accumulated = 0; fs_file_t_init(&file); LOG_DBG("Opening file '%s' for writing (expected size: %zd bytes, expected CRC32: 0x%08x)", filename, filesize, expected_crc32); @@ -96,8 +99,11 @@ int put_binary_file(const char *filename, ssize_t filesize, uint32_t expected_cr uint32_t start = k_uptime_get_32(); while (bytes_written < filesize) { - size_t to_write = MIN(sizeof(buffer), filesize - bytes_written); - ssize_t read = usb_read_buffer(buffer, to_write); + /* Nur so viel lesen, wie in den restlichen Puffer passt (oder bis zum Dateiende) */ + size_t remaining_file = filesize - bytes_written - accumulated; + size_t to_read = MIN(sizeof(buffer) - accumulated, remaining_file); + + ssize_t read = usb_read_buffer(buffer + accumulated, to_read); if (read < 0) { @@ -109,15 +115,13 @@ int put_binary_file(const char *filename, ssize_t filesize, uint32_t expected_cr { if (retry_count >= 10) { - LOG_ERR("No data received from USB after multiple attempts (received %zd bytes, expected %zd bytes)", bytes_written, filesize); + LOG_ERR("No data received from USB after multiple attempts"); fs_close(&file); return -ETIMEDOUT; } usb_resume_rx(); - // LOG_DBG("No data available from USB, waiting for data... (attempt %u)", retry_count + 1); - - if (bytes_written == 0) + if ((bytes_written + accumulated) == 0) { usb_wait_for_data(K_SECONDS(30)); } @@ -129,30 +133,43 @@ int put_binary_file(const char *filename, ssize_t filesize, uint32_t expected_cr continue; } - ssize_t written = fs_write(&file, buffer, read); - //ssize_t written = read; - if (written < 0) - { - LOG_ERR("Error writing to file '%s': %d", filename, (int)written); - fs_close(&file); - return (int)written; - } - running_crc32 = crc32_ieee_update(running_crc32, buffer, written); - - bytes_written += written; + /* Wir haben Daten bekommen: Zähler hochsetzen und USB weiterlauschen lassen */ + accumulated += read; retry_count = 0; usb_resume_rx(); + + /* SCHREIBEN: Erst auf den Flash schreiben, wenn der Puffer voll ist (4096 Bytes) + ODER wenn wir das Ende der Datei erreicht haben. */ + if (accumulated == sizeof(buffer) || (bytes_written + accumulated) == filesize) + { + ssize_t written = fs_write(&file, buffer, accumulated); + if (written < 0) + { + LOG_ERR("Error writing to file '%s': %d", filename, (int)written); + fs_close(&file); + return (int)written; + } + + /* CRC erst nach dem erfolgreichen Block-Schreiben berechnen */ + running_crc32 = crc32_ieee_update(running_crc32, buffer, accumulated); + bytes_written += accumulated; + + /* Puffer für die nächste Runde leeren */ + accumulated = 0; + } } + uint32_t duration = k_uptime_get_32() - start; - uint32_t kb_per_s = (filesize * 1000) / (duration * 1024 +1); + uint32_t kb_per_s = (filesize * 1000) / (duration * 1024 + 1); LOG_DBG("Received file '%s' (%zd bytes) in %u ms (%u kb/s), CRC32: 0x%08x", filename, filesize, duration, kb_per_s, running_crc32); fs_close(&file); - + LOG_DBG("Closed file '%s' after writing", filename); if (running_crc32 != expected_crc32) { LOG_ERR("CRC32 mismatch for file '%s': expected 0x%08x, got 0x%08x", filename, expected_crc32, running_crc32); return -EIO; } + LOG_DBG("File '%s' received successfully with matching CRC32", filename); return 0; } diff --git a/firmware/src/usb.c b/firmware/src/usb.c index 260ad9e..1a79342 100644 --- a/firmware/src/usb.c +++ b/firmware/src/usb.c @@ -118,9 +118,11 @@ void usb_write_buffer(const uint8_t *buf, size_t len) len -= written; buf += written; + uart_irq_tx_enable(cdc_dev); + if (len > 0) { - uart_irq_tx_enable(cdc_dev); + if (k_sem_take(&usb_tx_sem, K_MSEC(100)) != 0) { LOG_WRN("USB TX timeout - consumer not reading?");