1/*
2  Copyright (c) 2016 Arduino LLC.  All right reserved.
3
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License as published by the Free Software Foundation; either
7  version 2.1 of the License, or (at your option) any later version.
8
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12  See the GNU Lesser General Public License for more details.
13
14  You should have received a copy of the GNU Lesser General Public
15  License along with this library; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17*/
18
19#if defined(USBCON)
20
21#include <Arduino.h>
22
23#include "SAMD21_USBDevice.h"
24#include "PluggableUSB.h"
25#include "CDC.h"
26
27#include <stdlib.h>
28#include <stdio.h>
29#include <stdint.h>
30#include <limits.h>
31
32USBDevice_SAMD21G18x usbd;
33
34/** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */
35#define TX_RX_LED_PULSE_MS 100
36#ifdef PIN_LED_TXL
37static volatile uint8_t txLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */
38#endif
39#ifdef PIN_LED_RXL
40static volatile uint8_t rxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */
41#endif
42static char isRemoteWakeUpEnabled = 0;
43static char isEndpointHalt = 0;
44
45extern void (*gpf_isr)(void);
46
47// USB_Handler ISR
48extern "C" void UDD_Handler(void) {
49	USBDevice.ISRHandler();
50}
51
52const uint16_t STRING_LANGUAGE[2] = {
53	(3<<8) | (2+2),
54	0x0409	// English
55};
56
57#ifndef USB_PRODUCT
58// If no product is provided, use USB IO Board
59#define USB_PRODUCT     "USB IO Board"
60#endif
61
62const uint8_t STRING_PRODUCT[] = USB_PRODUCT;
63
64#if USB_VID == 0x2341
65#  if defined(USB_MANUFACTURER)
66#    undef USB_MANUFACTURER
67#  endif
68#  define USB_MANUFACTURER "Arduino LLC"
69#elif !defined(USB_MANUFACTURER)
70// Fall through to unknown if no manufacturer name was provided in a macro
71#  define USB_MANUFACTURER "Unknown"
72#endif
73
74const uint8_t STRING_MANUFACTURER[] = USB_MANUFACTURER;
75
76
77//	DEVICE DESCRIPTOR
78const DeviceDescriptor USB_DeviceDescriptorB = D_DEVICE(0xEF, 0x02, 0x01, 64, USB_VID, USB_PID, 0x100, IMANUFACTURER, IPRODUCT, ISERIAL, 1);
79const DeviceDescriptor USB_DeviceDescriptor = D_DEVICE(0x00, 0x00, 0x00, 64, USB_VID, USB_PID, 0x100, IMANUFACTURER, IPRODUCT, ISERIAL, 1);
80
81//==================================================================
82
83volatile uint32_t _usbConfiguration = 0;
84volatile uint32_t _usbSetInterface = 0;
85
86static __attribute__((__aligned__(4))) //__attribute__((__section__(".bss_hram0")))
87uint8_t udd_ep_out_cache_buffer[7][64];
88
89static __attribute__((__aligned__(4))) //__attribute__((__section__(".bss_hram0")))
90uint8_t udd_ep_in_cache_buffer[7][64];
91
92// Some EP are handled using EPHanlders.
93// Possibly all the sparse EP handling subroutines will be
94// converted into reusable EPHandlers in the future.
95static EPHandler *epHandlers[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
96
97//==================================================================
98
99// Send a USB descriptor string. The string is stored as a
100// plain ASCII string but is sent out as UTF-16 with the
101// correct 2-byte prefix
102bool USBDeviceClass::sendStringDescriptor(const uint8_t *string, uint32_t maxlen)
103{
104	if (maxlen < 2)
105		return false;
106
107	uint8_t* buffer = (uint8_t*)malloc(maxlen);
108	buffer[0] = strlen((const char*)string) * 2 + 2;
109	buffer[1] = 0x03;
110
111	uint8_t i;
112	for (i = 2; i < maxlen && *string; i++) {
113		buffer[i++] = *string++;
114		if (i == maxlen) break;
115		buffer[i] = 0;
116	}
117
118	bool ret = USBDevice.sendControl(buffer, i);
119	free(buffer);
120	return ret;
121}
122
123bool _dry_run = false;
124bool _pack_message = false;
125uint16_t _pack_size = 0;
126uint8_t _pack_buffer[256];
127
128void USBDeviceClass::packMessages(bool val)
129{
130	if (val) {
131		_pack_message = true;
132		_pack_size = 0;
133	} else {
134		_pack_message = false;
135		sendControl(_pack_buffer, _pack_size);
136	}
137}
138
139uint8_t USBDeviceClass::SendInterfaces(uint32_t* total)
140{
141	uint8_t interfaces = 0;
142
143#ifdef PLUGGABLE_USB_ENABLED
144	total[0] += PluggableUSB().getInterface(&interfaces);
145#endif
146
147	return interfaces;
148}
149
150// Construct a dynamic configuration descriptor
151// This really needs dynamic endpoint allocation etc
152uint32_t USBDeviceClass::sendConfiguration(uint32_t maxlen)
153{
154	uint32_t total = 0;
155	// Count and measure interfaces
156	_dry_run = true;
157	uint8_t interfaces = SendInterfaces(&total);
158
159	ConfigDescriptor config = D_CONFIG((uint16_t)(total + sizeof(ConfigDescriptor)), interfaces);
160
161	//	Now send them
162	_dry_run = false;
163
164	if (maxlen == sizeof(ConfigDescriptor)) {
165		sendControl(&config, sizeof(ConfigDescriptor));
166		return true;
167	}
168
169	total = 0;
170
171	packMessages(true);
172	sendControl(&config, sizeof(ConfigDescriptor));
173	SendInterfaces(&total);
174	packMessages(false);
175
176	return true;
177}
178
179bool USBDeviceClass::sendDescriptor(USBSetup &setup)
180{
181	uint8_t t = setup.wValueH;
182	uint8_t desc_length = 0;
183	bool _cdcComposite;
184	int ret;
185	const uint8_t *desc_addr = 0;
186
187	if (t == USB_CONFIGURATION_DESCRIPTOR_TYPE)
188	{
189		return USBDevice.sendConfiguration(setup.wLength);
190	}
191
192#ifdef PLUGGABLE_USB_ENABLED
193	ret = PluggableUSB().getDescriptor(setup);
194	if (ret != 0) {
195		return (ret > 0 ? true : false);
196	}
197#endif
198
199	if (t == USB_DEVICE_DESCRIPTOR_TYPE)
200	{
201		if (setup.wLength == 8)
202			_cdcComposite = 1;
203
204		desc_addr = _cdcComposite ?  (const uint8_t*)&USB_DeviceDescriptorB : (const uint8_t*)&USB_DeviceDescriptor;
205
206		if (*desc_addr > setup.wLength) {
207			desc_length = setup.wLength;
208		}
209	}
210	else if (USB_STRING_DESCRIPTOR_TYPE == t)
211	{
212		if (setup.wValueL == 0) {
213			desc_addr = (const uint8_t*)&STRING_LANGUAGE;
214		}
215		else if (setup.wValueL == IPRODUCT) {
216			return sendStringDescriptor(STRING_PRODUCT, setup.wLength);
217		}
218		else if (setup.wValueL == IMANUFACTURER) {
219			return sendStringDescriptor(STRING_MANUFACTURER, setup.wLength);
220		}
221		else if (setup.wValueL == ISERIAL) {
222			char name[ISERIAL_MAX_LEN];
223			memset(name, 0, sizeof(name));
224			uint8_t idx = 0;
225#ifdef PLUGGABLE_USB_ENABLED
226			idx += PluggableUSB().getShortName(&name[idx]);
227#endif
228			if (idx > 0) {
229				return sendStringDescriptor((uint8_t*)name, setup.wLength);
230			}
231		}
232		else {
233			return false;
234		}
235		if (*desc_addr > setup.wLength) {
236			desc_length = setup.wLength;
237		}
238	}
239	else
240	{
241	}
242
243	if (desc_addr == 0) {
244		return false;
245	}
246
247	if (desc_length == 0) {
248		desc_length = *desc_addr;
249	}
250
251	sendControl(desc_addr, desc_length);
252
253	return true;
254}
255
256void USBDeviceClass::standby() {
257	usbd.noRunInStandby();
258}
259
260void USBDeviceClass::init()
261{
262#ifdef PIN_LED_TXL
263	txLEDPulse = 0;
264	pinMode(PIN_LED_TXL, OUTPUT);
265	digitalWrite(PIN_LED_TXL, HIGH);
266#endif
267
268#ifdef PIN_LED_RXL
269	rxLEDPulse = 0;
270	pinMode(PIN_LED_RXL, OUTPUT);
271	digitalWrite(PIN_LED_RXL, HIGH);
272#endif
273
274	// Enable USB clock
275	PM->APBBMASK.reg |= PM_APBBMASK_USB;
276
277	// Set up the USB DP/DN pins
278	PORT->Group[0].PINCFG[PIN_PA24G_USB_DM].bit.PMUXEN = 1;
279	PORT->Group[0].PMUX[PIN_PA24G_USB_DM/2].reg &= ~(0xF << (4 * (PIN_PA24G_USB_DM & 0x01u)));
280	PORT->Group[0].PMUX[PIN_PA24G_USB_DM/2].reg |= MUX_PA24G_USB_DM << (4 * (PIN_PA24G_USB_DM & 0x01u));
281	PORT->Group[0].PINCFG[PIN_PA25G_USB_DP].bit.PMUXEN = 1;
282	PORT->Group[0].PMUX[PIN_PA25G_USB_DP/2].reg &= ~(0xF << (4 * (PIN_PA25G_USB_DP & 0x01u)));
283	PORT->Group[0].PMUX[PIN_PA25G_USB_DP/2].reg |= MUX_PA25G_USB_DP << (4 * (PIN_PA25G_USB_DP & 0x01u));
284
285	// Put Generic Clock Generator 0 as source for Generic Clock Multiplexer 6 (USB reference)
286	GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(6)     | // Generic Clock Multiplexer 6
287	                    GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source
288	                    GCLK_CLKCTRL_CLKEN;
289	while (GCLK->STATUS.bit.SYNCBUSY)
290		;
291
292	USB_SetHandler(&UDD_Handler);
293
294	// Reset USB Device
295	usbd.reset();
296
297	usbd.calibrate();
298	usbd.setDataSensitiveQoS();
299	usbd.setConfigSensitiveQoS();
300	usbd.setUSBDeviceMode();
301	usbd.runInStandby();
302	usbd.setFullSpeed();
303
304	// Configure interrupts
305	NVIC_SetPriority((IRQn_Type) USB_IRQn, 0UL);
306	NVIC_EnableIRQ((IRQn_Type) USB_IRQn);
307
308	usbd.enable();
309
310	initialized = true;
311
312#ifdef CDC_ENABLED
313	SerialUSB.begin(0);
314#endif
315}
316
317bool USBDeviceClass::attach()
318{
319	if (!initialized)
320		return false;
321
322	usbd.attach();
323	usbd.enableEndOfResetInterrupt();
324	usbd.enableStartOfFrameInterrupt();
325
326	_usbConfiguration = 0;
327	return true;
328}
329
330void USBDeviceClass::setAddress(uint32_t addr)
331{
332	usbd.epBank1SetByteCount(0, 0);
333	usbd.epBank1AckTransferComplete(0);
334
335	// RAM buffer is full, we can send data (IN)
336	usbd.epBank1SetReady(0);
337
338	// Wait for transfer to complete
339	while (!usbd.epBank1IsTransferComplete(0)) {}
340
341	// Set USB address to addr
342	USB->DEVICE.DADD.bit.DADD = addr; // Address
343	USB->DEVICE.DADD.bit.ADDEN = 1; // Enable
344}
345
346bool USBDeviceClass::detach()
347{
348	if (!initialized)
349		return false;
350	usbd.detach();
351	return true;
352}
353
354bool USBDeviceClass::end() {
355	if (!initialized)
356		return false;
357	usbd.disable();
358	return true;
359}
360
361bool USBDeviceClass::configured()
362{
363	return _usbConfiguration != 0;
364}
365
366bool USBDeviceClass::handleClassInterfaceSetup(USBSetup& setup)
367{
368#if defined(PLUGGABLE_USB_ENABLED)
369	bool ret = PluggableUSB().setup(setup);
370	if ( ret == false) {
371		sendZlp(0);
372	}
373	return ret;
374#endif
375
376	return false;
377}
378
379uint32_t EndPoints[] =
380{
381	USB_ENDPOINT_TYPE_CONTROL,
382
383#ifdef PLUGGABLE_USB_ENABLED
384	//allocate 9 endpoints and remove const so they can be changed by the user
385	0,
386	0,
387	0,
388	0,
389	0,
390	0,
391	0,
392	0,
393	0,
394#endif
395};
396#define EP_ARRAY_SIZE   (sizeof(EndPoints)/sizeof(EndPoints[0]))
397
398void USBDeviceClass::initEndpoints() {
399	for (uint8_t i = 1; (i < EP_ARRAY_SIZE) && (EndPoints[i] != 0); i++) {
400		initEP(i, EndPoints[i]);
401	}
402}
403
404void USBDeviceClass::initEP(uint32_t ep, uint32_t config)
405{
406	if (config == (USB_ENDPOINT_TYPE_INTERRUPT | USB_ENDPOINT_IN(0)))
407	{
408		usbd.epBank1SetSize(ep, 64);
409		usbd.epBank1SetAddress(ep, &udd_ep_in_cache_buffer[ep]);
410		usbd.epBank1SetType(ep, 4); // INTERRUPT IN
411	}
412	else if (config == (USB_ENDPOINT_TYPE_BULK | USB_ENDPOINT_OUT(0)))
413	{
414		if (epHandlers[ep] != NULL) {
415			delete (DoubleBufferedEPOutHandler*)epHandlers[ep];
416		}
417		epHandlers[ep] = new DoubleBufferedEPOutHandler(usbd, ep);
418	}
419	else if (config == (USB_ENDPOINT_TYPE_BULK | USB_ENDPOINT_IN(0)))
420	{
421		usbd.epBank1SetSize(ep, 64);
422		usbd.epBank1SetAddress(ep, &udd_ep_in_cache_buffer[ep]);
423		usbd.epBank1SetType(ep, 3); // BULK IN
424	}
425	else if (config == USB_ENDPOINT_TYPE_CONTROL)
426	{
427		// Setup Control OUT
428		usbd.epBank0SetSize(ep, 64);
429		usbd.epBank0SetAddress(ep, &udd_ep_out_cache_buffer[ep]);
430		usbd.epBank0SetType(ep, 1); // CONTROL OUT / SETUP
431
432		// Setup Control IN
433		usbd.epBank1SetSize(ep, 64);
434		usbd.epBank1SetAddress(ep, &udd_ep_in_cache_buffer[ep]);
435		usbd.epBank1SetType(ep, 1); // CONTROL IN
436
437		// Release OUT EP
438		usbd.epReleaseOutBank0(ep, 64);
439	}
440}
441
442void USBDeviceClass::flush(uint32_t ep)
443{
444	if (available(ep)) {
445		// RAM buffer is full, we can send data (IN)
446		usbd.epBank1SetReady(ep);
447
448	 	// Clear the transfer complete flag
449		usbd.epBank1AckTransferComplete(ep);
450	}
451}
452
453void USBDeviceClass::clear(uint32_t ep) {
454	usbd.epBank1SetAddress(ep, &udd_ep_in_cache_buffer[ep]);
455	usbd.epBank1SetByteCount(ep, 0);
456
457	// Clear the transfer complete flag
458	usbd.epBank1AckTransferComplete(ep);
459
460	// RAM buffer is full, we can send data (IN)
461	usbd.epBank1SetReady(ep);
462}
463
464void USBDeviceClass::stall(uint32_t ep)
465{
466	// TODO: test
467	// TODO: use .bit. notation
468
469	// Stall endpoint
470	USB->DEVICE.DeviceEndpoint[ep].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ(2);
471}
472
473bool USBDeviceClass::connected()
474{
475	// Count frame numbers
476	uint8_t f = USB->DEVICE.FNUM.bit.FNUM;
477	//delay(3);
478	return f != USB->DEVICE.FNUM.bit.FNUM;
479}
480
481
482uint32_t USBDeviceClass::recvControl(void *_data, uint32_t len)
483{
484	uint8_t *data = reinterpret_cast<uint8_t *>(_data);
485
486	//usbd.epBank0AckSetupReceived(0);
487	uint32_t read = armRecvCtrlOUT(0);
488	if (read > len)
489		read = len;
490	//while (!usbd.epBank0AckTransferComplete(0)) {}
491	uint8_t *buffer = udd_ep_out_cache_buffer[0];
492	for (uint32_t i=0; i<len; i++) {
493		data[i] = buffer[i];
494	}
495
496	return read;
497}
498
499// Number of bytes, assumes a rx endpoint
500uint32_t USBDeviceClass::available(uint32_t ep)
501{
502	if (epHandlers[ep]) {
503		return epHandlers[ep]->available();
504	} else {
505		return usbd.epBank0ByteCount(ep);
506	}
507}
508
509// Non Blocking receive
510// Return number of bytes read
511uint32_t USBDeviceClass::recv(uint32_t ep, void *_data, uint32_t len)
512{
513	if (!_usbConfiguration)
514		return -1;
515
516#ifdef PIN_LED_RXL
517	if (rxLEDPulse == 0)
518		digitalWrite(PIN_LED_RXL, LOW);
519
520	rxLEDPulse = TX_RX_LED_PULSE_MS;
521#endif
522
523	if (epHandlers[ep]) {
524		return epHandlers[ep]->recv(_data, len);
525	}
526
527	if (available(ep) < len)
528		len = available(ep);
529
530	usbd.epBank0SetByteCount(ep, 0);
531	usbd.epBank0DisableTransferComplete(ep);
532
533	memcpy(_data, udd_ep_out_cache_buffer[ep], len);
534
535	// release empty buffer
536	if (len && !available(ep)) {
537		// The RAM Buffer is empty: we can receive data
538		usbd.epBank0ResetReady(ep);
539
540		// Clear Transfer complete 0 flag
541		usbd.epBank0AckTransferComplete(ep);
542
543		// Enable Transfer complete 0 interrupt
544		usbd.epBank0EnableTransferComplete(ep);
545	}
546
547	return len;
548}
549
550// Recv 1 byte if ready
551int USBDeviceClass::recv(uint32_t ep)
552{
553	uint8_t c;
554	if (recv(ep, &c, 1) != 1) {
555		return -1;
556	} else {
557		return c;
558	}
559}
560
561uint8_t USBDeviceClass::armRecvCtrlOUT(uint32_t ep)
562{
563	// Get endpoint configuration from setting register
564	usbd.epBank0SetAddress(ep, &udd_ep_out_cache_buffer[ep]);
565	/* Atmel-42181G–SAM-D21_Datasheet–09/2015 / Page 806
566	 *
567	 * For OUT endpoints, MULTI_PACKET_SIZE holds the total
568	 * data size for the complete transfer. This value must
569	 * be a multiple of the maximum packet size.
570	 *
571	 * Since SIZE is 64 (see 'USBDeviceClass::initEP') for
572	 * all endpoints MULTI_PACKET_SIZE should not be set to
573	 * a value < SIZE, this means at least to 64.
574	 */
575	usbd.epBank0SetMultiPacketSize(ep, 64);
576	usbd.epBank0SetByteCount(ep, 0);
577
578	usbd.epBank0ResetReady(ep);
579
580	// Wait OUT
581	while (!usbd.epBank0IsReady(ep)) {}
582	while (!usbd.epBank0IsTransferComplete(ep)) {}
583	return usbd.epBank0ByteCount(ep);
584}
585
586// Timeout for sends
587#define TX_TIMEOUT_MS 70
588
589static char LastTransmitTimedOut[7] = {
590	0,
591	0,
592	0,
593	0,
594	0,
595	0,
596	0
597};
598
599// Blocking Send of data to an endpoint
600uint32_t USBDeviceClass::send(uint32_t ep, const void *data, uint32_t len)
601{
602	uint32_t written = 0;
603	uint32_t length = 0;
604
605	if (!_usbConfiguration)
606		return -1;
607	if (len > 16384)
608		return -1;
609
610#ifdef PIN_LED_TXL
611	if (txLEDPulse == 0)
612		digitalWrite(PIN_LED_TXL, LOW);
613
614	txLEDPulse = TX_RX_LED_PULSE_MS;
615#endif
616
617	// Flash area
618	while (len != 0)
619	{
620		if (usbd.epBank1IsReady(ep)) {
621			// previous transfer is still not complete
622
623			// convert the timeout from microseconds to a number of times through
624			// the wait loop; it takes (roughly) 23 clock cycles per iteration.
625			uint32_t timeout = microsecondsToClockCycles(TX_TIMEOUT_MS * 1000) / 23;
626
627			// Wait for (previous) transfer to complete
628			// inspired by Paul Stoffregen's work on Teensy
629			while (!usbd.epBank1IsTransferComplete(ep)) {
630				if (LastTransmitTimedOut[ep] || timeout-- == 0) {
631					LastTransmitTimedOut[ep] = 1;
632
633					// set byte count to zero, so that ZLP is sent
634					// instead of stale data
635					usbd.epBank1SetByteCount(ep, 0);
636					return -1;
637				}
638			}
639		}
640
641		LastTransmitTimedOut[ep] = 0;
642
643		if (len >= EPX_SIZE) {
644			usbd.epBank1EnableAutoZLP(ep);
645			length = EPX_SIZE;
646		} else {
647			length = len;
648		}
649
650		/* memcopy could be safer in multi threaded environment */
651		memcpy(&udd_ep_in_cache_buffer[ep], data, length);
652
653		usbd.epBank1SetAddress(ep, &udd_ep_in_cache_buffer[ep]);
654		usbd.epBank1SetByteCount(ep, length);
655
656		// Clear the transfer complete flag
657		usbd.epBank1AckTransferComplete(ep);
658
659		// RAM buffer is full, we can send data (IN)
660		usbd.epBank1SetReady(ep);
661
662		written += length;
663		len -= length;
664		data = (char *)data + length;
665	}
666	return written;
667}
668
669uint32_t USBDeviceClass::armSend(uint32_t ep, const void* data, uint32_t len)
670{
671	memcpy(&udd_ep_in_cache_buffer[ep], data, len);
672
673	// Get endpoint configuration from setting register
674	usbd.epBank1SetAddress(ep, &udd_ep_in_cache_buffer[ep]);
675	usbd.epBank1SetMultiPacketSize(ep, 0);
676	usbd.epBank1SetByteCount(ep, len);
677
678	return len;
679}
680
681uint32_t USBDeviceClass::sendControl(const void* _data, uint32_t len)
682{
683	const uint8_t *data = reinterpret_cast<const uint8_t *>(_data);
684	uint32_t length = len;
685	uint32_t sent = 0;
686	uint32_t pos = 0;
687
688	if (_dry_run == true)
689		return length;
690
691	if (_pack_message == true) {
692		memcpy(&_pack_buffer[_pack_size], data, len);
693		_pack_size += len;
694		return length;
695	}
696
697 	while (len > 0)
698 	{
699		sent = armSend(EP0, data + pos, len);
700		pos += sent;
701		len -= sent;
702 	}
703
704	return length;
705}
706
707void USBDeviceClass::sendZlp(uint32_t ep)
708{
709	// Set the byte count as zero
710	usbd.epBank1SetByteCount(ep, 0);
711}
712
713bool USBDeviceClass::handleStandardSetup(USBSetup &setup)
714{
715	switch (setup.bRequest) {
716	case GET_STATUS:
717		if (setup.bmRequestType == 0)  // device
718		{
719			// Send the device status
720			// TODO: Check current configuration for power mode (if device is configured)
721			// TODO: Check if remote wake-up is enabled
722			uint8_t buff[] = { 0, 0 };
723			armSend(0, buff, 2);
724			return true;
725		}
726		// if( setup.bmRequestType == 2 ) // Endpoint:
727		else
728		{
729			// Send the endpoint status
730			// Check if the endpoint if currently halted
731			uint8_t buff[] = { 0, 0 };
732			if (isEndpointHalt == 1)
733				buff[0] = 1;
734			armSend(0, buff, 2);
735			return true;
736		}
737
738	case CLEAR_FEATURE:
739		// Check which is the selected feature
740		if (setup.wValueL == 1) // DEVICEREMOTEWAKEUP
741		{
742			// Enable remote wake-up and send a ZLP
743			uint8_t buff[] = { 0, 0 };
744			if (isRemoteWakeUpEnabled == 1)
745				buff[0] = 1;
746			armSend(0, buff, 2);
747			return true;
748		}
749		else // if( setup.wValueL == 0) // ENDPOINTHALT
750		{
751			isEndpointHalt = 0;
752			sendZlp(0);
753			return true;
754		}
755
756	case SET_FEATURE:
757		// Check which is the selected feature
758		if (setup.wValueL == 1) // DEVICEREMOTEWAKEUP
759		{
760			// Enable remote wake-up and send a ZLP
761			isRemoteWakeUpEnabled = 1;
762			uint8_t buff[] = { 0 };
763			armSend(0, buff, 1);
764			return true;
765		}
766		if (setup.wValueL == 0) // ENDPOINTHALT
767		{
768			// Halt endpoint
769			isEndpointHalt = 1;
770			sendZlp(0);
771			return true;
772		}
773		break;
774
775	case SET_ADDRESS:
776		setAddress(setup.wValueL);
777		return true;
778
779	case GET_DESCRIPTOR:
780		return sendDescriptor(setup);
781
782	case SET_DESCRIPTOR:
783		return false;
784
785	case GET_CONFIGURATION:
786		armSend(0, (void*)&_usbConfiguration, 1);
787		return true;
788
789	case SET_CONFIGURATION:
790		if (REQUEST_DEVICE == (setup.bmRequestType & REQUEST_RECIPIENT)) {
791
792			initEndpoints();
793			_usbConfiguration = setup.wValueL;
794
795			#ifdef CDC_ENABLED
796			SerialUSB.enableInterrupt();
797			#endif
798
799			sendZlp(0);
800			return true;
801		} else {
802			return false;
803		}
804
805	case GET_INTERFACE:
806		armSend(0, (void*)&_usbSetInterface, 1);
807		return true;
808
809	case SET_INTERFACE:
810		_usbSetInterface = setup.wValueL;
811		sendZlp(0);
812		return true;
813
814	default:
815		return true;
816	}
817	return true;
818}
819
820void USBDeviceClass::ISRHandler()
821{
822	if (_pack_message == true) {
823		return;
824	}
825
826	// End-Of-Reset
827	if (usbd.isEndOfResetInterrupt())
828	{
829		usbd.ackEndOfResetInterrupt();
830
831		// Configure EP 0
832		initEP(0, USB_ENDPOINT_TYPE_CONTROL);
833
834		// Enable Setup-Received interrupt
835		usbd.epBank0EnableSetupReceived(0);
836
837		_usbConfiguration = 0;
838	}
839
840	// Start-Of-Frame
841	if (usbd.isStartOfFrameInterrupt())
842	{
843		usbd.ackStartOfFrameInterrupt();
844
845		// check whether the one-shot period has elapsed.  if so, turn off the LED
846#ifdef PIN_LED_TXL
847		if (txLEDPulse > 0) {
848			txLEDPulse--;
849			if (txLEDPulse == 0)
850				digitalWrite(PIN_LED_TXL, HIGH);
851		}
852#endif
853
854#ifdef PIN_LED_RXL
855		if (rxLEDPulse > 0) {
856			rxLEDPulse--;
857			if (rxLEDPulse == 0)
858				digitalWrite(PIN_LED_RXL, HIGH);
859		}
860#endif
861	}
862
863	/* Remove any stall requests for endpoint #0 */
864	if (usbd.epBank0IsStalled(0)) { usbd.epBank0DisableStalled(0); }
865
866	// Endpoint 0 Received Setup interrupt
867	if (usbd.epBank0IsSetupReceived(0))
868	{
869		/* Retrieve received endpoint #0 data from buffer */
870		USBSetup setup;
871		memcpy(&setup, udd_ep_out_cache_buffer[0], sizeof(USBSetup));
872
873		/* Tell the USB hardware that we are ready to receive more data for endpoint #0 and also reset the byte count
874		 * for endpoint #0 - the clearing seems to be necessary for the code to function correctly, although the datasheet
875		 * is not clear on the subject.
876		 *
877		 * Atmel-42181G–SAM-D21_Datasheet–09/2015 / Page 806
878		 *   For IN endpoints, BYTE_COUNT holds the number of bytes to be sent in the next IN transaction.
879		 *   For OUT endpoint or SETUP endpoints, BYTE_COUNT holds the number of bytes received upon the last OUT or SETUP transaction.
880		 */
881		usbd.epBank0SetByteCount(0, 0);
882		usbd.epBank0ResetReady(0);
883
884		bool ok;
885		if (REQUEST_STANDARD == (setup.bmRequestType & REQUEST_TYPE)) {
886			// Standard Requests
887			ok = handleStandardSetup(setup);
888		} else {
889			// Class Interface Requests
890			ok = handleClassInterfaceSetup(setup);
891		}
892
893		if (ok) {
894			usbd.epBank1SetReady(0);
895		} else {
896			stall(0);
897		}
898
899		if (usbd.epBank1IsStalled(0))
900		{
901			// Remove stall request
902			usbd.epBank1DisableStalled(0);
903		}
904	} // end Received Setup handler
905	usbd.epAckPendingInterrupts(0);
906
907	for (int ep = 1; ep < USB_EPT_NUM; ep++) {
908		// Endpoint Transfer Complete (0/1) Interrupt
909		if (usbd.epHasPendingInterrupts(ep)) {
910			if (epHandlers[ep]) {
911				epHandlers[ep]->handleEndpoint();
912			} else {
913				#if defined(PLUGGABLE_USB_ENABLED)
914				PluggableUSB().handleEndpoint(ep);
915				usbd.epAckPendingInterrupts(ep);
916				#endif
917			}
918		}
919	}
920}
921
922/*
923 * USB Device instance
924 * -------------------
925 */
926
927// USBDevice class instance
928USBDeviceClass USBDevice;
929
930#endif
931