19 #define CDC_OUT_PACKET_SIZE 64
20 #define CDC_IN_PACKET_SIZE 64
21 #define CDC_CONTROL_INTERFACE_NUMBER 0
22 #define CDC_DATA_INTERFACE_NUMBER 1
24 #define CDC_NOTIFICATION_ENDPOINT 1
25 #define CDC_NOTIFICATION_FIFO USBF1 // This must match CDC_NOTIFICATION_ENDPOINT!
27 #define CDC_DATA_ENDPOINT 4
28 #define CDC_DATA_FIFO USBF4 // This must match CDC_DATA_ENDPOINT!
33 #define CDC_CLASS 2 // (CDC 1.20 Section 4.1: Communications Device Class Code).
34 #define CDC_DATA_INTERFACE_CLASS 0xA // (CDC 1.20 Section 4.5: Data Class Interface Codes).
37 #define CDC_SUBCLASS_ACM 2 // (CDC 1.20 Section 4.3: Communications Class Subclass Codes). Refer to USBPSTN1.2.
40 #define CDC_PROTOCOL_V250 1 // (CDC 1.20 Section 4.4: Communications Class Protocol Codes).
43 #define CDC_DESCRIPTOR_TYPE_CS_INTERFACE 0x24
44 #define CDC_DESCRIPTOR_TYPE_CS_ENDPOINT 0x25
47 #define CDC_DESCRIPTOR_SUBTYPE_HEADER 0
48 #define CDC_DESCRIPTOR_SUBTYPE_CALL_MANAGEMENT 1
49 #define CDC_DESCRIPTOR_SUBTYPE_ABSTRACT_CONTROL_MANAGEMENT 2
50 #define CDC_DESCRIPTOR_SUBTYPE_UNION 6
53 #define ACM_GET_ENCAPSULATED_RESPONSE 0
54 #define ACM_SEND_ENCAPSULATED_COMMAND 1
57 #define ACM_REQUEST_SET_LINE_CODING 0x20
58 #define ACM_REQUEST_GET_LINE_CODING 0x21
59 #define ACM_REQUEST_SET_CONTROL_LINE_STATE 0x22
62 #define ACM_NOTIFICATION_RESPONSE_AVAILABLE 0x01
63 #define ACM_NOTIFICATION_SERIAL_STATE 0x20
66 static void doNothing();
71 uint8 usbComControlLineState = 0;
73 uint8 usbComSerialState = 0;
77 static uint8 lastReportedSerialState = 0xFF;
92 static BIT sendEmptyPacketSoon = 0;
100 static BIT startBootloaderSoon = 0;
105 static uint8 XDATA startBootloaderRequestTime;
112 USB_DESCRIPTOR_TYPE_DEVICE,
131 unsigned char class_specific[19];
137 } usbConfigurationDescriptor
142 USB_DESCRIPTOR_TYPE_CONFIGURATION,
152 USB_DESCRIPTOR_TYPE_INTERFACE,
153 CDC_CONTROL_INTERFACE_NUMBER,
164 CDC_DESCRIPTOR_TYPE_CS_INTERFACE,
165 CDC_DESCRIPTOR_SUBTYPE_HEADER,
170 CDC_DESCRIPTOR_TYPE_CS_INTERFACE,
171 CDC_DESCRIPTOR_SUBTYPE_ABSTRACT_CONTROL_MANAGEMENT,
176 CDC_DESCRIPTOR_TYPE_CS_INTERFACE,
177 CDC_DESCRIPTOR_SUBTYPE_UNION,
178 CDC_CONTROL_INTERFACE_NUMBER,
179 CDC_DATA_INTERFACE_NUMBER,
182 CDC_DESCRIPTOR_TYPE_CS_INTERFACE,
183 CDC_DESCRIPTOR_SUBTYPE_CALL_MANAGEMENT,
185 CDC_DATA_INTERFACE_NUMBER
189 USB_DESCRIPTOR_TYPE_ENDPOINT,
190 USB_ENDPOINT_ADDRESS_IN | CDC_NOTIFICATION_ENDPOINT,
191 USB_TRANSFER_TYPE_INTERRUPT,
197 USB_DESCRIPTOR_TYPE_INTERFACE,
198 CDC_DATA_INTERFACE_NUMBER,
201 CDC_DATA_INTERFACE_CLASS,
208 USB_DESCRIPTOR_TYPE_ENDPOINT,
209 USB_ENDPOINT_ADDRESS_OUT | CDC_DATA_ENDPOINT,
210 USB_TRANSFER_TYPE_BULK,
216 USB_DESCRIPTOR_TYPE_ENDPOINT,
217 USB_ENDPOINT_ADDRESS_IN | CDC_DATA_ENDPOINT,
218 USB_TRANSFER_TYPE_BULK,
226 DEFINE_STRING_DESCRIPTOR(manufacturer, 18, 'P','o','l','o','l','u',' ','C','o','r','p','o','r','a','t','i','o','n')
241 lastReportedSerialState = 0xFF;
256 case ACM_REQUEST_SET_LINE_CODING:
260 case ACM_REQUEST_GET_LINE_CODING:
264 case ACM_REQUEST_SET_CONTROL_LINE_STATE:
276 static void doNothing(
void)
290 startBootloaderSoon = 1;
307 USBINDEX = CDC_DATA_ENDPOINT;
308 if (USBCSOL & USBCSOL_OUTPKT_RDY)
329 USBINDEX = CDC_DATA_ENDPOINT;
334 USBCSOL &= ~USBCSOL_OUTPKT_RDY;
349 USBCSOL &= ~USBCSOL_OUTPKT_RDY;
358 static void sendPacketNow()
360 USBINDEX = CDC_DATA_ENDPOINT;
361 USBCSIL |= USBCSIL_INPKT_RDY;
364 sendEmptyPacketSoon = (inFifoBytesLoaded == CDC_IN_PACKET_SIZE);
367 inFifoBytesLoaded = 0;
378 if (startBootloaderSoon && (
uint8)(
getMs() - startBootloaderRequestTime) > 70)
402 USBINDEX = CDC_DATA_ENDPOINT;
403 if (inFifoBytesLoaded || ( sendEmptyPacketSoon && !(USBCSIL & USBCSIL_PKT_PRESENT) ) )
409 USBINDEX = CDC_NOTIFICATION_ENDPOINT;
410 if (usbComSerialState != lastReportedSerialState && !(USBCSIL & USBCSIL_INPKT_RDY))
416 CDC_NOTIFICATION_FIFO = 0b10100001;
417 CDC_NOTIFICATION_FIFO = ACM_NOTIFICATION_SERIAL_STATE;
420 CDC_NOTIFICATION_FIFO = 0;
421 CDC_NOTIFICATION_FIFO = 0;
424 CDC_NOTIFICATION_FIFO = CDC_CONTROL_INTERFACE_NUMBER;
425 CDC_NOTIFICATION_FIFO = 0;
428 CDC_NOTIFICATION_FIFO = 2;
429 CDC_NOTIFICATION_FIFO = 0;
432 CDC_NOTIFICATION_FIFO = usbComSerialState;
433 CDC_NOTIFICATION_FIFO = 0;
435 USBCSIL |= USBCSIL_INPKT_RDY;
440 lastReportedSerialState = usbComSerialState;
459 USBINDEX = CDC_DATA_ENDPOINT;
461 if (tmp & USBCSIL_PKT_PRESENT)
463 if (tmp & USBCSIL_INPKT_RDY)
467 return CDC_IN_PACKET_SIZE - inFifoBytesLoaded;
471 return (CDC_IN_PACKET_SIZE<<1) - inFifoBytesLoaded;
482 packetSize = CDC_IN_PACKET_SIZE - inFifoBytesLoaded;
483 if (packetSize > size){ packetSize = size; }
487 buffer += packetSize;
489 inFifoBytesLoaded += packetSize;
491 if (inFifoBytesLoaded == CDC_IN_PACKET_SIZE)
502 CDC_DATA_FIFO = byte;
505 if (inFifoBytesLoaded == CDC_IN_PACKET_SIZE)
517 return usbComControlLineState;
527 usbComSerialState |= signalEvents;
struct USB_DESCRIPTOR_DEVICE USB_DESCRIPTOR_DEVICE
void usbCallbackInitEndpoints(void)
uint8 CODE usbStringDescriptorCount
void boardStartBootloader()
ACM_LINE_CODING XDATA usbComLineCoding
void usbInitEndpointOut(uint8 endpointNumber, uint8 maxPacketSize)
void usbComTxSend(const uint8 XDATA *buffer, uint8 size)
HandlerFunction * usbComLineCodingChangeHandler
volatile BIT usbActivityFlag
#define USB_LANGUAGE_EN_US
#define USB_EP0_PACKET_SIZE
void usbComTxControlSignalEvents(uint8 signalEvents)
enum USB_DEVICE_STATES XDATA usbDeviceState
void usbControlWrite(uint16 bytesCount, uint8 XDATA *source)
USB_DESCRIPTOR_DEVICE CODE usbDeviceDescriptor
struct USB_DESCRIPTOR_CONFIGURATION USB_DESCRIPTOR_CONFIGURATION
struct USB_DESCRIPTOR_INTERFACE USB_DESCRIPTOR_INTERFACE
struct USB_DESCRIPTOR_ENDPOINT USB_DESCRIPTOR_ENDPOINT
USB_SETUP_PACKET XDATA usbSetupPacket
void usbComRxReceive(uint8 XDATA *buffer, uint8 size)
#define USB_VENDOR_ID_POLOLU
void usbWriteFifo(uint8 endpointNumber, uint8 count, const uint8 XDATA *buffer)
uint16 CODE serialNumberStringDescriptor[]
void usbInitEndpointIn(uint8 endpointNumber, uint8 maxPacketSize)
void usbReadFifo(uint8 endpointNumber, uint8 count, uint8 XDATA *buffer)
void usbComTxControlSignals(uint8 signals)
void usbComTxSendByte(uint8 byte)
void usbCallbackSetupHandler(void)
uint8 usbComRxControlSignals(void)
uint8 usbComRxReceiveByte(void)
void usbControlAcknowledge(void)
void usbCallbackControlWriteHandler(void)
uint8 usbComRxAvailable(void)
void usbControlRead(uint16 bytesCount, uint8 XDATA *source)
#define DEFINE_STRING_DESCRIPTOR(name, char_count,...)
void usbCallbackClassDescriptorHandler(void)
#define ACM_IRREGULAR_SIGNAL_MASK
uint16 CODE *CODE usbStringDescriptors[]
uint8 usbComTxAvailable(void)