mirror of
https://github.com/option8/RetroConnector.git
synced 2024-06-01 23:41:27 +00:00
added calibration to USB Joystick Interface
This commit is contained in:
parent
38540b4dea
commit
17ed3ad68d
|
@ -1,67 +0,0 @@
|
||||||
//--- SPI code
|
|
||||||
|
|
||||||
#define DATAOUT 11
|
|
||||||
#define SPICLOCK 13
|
|
||||||
#define SLAVESELECT 4
|
|
||||||
|
|
||||||
void SPIInitialize()
|
|
||||||
{
|
|
||||||
byte clr;
|
|
||||||
|
|
||||||
pinMode(DATAOUT, OUTPUT);
|
|
||||||
pinMode(SPICLOCK,OUTPUT);
|
|
||||||
pinMode(SLAVESELECT,OUTPUT);
|
|
||||||
|
|
||||||
digitalWrite(SLAVESELECT,HIGH); //disable device
|
|
||||||
|
|
||||||
SPCR = (1<<SPE)|(1<<MSTR);
|
|
||||||
clr=SPSR;
|
|
||||||
clr=SPDR;
|
|
||||||
delay(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
char SPITransfer(volatile char data)
|
|
||||||
{
|
|
||||||
SPDR = data; // Start the transmission
|
|
||||||
while (!(SPSR & (1<<SPIF))) // Wait the end of the transmission
|
|
||||||
{
|
|
||||||
};
|
|
||||||
return SPDR; // return the received byte
|
|
||||||
}
|
|
||||||
|
|
||||||
//--- MCP42100 code
|
|
||||||
|
|
||||||
byte SetPot(int address, int value)
|
|
||||||
{
|
|
||||||
// Slave Select set low to allow commands
|
|
||||||
digitalWrite(SLAVESELECT, LOW);
|
|
||||||
|
|
||||||
// 2 byte command
|
|
||||||
SPITransfer(0x10 + address); // 0x10 = 'set pot' command
|
|
||||||
SPITransfer(value); // Value to set pot
|
|
||||||
|
|
||||||
// Release chip, signal end transfer
|
|
||||||
digitalWrite(SLAVESELECT, HIGH);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--- Application code
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
SPIInitialize(); // Initialize the SPI interface
|
|
||||||
SetPot(1,255);
|
|
||||||
SetPot(0,255);
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop()
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
for (int level = 0; level < 255; level++) {
|
|
||||||
SetPot(1,level);;
|
|
||||||
SetPot(2,255 - level);;
|
|
||||||
delay(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -9,10 +9,6 @@ const int Butt0Pin = A4;
|
||||||
const int Butt1Pin = A5;
|
const int Butt1Pin = A5;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
|
|
||||||
#include <avrpins.h>
|
#include <avrpins.h>
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
|
||||||
|
|
||||||
|
#include <SPI.h>
|
||||||
|
|
||||||
|
// set pin 4 as the slave select for the digital pot:
|
||||||
|
const int slaveSelectPin = A0; //4;
|
||||||
|
//const float foo = .21;
|
||||||
|
const int TrimPin = A3;
|
||||||
|
|
||||||
|
const int Butt0Pin = A4;
|
||||||
|
const int Butt1Pin = A5;
|
||||||
|
|
||||||
|
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
|
||||||
|
#include <avrpins.h>
|
||||||
|
#include <max3421e.h>
|
||||||
|
#include <usbhost.h>
|
||||||
|
#include <usb_ch9.h>
|
||||||
|
#include <Usb.h>
|
||||||
|
#include <usbhub.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#include <address.h>
|
||||||
|
#include <hid.h>
|
||||||
|
#include <hiduniversal.h>
|
||||||
|
|
||||||
|
#include "hidjoystickrptparser.h"
|
||||||
|
|
||||||
|
#include <printhex.h>
|
||||||
|
#include <message.h>
|
||||||
|
#include <hexdump.h>
|
||||||
|
#include <parsetools.h>
|
||||||
|
|
||||||
|
USB Usb;
|
||||||
|
USBHub Hub(&Usb);
|
||||||
|
HIDUniversal Hid(&Usb);
|
||||||
|
JoystickEvents JoyEvents;
|
||||||
|
JoystickReportParser Joy(&JoyEvents);
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
// set the slaveSelectPin as an output:
|
||||||
|
pinMode (slaveSelectPin, OUTPUT);
|
||||||
|
|
||||||
|
|
||||||
|
pinMode (Butt0Pin, OUTPUT);
|
||||||
|
pinMode (Butt1Pin, OUTPUT);
|
||||||
|
|
||||||
|
|
||||||
|
// initialize SPI:
|
||||||
|
SPI.begin();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Serial.begin( 115200 );
|
||||||
|
Serial.println("Start");
|
||||||
|
|
||||||
|
if (Usb.Init() == -1)
|
||||||
|
Serial.println("OSC did not start.");
|
||||||
|
|
||||||
|
delay( 200 );
|
||||||
|
|
||||||
|
if (!Hid.SetReportParser(0, &Joy))
|
||||||
|
ErrorMessage<uint8_t>(PSTR("SetReportParser"), 1 );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
Usb.Task();
|
||||||
|
|
||||||
|
float foo = float(analogRead(TrimPin))/1023.000;
|
||||||
|
|
||||||
|
|
||||||
|
int joyX = JoyEvents.X;
|
||||||
|
int channel = 5;
|
||||||
|
|
||||||
|
digitalPotWrite(channel, joyX);
|
||||||
|
digitalPotWrite(channel - 1, joyX * foo);
|
||||||
|
|
||||||
|
int joyY = JoyEvents.Y;
|
||||||
|
channel = 3;
|
||||||
|
|
||||||
|
digitalPotWrite(channel, joyY);
|
||||||
|
digitalPotWrite(channel - 1, joyY * foo);
|
||||||
|
|
||||||
|
|
||||||
|
digitalWrite(Butt0Pin,JoyEvents.Butt0);
|
||||||
|
digitalWrite(Butt1Pin,JoyEvents.Butt1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void digitalPotWrite(int address, int value) {
|
||||||
|
// take the SS pin low to select the chip:
|
||||||
|
digitalWrite(slaveSelectPin,LOW);
|
||||||
|
// send in the address and value via SPI:
|
||||||
|
SPI.transfer(address);
|
||||||
|
SPI.transfer(value);
|
||||||
|
// take the SS pin high to de-select the chip:
|
||||||
|
digitalWrite(slaveSelectPin,HIGH);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "hidjoystickrptparser.h"
|
||||||
|
|
||||||
|
JoystickReportParser::JoystickReportParser(JoystickEvents *evt) :
|
||||||
|
joyEvents(evt),
|
||||||
|
oldHat(0xDE),
|
||||||
|
oldButtons(0)
|
||||||
|
{
|
||||||
|
for (uint8_t i=0; i<RPT_GEMEPAD_LEN; i++)
|
||||||
|
oldPad[i] = 0xD;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoystickReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
|
||||||
|
{
|
||||||
|
bool match = true;
|
||||||
|
|
||||||
|
// Checking if there are changes in report since the method was last called
|
||||||
|
for (uint8_t i=0; i<RPT_GEMEPAD_LEN; i++)
|
||||||
|
if (buf[i] != oldPad[i])
|
||||||
|
{
|
||||||
|
match = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calling Game Pad event handler
|
||||||
|
if (!match && joyEvents)
|
||||||
|
{
|
||||||
|
joyEvents->OnGamePadChanged((const GamePadEventData*)buf);
|
||||||
|
|
||||||
|
for (uint8_t i=0; i<RPT_GEMEPAD_LEN; i++) oldPad[i] = buf[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t buttons = (0x0000 | buf[6]);
|
||||||
|
buttons <<= 4;
|
||||||
|
buttons |= (buf[5] >> 4);
|
||||||
|
uint16_t changes = (buttons ^ oldButtons);
|
||||||
|
|
||||||
|
// Calling Button Event Handler for every button changed
|
||||||
|
if (changes)
|
||||||
|
{
|
||||||
|
for (uint8_t i=0; i<0x0C; i++)
|
||||||
|
{
|
||||||
|
uint16_t mask = (0x0001 << i);
|
||||||
|
|
||||||
|
if (((mask & changes) > 0) && joyEvents)
|
||||||
|
if ((buttons & mask) > 0)
|
||||||
|
joyEvents->OnButtonDn(i+1);
|
||||||
|
else
|
||||||
|
joyEvents->OnButtonUp(i+1);
|
||||||
|
}
|
||||||
|
oldButtons = buttons;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoystickEvents::OnGamePadChanged(const GamePadEventData *evt)
|
||||||
|
{
|
||||||
|
|
||||||
|
X = evt->X;
|
||||||
|
Y = evt->Y;
|
||||||
|
Serial.print("X: ");
|
||||||
|
Serial.print(X);
|
||||||
|
//PrintHex<uint8_t>(evt->X, 0x80);
|
||||||
|
Serial.print("\tY: ");
|
||||||
|
Serial.print(Y);
|
||||||
|
// PrintHex<uint8_t>(evt->Y, 0x80);
|
||||||
|
Serial.println("");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void JoystickEvents::OnButtonUp(uint8_t but_id)
|
||||||
|
{
|
||||||
|
Serial.print("Up: ");
|
||||||
|
Serial.println(but_id);
|
||||||
|
if(but_id == 1) {
|
||||||
|
Butt0 = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(but_id == 2) {
|
||||||
|
Butt1 = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoystickEvents::OnButtonDn(uint8_t but_id)
|
||||||
|
{
|
||||||
|
Serial.print("Dn: ");
|
||||||
|
Serial.println(but_id);
|
||||||
|
|
||||||
|
|
||||||
|
if(but_id == 1) {
|
||||||
|
Butt0 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(but_id == 2) {
|
||||||
|
Butt1 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
#if !defined(__HIDJOYSTICKRPTPARSER_H__)
|
||||||
|
#define __HIDJOYSTICKRPTPARSER_H__
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#include "avrpins.h"
|
||||||
|
#include "max3421e.h"
|
||||||
|
#include "usbhost.h"
|
||||||
|
#include "usb_ch9.h"
|
||||||
|
#include "Usb.h"
|
||||||
|
|
||||||
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
|
#include "Arduino.h"
|
||||||
|
#else
|
||||||
|
#include <WProgram.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "printhex.h"
|
||||||
|
#include "hexdump.h"
|
||||||
|
#include "message.h"
|
||||||
|
#include "confdescparser.h"
|
||||||
|
#include "hid.h"
|
||||||
|
|
||||||
|
struct GamePadEventData
|
||||||
|
{
|
||||||
|
uint8_t X, Y;
|
||||||
|
};
|
||||||
|
|
||||||
|
class JoystickEvents
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void OnGamePadChanged(const GamePadEventData *evt);
|
||||||
|
virtual void OnButtonUp(uint8_t but_id);
|
||||||
|
virtual void OnButtonDn(uint8_t but_id);
|
||||||
|
|
||||||
|
uint8_t X;
|
||||||
|
uint8_t Y;
|
||||||
|
|
||||||
|
boolean Butt0;
|
||||||
|
boolean Butt1;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#define RPT_GEMEPAD_LEN 5
|
||||||
|
|
||||||
|
class JoystickReportParser : public HIDReportParser
|
||||||
|
{
|
||||||
|
JoystickEvents *joyEvents;
|
||||||
|
|
||||||
|
uint8_t oldPad[RPT_GEMEPAD_LEN];
|
||||||
|
uint8_t oldHat;
|
||||||
|
uint16_t oldButtons;
|
||||||
|
|
||||||
|
public:
|
||||||
|
JoystickReportParser(JoystickEvents *evt);
|
||||||
|
|
||||||
|
virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __HIDJOYSTICKRPTPARSER_H__
|
|
@ -1,90 +0,0 @@
|
||||||
/*
|
|
||||||
Digital Pot Control
|
|
||||||
|
|
||||||
Based on the original sketch for AD5206....
|
|
||||||
|
|
||||||
This example controls a Microchip digital potentiometer.
|
|
||||||
The MCP42 has 2 potentiometer channels. Each channel's pins are labeled
|
|
||||||
PAx - connect this to voltage
|
|
||||||
PWx - this is the pot's wiper, which changes when you set it
|
|
||||||
PBx - connect this to ground.
|
|
||||||
|
|
||||||
The MCP42 is SPI-compatible,and to command it, you send two bytes:
|
|
||||||
|
|
||||||
The first byte is the Command Byte which has this format when
|
|
||||||
the next byte is to be data: XX01XXpp
|
|
||||||
note these bits ...............^^.... the 01 means the next byte is data
|
|
||||||
(where pp = potentiometer selection, X= don't care)
|
|
||||||
pp= 00 = dummy code, no pot selected
|
|
||||||
pp= 01 = pot0
|
|
||||||
pp= 10 = pot1
|
|
||||||
pp= 11 = both pots
|
|
||||||
|
|
||||||
Simplest case is to have X= 0 so the Command Byte will be:
|
|
||||||
pp= 00: 00010000 = 16
|
|
||||||
pp= 01: 00010001 = 17
|
|
||||||
pp= 10: 00010010 = 18
|
|
||||||
pp= 11: 00010011 = 19
|
|
||||||
|
|
||||||
The second byte is the resistance value for the channel (0 - 255).
|
|
||||||
|
|
||||||
The circuit:
|
|
||||||
* All PA pins of MCP42 connected to +5V
|
|
||||||
* All PB pins of MCP42 connected to ground
|
|
||||||
* An LED and a 220-ohm resisor in series connected from each PW pin to ground
|
|
||||||
* CS - to digital pin 10 (SS pin)
|
|
||||||
* SI - to digital pin 11 (MOSI pin)
|
|
||||||
* SCK - to digital pin 13 (SCK pin)
|
|
||||||
|
|
||||||
created 10 Aug 2010
|
|
||||||
by Tom Igoe
|
|
||||||
|
|
||||||
Thanks to Heather Dewey-Hagborg for the original tutorial, 2005
|
|
||||||
|
|
||||||
Version for MCP42xx April 2013, Jim Brown
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
// include the SPI library:
|
|
||||||
#include <SPI.h>
|
|
||||||
|
|
||||||
|
|
||||||
// set pin 4 as the slave select for the digital pot:
|
|
||||||
const int slaveSelectPin = 4;
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
// set the slaveSelectPin as an output:
|
|
||||||
pinMode (slaveSelectPin, OUTPUT);
|
|
||||||
// initialize SPI:
|
|
||||||
SPI.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
// go through pp=01, 10, 11 for pot0, pot1 and both together of the digital pot:
|
|
||||||
for (int CommandByte = 17; CommandByte < 19; CommandByte++) { // 17, 18 and 19
|
|
||||||
// change the resistance on this pot from min to max:
|
|
||||||
for (int level = 0; level < 255; level++) {
|
|
||||||
digitalPotWrite(CommandByte, level);
|
|
||||||
delay(10);
|
|
||||||
}
|
|
||||||
// wait at the top:
|
|
||||||
delay(100);
|
|
||||||
// change the resistance on this channel from max to min:
|
|
||||||
for (int level = 0; level < 255; level++) {
|
|
||||||
digitalPotWrite(CommandByte, 255 - level);
|
|
||||||
delay(10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int digitalPotWrite(int CommandByte, int value) {
|
|
||||||
// take the SS pin low to select the chip:
|
|
||||||
digitalWrite(slaveSelectPin,LOW);
|
|
||||||
// send in the address and value via SPI:
|
|
||||||
SPI.transfer(CommandByte);
|
|
||||||
SPI.transfer(value);
|
|
||||||
// take the SS pin high to de-select the chip:
|
|
||||||
digitalWrite(slaveSelectPin,HIGH);
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
// inslude the SPI library:
|
|
||||||
#include <SPI.h>
|
|
||||||
|
|
||||||
|
|
||||||
// set pin 10 as the slave select for the digital pot:
|
|
||||||
const int slaveSelectPin = 4;
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
// set the slaveSelectPin as an output:
|
|
||||||
pinMode (slaveSelectPin, OUTPUT);
|
|
||||||
// initialize SPI:
|
|
||||||
SPI.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
|
|
||||||
int channel = 5;
|
|
||||||
float foo = .21;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
delay(1000);
|
|
||||||
|
|
||||||
|
|
||||||
// change the resistance on this channel from min to max:
|
|
||||||
for (int level = 0; level < 255; level++) {
|
|
||||||
digitalPotWrite(channel, level);
|
|
||||||
digitalPotWrite(channel - 1, level * foo);
|
|
||||||
delay(10);
|
|
||||||
}
|
|
||||||
// wait a second at the top:
|
|
||||||
delay(1000);
|
|
||||||
// change the resistance on this channel from max to min:
|
|
||||||
for (int level = 0; level < 255; level++) {
|
|
||||||
digitalPotWrite(channel, 255 - level);
|
|
||||||
digitalPotWrite(channel - 1, (255 - level) * foo);
|
|
||||||
delay(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void digitalPotWrite(int address, int value) {
|
|
||||||
// take the SS pin low to select the chip:
|
|
||||||
digitalWrite(slaveSelectPin,LOW);
|
|
||||||
// send in the address and value via SPI:
|
|
||||||
SPI.transfer(address);
|
|
||||||
SPI.transfer(value);
|
|
||||||
// take the SS pin high to de-select the chip:
|
|
||||||
digitalWrite(slaveSelectPin,HIGH);
|
|
||||||
}
|
|
BIN
USB_Joystick/PCB/USB_Joystick-rev2.fzz
Normal file
BIN
USB_Joystick/PCB/USB_Joystick-rev2.fzz
Normal file
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user