diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp index db6b149..ee77b45 100644 --- a/cores/arduino/HardwareSerial.cpp +++ b/cores/arduino/HardwareSerial.cpp @@ -50,6 +50,10 @@ struct ring_buffer volatile int tail; }; +#if defined(USBCON) + ring_buffer rx_buffer = { { 0 }, 0, 0}; + ring_buffer tx_buffer = { { 0 }, 0, 0}; +#endif #if defined(UBRRH) || defined(UBRR0H) ring_buffer rx_buffer = { { 0 }, 0, 0 }; ring_buffer tx_buffer = { { 0 }, 0, 0 }; @@ -81,6 +85,15 @@ inline void store_char(unsigned char c, ring_buffer *buffer) } } +#if defined(__AVR_ATmega32U4__) + void serialEvent() __attribute__((weak)); + void serialEvent() {} + SIGNAL(USART1_RX_vect) { + unsigned char c = UDR1; + store_char(c, &rx_buffer); + serialEvent(); + } +#else #if !defined(USART_RX_vect) && !defined(SIG_USART0_RECV) && \ !defined(SIG_UART0_RECV) && !defined(USART0_RX_vect) && \ !defined(SIG_UART_RECV) @@ -150,8 +163,19 @@ inline void store_char(unsigned char c, ring_buffer *buffer) #elif defined(SIG_USART3_RECV) #error SIG_USART3_RECV #endif +#endif - +#if defined(__AVR_ATmega32U4__) +ISR(USART1_UDRE_vect) { + if (tx_buffer.head == tx_buffer.tail) { + cbi(UCSR1B, UDRIE1); + } else { + unsigned char c = tx_buffer.buffer[tx_buffer.tail]; + tx_buffer.tail = (tx_buffer.tail + 1) % SERIAL_BUFFER_SIZE; + UDR1 = c; + } +} +#else #if !defined(UART0_UDRE_vect) && !defined(UART_UDRE_vect) && !defined(USART0_UDRE_vect) && !defined(USART_UDRE_vect) #error Don't know what the Data Register Empty vector is called for the first UART #else @@ -205,6 +229,7 @@ ISR(USART1_UDRE_vect) } } #endif +#endif #ifdef USART2_UDRE_vect ISR(USART2_UDRE_vect) diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h index eefdcbe..a5b1ed3 100644 --- a/cores/arduino/HardwareSerial.h +++ b/cores/arduino/HardwareSerial.h @@ -63,6 +63,7 @@ class HardwareSerial : public Stream extern HardwareSerial Serial; #elif defined(USBCON) #include "usb_api.h" + extern HardwareSerial Serial_; #endif #if defined(UBRR1H) extern HardwareSerial Serial1; diff --git a/cores/arduino/usb_api.h b/cores/arduino/usb_api.h new file mode 100644 index 0000000..4d26d23 --- /dev/null +++ b/cores/arduino/usb_api.h @@ -0,0 +1,156 @@ + + +#ifndef __USBAPI__ +#define __USBAPI__ + +//================================================================================ +//================================================================================ +// USB + +class USB_ +{ +public: + USB_(); + bool configured(); + + void attach(); + void detach(); // Serial port goes down too... + void poll(); +}; +extern USB_ USB; + +//================================================================================ +//================================================================================ +// Serial over CDC (Serial1 is the physical port) + +class Serial_ : public Stream +{ +public: + void begin(uint16_t baud_count); + void end(void); + + virtual int available(void); + virtual int peek(void); + virtual int read(void); + virtual void flush(void); + virtual void write(uint8_t); +}; +extern Serial_ Serial; + +//================================================================================ +//================================================================================ +// Mouse + +#define MOUSE_LEFT 1 +#define MOUSE_MIDDLE 2 +#define MOUSE_RIGHT 4 + +class Mouse_ +{ + uint8_t _buttons; +public: + Mouse_(); + void click(uint8_t b = MOUSE_LEFT); + void move(signed char x, signed char y, signed char wheel = 0); + void buttons(uint8_t b); +}; +extern Mouse_ Mouse; + +//================================================================================ +//================================================================================ +// Keyboard + +#define KEY_MODIFIER_LEFT_CTRL 0x01 +#define KEY_MODIFIER_LEFT_SHIFT 0x02 +#define KEY_MODIFIER_LEFT_ALT 0x04 +#define KEY_MODIFIER_LEFT_GUI 0x08 +#define KEY_MODIFIER_RIGHT_CTRL 0x010 +#define KEY_MODIFIER_RIGHT_SHIFT 0x020 +#define KEY_MODIFIER_RIGHT_ALT 0x040 +#define KEY_MODIFIER_RIGHT_GUI 0x080 + +// Low level key report: up to 6 keys and shift, ctrl etc at once +typedef struct +{ + uint8_t modifiers; + uint8_t reserved; + uint8_t keys[6]; +} KeyReport; + +// Map a character into a key report +// Called from Print to map text to keycodes +class KeyMap +{ +public: + virtual void charToKey(int c, KeyReport* keyReport) = 0; +}; + +// +class Keyboard_ : public Print +{ + KeyMap* _keyMap; +public: + Keyboard_(); + void sendReport(KeyReport* keys); + void setKeyMap(KeyMap* keyMap); + virtual void write(uint8_t); +}; +extern Keyboard_ Keyboard; + +//================================================================================ +//================================================================================ +// Low level API + +typedef struct +{ + uint8_t bmRequestType; + uint8_t bRequest; + uint8_t wValueL; + uint8_t wValueH; + uint16_t wIndex; + uint16_t wLength; +} Setup; + +//================================================================================ +//================================================================================ +// HID 'Driver' + +int HID_GetInterface(uint8_t* interfaceNum); +int HID_GetDescriptor(int i); +bool HID_Setup(Setup& setup); +void HID_SendReport(uint8_t id, const void* data, int len); + +//================================================================================ +//================================================================================ +// MSC 'Driver' + +int MSC_GetInterface(uint8_t* interfaceNum); +int MSC_GetDescriptor(int i); +bool MSC_Setup(Setup& setup); +bool MSC_Data(uint8_t rx,uint8_t tx); + +//================================================================================ +//================================================================================ +// CSC 'Driver' + +int CDC_GetInterface(uint8_t* interfaceNum); +int CDC_GetDescriptor(int i); +bool CDC_Setup(Setup& setup); + +//================================================================================ +//================================================================================ + +#define TRANSFER_PGM 0x80 +#define TRANSFER_RELEASE 0x40 +#define TRANSFER_ZERO 0x20 + +int USB_SendControl(uint8_t flags, const void* d, int len); +int USB_RecvControl(void* d, int len); + +uint8_t USB_Available(uint8_t ep); +int USB_Send(uint8_t ep, const void* data, int len); // blocking +int USB_Recv(uint8_t ep, void* data, int len); // non-blocking +int USB_Recv(uint8_t ep); // non-blocking +void USB_Flush(uint8_t ep); + +#endif \ No newline at end of file