Skip to content

Commit 909644d

Browse files
committed
Configure USB device and process pybricks commands
Configures the USB device and processes pybricks commands.
1 parent 15ca204 commit 909644d

File tree

1 file changed

+96
-1
lines changed

1 file changed

+96
-1
lines changed

lib/pbio/drv/usb/usb_stm32.c

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,33 @@
88
#if PBDRV_CONFIG_USB_STM32F4
99

1010
#include <stdbool.h>
11+
#include <string.h>
1112

1213
#include <contiki.h>
1314
#include <stm32f4xx_hal.h>
1415
#include <stm32f4xx_hal_pcd_ex.h>
1516
#include <usbd_core.h>
17+
#include <usbd_pybricks.h>
1618

1719
#include <pbdrv/usb.h>
1820
#include <pbio/util.h>
21+
#include <pbsys/command.h>
1922

2023
#include "../charger/charger.h"
2124
#include "./usb_stm32.h"
2225

26+
#define UUID_SZ (128 / 8)
27+
2328
PROCESS(pbdrv_usb_process, "USB");
2429

30+
static uint8_t usb_in_buf[PYBRICKS_MAX_PACKET_SIZE];
31+
static uint8_t usb_out_buf[PYBRICKS_MAX_PACKET_SIZE];
32+
static volatile uint32_t usb_in_sz;
33+
static volatile uint32_t usb_out_sz;
34+
2535
static USBD_HandleTypeDef husbd;
2636
static PCD_HandleTypeDef hpcd;
37+
2738
static volatile bool vbus_active;
2839
static pbdrv_usb_bcd_t pbdrv_usb_bcd;
2940

@@ -121,14 +132,86 @@ void pbdrv_usb_stm32_handle_vbus_irq(bool active) {
121132
process_poll(&pbdrv_usb_process);
122133
}
123134

135+
/**
136+
* @brief Pybricks_Itf_Init
137+
* Initializes the Pybricks media low layer
138+
* @param None
139+
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
140+
*/
141+
static int8_t Pybricks_Itf_Init(void) {
142+
USBD_Pybricks_SetTxBuffer(&husbd, usb_out_buf, sizeof(usb_out_buf));
143+
USBD_Pybricks_SetRxBuffer(&husbd, usb_in_buf);
144+
usb_in_sz = 0;
145+
usb_out_sz = 0;
146+
147+
return USBD_OK;
148+
}
149+
150+
/**
151+
* @brief Pybricks_Itf_DeInit
152+
* DeInitializes the Pybricks media low layer
153+
* @param None
154+
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
155+
*/
156+
static int8_t Pybricks_Itf_DeInit(void) {
157+
return USBD_OK;
158+
}
159+
160+
/**
161+
* @brief Pybricks_Itf_DataRx
162+
* Data received over USB OUT endpoint are sent over CDC interface
163+
* through this function.
164+
* @param Buf: Buffer of data to be transmitted
165+
* @param Len: Number of data received (in bytes)
166+
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
167+
*/
168+
static int8_t Pybricks_Itf_Receive(uint8_t *Buf, uint32_t *Len) {
169+
if (*Len > sizeof(usb_in_buf))
170+
return USBD_FAIL;
171+
172+
memcpy(usb_in_buf, Buf, *Len);
173+
usb_in_sz = *Len;
174+
process_poll(&pbdrv_usb_process);
175+
return USBD_OK;
176+
}
177+
178+
/**
179+
* @brief Pybricks_Itf_TransmitCplt
180+
* Data transmitted callback
181+
*
182+
* @note
183+
* This function is IN transfer complete callback used to inform user that
184+
* the submitted Data is successfully sent over USB.
185+
*
186+
* @param Buf: Buffer of data to be received
187+
* @param Len: Number of data received (in bytes)
188+
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
189+
*/
190+
static int8_t Pybricks_Itf_TransmitCplt(uint8_t *Buf, uint32_t *Len, uint8_t epnum) {
191+
usb_out_sz = 0;
192+
process_poll(&pbdrv_usb_process);
193+
return USBD_OK;
194+
}
195+
196+
static USBD_Pybricks_ItfTypeDef USBD_Pybricks_fops = {
197+
.Init = Pybricks_Itf_Init,
198+
.DeInit = Pybricks_Itf_DeInit,
199+
.Receive = Pybricks_Itf_Receive,
200+
.TransmitCplt = Pybricks_Itf_TransmitCplt,
201+
};
202+
124203
// Common USB driver implementation.
125204

126205
void pbdrv_usb_init(void) {
127206
// Link the driver data structures
128207
husbd.pData = &hpcd;
129208
hpcd.pData = &husbd;
130209

131-
USBD_Init(&husbd, NULL, 0);
210+
USBD_Init(&husbd, &Pybricks_Desc, 0);
211+
USBD_RegisterClass(&husbd, &USBD_Pybricks_ClassDriver);
212+
USBD_Pybricks_RegisterInterface(&husbd, &USBD_Pybricks_fops);
213+
USBD_Start(&husbd);
214+
132215
process_start(&pbdrv_usb_process);
133216

134217
// VBUS may already be active
@@ -164,12 +247,24 @@ PROCESS_THREAD(pbdrv_usb_process, ev, data) {
164247

165248
PROCESS_BEGIN();
166249

250+
USBD_Pybricks_ReceivePacket(&husbd);
251+
167252
for (;;) {
168253
PROCESS_WAIT_EVENT();
169254

170255
if (bcd_busy) {
171256
bcd_busy = PT_SCHEDULE(pbdrv_usb_stm32_bcd_detect(&bcd_pt));
172257
}
258+
259+
if (usb_in_sz) {
260+
if ((usb_in_sz >= UUID_SZ) &&
261+
pbio_uuid128_le_compare(usb_in_buf, pbio_pybricks_command_event_char_uuid)) {
262+
pbsys_command(usb_in_buf + UUID_SZ, usb_in_sz - UUID_SZ);
263+
}
264+
265+
usb_in_sz = 0;
266+
USBD_Pybricks_ReceivePacket(&husbd);
267+
}
173268
}
174269

175270
PROCESS_END();

0 commit comments

Comments
 (0)