Skip to content

Commit caa1fbf

Browse files
nkarstensdlech
authored andcommitted
pbdrv/usb: Transmit response message.
Transmit the response to a command. This is used to communicate any errors in handling the command back to the user and provide backpressure to ensure the next command isn't sent until the previous has been handled. Signed-off-by: Nate Karstens <[email protected]>
1 parent 4dc64d8 commit caa1fbf

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

lib/pbio/drv/usb/usb_stm32.c

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// SPDX-License-Identifier: MIT
2-
// Copyright (c) 2022 The Pybricks Authors
2+
// Copyright (c) 2022-2025 The Pybricks Authors
33

44
// Main file for STM32F4 USB driver.
55

@@ -18,6 +18,7 @@
1818
#include <usbd_pybricks.h>
1919

2020
#include <pbdrv/usb.h>
21+
#include <pbio/protocol.h>
2122
#include <pbio/util.h>
2223
#include <pbsys/command.h>
2324
#include <pbsys/status.h>
@@ -30,7 +31,10 @@ PROCESS(pbdrv_usb_process, "USB");
3031
// These buffers need to be 32-bit aligned because the USB driver moves data
3132
// to/from FIFOs in 32-bit chunks.
3233
static uint8_t usb_in_buf[USBD_PYBRICKS_MAX_PACKET_SIZE] __aligned(4);
34+
static uint8_t usb_response_buf[1 + sizeof(uint32_t)] __aligned(4) __aligned(4);
3335
static volatile uint32_t usb_in_sz;
36+
static volatile uint32_t usb_response_sz;
37+
static volatile bool transmitting;
3438

3539
static USBD_HandleTypeDef husbd;
3640
static PCD_HandleTypeDef hpcd;
@@ -141,6 +145,8 @@ void pbdrv_usb_stm32_handle_vbus_irq(bool active) {
141145
static USBD_StatusTypeDef Pybricks_Itf_Init(void) {
142146
USBD_Pybricks_SetRxBuffer(&husbd, usb_in_buf);
143147
usb_in_sz = 0;
148+
usb_response_sz = 0;
149+
transmitting = false;
144150

145151
return USBD_OK;
146152
}
@@ -183,8 +189,17 @@ static USBD_StatusTypeDef Pybricks_Itf_Receive(uint8_t *Buf, uint32_t Len) {
183189
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
184190
*/
185191
static USBD_StatusTypeDef Pybricks_Itf_TransmitCplt(uint8_t *Buf, uint32_t Len, uint8_t epnum) {
192+
USBD_StatusTypeDef ret = USBD_OK;
193+
194+
if (Buf == usb_response_buf) {
195+
usb_response_sz = 0;
196+
} else {
197+
ret = USBD_FAIL;
198+
}
199+
200+
transmitting = false;
186201
process_poll(&pbdrv_usb_process);
187-
return USBD_OK;
202+
return ret;
188203
}
189204

190205
static USBD_Pybricks_ItfTypeDef USBD_Pybricks_fops = {
@@ -225,6 +240,7 @@ PROCESS_THREAD(pbdrv_usb_process, ev, data) {
225240
static PBIO_ONESHOT(bcd_oneshot);
226241
static PBIO_ONESHOT(pwrdn_oneshot);
227242
static bool bcd_busy;
243+
static pbio_pybricks_error_t result;
228244

229245
PROCESS_POLLHANDLER({
230246
if (!bcd_busy && pbio_oneshot(!vbus_active, &no_vbus_oneshot)) {
@@ -269,14 +285,28 @@ PROCESS_THREAD(pbdrv_usb_process, ev, data) {
269285
if (usb_in_sz) {
270286
switch (usb_in_buf[0]) {
271287
case USBD_PYBRICKS_OUT_EP_MSG_COMMAND:
272-
pbsys_command(usb_in_buf + 1, usb_in_sz - 1);
288+
if (usb_response_sz == 0) {
289+
result = pbsys_command(usb_in_buf + 1, usb_in_sz - 1);
290+
usb_response_buf[0] = USBD_PYBRICKS_IN_EP_MSG_RESPONSE;
291+
pbio_set_uint32_le(&usb_response_buf[1], result);
292+
usb_response_sz = sizeof(usb_response_buf);
293+
}
273294
break;
274295
}
275296

276297
// Prepare to receive the next packet
277298
usb_in_sz = 0;
278299
USBD_Pybricks_ReceivePacket(&husbd);
279300
}
301+
302+
if (transmitting) {
303+
continue;
304+
}
305+
306+
if (usb_response_sz) {
307+
transmitting = true;
308+
USBD_Pybricks_TransmitPacket(&husbd, usb_response_buf, usb_response_sz);
309+
}
280310
}
281311

282312
PROCESS_END();

0 commit comments

Comments
 (0)