| @@ -51,8 +51,8 @@ | |||
| #include "usb_serial.h" | |||
| #include "usb_seremu.h" | |||
| #include "usb_keyboard.h" | |||
| //#include "usb_mouse.h" | |||
| //#include "usb_joystick.h" | |||
| #include "usb_mouse.h" | |||
| #include "usb_joystick.h" | |||
| //#include "usb_midi.h" | |||
| #include "usb_rawhid.h" | |||
| //#include "usb_flightsim.h" | |||
| @@ -4,6 +4,8 @@ | |||
| #include "usb_serial.h" | |||
| #include "usb_seremu.h" | |||
| #include "usb_keyboard.h" | |||
| #include "usb_mouse.h" | |||
| #include "usb_joystick.h" | |||
| #include "core_pins.h" // for delay() | |||
| #include "avr/pgmspace.h" | |||
| #include <string.h> | |||
| @@ -370,6 +372,12 @@ static void endpoint0_setup(uint64_t setupdata) | |||
| #if defined(KEYBOARD_INTERFACE) | |||
| usb_keyboard_configure(); | |||
| #endif | |||
| #if defined(MOUSE_INTERFACE) | |||
| usb_mouse_configure(); | |||
| #endif | |||
| #if defined(JOYSTICK_INTERFACE) | |||
| usb_joystick_configure(); | |||
| #endif | |||
| endpoint0_receive(NULL, 0, 0); | |||
| return; | |||
| case 0x0880: // GET_CONFIGURATION | |||
| @@ -78,12 +78,6 @@ interfaces, usually these other settings should not be changed. | |||
| Edit NUM_ENDPOINTS to be at least the largest endpoint number used. | |||
| Edit NUM_USB_BUFFERS to control how much memory the USB stack will | |||
| allocate. At least 2 should be used for each endpoint. More | |||
| memory will allow higher throughput for user programs that have | |||
| high latency (eg, spending time doing things other than interacting | |||
| with the USB). | |||
| Edit the ENDPOINT*_CONFIG lines so each endpoint is configured | |||
| the proper way (transmit, receive, or both). | |||
| @@ -185,7 +179,7 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define NUM_USB_BUFFERS 24 | |||
| #define NUM_INTERFACE 5 | |||
| #define SEREMU_INTERFACE 2 // Serial emulation | |||
| #define SEREMU_TX_ENDPOINT 1 | |||
| #define SEREMU_TX_ENDPOINT 2 | |||
| #define SEREMU_TX_SIZE 64 | |||
| #define SEREMU_TX_INTERVAL 1 | |||
| #define SEREMU_RX_ENDPOINT 2 | |||
| @@ -196,7 +190,7 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define KEYBOARD_SIZE 8 | |||
| #define KEYBOARD_INTERVAL 1 | |||
| #define KEYMEDIA_INTERFACE 4 // Keyboard Media Keys | |||
| #define KEYMEDIA_ENDPOINT 6 | |||
| #define KEYMEDIA_ENDPOINT 4 | |||
| #define KEYMEDIA_SIZE 8 | |||
| #define KEYMEDIA_INTERVAL 4 | |||
| #define MOUSE_INTERFACE 1 // Mouse | |||
| @@ -204,15 +198,14 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define MOUSE_SIZE 8 | |||
| #define MOUSE_INTERVAL 1 | |||
| #define JOYSTICK_INTERFACE 3 // Joystick | |||
| #define JOYSTICK_ENDPOINT 4 | |||
| #define JOYSTICK_ENDPOINT 6 | |||
| #define JOYSTICK_SIZE 12 // 12 = normal, 64 = extreme joystick | |||
| #define JOYSTICK_INTERVAL 2 | |||
| #define ENDPOINT1_CONFIG ENDPOINT_TRANSMIT_ONLY | |||
| #define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY | |||
| #define ENDPOINT3_CONFIG ENDPOINT_TRANSMIT_ONLY | |||
| #define ENDPOINT4_CONFIG ENDPOINT_TRANSMIT_ONLY | |||
| #define ENDPOINT5_CONFIG ENDPOINT_TRANSMIT_ONLY | |||
| #define ENDPOINT6_CONFIG ENDPOINT_TRANSMIT_ONLY | |||
| #define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_INTERRUPT + ENDPOINT_TRANSMIT_INTERRUPT | |||
| #define ENDPOINT3_CONFIG ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT | |||
| #define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT | |||
| #define ENDPOINT5_CONFIG ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT | |||
| #define ENDPOINT6_CONFIG ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT | |||
| #elif defined(USB_SERIAL_HID) | |||
| #define VENDOR_ID 0x16C0 | |||
| @@ -226,40 +219,40 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define PRODUCT_NAME_LEN 30 | |||
| #define EP0_SIZE 64 | |||
| #define NUM_ENDPOINTS 7 | |||
| #define NUM_USB_BUFFERS 30 | |||
| #define NUM_INTERFACE 6 | |||
| #define CDC_IAD_DESCRIPTOR 1 | |||
| #define CDC_STATUS_INTERFACE 0 | |||
| #define CDC_DATA_INTERFACE 1 // Serial | |||
| #define CDC_ACM_ENDPOINT 2 | |||
| #define CDC_RX_ENDPOINT 3 | |||
| #define CDC_TX_ENDPOINT 4 | |||
| #define CDC_TX_ENDPOINT 3 | |||
| #define CDC_ACM_SIZE 16 | |||
| #define CDC_RX_SIZE 64 | |||
| #define CDC_TX_SIZE 64 | |||
| #define CDC_RX_SIZE_480 512 | |||
| #define CDC_TX_SIZE_480 512 | |||
| #define CDC_RX_SIZE_12 64 | |||
| #define CDC_TX_SIZE_12 64 | |||
| #define KEYBOARD_INTERFACE 2 // Keyboard | |||
| #define KEYBOARD_ENDPOINT 1 | |||
| #define KEYBOARD_ENDPOINT 4 | |||
| #define KEYBOARD_SIZE 8 | |||
| #define KEYBOARD_INTERVAL 1 | |||
| #define KEYMEDIA_INTERFACE 5 // Keyboard Media Keys | |||
| #define KEYMEDIA_ENDPOINT 7 | |||
| #define KEYMEDIA_ENDPOINT 5 | |||
| #define KEYMEDIA_SIZE 8 | |||
| #define KEYMEDIA_INTERVAL 4 | |||
| #define MOUSE_INTERFACE 3 // Mouse | |||
| #define MOUSE_ENDPOINT 5 | |||
| #define MOUSE_ENDPOINT 6 | |||
| #define MOUSE_SIZE 8 | |||
| #define MOUSE_INTERVAL 2 | |||
| #define JOYSTICK_INTERFACE 4 // Joystick | |||
| #define JOYSTICK_ENDPOINT 6 | |||
| #define JOYSTICK_ENDPOINT 7 | |||
| #define JOYSTICK_SIZE 12 // 12 = normal, 64 = extreme joystick | |||
| #define JOYSTICK_INTERVAL 1 | |||
| #define ENDPOINT1_CONFIG ENDPOINT_TRANSMIT_ONLY | |||
| #define ENDPOINT2_CONFIG ENDPOINT_TRANSMIT_ONLY | |||
| #define ENDPOINT3_CONFIG ENDPOINT_RECEIVE_ONLY | |||
| #define ENDPOINT4_CONFIG ENDPOINT_TRANSMIT_ONLY | |||
| #define ENDPOINT5_CONFIG ENDPOINT_TRANSMIT_ONLY | |||
| #define ENDPOINT6_CONFIG ENDPOINT_TRANSMIT_ONLY | |||
| #define ENDPOINT7_CONFIG ENDPOINT_TRANSMIT_ONLY | |||
| #define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT | |||
| #define ENDPOINT3_CONFIG ENDPOINT_RECEIVE_BULK + ENDPOINT_TRANSMIT_BULK | |||
| #define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT | |||
| #define ENDPOINT5_CONFIG ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT | |||
| #define ENDPOINT6_CONFIG ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT | |||
| #define ENDPOINT7_CONFIG ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT | |||
| #elif defined(USB_TOUCHSCREEN) | |||
| #define VENDOR_ID 0x16C0 | |||
| @@ -270,7 +263,6 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define PRODUCT_NAME_LEN 20 | |||
| #define EP0_SIZE 64 | |||
| #define NUM_ENDPOINTS 5 | |||
| #define NUM_USB_BUFFERS 15 | |||
| #define NUM_INTERFACE 4 | |||
| #define SEREMU_INTERFACE 1 // Serial emulation | |||
| #define SEREMU_TX_ENDPOINT 1 | |||
| @@ -306,7 +298,6 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define PRODUCT_NAME_LEN 26 | |||
| #define EP0_SIZE 64 | |||
| #define NUM_ENDPOINTS 6 | |||
| #define NUM_USB_BUFFERS 20 | |||
| #define NUM_INTERFACE 5 | |||
| #define SEREMU_INTERFACE 2 // Serial emulation | |||
| #define SEREMU_TX_ENDPOINT 1 | |||
| @@ -347,7 +338,6 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define PRODUCT_NAME_LEN 11 | |||
| #define EP0_SIZE 64 | |||
| #define NUM_ENDPOINTS 4 | |||
| #define NUM_USB_BUFFERS 16 | |||
| #define NUM_INTERFACE 2 | |||
| #define SEREMU_INTERFACE 1 // Serial emulation | |||
| #define SEREMU_TX_ENDPOINT 1 | |||
| @@ -377,7 +367,6 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define PRODUCT_NAME_LEN 13 | |||
| #define EP0_SIZE 64 | |||
| #define NUM_ENDPOINTS 4 | |||
| #define NUM_USB_BUFFERS 16 | |||
| #define NUM_INTERFACE 2 | |||
| #define SEREMU_INTERFACE 1 // Serial emulation | |||
| #define SEREMU_TX_ENDPOINT 1 | |||
| @@ -407,7 +396,6 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define PRODUCT_NAME_LEN 14 | |||
| #define EP0_SIZE 64 | |||
| #define NUM_ENDPOINTS 4 | |||
| #define NUM_USB_BUFFERS 16 | |||
| #define NUM_INTERFACE 2 | |||
| #define SEREMU_INTERFACE 1 // Serial emulation | |||
| #define SEREMU_TX_ENDPOINT 1 | |||
| @@ -436,7 +424,6 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define PRODUCT_NAME_LEN 11 | |||
| #define EP0_SIZE 64 | |||
| #define NUM_ENDPOINTS 5 | |||
| #define NUM_USB_BUFFERS 30 | |||
| #define NUM_INTERFACE 3 | |||
| #define CDC_IAD_DESCRIPTOR 1 | |||
| #define CDC_STATUS_INTERFACE 0 | |||
| @@ -469,7 +456,6 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define PRODUCT_NAME_LEN 13 | |||
| #define EP0_SIZE 64 | |||
| #define NUM_ENDPOINTS 5 | |||
| #define NUM_USB_BUFFERS 30 | |||
| #define NUM_INTERFACE 3 | |||
| #define CDC_IAD_DESCRIPTOR 1 | |||
| #define CDC_STATUS_INTERFACE 0 | |||
| @@ -502,7 +488,6 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define PRODUCT_NAME_LEN 14 | |||
| #define EP0_SIZE 64 | |||
| #define NUM_ENDPOINTS 5 | |||
| #define NUM_USB_BUFFERS 30 | |||
| #define NUM_INTERFACE 3 | |||
| #define CDC_IAD_DESCRIPTOR 1 | |||
| #define CDC_STATUS_INTERFACE 0 | |||
| @@ -536,7 +521,6 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define PRODUCT_NAME_LEN 18 | |||
| #define EP0_SIZE 64 | |||
| #define NUM_ENDPOINTS 4 | |||
| #define NUM_USB_BUFFERS 12 | |||
| #define NUM_INTERFACE 2 | |||
| #define RAWHID_INTERFACE 0 // RawHID | |||
| #define RAWHID_TX_ENDPOINT 3 | |||
| @@ -565,7 +549,6 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define PRODUCT_NAME_LEN 26 | |||
| #define EP0_SIZE 64 | |||
| #define NUM_ENDPOINTS 4 | |||
| #define NUM_USB_BUFFERS 20 | |||
| #define NUM_INTERFACE 2 | |||
| #define FLIGHTSIM_INTERFACE 0 // Flight Sim Control | |||
| #define FLIGHTSIM_TX_ENDPOINT 3 | |||
| @@ -596,7 +579,6 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define PRODUCT_NAME_LEN 26 | |||
| #define EP0_SIZE 64 | |||
| #define NUM_ENDPOINTS 5 | |||
| #define NUM_USB_BUFFERS 20 | |||
| #define NUM_INTERFACE 3 | |||
| #define FLIGHTSIM_INTERFACE 0 // Flight Sim Control | |||
| #define FLIGHTSIM_TX_ENDPOINT 3 | |||
| @@ -632,7 +614,6 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define PRODUCT_NAME_LEN 15 | |||
| #define EP0_SIZE 64 | |||
| #define NUM_ENDPOINTS 4 | |||
| #define NUM_USB_BUFFERS 20 | |||
| #define NUM_INTERFACE 2 | |||
| #define MTP_INTERFACE 0 // MTP Disk | |||
| #define MTP_TX_ENDPOINT 3 | |||
| @@ -663,7 +644,6 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define PRODUCT_NAME_LEN 12 | |||
| #define EP0_SIZE 64 | |||
| #define NUM_ENDPOINTS 5 | |||
| #define NUM_USB_BUFFERS 16 | |||
| #define NUM_INTERFACE 4 | |||
| #define SEREMU_INTERFACE 0 // Serial emulation | |||
| #define SEREMU_TX_ENDPOINT 1 | |||
| @@ -693,7 +673,6 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define PRODUCT_NAME_LEN 17 | |||
| #define EP0_SIZE 64 | |||
| #define NUM_ENDPOINTS 8 | |||
| #define NUM_USB_BUFFERS 30 | |||
| #define NUM_INTERFACE 6 | |||
| #define CDC_IAD_DESCRIPTOR 1 | |||
| #define CDC_STATUS_INTERFACE 0 | |||
| @@ -735,7 +714,6 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define PRODUCT_NAME_LEN 20 | |||
| #define EP0_SIZE 64 | |||
| #define NUM_ENDPOINTS 8 | |||
| #define NUM_USB_BUFFERS 30 | |||
| #define NUM_INTERFACE 6 | |||
| #define CDC_IAD_DESCRIPTOR 1 | |||
| #define CDC_STATUS_INTERFACE 0 | |||
| @@ -781,7 +759,6 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define PRODUCT_NAME_LEN 14 | |||
| #define EP0_SIZE 64 | |||
| #define NUM_ENDPOINTS 15 | |||
| #define NUM_USB_BUFFERS 31 | |||
| #define NUM_INTERFACE 13 | |||
| #define CDC_IAD_DESCRIPTOR 1 | |||
| #define CDC_STATUS_INTERFACE 0 | |||
| @@ -0,0 +1,109 @@ | |||
| /* Teensyduino Core Library | |||
| * http://www.pjrc.com/teensy/ | |||
| * Copyright (c) 2017 PJRC.COM, LLC. | |||
| * | |||
| * Permission is hereby granted, free of charge, to any person obtaining | |||
| * a copy of this software and associated documentation files (the | |||
| * "Software"), to deal in the Software without restriction, including | |||
| * without limitation the rights to use, copy, modify, merge, publish, | |||
| * distribute, sublicense, and/or sell copies of the Software, and to | |||
| * permit persons to whom the Software is furnished to do so, subject to | |||
| * the following conditions: | |||
| * | |||
| * 1. The above copyright notice and this permission notice shall be | |||
| * included in all copies or substantial portions of the Software. | |||
| * | |||
| * 2. If the Software is incorporated into a build system that allows | |||
| * selection among a list of target devices, then similar target | |||
| * devices manufactured by PJRC.COM must be included in the list of | |||
| * target devices and selectable in the same manner. | |||
| * | |||
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||
| * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |||
| * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |||
| * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |||
| * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
| * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| * SOFTWARE. | |||
| */ | |||
| #include "usb_dev.h" | |||
| #include "usb_joystick.h" | |||
| #include "core_pins.h" // for yield() | |||
| #include <string.h> // for memcpy() | |||
| #include "avr/pgmspace.h" // for PROGMEM, DMAMEM, FASTRUN | |||
| #include "debug/printf.h" | |||
| #include "core_pins.h" | |||
| #ifdef JOYSTICK_INTERFACE // defined by usb_dev.h -> usb_desc.h | |||
| uint32_t usb_joystick_data[(JOYSTICK_SIZE+3)/4]; | |||
| static uint8_t transmit_previous_timeout=0; | |||
| // When the PC isn't listening, how long do we wait before discarding data? | |||
| #define TX_TIMEOUT_MSEC 30 | |||
| #define TX_NUM 4 | |||
| #if JOYSTICK_SIZE <= 32 | |||
| #define TX_BUFSIZE 32 | |||
| #else | |||
| #define TX_BUFSIZE 64 | |||
| #endif | |||
| static transfer_t tx_transfer[TX_NUM] __attribute__ ((used, aligned(32))); | |||
| DMAMEM static uint8_t txbuffer[TX_NUM * TX_BUFSIZE] __attribute__ ((aligned(32))); | |||
| static uint8_t tx_head=0; | |||
| #if JOYSTICK_SIZE > TX_BUFSIZE | |||
| #error "Internal error, transmit buffer size is too small for joystick endpoint" | |||
| #endif | |||
| void usb_joystick_configure(void) | |||
| { | |||
| memset(tx_transfer, 0, sizeof(tx_transfer)); | |||
| tx_head = 0; | |||
| usb_config_tx(JOYSTICK_ENDPOINT, JOYSTICK_SIZE, 0, NULL); | |||
| } | |||
| int usb_joystick_send() | |||
| { | |||
| if (!usb_configuration) return -1; | |||
| uint32_t head = tx_head; | |||
| transfer_t *xfer = tx_transfer + head; | |||
| uint32_t wait_begin_at = systick_millis_count; | |||
| while (1) { | |||
| uint32_t status = usb_transfer_status(xfer); | |||
| if (!(status & 0x80)) { | |||
| if (status & 0x68) { | |||
| // TODO: what if status has errors??? | |||
| printf("ERROR status = %x, i=%d, ms=%u\n", | |||
| status, tx_head, systick_millis_count); | |||
| } | |||
| transmit_previous_timeout = 0; | |||
| break; | |||
| } | |||
| if (transmit_previous_timeout) return -1; | |||
| if (systick_millis_count - wait_begin_at > TX_TIMEOUT_MSEC) { | |||
| // waited too long, assume the USB host isn't listening | |||
| transmit_previous_timeout = 1; | |||
| return -1; | |||
| } | |||
| if (!usb_configuration) return -1; | |||
| yield(); | |||
| } | |||
| uint8_t *buffer = txbuffer + head * TX_BUFSIZE; | |||
| memcpy(buffer, usb_joystick_data, JOYSTICK_SIZE); | |||
| usb_prepare_transfer(xfer, buffer, JOYSTICK_SIZE, 0); | |||
| arm_dcache_flush_delete(buffer, TX_BUFSIZE); | |||
| usb_transmit(JOYSTICK_ENDPOINT, xfer); | |||
| if (++head >= TX_NUM) head = 0; | |||
| tx_head = head; | |||
| return 0; | |||
| } | |||
| #endif // JOYSTICK_INTERFACE | |||
| @@ -0,0 +1,194 @@ | |||
| /* Teensyduino Core Library | |||
| * http://www.pjrc.com/teensy/ | |||
| * Copyright (c) 2017 PJRC.COM, LLC. | |||
| * | |||
| * Permission is hereby granted, free of charge, to any person obtaining | |||
| * a copy of this software and associated documentation files (the | |||
| * "Software"), to deal in the Software without restriction, including | |||
| * without limitation the rights to use, copy, modify, merge, publish, | |||
| * distribute, sublicense, and/or sell copies of the Software, and to | |||
| * permit persons to whom the Software is furnished to do so, subject to | |||
| * the following conditions: | |||
| * | |||
| * 1. The above copyright notice and this permission notice shall be | |||
| * included in all copies or substantial portions of the Software. | |||
| * | |||
| * 2. If the Software is incorporated into a build system that allows | |||
| * selection among a list of target devices, then similar target | |||
| * devices manufactured by PJRC.COM must be included in the list of | |||
| * target devices and selectable in the same manner. | |||
| * | |||
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||
| * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |||
| * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |||
| * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |||
| * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
| * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| * SOFTWARE. | |||
| */ | |||
| #ifndef USBjoystick_h_ | |||
| #define USBjoystick_h_ | |||
| #include "usb_desc.h" | |||
| #if defined(JOYSTICK_INTERFACE) | |||
| #include <inttypes.h> | |||
| // C language implementation | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| void usb_joystick_configure(void); | |||
| int usb_joystick_send(void); | |||
| extern uint32_t usb_joystick_data[(JOYSTICK_SIZE+3)/4]; | |||
| extern volatile uint8_t usb_configuration; | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| // C++ interface | |||
| #ifdef __cplusplus | |||
| class usb_joystick_class | |||
| { | |||
| public: | |||
| void begin(void) { } | |||
| void end(void) { } | |||
| #if JOYSTICK_SIZE == 12 | |||
| void button(uint8_t button, bool val) { | |||
| if (--button >= 32) return; | |||
| if (val) usb_joystick_data[0] |= (1 << button); | |||
| else usb_joystick_data[0] &= ~(1 << button); | |||
| if (!manual_mode) usb_joystick_send(); | |||
| } | |||
| void X(unsigned int val) { | |||
| if (val > 1023) val = 1023; | |||
| usb_joystick_data[1] = (usb_joystick_data[1] & 0xFFFFC00F) | (val << 4); | |||
| if (!manual_mode) usb_joystick_send(); | |||
| } | |||
| void Y(unsigned int val) { | |||
| if (val > 1023) val = 1023; | |||
| usb_joystick_data[1] = (usb_joystick_data[1] & 0xFF003FFF) | (val << 14); | |||
| if (!manual_mode) usb_joystick_send(); | |||
| } | |||
| void position(unsigned int x, unsigned int y) { | |||
| if (x > 1023) x = 1023; | |||
| if (y > 1023) y = 1023; | |||
| usb_joystick_data[1] = (usb_joystick_data[1] & 0xFFF00000) | |||
| | (x << 4) | (y << 14); | |||
| if (!manual_mode) usb_joystick_send(); | |||
| } | |||
| void Z(unsigned int val) { | |||
| if (val > 1023) val = 1023; | |||
| usb_joystick_data[1] = (usb_joystick_data[1] & 0x00FFFFFF) | (val << 24); | |||
| usb_joystick_data[2] = (usb_joystick_data[2] & 0xFFFFFFFC) | (val >> 8); | |||
| if (!manual_mode) usb_joystick_send(); | |||
| } | |||
| void Zrotate(unsigned int val) { | |||
| if (val > 1023) val = 1023; | |||
| usb_joystick_data[2] = (usb_joystick_data[2] & 0xFFFFF003) | (val << 2); | |||
| if (!manual_mode) usb_joystick_send(); | |||
| } | |||
| void sliderLeft(unsigned int val) { | |||
| if (val > 1023) val = 1023; | |||
| usb_joystick_data[2] = (usb_joystick_data[2] & 0xFFC00FFF) | (val << 12); | |||
| if (!manual_mode) usb_joystick_send(); | |||
| } | |||
| void sliderRight(unsigned int val) { | |||
| if (val > 1023) val = 1023; | |||
| usb_joystick_data[2] = (usb_joystick_data[2] & 0x003FFFFF) | (val << 22); | |||
| if (!manual_mode) usb_joystick_send(); | |||
| } | |||
| void slider(unsigned int val) { | |||
| if (val > 1023) val = 1023; | |||
| usb_joystick_data[2] = (usb_joystick_data[2] & 0x00000FFF) | |||
| | (val << 12) | (val << 22); | |||
| if (!manual_mode) usb_joystick_send(); | |||
| } | |||
| inline void hat(int dir) { | |||
| uint32_t val = 0; | |||
| if (dir < 0) val = 15; | |||
| else if (dir < 23) val = 0; | |||
| else if (dir < 68) val = 1; | |||
| else if (dir < 113) val = 2; | |||
| else if (dir < 158) val = 3; | |||
| else if (dir < 203) val = 4; | |||
| else if (dir < 245) val = 5; | |||
| else if (dir < 293) val = 6; | |||
| else if (dir < 338) val = 7; | |||
| usb_joystick_data[1] = (usb_joystick_data[1] & 0xFFFFFFF0) | val; | |||
| if (!manual_mode) usb_joystick_send(); | |||
| } | |||
| #elif JOYSTICK_SIZE == 64 | |||
| void button(unsigned int num, bool val) { | |||
| if (--num >= 128) return; | |||
| uint32_t *p = usb_joystick_data + (num >> 5); | |||
| num &= 0x1F; | |||
| if (val) *p |= (1 << num); | |||
| else *p &= ~(1 << num); | |||
| if (!manual_mode) usb_joystick_send(); | |||
| } | |||
| void X(unsigned int position) { analog16(0, position); } | |||
| void Y(unsigned int position) { analog16(1, position); } | |||
| void Z(unsigned int position) { analog16(2, position); } | |||
| void Xrotate(unsigned int position) { analog16(3, position); } | |||
| void Yrotate(unsigned int position) { analog16(4, position); } | |||
| void Zrotate(unsigned int position) { analog16(5, position); } | |||
| void slider(unsigned int num, unsigned int position) { | |||
| if (--num >= 17) return; | |||
| analog16(num + 6, position); | |||
| } | |||
| inline void hat(unsigned int num, int angle) { | |||
| uint32_t val=15; | |||
| if (angle > 0 && angle < 23) val = 0; | |||
| else if (angle < 68) val = 1; | |||
| else if (angle < 113) val = 2; | |||
| else if (angle < 158) val = 3; | |||
| else if (angle < 203) val = 4; | |||
| else if (angle < 245) val = 5; | |||
| else if (angle < 293) val = 6; | |||
| else if (angle < 338) val = 7; | |||
| else if (angle < 360) val = 0; | |||
| uint32_t *p = usb_joystick_data; | |||
| switch(num) { | |||
| case 1: | |||
| p[15] = (p[15] & 0xFFF0FFFF) | (val << 16); break; | |||
| case 2: | |||
| p[15] = (p[15] & 0xFF0FFFFF) | (val << 20); break; | |||
| case 3: | |||
| p[15] = (p[15] & 0xF0FFFFFF) | (val << 24); break; | |||
| case 4: | |||
| p[15] = (p[15] & 0x0FFFFFFF) | (val << 28); break; | |||
| default: | |||
| return; | |||
| } | |||
| if (!manual_mode) usb_joystick_send(); | |||
| } | |||
| #endif | |||
| void useManualSend(bool mode) { | |||
| manual_mode = mode; | |||
| } | |||
| void send_now(void) { | |||
| usb_joystick_send(); | |||
| } | |||
| private: | |||
| static uint8_t manual_mode; | |||
| #if JOYSTICK_SIZE == 64 | |||
| void analog16(unsigned int num, unsigned int value) { | |||
| if (value > 0xFFFF) value = 0xFFFF; | |||
| uint16_t *p = (uint16_t *)(&usb_joystick_data[4]); | |||
| p[num] = value; | |||
| if (!manual_mode) usb_joystick_send(); | |||
| } | |||
| #endif | |||
| }; | |||
| extern usb_joystick_class Joystick; | |||
| #endif // __cplusplus | |||
| #endif // JOYSTICK_INTERFACE | |||
| #endif // USBjoystick_h_ | |||
| @@ -518,7 +518,7 @@ static uint8_t transmit_previous_timeout=0; | |||
| // When the PC isn't listening, how long do we wait before discarding data? | |||
| #define TX_TIMEOUT_MSEC 50 | |||
| int usb_keyboard_transmit(int endpoint, const uint8_t *data, uint32_t len) | |||
| static int usb_keyboard_transmit(int endpoint, const uint8_t *data, uint32_t len) | |||
| { | |||
| if (!usb_configuration) return -1; | |||
| uint32_t head = tx_head; | |||
| @@ -0,0 +1,236 @@ | |||
| /* Teensyduino Core Library | |||
| * http://www.pjrc.com/teensy/ | |||
| * Copyright (c) 2019 PJRC.COM, LLC. | |||
| * | |||
| * Permission is hereby granted, free of charge, to any person obtaining | |||
| * a copy of this software and associated documentation files (the | |||
| * "Software"), to deal in the Software without restriction, including | |||
| * without limitation the rights to use, copy, modify, merge, publish, | |||
| * distribute, sublicense, and/or sell copies of the Software, and to | |||
| * permit persons to whom the Software is furnished to do so, subject to | |||
| * the following conditions: | |||
| * | |||
| * 1. The above copyright notice and this permission notice shall be | |||
| * included in all copies or substantial portions of the Software. | |||
| * | |||
| * 2. If the Software is incorporated into a build system that allows | |||
| * selection among a list of target devices, then similar target | |||
| * devices manufactured by PJRC.COM must be included in the list of | |||
| * target devices and selectable in the same manner. | |||
| * | |||
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||
| * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |||
| * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |||
| * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |||
| * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
| * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| * SOFTWARE. | |||
| */ | |||
| #include "usb_dev.h" | |||
| #include "usb_mouse.h" | |||
| #include "core_pins.h" // for yield() | |||
| #include <string.h> // for memcpy() | |||
| #include "avr/pgmspace.h" // for PROGMEM, DMAMEM, FASTRUN | |||
| #include "debug/printf.h" | |||
| #include "core_pins.h" | |||
| #ifdef MOUSE_INTERFACE // defined by usb_dev.h -> usb_desc.h | |||
| // which buttons are currently pressed | |||
| uint8_t usb_mouse_buttons_state=0; | |||
| //#define DEFAULT_XRES 640 | |||
| //#define DEFAULT_YRES 480 | |||
| //#define DEFAULT_XRES 800 | |||
| //#define DEFAULT_YRES 600 | |||
| //#define DEFAULT_XRES 1024 | |||
| //#define DEFAULT_YRES 768 | |||
| //#define DEFAULT_XRES 1280 | |||
| //#define DEFAULT_YRES 720 | |||
| //#define DEFAULT_XRES 1280 | |||
| //#define DEFAULT_YRES 800 | |||
| #define DEFAULT_XRES 1366 | |||
| #define DEFAULT_YRES 768 | |||
| //#define DEFAULT_XRES 1440 | |||
| //#define DEFAULT_YRES 900 | |||
| //#define DEFAULT_XRES 1920 | |||
| //#define DEFAULT_YRES 1080 | |||
| //#define DEFAULT_XRES 2560 | |||
| //#define DEFAULT_YRES 1440 | |||
| //#define DEFAULT_XRES 2560 | |||
| //#define DEFAULT_YRES 1600 | |||
| //#define DEFAULT_XRES 2880 | |||
| //#define DEFAULT_YRES 1800 | |||
| //#define DEFAULT_XRES 3840 | |||
| //#define DEFAULT_YRES 2160 | |||
| //#define DEFAULT_XRES 7680 | |||
| //#define DEFAULT_YRES 4320 | |||
| #define DEFAULT_XSCALE ((0x80000000ul+DEFAULT_XRES/2)/DEFAULT_XRES) | |||
| #define DEFAULT_YSCALE ((0x80000000ul+DEFAULT_YRES/2)/DEFAULT_YRES) | |||
| static uint16_t usb_mouse_resolution_x=DEFAULT_XRES; | |||
| static uint16_t usb_mouse_resolution_y=DEFAULT_YRES; | |||
| static uint16_t usb_mouse_position_x=DEFAULT_XRES/2; | |||
| static uint16_t usb_mouse_position_y=DEFAULT_YRES/2; | |||
| static uint32_t usb_mouse_scale_x=DEFAULT_XSCALE; | |||
| static uint32_t usb_mouse_scale_y=DEFAULT_YSCALE; | |||
| static uint32_t usb_mouse_offset_x=DEFAULT_XSCALE/2-1; | |||
| static uint32_t usb_mouse_offset_y=DEFAULT_YSCALE/2-1; | |||
| #define TX_NUM 4 | |||
| #define TX_BUFSIZE 32 | |||
| static transfer_t tx_transfer[TX_NUM] __attribute__ ((used, aligned(32))); | |||
| DMAMEM static uint8_t txbuffer[TX_NUM * TX_BUFSIZE] __attribute__ ((aligned(32))); | |||
| static uint8_t tx_head=0; | |||
| #if MOUSE_SIZE > TX_BUFSIZE | |||
| #error "Internal error, transmit buffer size is too small for mouse endpoint" | |||
| #endif | |||
| void usb_mouse_configure(void) | |||
| { | |||
| memset(tx_transfer, 0, sizeof(tx_transfer)); | |||
| tx_head = 0; | |||
| usb_config_tx(MOUSE_ENDPOINT, MOUSE_SIZE, 0, NULL); | |||
| } | |||
| // Set the mouse buttons. To create a "click", 2 calls are needed, | |||
| // one to push the button down and the second to release it | |||
| int usb_mouse_buttons(uint8_t left, uint8_t middle, uint8_t right, uint8_t back, uint8_t forward) | |||
| { | |||
| uint8_t mask=0; | |||
| if (left) mask |= 1; | |||
| if (middle) mask |= 4; | |||
| if (right) mask |= 2; | |||
| if (back) mask |= 8; | |||
| if (forward) mask |= 16; | |||
| usb_mouse_buttons_state = mask; | |||
| return usb_mouse_move(0, 0, 0, 0); | |||
| } | |||
| static uint8_t transmit_previous_timeout=0; | |||
| // When the PC isn't listening, how long do we wait before discarding data? | |||
| #define TX_TIMEOUT_MSEC 30 | |||
| static int usb_mouse_transmit(const uint8_t *data, uint32_t len) | |||
| { | |||
| if (!usb_configuration) return -1; | |||
| uint32_t head = tx_head; | |||
| transfer_t *xfer = tx_transfer + head; | |||
| uint32_t wait_begin_at = systick_millis_count; | |||
| while (1) { | |||
| uint32_t status = usb_transfer_status(xfer); | |||
| if (!(status & 0x80)) { | |||
| if (status & 0x68) { | |||
| // TODO: what if status has errors??? | |||
| printf("ERROR status = %x, i=%d, ms=%u\n", | |||
| status, tx_head, systick_millis_count); | |||
| } | |||
| transmit_previous_timeout = 0; | |||
| break; | |||
| } | |||
| if (transmit_previous_timeout) return -1; | |||
| if (systick_millis_count - wait_begin_at > TX_TIMEOUT_MSEC) { | |||
| // waited too long, assume the USB host isn't listening | |||
| transmit_previous_timeout = 1; | |||
| return -1; | |||
| } | |||
| if (!usb_configuration) return -1; | |||
| yield(); | |||
| } | |||
| uint8_t *buffer = txbuffer + head * TX_BUFSIZE; | |||
| memcpy(buffer, data, len); | |||
| usb_prepare_transfer(xfer, buffer, len, 0); | |||
| arm_dcache_flush_delete(buffer, TX_BUFSIZE); | |||
| usb_transmit(MOUSE_ENDPOINT, xfer); | |||
| if (++head >= TX_NUM) head = 0; | |||
| tx_head = head; | |||
| return 0; | |||
| } | |||
| // Move the mouse. x, y and wheel are -127 to 127. Use 0 for no movement. | |||
| int usb_mouse_move(int8_t x, int8_t y, int8_t wheel, int8_t horiz) | |||
| { | |||
| //printf("move\n"); | |||
| if (x == -128) x = -127; | |||
| if (y == -128) y = -127; | |||
| if (wheel == -128) wheel = -127; | |||
| if (horiz == -128) horiz = -127; | |||
| uint8_t buffer[6]; | |||
| buffer[0] = 1; | |||
| buffer[1] = usb_mouse_buttons_state; | |||
| buffer[2] = x; | |||
| buffer[3] = y; | |||
| buffer[4] = wheel; | |||
| buffer[5] = horiz; // horizontal scroll | |||
| return usb_mouse_transmit(buffer, 6); | |||
| } | |||
| int usb_mouse_position(uint16_t x, uint16_t y) | |||
| { | |||
| if (x >= usb_mouse_resolution_x) x = usb_mouse_resolution_x - 1; | |||
| usb_mouse_position_x = x; | |||
| if (y >= usb_mouse_resolution_y) y = usb_mouse_resolution_y - 1; | |||
| usb_mouse_position_y = y; | |||
| uint8_t buffer[5]; | |||
| buffer[0] = 2; | |||
| uint32_t val32 = usb_mouse_position_x * usb_mouse_scale_x + usb_mouse_offset_x; | |||
| //printf("position: %u -> %u", usb_mouse_position_x, val32); | |||
| buffer[1] = val32 >> 16; | |||
| buffer[2] = val32 >> 24; | |||
| val32 = usb_mouse_position_y * usb_mouse_scale_y + usb_mouse_offset_y; | |||
| //printf(", %u -> %u\n", usb_mouse_position_y, val32); | |||
| buffer[3] = val32 >> 16; | |||
| buffer[4] = val32 >> 24; | |||
| return usb_mouse_transmit(buffer, 5); | |||
| } | |||
| void usb_mouse_screen_size(uint16_t width, uint16_t height, uint8_t mac) | |||
| { | |||
| if (width < 128) width = 128; | |||
| else if (width > 7680) width = 7680; | |||
| if (height < 128) height = 128; | |||
| else if (height > 7680) height = 7680; | |||
| usb_mouse_resolution_x = width; | |||
| usb_mouse_resolution_y = height; | |||
| usb_mouse_position_x = width / 2; | |||
| usb_mouse_position_y = height / 2; | |||
| usb_mouse_scale_x = (0x80000000ul + (width >> 1)) / width; | |||
| usb_mouse_scale_y = (0x80000000ul + (height >> 1)) / height; | |||
| usb_mouse_offset_x = (usb_mouse_scale_x >> 1) - 1; | |||
| usb_mouse_offset_y = (usb_mouse_scale_y >> 1) - 1; | |||
| if (mac) { | |||
| // ugly workaround for Mac's HID coordinate scaling: | |||
| // http://lists.apple.com/archives/usb/2011/Jun/msg00032.html | |||
| usb_mouse_offset_x += 161061273ul; | |||
| usb_mouse_offset_y += 161061273ul; | |||
| usb_mouse_scale_x = (1825361101ul + (width >> 1)) / width; | |||
| usb_mouse_scale_y = (1825361101ul + (height >> 1)) / height; | |||
| } | |||
| } | |||
| #endif // MOUSE_INTERFACE | |||
| @@ -0,0 +1,111 @@ | |||
| /* Teensyduino Core Library | |||
| * http://www.pjrc.com/teensy/ | |||
| * Copyright (c) 2017 PJRC.COM, LLC. | |||
| * | |||
| * Permission is hereby granted, free of charge, to any person obtaining | |||
| * a copy of this software and associated documentation files (the | |||
| * "Software"), to deal in the Software without restriction, including | |||
| * without limitation the rights to use, copy, modify, merge, publish, | |||
| * distribute, sublicense, and/or sell copies of the Software, and to | |||
| * permit persons to whom the Software is furnished to do so, subject to | |||
| * the following conditions: | |||
| * | |||
| * 1. The above copyright notice and this permission notice shall be | |||
| * included in all copies or substantial portions of the Software. | |||
| * | |||
| * 2. If the Software is incorporated into a build system that allows | |||
| * selection among a list of target devices, then similar target | |||
| * devices manufactured by PJRC.COM must be included in the list of | |||
| * target devices and selectable in the same manner. | |||
| * | |||
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||
| * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |||
| * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |||
| * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |||
| * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
| * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| * SOFTWARE. | |||
| */ | |||
| #ifndef USBmouse_h_ | |||
| #define USBmouse_h_ | |||
| #include "usb_desc.h" | |||
| #if defined(MOUSE_INTERFACE) | |||
| #include <inttypes.h> | |||
| // C language implementation | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| void usb_mouse_configure(void); | |||
| int usb_mouse_buttons(uint8_t left, uint8_t middle, uint8_t right, uint8_t back, uint8_t forward); | |||
| int usb_mouse_move(int8_t x, int8_t y, int8_t wheel, int8_t horiz); | |||
| int usb_mouse_position(uint16_t x, uint16_t y); | |||
| void usb_mouse_screen_size(uint16_t width, uint16_t height, uint8_t mac); | |||
| extern uint8_t usb_mouse_buttons_state; | |||
| extern volatile uint8_t usb_configuration; | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #define MOUSE_LEFT 1 | |||
| #define MOUSE_MIDDLE 4 | |||
| #define MOUSE_RIGHT 2 | |||
| #define MOUSE_BACK 8 | |||
| #define MOUSE_FORWARD 16 | |||
| #define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE | MOUSE_BACK | MOUSE_FORWARD) | |||
| // C++ interface | |||
| #ifdef __cplusplus | |||
| class usb_mouse_class | |||
| { | |||
| public: | |||
| void begin(void) { } | |||
| void end(void) { } | |||
| void move(int8_t x, int8_t y, int8_t wheel=0, int8_t horiz=0) { | |||
| usb_mouse_move(x, y, wheel, horiz); | |||
| } | |||
| void moveTo(uint16_t x, uint16_t y) { usb_mouse_position(x, y); } | |||
| void screenSize(uint16_t width, uint16_t height, bool isMacintosh = false) { | |||
| usb_mouse_screen_size(width, height, isMacintosh ? 1 : 0); | |||
| } | |||
| void click(uint8_t b = MOUSE_LEFT) { | |||
| usb_mouse_buttons_state = b; | |||
| usb_mouse_move(0, 0, 0, 0); | |||
| usb_mouse_buttons_state = 0; | |||
| usb_mouse_move(0, 0, 0, 0); | |||
| } | |||
| void scroll(int8_t wheel, int8_t horiz=0) { usb_mouse_move(0, 0, wheel, horiz); } | |||
| void set_buttons(uint8_t left, uint8_t middle=0, uint8_t right=0, uint8_t back=0, uint8_t forward=0) { | |||
| usb_mouse_buttons(left, middle, right, back, forward); | |||
| } | |||
| void press(uint8_t b = MOUSE_LEFT) { | |||
| uint8_t buttons = usb_mouse_buttons_state | (b & MOUSE_ALL); | |||
| if (buttons != usb_mouse_buttons_state) { | |||
| usb_mouse_buttons_state = buttons; | |||
| usb_mouse_move(0, 0, 0, 0); | |||
| } | |||
| } | |||
| void release(uint8_t b = MOUSE_LEFT) { | |||
| uint8_t buttons = usb_mouse_buttons_state & ~(b & MOUSE_ALL); | |||
| if (buttons != usb_mouse_buttons_state) { | |||
| usb_mouse_buttons_state = buttons; | |||
| usb_mouse_move(0, 0, 0, 0); | |||
| } | |||
| } | |||
| bool isPressed(uint8_t b = MOUSE_ALL) { | |||
| return ((usb_mouse_buttons_state & (b & MOUSE_ALL)) != 0); | |||
| } | |||
| }; | |||
| extern usb_mouse_class Mouse; | |||
| #endif // __cplusplus | |||
| #endif // MOUSE_INTERFACE | |||
| #endif // USBmouse_h_ | |||