Skip to content

Commit b38cbc6

Browse files
Add Serial::onUsbSetupPacket() on CDC serial objects
This allows executing an arbitrary callback on receipt on a USB setup packet on the CDC serial interface. This allows running code directly when settings change, or handle messages not handled by the Arduino core (like CDC_SEND_BREAK).
1 parent 997462e commit b38cbc6

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

hardware/arduino/avr/cores/arduino/CDC.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ typedef struct
3131
u8 lineState;
3232
} LineInfo;
3333

34+
static bool (*on_cdc_setup_packet)(const Setup&) = NULL;
35+
3436
static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 };
3537

3638
#define WEAK __attribute__ ((weak))
@@ -62,6 +64,8 @@ int WEAK CDC_GetInterface(u8* interfaceNum)
6264

6365
bool WEAK CDC_Setup(Setup& setup)
6466
{
67+
bool result = false;
68+
6569
u8 r = setup.bRequest;
6670
u8 requestType = setup.bmRequestType;
6771

@@ -70,7 +74,7 @@ bool WEAK CDC_Setup(Setup& setup)
7074
if (CDC_GET_LINE_CODING == r)
7175
{
7276
USB_SendControl(0,(void*)&_usbLineInfo,7);
73-
return true;
77+
result = true;
7478
}
7579
}
7680

@@ -111,9 +115,14 @@ bool WEAK CDC_Setup(Setup& setup)
111115
*(uint16_t *)0x0800 = 0x0;
112116
}
113117
}
114-
return true;
118+
result = true;
115119
}
116-
return false;
120+
121+
// Call callback to allow sketch to do additional processing
122+
if (on_cdc_setup_packet)
123+
return on_cdc_setup_packet(setup) || result;
124+
else
125+
return result;
117126
}
118127

119128

@@ -229,6 +238,10 @@ bool Serial_::rts() {
229238
return _usbLineInfo.lineState & 0x2;
230239
}
231240

241+
void Serial_::onUsbSetupPacket(bool (*func)(const Setup&)) {
242+
on_cdc_setup_packet = func;
243+
}
244+
232245
Serial_ Serial;
233246

234247
#endif

hardware/arduino/avr/cores/arduino/USBAPI.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ struct ring_buffer;
7070
#error Please lower the CDC Buffer size
7171
#endif
7272

73+
// Forward declaration so we can take a reference below:
74+
struct Setup;
75+
7376
class Serial_ : public Stream
7477
{
7578
private:
@@ -115,6 +118,13 @@ class Serial_ : public Stream
115118
SPACE_PARITY = 4,
116119
};
117120

121+
// This allows setting a callback for every USB setup packet
122+
// received (called after regular processing). If the callback
123+
// returns true, the packet will be acknowledged. If the
124+
// callback returns false, the regular handling determines the
125+
// result. Note that the callback will run in ISR context, so it
126+
// should be short and not block.
127+
void onUsbSetupPacket(bool (*func)(const Setup&));
118128
};
119129
extern Serial_ Serial;
120130

0 commit comments

Comments
 (0)