This commit is contained in:
2026-02-25 12:07:03 +01:00
parent 5c8a35440e
commit dc2e8c2270
3 changed files with 31 additions and 19 deletions

View File

@@ -90,22 +90,27 @@ class BuzzerConnection:
with open(filepath, 'rb') as f:
while bytes_sent < file_size:
# NEU: Prüfe, ob der Controller VORZEITIG abgebrochen hat (z.B. ERR)
# 1. Nicht blockierende Fehlerprüfung vor jedem Chunk
if self.serial.in_waiting > 0:
line = self.serial.readline().decode('utf-8', errors='ignore').strip()
if line.startswith("ERR"):
raise BuzzerError(f"Controller hat Transfer abgebrochen: {line}")
# 2. Chunk lesen und schreiben
chunk = f.read(chunk_size)
if not chunk:
break
self.serial.write(chunk)
self.serial.flush()
# WICHTIG: self.serial.flush() hier entfernen.
# Dies verhindert den Deadlock mit dem OS-USB-Puffer.
bytes_sent += len(chunk)
# 3. Callback für UI
if progress_callback:
progress_callback(len(chunk))
# 3. Warte auf das finale OK (oder ERR bei CRC/Schreib-Fehlern)
start_time = time.time()
while (time.time() - start_time) < timeout:

View File

@@ -109,7 +109,7 @@ 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");
LOG_ERR("No data received from USB after multiple attempts (received %zd bytes, expected %zd bytes)", bytes_written, filesize);
fs_close(&file);
return -ETIMEDOUT;
}

View File

@@ -2,6 +2,7 @@
#include <zephyr/logging/log.h>
#include <zephyr/usb/usb_device.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/sys/ring_buffer.h> /* NEU */
#include <io.h>
@@ -13,6 +14,10 @@ K_SEM_DEFINE(usb_tx_sem, 0, 1);
#define UART_NODE DT_ALIAS(usb_uart)
const struct device *cdc_dev = DEVICE_DT_GET(UART_NODE);
/* NEU: Ringbuffer für stabilen asynchronen USB-Empfang */
#define RX_RING_BUF_SIZE 4096
RING_BUF_DECLARE(rx_ringbuf, RX_RING_BUF_SIZE);
static void cdc_acm_irq_cb(const struct device *dev, void *user_data)
{
ARG_UNUSED(user_data);
@@ -21,43 +26,45 @@ static void cdc_acm_irq_cb(const struct device *dev, void *user_data)
return;
}
/* Der Interrupt bleibt permanent an. Daten sofort in Ringbuffer schieben. */
if (uart_irq_rx_ready(dev)) {
uart_irq_rx_disable(dev);
uint8_t buffer[64];
int len;
while ((len = uart_fifo_read(dev, buffer, sizeof(buffer))) > 0) {
ring_buf_put(&rx_ringbuf, buffer, len);
}
k_sem_give(&usb_rx_sem);
LOG_DBG("RX interrupt: data available");
}
if (uart_irq_tx_ready(dev)) {
uart_irq_tx_disable(dev);
k_sem_give(&usb_tx_sem);
LOG_DBG("TX interrupt: ready for more data");
}
}
bool usb_wait_for_data(k_timeout_t timeout)
{
/* Wenn Daten im Puffer sind, nicht blockieren */
if (!ring_buf_is_empty(&rx_ringbuf)) {
return true;
}
return (k_sem_take(&usb_rx_sem, timeout) == 0);
}
int usb_read_char(uint8_t *c)
{
if (!device_is_ready(cdc_dev)) return 0;
return uart_fifo_read(cdc_dev, c, 1);
return ring_buf_get(&rx_ringbuf, c, 1);
}
int usb_read_buffer(uint8_t *buf, size_t max_len)
{
if (!device_is_ready(cdc_dev)) return 0;
return uart_fifo_read(cdc_dev, buf, max_len);
return ring_buf_get(&rx_ringbuf, buf, max_len);
}
void usb_resume_rx(void)
{
if (device_is_ready(cdc_dev)) {
uart_irq_rx_enable(cdc_dev);
LOG_DBG("RX interrupt re-enabled");
}
/* Leere Funktion - Interrupt wird nicht mehr deaktiviert */
}
void usb_write_char(uint8_t c)
@@ -100,12 +107,12 @@ void usb_flush_rx(void)
uint8_t dummy;
if (!device_is_ready(cdc_dev)) return;
// Alles lesen, was gerade im Hardware-FIFO liegt
/* Hardware-FIFO leeren, falls Reste vorhanden */
while (uart_fifo_read(cdc_dev, &dummy, 1) > 0);
// Semaphore zurücksetzen, falls sie gesetzt war
/* Ringpuffer und Semaphore zurücksetzen */
ring_buf_reset(&rx_ringbuf);
k_sem_reset(&usb_rx_sem);
usb_resume_rx();
}
static void usb_status_cb(enum usb_dc_status_code cb_status, const uint8_t *param)