Created
March 5, 2020 15:58
-
-
Save pwillard/e2f042177a47ef53e5eff682ea354b7c to your computer and use it in GitHub Desktop.
TINY85 (trinket) Clock Source for Ben Eater's 6502 computer - code from comment section by Florimel (I didn't write this)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//============================================================================== | |
// 666 55555 000 2222 CCCC L K K III N N OOOOO | |
// 6 5 0 00 2 C L K K I NN N O O | |
// 6666 5555 0 0 0 222 C L KK I N N N O O | |
// 6 6 5 00 0 2 C L K K .. I N NN O O | |
// 666 5555 000 22222 CCCC LLLLL K K .. III N N OOOOO | |
//============================================================================== | |
// Program: 6502clk.ino | |
// Version: 1.0 | |
// Target: TrinketPro | |
// Date: 2020/03/05 | |
// Time: 09:27:28 | |
// Notes: The Tiny85 version of TimerOne library needs to be used since the one | |
// from the PJRC website fails to compile for the ATTiny85 | |
// (aka Adafruit Trinket). Use: https://github.com/StoykoDimitrov/TimerOne | |
//============================================================================== | |
// | |
// Reference: Code from florimel @ Ben Eater's Comment section | |
// @ https://eater.net/6502 | |
//============================================================================== | |
//=====[ INCLUDE ]============================================================== | |
#include "TimerOne.h" | |
//=====[ CONSTANTS ]============================================================ | |
#define DEBUG 0 // 0 = debugging disabled, 1 = enabled | |
#define DEBOUNCE_DELAY 20 // Milliseconds | |
#define NUM_SPEEDS 3 // # of microsecond options for delays timer | |
//=====[ OBJECT DEFINITIONS ]=================================================== | |
class Button { | |
unsigned long lastTick = 0; | |
int pin , value = HIGH, candidate = HIGH; | |
public: | |
Button(int p) { | |
pin = p; | |
pinMode(pin, INPUT_PULLUP); | |
} | |
// Debounce Button Press | |
void tick() { | |
int read = digitalRead(pin); | |
unsigned long now = millis(); | |
if (read != candidate) { | |
candidate = read; | |
lastTick = now; | |
} | |
else if (candidate != value && (now - lastTick) >= DEBOUNCE_DELAY) { | |
value = candidate; | |
if (isDown() && onDown != NULL) onDown(); | |
if (isUp() && onUp != NULL) onUp(); | |
} | |
} | |
bool isDown() { | |
return value == LOW; | |
} | |
bool isUp() { | |
return value == HIGH; | |
} | |
void (*onUp)() = NULL; | |
void (*onDown)() = NULL; | |
}; | |
//=====[ VARIABLES ]============================================================ | |
Button buttons[] = { PB2, PB3 }; // PB2 and PB3 are marked #2 and #3 on Trinket | |
// 4Hz , 40Hz , 40kHz. | |
unsigned long delays[NUM_SPEEDS] = {250000, 25000, 25}; | |
int speed = 0; | |
//=====[ SETUP ]================================================================ | |
// Runs only one time at startup | |
void setup() { | |
pinMode(PB0, OUTPUT); | |
Timer1.initialize(delays[0]); Timer1.attachInterrupt(blink); | |
buttons[0].onDown = onClickManual; | |
buttons[1].onDown = onClickAuto; | |
} | |
//============================================================================== | |
//=====[ MAIN PROCESS LOOP ]==================================================== | |
void loop() { | |
for (Button& b : buttons) b.tick(); | |
} | |
//============================================================================== | |
//=====[ SUBROUTINES ]========================================================== | |
void onClickManual() { | |
if (speed >= 0) { | |
Timer1.attachInterrupt(blinkOnce); | |
speed = -1; | |
} | |
else { | |
Timer1.restart(); | |
Timer1.attachInterrupt(blinkOnce, delays[0]); | |
} | |
} | |
//============================================================================== | |
void onClickAuto() { | |
if (speed == -1) { | |
speed = 0; | |
Timer1.restart(); | |
Timer1.attachInterrupt(blink, delays[speed]); | |
} | |
else { | |
speed = (speed + 1) % NUM_SPEEDS; | |
Timer1.setPeriod(delays[speed]); | |
} | |
} | |
//============================================================================== | |
void blink() { | |
PORTB ^= (1 << PB0); | |
} | |
void blinkOnce() { | |
PORTB ^= (1 << PB0); | |
if ((PORTB & (1 << PB0)) == 0) Timer1.detachInterrupt(); | |
} | |
//============================================================================== |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment