sync
This commit is contained in:
@@ -26,15 +26,25 @@ 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)) {
|
||||
uint8_t buffer[64];
|
||||
int len;
|
||||
uint32_t space = ring_buf_space_get(&rx_ringbuf);
|
||||
|
||||
while ((len = uart_fifo_read(dev, buffer, sizeof(buffer))) > 0) {
|
||||
ring_buf_put(&rx_ringbuf, buffer, len);
|
||||
if (space == 0) {
|
||||
/* Backpressure anwenden: Ringpuffer ist voll.
|
||||
Interrupt deaktivieren, damit Daten im HW-FIFO bleiben
|
||||
und der USB-Stack den Host drosselt (NAK). */
|
||||
uart_irq_rx_disable(dev);
|
||||
} else {
|
||||
/* Nur so viele Daten lesen, wie Platz im Ringpuffer ist */
|
||||
int to_read = MIN(sizeof(buffer), space);
|
||||
int len = uart_fifo_read(dev, buffer, to_read);
|
||||
|
||||
if (len > 0) {
|
||||
ring_buf_put(&rx_ringbuf, buffer, len);
|
||||
k_sem_give(&usb_rx_sem);
|
||||
}
|
||||
}
|
||||
k_sem_give(&usb_rx_sem);
|
||||
}
|
||||
|
||||
if (uart_irq_tx_ready(dev)) {
|
||||
@@ -45,26 +55,44 @@ static void cdc_acm_irq_cb(const struct device *dev, void *user_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;
|
||||
}
|
||||
|
||||
/* Wenn der Puffer leer ist, sicherstellen, dass der RX-Interrupt
|
||||
aktiviert ist, da sonst keine neuen Daten empfangen werden können. */
|
||||
if (device_is_ready(cdc_dev)) {
|
||||
uart_irq_rx_enable(cdc_dev);
|
||||
}
|
||||
|
||||
return (k_sem_take(&usb_rx_sem, timeout) == 0);
|
||||
}
|
||||
|
||||
int usb_read_char(uint8_t *c)
|
||||
{
|
||||
return ring_buf_get(&rx_ringbuf, c, 1);
|
||||
int ret = ring_buf_get(&rx_ringbuf, c, 1);
|
||||
if (ret > 0 && device_is_ready(cdc_dev)) {
|
||||
/* Platz geschaffen -> Empfang wieder aktivieren */
|
||||
uart_irq_rx_enable(cdc_dev);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usb_read_buffer(uint8_t *buf, size_t max_len)
|
||||
{
|
||||
return ring_buf_get(&rx_ringbuf, buf, max_len);
|
||||
int ret = ring_buf_get(&rx_ringbuf, buf, max_len);
|
||||
if (ret > 0 && device_is_ready(cdc_dev)) {
|
||||
/* Platz geschaffen -> Empfang wieder aktivieren */
|
||||
uart_irq_rx_enable(cdc_dev);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void usb_resume_rx(void)
|
||||
{
|
||||
/* Leere Funktion - Interrupt wird nicht mehr deaktiviert */
|
||||
if (device_is_ready(cdc_dev)) {
|
||||
uart_irq_rx_enable(cdc_dev);
|
||||
}
|
||||
}
|
||||
|
||||
void usb_write_char(uint8_t c)
|
||||
|
||||
Reference in New Issue
Block a user