I see; Thanks KurtE for the pointer.
So you don't just change settings using the IDE via the library, but you need to write a descriptor to identify the joystick from the ground up, and the code with the implementation.
I did come up with this; after searching on the forum and grabbing most of the code made in another post; although it is my first time so I am not even sure if that is correct.
I will try this later during the day; did I miss anything in the implementation or made any error that could risk to damage the computer or the Teensy? Thanks!
Added in usb_desc.h:
Code:
#elif defined(USB_CONTROLBOX)
#define VENDOR_ID 0x16C0
#define PRODUCT_ID 0x0489
#define DEVICE_CLASS 0x03
#define MANUFACTURER_NAME {'T','e','e','n','s','y','d','u','i','n','o'}
#define MANUFACTURER_NAME_LEN 11
#define PRODUCT_NAME {'C', 'o', 'n', 't', 'r', 'o', 'l', ' ', 'B', 'o', 'x'}
#define PRODUCT_NAME_LEN 11
#define EP0_SIZE 64
#define NUM_ENDPOINTS 2
#define NUM_USB_BUFFERS 30
#define NUM_INTERFACE 1
#define ARCADE_INTERFACE 0 // Joystick
#define ARCADE_ENDPOINT 1
#define ARCADE_SIZE 16
#define ARCADE_INTERVAL 1
#define ARCADE_DESC_OFFSET (9)
#define CONFIG_DESC_SIZE (9 + 9+9+7)
#define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY
In usb_desc.c:
Code:
#ifdef ARCADE_INTERFACE
{ 0x2200, ARCADE_INTERFACE, arcade_report_desc, sizeof(arcade_report_desc) },
{ 0x2100, ARCADE_INTERFACE, config_descriptor + ARCADE_DESC_OFFSET, 9 },
#endif
created usb_box.h and usb_box.c from a different thread, changing only the button value:
Code:
// usb_arcade.h
#ifndef _USB_ARCADE_H_
#define _USB_ARCADE_H_
#if defined(USB_ARCADE)
#include <inttypes.h>
// C language implementation
#ifdef __cplusplus
extern "C" {
#endif
int usb_arcade_send(void);
// we have packets that are 6 bytes long
extern uint8_t usb_arcade_data[6];
#ifdef __cplusplus
}
#endif
// C++ interface
#ifdef __cplusplus
class usb_arcade_class
{
private:
static uint8_t auto_send;
public:
void button(uint8_t button, bool val) {
if (--button >= 40) return;
if (val) usb_arcade_data[button >= 8 ? 5 : 4] |= (1 << (button >= 8 ? (button - 8) : button));
else usb_arcade_data[button >= 8 ? 5 : 4] &= ~(1 << (button >= 8 ? (button - 8) : button));
if (auto_send) usb_arcade_send();
}
void axis(uint8_t axis, int8_t val) {
if (axis >= 2) return;
if (val > 0) usb_arcade_data[axis] = 127;
else if (val < 0) usb_arcade_data[axis] = -127;
else usb_arcade_data[axis] = 0;
if (auto_send) usb_arcade_send();
}
void setAutoSend(bool send) {
auto_send = send;
}
void send() {
usb_arcade_send();
}
};
extern usb_arcade_class Arcade;
#endif // __cplusplus
#endif // USB_ARCADE
#endif // _USB_ARCADE_H_
Code:
// usb_arcade.c
#include "usb_dev.h"
#include "usb_arcade.h"
#include "core_pins.h" // for yield()
#include "HardwareSerial.h"
#include <string.h> // for memcpy()
#ifdef USB_ARCADE // defined by usb_dev.h -> usb_desc.h
uint8_t usb_arcade_data[6];
// Maximum number of transmit packets to queue so we don't starve other endpoints for memory
#define TX_PACKET_LIMIT 3
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
#if F_CPU == 96000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 596)
#elif F_CPU == 48000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 428)
#elif F_CPU == 24000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 262)
#endif
int usb_arcade_send(void)
{
uint32_t wait_count = 0;
usb_packet_t *tx_packet;
while (1) {
if (!usb_configuration) {
return -1;
}
if (usb_tx_packet_count(ARCADE_ENDPOINT) < TX_PACKET_LIMIT) { tx_packet = usb_malloc(); if (tx_packet) break; } if (++wait_count > TX_TIMEOUT || transmit_previous_timeout) {
transmit_previous_timeout = 1;
return -1;
}
yield();
}
transmit_previous_timeout = 0;
memcpy(tx_packet->buf, usb_arcade_data, 6);
tx_packet->len = 6;
usb_tx(ARCADE_ENDPOINT, tx_packet);
return 0;
}
#endif // USB_ARCADE
The following went in usb_inst.cpp and WProgram.h for the IDE editor
Code:
#ifdef USB_ARCADE
usb_arcade_class Arcade;
uint8_t usb_arcade_class::auto_send = 0;
#endif
Code:
/* 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 WProgram_h
#define WProgram_h
#include <stdlib.h>
#include <string.h>
#include <math.h>
// some libraries and sketches depend on this
// AVR stuff, assuming Arduino.h or WProgram.h
// automatically includes it...
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include "avr_functions.h"
#include "wiring.h"
#include "HardwareSerial.h"
#define DMAMEM __attribute__ ((section(".dmabuffers"), used))
#define FASTRUN __attribute__ ((section(".fastrun"), noinline, noclone ))
#ifdef __cplusplus
#include "avr_emulation.h"
#include "usb_serial.h"
#include "usb_seremu.h"
#include "usb_keyboard.h"
#include "usb_mouse.h"
#include "usb_joystick.h"
#include "usb_arcade.h"
#include "usb_midi.h"
#include "usb_rawhid.h"
#include "usb_flightsim.h"
#include "usb_mtp.h"
#include "usb_audio.h"
#include "usb_touch.h"
#include "usb_undef.h" // do not allow usb_desc.h stuff to leak to user programs
#include "WCharacter.h"
#include "WString.h"
#include "elapsedMillis.h"
#include "IntervalTimer.h"
uint16_t makeWord(uint16_t w);
uint16_t makeWord(byte h, byte l);
#define word(...) makeWord(__VA_ARGS__)
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
void tone(uint8_t pin, uint16_t frequency, uint32_t duration = 0);
void noTone(uint8_t pin);
// WMath prototypes
int32_t random(void);
uint32_t random(uint32_t howbig);
int32_t random(int32_t howsmall, int32_t howbig);
void randomSeed(uint32_t newseed);
void srandom(unsigned int newseed);
#include "pins_arduino.h"
#endif // __cplusplus
// Fast memcpy
#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
#ifdef __cplusplus
extern "C" {
extern void *memcpy (void *dst, const void *src, size_t count);
}
#else
extern void *memcpy (void *dst, const void *src, size_t count);
#endif
#endif
#endif // WProgram_h