Skip to content

Commit 02bd2e2

Browse files
authored
Merge pull request arduino#21 from Seeed-Studio/usbdisp
merge Usbdisp
2 parents 1cbd186 + db82d55 commit 02bd2e2

11 files changed

+180
-105
lines changed

cores/arduino/Print.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@
1616
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1717
*/
1818

19-
#include <stdlib.h>
20-
#include <stdio.h>
21-
#include <string.h>
2219
#include <math.h>
2320
#include "Arduino.h"
2421

cores/arduino/SERCOM.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ SERCOM::SERCOM(Sercom* s)
4747
#elif SERCOM_SPI_FREQ_REF == 100000000 // 100 MHz clock = GCLK2
4848
clockSource = SERCOM_CLOCK_SOURCE_100M;
4949
#endif
50+
#ifdef SEEED_GROVE_UI_WIRELESS
51+
if (sercom == SERCOM7 /* LCD interface */) {
52+
clockSource = SERCOM_CLOCK_SOURCE_FCPU;
53+
}
54+
#endif
5055
#endif // end __SAMD51__
5156
}
5257

cores/arduino/USB/CDC.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ bool CDC_Setup(USBSetup &setup)
119119
// auto-reset into the bootloader is triggered when the port, already
120120
// open at 1200 bps, is closed. We check DTR state to determine if host
121121
// port is open (bit 0 of lineState).
122-
if (_usbLineInfo.dwDTERate == 1200 && (_usbLineInfo.lineState & 0x01) == 0)
122+
if (_usbLineInfo.dwDTERate == 1200 && (_usbLineInfo.lineState & CDC_LINESTATE_DTR) == 0)
123123
{
124124
initiateReset(250);
125125
}
@@ -139,6 +139,16 @@ bool CDC_Setup(USBSetup &setup)
139139
return false;
140140
}
141141

142+
/*
143+
Serial_::Serial_(USBDeviceClass &_usb) : PluggableUSBModule(3, 2, epType), usb(_usb), stalled(false)
144+
{
145+
epType[0] = USB_ENDPOINT_TYPE_INTERRUPT | USB_ENDPOINT_IN(0);
146+
epType[1] = USB_ENDPOINT_TYPE_BULK | USB_ENDPOINT_OUT(0);
147+
epType[2] = USB_ENDPOINT_TYPE_BULK | USB_ENDPOINT_IN(0);
148+
PluggableUSB().plug(this);
149+
}
150+
*/
151+
142152
void Serial_::begin(uint32_t /* baud_count */)
143153
{
144154
// uart config is ignored in USB-CDC
@@ -168,9 +178,11 @@ void Serial_::end(void)
168178
memset((void *)&_usbLineInfo, 0, sizeof(_usbLineInfo));
169179
}
170180

181+
int _serialPeek = -1;
182+
171183
int Serial_::available(void)
172184
{
173-
return usb.available(CDC_ENDPOINT_OUT);
185+
return usb.available(CDC_ENDPOINT_OUT) + (_serialPeek != -1);
174186
}
175187

176188
int Serial_::availableForWrite(void)
@@ -180,8 +192,6 @@ int Serial_::availableForWrite(void)
180192
return (EPX_SIZE - 1);
181193
}
182194

183-
int _serialPeek = -1;
184-
185195
int Serial_::peek(void)
186196
{
187197
if (_serialPeek != -1)
@@ -220,6 +230,10 @@ void Serial_::flush(void)
220230
usb.flush(CDC_ENDPOINT_IN);
221231
}
222232

233+
void Serial_::clear(void) {
234+
usb.clear(CDC_ENDPOINT_IN);
235+
}
236+
223237
size_t Serial_::write(const uint8_t *buffer, size_t size)
224238
{
225239
/* only try to send bytes if the high-level CDC connection itself
@@ -274,12 +288,12 @@ uint8_t Serial_::numbits()
274288

275289
bool Serial_::dtr()
276290
{
277-
return _usbLineInfo.lineState & 0x1;
291+
return _usbLineInfo.lineState & CDC_LINESTATE_DTR;
278292
}
279293

280294
bool Serial_::rts()
281295
{
282-
return _usbLineInfo.lineState & 0x2;
296+
return _usbLineInfo.lineState & CDC_LINESTATE_RTS;
283297
}
284298

285299
// This operator is a convenient way for a sketch to check whether the

cores/arduino/USB/PluggableUSB.cpp

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,23 @@ int PluggableUSB_::getDescriptor(USBSetup& setup)
5454
return 0;
5555
}
5656

57-
void PluggableUSB_::getShortName(char *iSerialNum)
57+
uint8_t PluggableUSB_::getShortName(char *iSerialNum)
5858
{
59-
PluggableUSBModule* node;
60-
for (node = rootNode; node; node = node->next) {
61-
iSerialNum += node->getShortName(iSerialNum);
62-
}
63-
*iSerialNum = 0;
59+
PluggableUSBModule* node;
60+
uint8_t size = 0;
61+
for (node = rootNode; node; node = node->next) {
62+
uint8_t len = node->getShortName(iSerialNum);
63+
iSerialNum += len;
64+
size += len;
65+
}
66+
*iSerialNum = 0;
67+
return size;
6468
}
6569

6670
bool PluggableUSB_::setup(USBSetup& setup)
6771
{
6872
PluggableUSBModule* node;
73+
6974
for (node = rootNode; node; node = node->next) {
7075
if (node->setup(setup)) {
7176
return true;
@@ -74,6 +79,18 @@ bool PluggableUSB_::setup(USBSetup& setup)
7479
return false;
7580
}
7681

82+
int PluggableUSB_::handleEndpoint(int ep)
83+
{
84+
PluggableUSBModule* node;
85+
for (node = rootNode; node; node = node->next) {
86+
int r = node->handleEndpoint(ep);
87+
if (r != 0) {
88+
return r;
89+
}
90+
}
91+
return 0;
92+
}
93+
7794
bool PluggableUSB_::plug(PluggableUSBModule *node)
7895
{
7996
if ((lastEp + node->numEndpoints) > USB_ENDPOINTS) {

cores/arduino/USB/PluggableUSB.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class PluggableUSBModule {
3535
virtual bool setup(USBSetup& setup) = 0;
3636
virtual int getInterface(uint8_t* interfaceCount) = 0;
3737
virtual int getDescriptor(USBSetup& setup) = 0;
38+
virtual int handleEndpoint(int ep) { (void)ep;/* Do nothing */; return 0; }
3839
virtual uint8_t getShortName(char *name) { name[0] = 'A'+pluggedInterface; return 1; }
3940

4041
uint8_t pluggedInterface;
@@ -56,7 +57,8 @@ class PluggableUSB_ {
5657
int getInterface(uint8_t* interfaceCount);
5758
int getDescriptor(USBSetup& setup);
5859
bool setup(USBSetup& setup);
59-
void getShortName(char *iSerialNum);
60+
int handleEndpoint(int ep);
61+
uint8_t getShortName(char *iSerialNum);
6062

6163
private:
6264
uint8_t lastIf;

cores/arduino/USB/SAMD21_USBDevice.h

Lines changed: 80 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ class USBDevice_SAMD21G18x {
6161
inline void noRunInStandby() { usb.CTRLA.bit.RUNSTDBY = 0; }
6262
inline void wakeupHost() { usb.CTRLB.bit.UPRSM = 1; }
6363

64+
// USB QoS
65+
inline void setDataSensitiveQoS() { usb.QOSCTRL.bit.DQOS = 2; }
66+
inline void setConfigSensitiveQoS() { usb.QOSCTRL.bit.CQOS = 2; }
67+
6468
// USB speed
6569
inline void setFullSpeed() { usb.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_FS_Val; }
6670
inline void setLowSpeed() { usb.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_LS_Val; }
@@ -102,27 +106,37 @@ class USBDevice_SAMD21G18x {
102106
// Interrupts
103107
inline uint16_t epInterruptSummary() { return usb.EPINTSMRY.reg; }
104108

109+
inline bool epHasPendingInterrupts(ep_t ep) { return usb.DeviceEndpoint[ep].EPINTFLAG.reg != 0; }
105110
inline bool epBank0IsSetupReceived(ep_t ep) { return usb.DeviceEndpoint[ep].EPINTFLAG.bit.RXSTP; }
106111
inline bool epBank0IsStalled(ep_t ep) { return usb.DeviceEndpoint[ep].EPINTFLAG.bit.STALL0; }
107112
inline bool epBank1IsStalled(ep_t ep) { return usb.DeviceEndpoint[ep].EPINTFLAG.bit.STALL1; }
113+
inline bool epBank0IsTransferFailed(ep_t ep) { return usb.DeviceEndpoint[ep].EPINTFLAG.bit.TRFAIL0; }
114+
inline bool epBank1IsTransferFailed(ep_t ep) { return usb.DeviceEndpoint[ep].EPINTFLAG.bit.TRFAIL1; }
108115
inline bool epBank0IsTransferComplete(ep_t ep) { return usb.DeviceEndpoint[ep].EPINTFLAG.bit.TRCPT0; }
109116
inline bool epBank1IsTransferComplete(ep_t ep) { return usb.DeviceEndpoint[ep].EPINTFLAG.bit.TRCPT1; }
110117

118+
inline void epAckPendingInterrupts(ep_t ep) { usb.DeviceEndpoint[ep].EPINTFLAG.reg = 0x7F; }
111119
inline void epBank0AckSetupReceived(ep_t ep) { usb.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_RXSTP; }
112120
inline void epBank0AckStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL(1); }
113121
inline void epBank1AckStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL(2); }
122+
inline void epBank0AckTransferFailed(ep_t ep) { usb.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRFAIL(1); }
123+
inline void epBank1AckTransferFailed(ep_t ep) { usb.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRFAIL(2); }
114124
inline void epBank0AckTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT(1); }
115125
inline void epBank1AckTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT(2); }
116126

117127
inline void epBank0EnableSetupReceived(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENSET.bit.RXSTP = 1; }
118128
inline void epBank0EnableStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENSET.bit.STALL0 = 1; }
119129
inline void epBank1EnableStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENSET.bit.STALL1 = 1; }
130+
inline void epBank0EnableTransferFailed(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENSET.bit.TRFAIL0 = 1; }
131+
inline void epBank1EnableTransferFailed(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENSET.bit.TRFAIL1 = 1; }
120132
inline void epBank0EnableTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENSET.bit.TRCPT0 = 1; }
121133
inline void epBank1EnableTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENSET.bit.TRCPT1 = 1; }
122134

123135
inline void epBank0DisableSetupReceived(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENCLR.bit.RXSTP = 1; }
124136
inline void epBank0DisableStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENCLR.bit.STALL0 = 1; }
125137
inline void epBank1DisableStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENCLR.bit.STALL1 = 1; }
138+
inline void epBank0DisableTransferFailed(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENCLR.bit.TRFAIL0 = 1; }
139+
inline void epBank1DisableTransferFailed(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENCLR.bit.TRFAIL1 = 1; }
126140
inline void epBank0DisableTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENCLR.bit.TRCPT0 = 1; }
127141
inline void epBank1DisableTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENCLR.bit.TRCPT1 = 1; }
128142

@@ -170,6 +184,15 @@ class USBDevice_SAMD21G18x {
170184
inline void epBank0EnableAutoZLP(ep_t ep) { EP[ep].DeviceDescBank[0].PCKSIZE.bit.AUTO_ZLP = 1; }
171185
inline void epBank1EnableAutoZLP(ep_t ep) { EP[ep].DeviceDescBank[1].PCKSIZE.bit.AUTO_ZLP = 1; }
172186

187+
// USB Device Endpoint transactions helpers
188+
// ----------------------------------------
189+
190+
inline void epReleaseOutBank0(ep_t ep, uint16_t s) {
191+
epBank0SetMultiPacketSize(ep, s);
192+
epBank0SetByteCount(ep, 0);
193+
epBank0ResetReady(ep);
194+
}
195+
173196
private:
174197
// USB Device registers
175198
UsbDevice &usb;
@@ -211,9 +234,9 @@ class EPHandler {
211234
public:
212235
virtual void handleEndpoint() = 0;
213236
virtual uint32_t recv(void *_data, uint32_t len) = 0;
214-
virtual uint32_t available() const = 0;
215-
216237
virtual void init() = 0;
238+
virtual uint32_t available() = 0;
239+
virtual int peek() = 0;
217240
};
218241

219242
class DoubleBufferedEPOutHandler : public EPHandler {
@@ -233,19 +256,23 @@ class DoubleBufferedEPOutHandler : public EPHandler {
233256
usbd.epBank0SetType(ep, 3); // BULK OUT
234257

235258
usbd.epBank0SetAddress(ep, const_cast<uint8_t *>(data0));
259+
usbd.epBank0EnableTransferComplete(ep);
236260

237261
release();
238262
}
239263

240264
virtual ~DoubleBufferedEPOutHandler() {
241-
free((void*)data0);
242-
free((void*)data1);
243265
}
244266
void init() {};
245267

246-
virtual uint32_t recv(void *_data, uint32_t len)
268+
uint32_t _recv()
247269
{
248-
uint8_t *data = reinterpret_cast<uint8_t *>(_data);
270+
uint32_t i = 0;
271+
uint32_t len = 0;
272+
273+
synchronized {
274+
len = _rx_buffer.availableForStore();
275+
}
249276

250277
// R/W: current, first0/1, ready0/1, notify
251278
// R : last0/1, data0/1
@@ -256,9 +283,8 @@ class DoubleBufferedEPOutHandler : public EPHandler {
256283
}
257284
}
258285
// when ready0==true the buffer is not being filled and last0 is constant
259-
uint32_t i;
260-
for (i=0; i<len && first0 < last0; i++) {
261-
data[i] = data0[first0++];
286+
for (; i<len && first0 < last0; i++) {
287+
_rx_buffer.store_char(data0[first0++]);
262288
}
263289
if (first0 == last0) {
264290
first0 = 0;
@@ -279,9 +305,8 @@ class DoubleBufferedEPOutHandler : public EPHandler {
279305
}
280306
}
281307
// when ready1==true the buffer is not being filled and last1 is constant
282-
uint32_t i;
283-
for (i=0; i<len && first1 < last1; i++) {
284-
data[i] = data1[first1++];
308+
for (; i<len && first1 < last1; i++) {
309+
_rx_buffer.store_char(data1[first1++]);
285310
}
286311
if (first1 == last1) {
287312
first1 = 0;
@@ -298,6 +323,34 @@ class DoubleBufferedEPOutHandler : public EPHandler {
298323
}
299324
}
300325

326+
virtual uint32_t recv(void *_data, uint32_t len) {
327+
_recv();
328+
uint32_t i = 0;
329+
uint8_t *data = reinterpret_cast<uint8_t *>(_data);
330+
synchronized {
331+
for (; i < len && _rx_buffer.available(); i++) {
332+
data[i] = _rx_buffer.read_char();
333+
}
334+
}
335+
return i;
336+
}
337+
338+
virtual uint32_t _available() const {
339+
if (current == 0) {
340+
bool ready = ready0;
341+
synchronized {
342+
ready = ready0;
343+
}
344+
return ready ? (last0 - first0) : 0;
345+
} else {
346+
bool ready = false;
347+
synchronized {
348+
ready = ready1;
349+
}
350+
return ready ? (last1 - first1) : 0;
351+
}
352+
}
353+
301354
virtual void handleEndpoint()
302355
{
303356
// R/W : incoming, ready0/1
@@ -340,39 +393,34 @@ class DoubleBufferedEPOutHandler : public EPHandler {
340393
}
341394
release();
342395
}
396+
if (usbd.epBank0IsTransferComplete(ep) || usbd.epBank1IsTransferComplete(ep)) {
397+
usbd.epAckPendingInterrupts(ep);
398+
}
343399
}
344400

345401
// Returns how many bytes are stored in the buffers
346-
virtual uint32_t available() const {
347-
if (current == 0) {
348-
bool ready = false;
349-
synchronized {
350-
ready = ready0;
351-
}
352-
return ready ? (last0 - first0) : 0;
353-
} else {
354-
bool ready = false;
355-
synchronized {
356-
ready = ready1;
357-
}
358-
return ready ? (last1 - first1) : 0;
359-
}
402+
virtual uint32_t available() {
403+
_recv();
404+
return _rx_buffer.available();
405+
}
406+
407+
virtual int peek() {
408+
_recv();
409+
return _rx_buffer.peek();
360410
}
361411

362412
void release() {
363-
// Release OUT EP
364-
usbd.epBank0EnableTransferComplete(ep);
365-
usbd.epBank0SetMultiPacketSize(ep, size);
366-
usbd.epBank0SetByteCount(ep, 0);
367-
usbd.epBank0ResetReady(ep);
413+
usbd.epReleaseOutBank0(ep, size);
368414
}
369415

370416
private:
371417
USBDevice_SAMD21G18x &usbd;
372418

419+
RingBuffer _rx_buffer;
420+
373421
const uint32_t ep;
374422
const uint32_t size;
375-
uint32_t current, incoming;
423+
volatile uint32_t current, incoming;
376424

377425
volatile uint8_t *data0;
378426
uint32_t first0;

cores/arduino/USB/USBAPI.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ class USBDeviceClass {
102102
int recv(uint32_t ep);
103103
uint32_t available(uint32_t ep);
104104
void flush(uint32_t ep);
105+
void clear(uint32_t ep);
105106
void stall(uint32_t ep);
106107

107108
// private?
@@ -135,6 +136,7 @@ class Serial_ : public Stream
135136
virtual int peek(void);
136137
virtual int read(void);
137138
virtual void flush(void);
139+
virtual void clear(void);
138140
virtual size_t write(uint8_t);
139141
virtual size_t write(const uint8_t *buffer, size_t size);
140142
using Print::write; // pull in write(str) from Print

0 commit comments

Comments
 (0)