Hi,
I'll create a branch of the github project and check in the code changes. There was a bit of confusion on my part with respect to GitHub. There are two related projects:
https://github.com/planeturban/ubeswitch
and
https://github.com/planeturban/ubeswitchmk6 (No license in this project tree, which I just noticed)
I based my work off of the Mk6 project tree since I assumed that it is the most up to date.
In truth I can't say that I was aware of the commercial license terms, but my intention isn't to infringe on Ube's rights under the license terms. I'll update the terms of sale to include a donation of ~2 euro to a charity of your choice.
The listing for the device is:
https://www.ebay.com/itm/Open-Source-In ... 3835086994
Ebay won't allow an automatic donation of exactly 2 euro if the sale is conducted in US dollars and the donation amount is specified in percentage of sales price. If the choice of charity is up to me I would likely split the donation amount between the EFF (Electronic Frontier Foundation) and Saint Jude Children's Research Hospital. Both are US based charities that are highly regarded.
The background for this project is that I wanted to buy the UBESwitch, but the only place I could find the adapter for sale is Exxos and atarisales.co.uk. Exxos out of stock and the atarisales.co.uk price was too high for my liking so seeing that the design was available on GitHub I ordered the PCB and parts. Economies of scale kick in with parts quantities and shipping costs so I scaled the order up so that if the project is worth the effort I can share the result with a limited number of people. Selling 20 or so switches for ~$32 US (that includes US shipping) generates a little extra cash that I intended to use to offset the expense of the project. This is pretty much a hobby and learning opportunity, not a commercial project.
Using the name UBESwitch is intended as a part of Open Source credit attribution, but I can remove the use of the UBESwitch from the listing since I did change the firmware source since the version that I found in GitHub appeared to be a WIP and didn't work with the Board library I'm using in the Arduino IDE.
Code: Select all
/*
Compiled with MicroCore: 980 bytes. (Not working..)
Compiled for Attiny85: 956 bytes.
5244 bytes with debug.
How to read this code:
1. Don't. It's ugly.
2. When "pin" is referred in code (or text) it's the Atari side of things. The ATtiny's pins are always referred to as PBX.
*/
#define LEGACY // Uncomment this if your device does not have a ISP header.
//#define ALT_DETECT
#define DEBUG
// Timings.
#define switchTime 250000
#define saveTime 2000000
#define bootWait 4000 // Wait for computer to stabilize, 3-4s seems ok.
#define pulseThreshold 50000
#define SELECT_PORT PORTB
//#define SELECT_PORT DDRB
#define SAVE_LOCATION 0x1830 //6192
#include <util/delay.h>
#include <EEPROM.h>
#ifdef LEGACY
#define buttonPin PB0 // Connected to switch
#define selectPin PB1 // TS5V330 pin 1
#define pulsePin PB2 // VSync
#define serialRX PB3
#define serialTX PB4
#else
#defien serialRX PB0
#define serialTX PB1
#define pulsePin PB2 // VSync
#define selectPin PB3 // TS5V330 pin 1
#define buttonPin PB4 // Connected to switch
#endif
// Now that the pins are set, undefine LEGACY so that the ifdef's around the DEBUG statements are happy
#undef LEGACY
#if defined(DEBUG)
#include <SoftwareSerial.h>
SoftwareSerial mySerial(serialRX, serialTX); // RX, TX
#endif
unsigned long buttonPressedTime;
byte state;
byte state_changed = 0;
byte tosState;
#ifdef DEBUG
bool done = false;
String buff;
char data;
int i = 0;
#endif
unsigned long pulse = 0;
void setup() {
// IDEA: check if a jumper is placed on the ISP header to enter some kind of other operations mode.
// Set state to an invalid value to make sure the read from flash works
state = 3;
// Do the hardware setup for the Atari before setting up the serial port.
state = EEPROM.read(SAVE_LOCATION);
PORTB |= bit(buttonPin); // Input pullup.
// Instead of sending +5V to the Atari, let the pullup on pin4 handle the high part.
bitWrite(SELECT_PORT, selectPin, state);
#if defined (DEBUG) && !defined(LEGACY)
mySerial.begin(9600);
mySerial.println("Boot");
#endif
#if defined (DEBUG) && !defined(LEGACY)
mySerial.print("Reading state from flash: Saved state ");
mySerial.println(state);
#endif
// Instead of sending +5V to the Atari, let the pullup on pin4 handle the high part.
bitWrite(DDRB, selectPin, state);
#if defined (DEBUG) && !defined(LEGACY)
mySerial.print("Waiting for ");
mySerial.print(bootWait);
mySerial.println(" milliseconds.");
#endif
_delay_ms(bootWait);
state_changed = 0;
#if defined (DEBUG) && !defined(LEGACY)
mySerial.println("Loop.");
#endif
}
#ifdef DEBUG
void clearBuff() {
buff = "";
i = 0;
mySerial.print("> ");
}
void printHelp() {
mySerial.println("Help");
mySerial.println("-----------");
mySerial.println("b - Simulate button press.");
mySerial.println("p - Print information.");
mySerial.println("q - Quit prompt.");
mySerial.println("s <num> - Set pulse threashold.");
}
#endif
void toggle_state(void)
{
if (state == 0)
{
state = 1;
}
else
{
state = 0;
}
state_changed = 1;
}
void loop() {
byte save_now = 0;
/*
Detection..
*/
pulse = 0;
#ifdef ALT_DETECT
while ( pulse < 10000 ) // 10000 since sometimes you'd get 14 from getPulse();
pulse = getPulse();
#else
// disable the pulse detection.
#ifdef foo
// Check for pulsePin going high. This is to allow for Atari ST program control over the video mode
while ( ! pulse )
pulse = pulseIn(pulsePin, HIGH, 1000000L);
#endif
if ( 0 != pulse )
{
if (pulse < pulseThreshold)
{
//mySerial.println("Pulse detected, but below pulse threshold");
//mySerial.print("Pulse: ");
//mySerial.println(pulse);
}
else
{
#if defined (DEBUG) && !defined(LEGACY)
mySerial.println("Pulse detected, and above pulse threshold");
mySerial.print("Pulse: ");
mySerial.println(pulse);
#endif
save_now = 1;
toggle_state();
}
}
#endif
// Check for button press. This is to allow for manual user control over the video mode
// Short press (> 0.25s and < 2.0s) change mode
// Long press (>= 2.0s) save mode
if ( !bitRead(PINB, buttonPin) )
{
buttonPressedTime = micros();
while ( ! bitRead(PINB, buttonPin)); // Ugly debounce
if ( micros() > saveTime + buttonPressedTime )
{
#if defined (DEBUG) && !defined(LEGACY)
mySerial.println("Long Button Press");
#endif
save_now = 1;
}
else if ( micros() > buttonPressedTime + switchTime )
{
#if defined (DEBUG) && !defined(LEGACY)
mySerial.println("Short Button Press");
#endif
// Toggle the state
save_now = 1;
toggle_state();
}
}
// Check to see if the state should be saved due to a long button press
if ( 1 == save_now )
{
#if defined (DEBUG) && !defined(LEGACY)
mySerial.println("Save");
mySerial.print("Value: ");
mySerial.println(state);
#endif
save_now = 0;
EEPROM.write(SAVE_LOCATION, state);
}
// If the state has changed, update the state of the selectPin
if ( 1 == state_changed )
{
#if defined (DEBUG) && !defined(LEGACY)
//mySerial.println("State change");
//mySerial.print("New state: ");
//mySerial.println(state);
#endif
bitWrite(SELECT_PORT, selectPin, state);
// Reset the state_changed flag.
state_changed = 0;
_delay_ms(1000); // Wait for computer to change video modes
}
}
unsigned long getPulse() {
pulse = bitRead(PINB, pulsePin);
while ( bitRead(PINB, pulsePin) == pulse);
unsigned long pstart = micros();
while ( bitRead(PINB, pulsePin) != pulse);
return ( micros() - pstart);
}
This code is also a work in progress.
The use of DDRB when doing the bitWrite() failed to enable 5V output on the select pin, so I changed that to PORTB. That was the major operational defect I noticed. Enabling debug output on the MK6 LEAGACY board type was an attempt to figure out why the switch wasn't working. The debug output looked like things were working, but the select pin was not behaving as expected.
As a secondary issue I noticed the pulse detect logic seeing lots of spurious pulse events. I tried using a pulldown resistor on this line and that did suppress most of the spurious pulses, but for some reason that broke the button detection. I need to read the ATTINY85 documentation to figure out what is going on with internal pullups / pulldowns.