#include "usb_serial.h" | #include "usb_serial.h" | ||||
#include "usb_seremu.h" | #include "usb_seremu.h" | ||||
#include "usb_keyboard.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_midi.h" | ||||
#include "usb_rawhid.h" | #include "usb_rawhid.h" | ||||
//#include "usb_flightsim.h" | //#include "usb_flightsim.h" |
#include "usb_serial.h" | #include "usb_serial.h" | ||||
#include "usb_seremu.h" | #include "usb_seremu.h" | ||||
#include "usb_keyboard.h" | #include "usb_keyboard.h" | ||||
#include "usb_mouse.h" | |||||
#include "usb_joystick.h" | |||||
#include "core_pins.h" // for delay() | #include "core_pins.h" // for delay() | ||||
#include "avr/pgmspace.h" | #include "avr/pgmspace.h" | ||||
#include <string.h> | #include <string.h> | ||||
#if defined(KEYBOARD_INTERFACE) | #if defined(KEYBOARD_INTERFACE) | ||||
usb_keyboard_configure(); | usb_keyboard_configure(); | ||||
#endif | #endif | ||||
#if defined(MOUSE_INTERFACE) | |||||
usb_mouse_configure(); | |||||
#endif | |||||
#if defined(JOYSTICK_INTERFACE) | |||||
usb_joystick_configure(); | |||||
#endif | |||||
endpoint0_receive(NULL, 0, 0); | endpoint0_receive(NULL, 0, 0); | ||||
return; | return; | ||||
case 0x0880: // GET_CONFIGURATION | case 0x0880: // GET_CONFIGURATION |
Edit NUM_ENDPOINTS to be at least the largest endpoint number used. | 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 | Edit the ENDPOINT*_CONFIG lines so each endpoint is configured | ||||
the proper way (transmit, receive, or both). | the proper way (transmit, receive, or both). | ||||
#define NUM_USB_BUFFERS 24 | #define NUM_USB_BUFFERS 24 | ||||
#define NUM_INTERFACE 5 | #define NUM_INTERFACE 5 | ||||
#define SEREMU_INTERFACE 2 // Serial emulation | #define SEREMU_INTERFACE 2 // Serial emulation | ||||
#define SEREMU_TX_ENDPOINT 1 | |||||
#define SEREMU_TX_ENDPOINT 2 | |||||
#define SEREMU_TX_SIZE 64 | #define SEREMU_TX_SIZE 64 | ||||
#define SEREMU_TX_INTERVAL 1 | #define SEREMU_TX_INTERVAL 1 | ||||
#define SEREMU_RX_ENDPOINT 2 | #define SEREMU_RX_ENDPOINT 2 | ||||
#define KEYBOARD_SIZE 8 | #define KEYBOARD_SIZE 8 | ||||
#define KEYBOARD_INTERVAL 1 | #define KEYBOARD_INTERVAL 1 | ||||
#define KEYMEDIA_INTERFACE 4 // Keyboard Media Keys | #define KEYMEDIA_INTERFACE 4 // Keyboard Media Keys | ||||
#define KEYMEDIA_ENDPOINT 6 | |||||
#define KEYMEDIA_ENDPOINT 4 | |||||
#define KEYMEDIA_SIZE 8 | #define KEYMEDIA_SIZE 8 | ||||
#define KEYMEDIA_INTERVAL 4 | #define KEYMEDIA_INTERVAL 4 | ||||
#define MOUSE_INTERFACE 1 // Mouse | #define MOUSE_INTERFACE 1 // Mouse | ||||
#define MOUSE_SIZE 8 | #define MOUSE_SIZE 8 | ||||
#define MOUSE_INTERVAL 1 | #define MOUSE_INTERVAL 1 | ||||
#define JOYSTICK_INTERFACE 3 // Joystick | #define JOYSTICK_INTERFACE 3 // Joystick | ||||
#define JOYSTICK_ENDPOINT 4 | |||||
#define JOYSTICK_ENDPOINT 6 | |||||
#define JOYSTICK_SIZE 12 // 12 = normal, 64 = extreme joystick | #define JOYSTICK_SIZE 12 // 12 = normal, 64 = extreme joystick | ||||
#define JOYSTICK_INTERVAL 2 | #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) | #elif defined(USB_SERIAL_HID) | ||||
#define VENDOR_ID 0x16C0 | #define VENDOR_ID 0x16C0 | ||||
#define PRODUCT_NAME_LEN 30 | #define PRODUCT_NAME_LEN 30 | ||||
#define EP0_SIZE 64 | #define EP0_SIZE 64 | ||||
#define NUM_ENDPOINTS 7 | #define NUM_ENDPOINTS 7 | ||||
#define NUM_USB_BUFFERS 30 | |||||
#define NUM_INTERFACE 6 | #define NUM_INTERFACE 6 | ||||
#define CDC_IAD_DESCRIPTOR 1 | #define CDC_IAD_DESCRIPTOR 1 | ||||
#define CDC_STATUS_INTERFACE 0 | #define CDC_STATUS_INTERFACE 0 | ||||
#define CDC_DATA_INTERFACE 1 // Serial | #define CDC_DATA_INTERFACE 1 // Serial | ||||
#define CDC_ACM_ENDPOINT 2 | #define CDC_ACM_ENDPOINT 2 | ||||
#define CDC_RX_ENDPOINT 3 | #define CDC_RX_ENDPOINT 3 | ||||
#define CDC_TX_ENDPOINT 4 | |||||
#define CDC_TX_ENDPOINT 3 | |||||
#define CDC_ACM_SIZE 16 | #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_INTERFACE 2 // Keyboard | ||||
#define KEYBOARD_ENDPOINT 1 | |||||
#define KEYBOARD_ENDPOINT 4 | |||||
#define KEYBOARD_SIZE 8 | #define KEYBOARD_SIZE 8 | ||||
#define KEYBOARD_INTERVAL 1 | #define KEYBOARD_INTERVAL 1 | ||||
#define KEYMEDIA_INTERFACE 5 // Keyboard Media Keys | #define KEYMEDIA_INTERFACE 5 // Keyboard Media Keys | ||||
#define KEYMEDIA_ENDPOINT 7 | |||||
#define KEYMEDIA_ENDPOINT 5 | |||||
#define KEYMEDIA_SIZE 8 | #define KEYMEDIA_SIZE 8 | ||||
#define KEYMEDIA_INTERVAL 4 | #define KEYMEDIA_INTERVAL 4 | ||||
#define MOUSE_INTERFACE 3 // Mouse | #define MOUSE_INTERFACE 3 // Mouse | ||||
#define MOUSE_ENDPOINT 5 | |||||
#define MOUSE_ENDPOINT 6 | |||||
#define MOUSE_SIZE 8 | #define MOUSE_SIZE 8 | ||||
#define MOUSE_INTERVAL 2 | #define MOUSE_INTERVAL 2 | ||||
#define JOYSTICK_INTERFACE 4 // Joystick | #define JOYSTICK_INTERFACE 4 // Joystick | ||||
#define JOYSTICK_ENDPOINT 6 | |||||
#define JOYSTICK_ENDPOINT 7 | |||||
#define JOYSTICK_SIZE 12 // 12 = normal, 64 = extreme joystick | #define JOYSTICK_SIZE 12 // 12 = normal, 64 = extreme joystick | ||||
#define JOYSTICK_INTERVAL 1 | #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) | #elif defined(USB_TOUCHSCREEN) | ||||
#define VENDOR_ID 0x16C0 | #define VENDOR_ID 0x16C0 | ||||
#define PRODUCT_NAME_LEN 20 | #define PRODUCT_NAME_LEN 20 | ||||
#define EP0_SIZE 64 | #define EP0_SIZE 64 | ||||
#define NUM_ENDPOINTS 5 | #define NUM_ENDPOINTS 5 | ||||
#define NUM_USB_BUFFERS 15 | |||||
#define NUM_INTERFACE 4 | #define NUM_INTERFACE 4 | ||||
#define SEREMU_INTERFACE 1 // Serial emulation | #define SEREMU_INTERFACE 1 // Serial emulation | ||||
#define SEREMU_TX_ENDPOINT 1 | #define SEREMU_TX_ENDPOINT 1 | ||||
#define PRODUCT_NAME_LEN 26 | #define PRODUCT_NAME_LEN 26 | ||||
#define EP0_SIZE 64 | #define EP0_SIZE 64 | ||||
#define NUM_ENDPOINTS 6 | #define NUM_ENDPOINTS 6 | ||||
#define NUM_USB_BUFFERS 20 | |||||
#define NUM_INTERFACE 5 | #define NUM_INTERFACE 5 | ||||
#define SEREMU_INTERFACE 2 // Serial emulation | #define SEREMU_INTERFACE 2 // Serial emulation | ||||
#define SEREMU_TX_ENDPOINT 1 | #define SEREMU_TX_ENDPOINT 1 | ||||
#define PRODUCT_NAME_LEN 11 | #define PRODUCT_NAME_LEN 11 | ||||
#define EP0_SIZE 64 | #define EP0_SIZE 64 | ||||
#define NUM_ENDPOINTS 4 | #define NUM_ENDPOINTS 4 | ||||
#define NUM_USB_BUFFERS 16 | |||||
#define NUM_INTERFACE 2 | #define NUM_INTERFACE 2 | ||||
#define SEREMU_INTERFACE 1 // Serial emulation | #define SEREMU_INTERFACE 1 // Serial emulation | ||||
#define SEREMU_TX_ENDPOINT 1 | #define SEREMU_TX_ENDPOINT 1 | ||||
#define PRODUCT_NAME_LEN 13 | #define PRODUCT_NAME_LEN 13 | ||||
#define EP0_SIZE 64 | #define EP0_SIZE 64 | ||||
#define NUM_ENDPOINTS 4 | #define NUM_ENDPOINTS 4 | ||||
#define NUM_USB_BUFFERS 16 | |||||
#define NUM_INTERFACE 2 | #define NUM_INTERFACE 2 | ||||
#define SEREMU_INTERFACE 1 // Serial emulation | #define SEREMU_INTERFACE 1 // Serial emulation | ||||
#define SEREMU_TX_ENDPOINT 1 | #define SEREMU_TX_ENDPOINT 1 | ||||
#define PRODUCT_NAME_LEN 14 | #define PRODUCT_NAME_LEN 14 | ||||
#define EP0_SIZE 64 | #define EP0_SIZE 64 | ||||
#define NUM_ENDPOINTS 4 | #define NUM_ENDPOINTS 4 | ||||
#define NUM_USB_BUFFERS 16 | |||||
#define NUM_INTERFACE 2 | #define NUM_INTERFACE 2 | ||||
#define SEREMU_INTERFACE 1 // Serial emulation | #define SEREMU_INTERFACE 1 // Serial emulation | ||||
#define SEREMU_TX_ENDPOINT 1 | #define SEREMU_TX_ENDPOINT 1 | ||||
#define PRODUCT_NAME_LEN 11 | #define PRODUCT_NAME_LEN 11 | ||||
#define EP0_SIZE 64 | #define EP0_SIZE 64 | ||||
#define NUM_ENDPOINTS 5 | #define NUM_ENDPOINTS 5 | ||||
#define NUM_USB_BUFFERS 30 | |||||
#define NUM_INTERFACE 3 | #define NUM_INTERFACE 3 | ||||
#define CDC_IAD_DESCRIPTOR 1 | #define CDC_IAD_DESCRIPTOR 1 | ||||
#define CDC_STATUS_INTERFACE 0 | #define CDC_STATUS_INTERFACE 0 | ||||
#define PRODUCT_NAME_LEN 13 | #define PRODUCT_NAME_LEN 13 | ||||
#define EP0_SIZE 64 | #define EP0_SIZE 64 | ||||
#define NUM_ENDPOINTS 5 | #define NUM_ENDPOINTS 5 | ||||
#define NUM_USB_BUFFERS 30 | |||||
#define NUM_INTERFACE 3 | #define NUM_INTERFACE 3 | ||||
#define CDC_IAD_DESCRIPTOR 1 | #define CDC_IAD_DESCRIPTOR 1 | ||||
#define CDC_STATUS_INTERFACE 0 | #define CDC_STATUS_INTERFACE 0 | ||||
#define PRODUCT_NAME_LEN 14 | #define PRODUCT_NAME_LEN 14 | ||||
#define EP0_SIZE 64 | #define EP0_SIZE 64 | ||||
#define NUM_ENDPOINTS 5 | #define NUM_ENDPOINTS 5 | ||||
#define NUM_USB_BUFFERS 30 | |||||
#define NUM_INTERFACE 3 | #define NUM_INTERFACE 3 | ||||
#define CDC_IAD_DESCRIPTOR 1 | #define CDC_IAD_DESCRIPTOR 1 | ||||
#define CDC_STATUS_INTERFACE 0 | #define CDC_STATUS_INTERFACE 0 | ||||
#define PRODUCT_NAME_LEN 18 | #define PRODUCT_NAME_LEN 18 | ||||
#define EP0_SIZE 64 | #define EP0_SIZE 64 | ||||
#define NUM_ENDPOINTS 4 | #define NUM_ENDPOINTS 4 | ||||
#define NUM_USB_BUFFERS 12 | |||||
#define NUM_INTERFACE 2 | #define NUM_INTERFACE 2 | ||||
#define RAWHID_INTERFACE 0 // RawHID | #define RAWHID_INTERFACE 0 // RawHID | ||||
#define RAWHID_TX_ENDPOINT 3 | #define RAWHID_TX_ENDPOINT 3 | ||||
#define PRODUCT_NAME_LEN 26 | #define PRODUCT_NAME_LEN 26 | ||||
#define EP0_SIZE 64 | #define EP0_SIZE 64 | ||||
#define NUM_ENDPOINTS 4 | #define NUM_ENDPOINTS 4 | ||||
#define NUM_USB_BUFFERS 20 | |||||
#define NUM_INTERFACE 2 | #define NUM_INTERFACE 2 | ||||
#define FLIGHTSIM_INTERFACE 0 // Flight Sim Control | #define FLIGHTSIM_INTERFACE 0 // Flight Sim Control | ||||
#define FLIGHTSIM_TX_ENDPOINT 3 | #define FLIGHTSIM_TX_ENDPOINT 3 | ||||
#define PRODUCT_NAME_LEN 26 | #define PRODUCT_NAME_LEN 26 | ||||
#define EP0_SIZE 64 | #define EP0_SIZE 64 | ||||
#define NUM_ENDPOINTS 5 | #define NUM_ENDPOINTS 5 | ||||
#define NUM_USB_BUFFERS 20 | |||||
#define NUM_INTERFACE 3 | #define NUM_INTERFACE 3 | ||||
#define FLIGHTSIM_INTERFACE 0 // Flight Sim Control | #define FLIGHTSIM_INTERFACE 0 // Flight Sim Control | ||||
#define FLIGHTSIM_TX_ENDPOINT 3 | #define FLIGHTSIM_TX_ENDPOINT 3 | ||||
#define PRODUCT_NAME_LEN 15 | #define PRODUCT_NAME_LEN 15 | ||||
#define EP0_SIZE 64 | #define EP0_SIZE 64 | ||||
#define NUM_ENDPOINTS 4 | #define NUM_ENDPOINTS 4 | ||||
#define NUM_USB_BUFFERS 20 | |||||
#define NUM_INTERFACE 2 | #define NUM_INTERFACE 2 | ||||
#define MTP_INTERFACE 0 // MTP Disk | #define MTP_INTERFACE 0 // MTP Disk | ||||
#define MTP_TX_ENDPOINT 3 | #define MTP_TX_ENDPOINT 3 | ||||
#define PRODUCT_NAME_LEN 12 | #define PRODUCT_NAME_LEN 12 | ||||
#define EP0_SIZE 64 | #define EP0_SIZE 64 | ||||
#define NUM_ENDPOINTS 5 | #define NUM_ENDPOINTS 5 | ||||
#define NUM_USB_BUFFERS 16 | |||||
#define NUM_INTERFACE 4 | #define NUM_INTERFACE 4 | ||||
#define SEREMU_INTERFACE 0 // Serial emulation | #define SEREMU_INTERFACE 0 // Serial emulation | ||||
#define SEREMU_TX_ENDPOINT 1 | #define SEREMU_TX_ENDPOINT 1 | ||||
#define PRODUCT_NAME_LEN 17 | #define PRODUCT_NAME_LEN 17 | ||||
#define EP0_SIZE 64 | #define EP0_SIZE 64 | ||||
#define NUM_ENDPOINTS 8 | #define NUM_ENDPOINTS 8 | ||||
#define NUM_USB_BUFFERS 30 | |||||
#define NUM_INTERFACE 6 | #define NUM_INTERFACE 6 | ||||
#define CDC_IAD_DESCRIPTOR 1 | #define CDC_IAD_DESCRIPTOR 1 | ||||
#define CDC_STATUS_INTERFACE 0 | #define CDC_STATUS_INTERFACE 0 | ||||
#define PRODUCT_NAME_LEN 20 | #define PRODUCT_NAME_LEN 20 | ||||
#define EP0_SIZE 64 | #define EP0_SIZE 64 | ||||
#define NUM_ENDPOINTS 8 | #define NUM_ENDPOINTS 8 | ||||
#define NUM_USB_BUFFERS 30 | |||||
#define NUM_INTERFACE 6 | #define NUM_INTERFACE 6 | ||||
#define CDC_IAD_DESCRIPTOR 1 | #define CDC_IAD_DESCRIPTOR 1 | ||||
#define CDC_STATUS_INTERFACE 0 | #define CDC_STATUS_INTERFACE 0 | ||||
#define PRODUCT_NAME_LEN 14 | #define PRODUCT_NAME_LEN 14 | ||||
#define EP0_SIZE 64 | #define EP0_SIZE 64 | ||||
#define NUM_ENDPOINTS 15 | #define NUM_ENDPOINTS 15 | ||||
#define NUM_USB_BUFFERS 31 | |||||
#define NUM_INTERFACE 13 | #define NUM_INTERFACE 13 | ||||
#define CDC_IAD_DESCRIPTOR 1 | #define CDC_IAD_DESCRIPTOR 1 | ||||
#define CDC_STATUS_INTERFACE 0 | #define CDC_STATUS_INTERFACE 0 |
/* 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 |
/* 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_ | |||||
// When the PC isn't listening, how long do we wait before discarding data? | // When the PC isn't listening, how long do we wait before discarding data? | ||||
#define TX_TIMEOUT_MSEC 50 | #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; | if (!usb_configuration) return -1; | ||||
uint32_t head = tx_head; | uint32_t head = tx_head; |
/* 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 |
/* 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_ |