Skip to content

Commit 5e5ca1d

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 c814816 commit 5e5ca1d

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

@@ -17,6 +17,7 @@
1717
#include <usbd_pybricks.h>
1818

1919
#include <pbdrv/usb.h>
20+
#include <pbio/protocol.h>
2021
#include <pbio/util.h>
2122
#include <pbsys/command.h>
2223
#include <pbsys/status.h>
@@ -29,7 +30,10 @@ PROCESS(pbdrv_usb_process, "USB");
2930
// These buffers need to be 32-bit aligned because the USB driver moves data
3031
// to/from FIFOs in 32-bit chunks.
3132
static uint8_t usb_in_buf[USBD_PYBRICKS_MAX_PACKET_SIZE] __aligned(4);
33+
static uint8_t usb_response_buf[1 + sizeof(uint32_t)] __aligned(4);
3234
static volatile uint32_t usb_in_sz;
35+
static volatile uint32_t usb_response_sz;
36+
static volatile bool transmitting;
3337

3438
static USBD_HandleTypeDef husbd;
3539
static PCD_HandleTypeDef hpcd;
@@ -140,6 +144,8 @@ void pbdrv_usb_stm32_handle_vbus_irq(bool active) {
140144
static USBD_StatusTypeDef Pybricks_Itf_Init(void) {
141145
USBD_Pybricks_SetRxBuffer(&husbd, usb_in_buf);
142146
usb_in_sz = 0;
147+
usb_response_sz = 0;
148+
transmitting = false;
143149

144150
return USBD_OK;
145151
}
@@ -182,8 +188,17 @@ static USBD_StatusTypeDef Pybricks_Itf_Receive(uint8_t *Buf, uint32_t Len) {
182188
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
183189
*/
184190
static USBD_StatusTypeDef Pybricks_Itf_TransmitCplt(uint8_t *Buf, uint32_t Len, uint8_t epnum) {
191+
USBD_StatusTypeDef ret = USBD_OK;
192+
193+
if (Buf == usb_response_buf) {
194+
usb_response_sz = 0;
195+
} else {
196+
ret = USBD_FAIL;
197+
}
198+
199+
transmitting = false;
185200
process_poll(&pbdrv_usb_process);
186-
return USBD_OK;
201+
return ret;
187202
}
188203

189204
static USBD_Pybricks_ItfTypeDef USBD_Pybricks_fops = {
@@ -224,6 +239,7 @@ PROCESS_THREAD(pbdrv_usb_process, ev, data) {
224239
static PBIO_ONESHOT(bcd_oneshot);
225240
static PBIO_ONESHOT(pwrdn_oneshot);
226241
static bool bcd_busy;
242+
static pbio_pybricks_error_t result;
227243

228244
PROCESS_POLLHANDLER({
229245
if (!bcd_busy && pbio_oneshot(!vbus_active, &no_vbus_oneshot)) {
@@ -268,14 +284,28 @@ PROCESS_THREAD(pbdrv_usb_process, ev, data) {
268284
if (usb_in_sz) {
269285
switch (usb_in_buf[0]) {
270286
case USBD_PYBRICKS_OUT_EP_MSG_COMMAND:
271-
pbsys_command(usb_in_buf + 1, usb_in_sz - 1);
287+
if (usb_response_sz == 0) {
288+
result = pbsys_command(usb_in_buf + 1, usb_in_sz - 1);
289+
usb_response_buf[0] = USBD_PYBRICKS_IN_EP_MSG_RESPONSE;
290+
pbio_set_uint32_le(&usb_response_buf[1], result);
291+
usb_response_sz = sizeof(usb_response_buf);
292+
}
272293
break;
273294
}
274295

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

281311
PROCESS_END();

0 commit comments

Comments
 (0)