Fix timers in main program too

This commit is contained in:
Neale Pickett 2013-06-30 14:57:44 -06:00
parent a5936d5590
commit fa12096630
7 changed files with 104 additions and 200 deletions

View File

@ -1,6 +1,40 @@
ARCH = avr PROG = main
CFLAGS += -DARCH=$(ARCH) MCU = attiny84
include Makefile.$(ARCH) CC = avr-gcc
CFLAGS += -mmcu=$(MCU)
CFLAGS += -Os
CFLAGS += -w
LDFLAGS += -mmcu=$(MCU)
AVDFLAGS += -p $(MCU)
AVDFLAGS += -c usbtiny
CLOCK_HZ = 16000000
FUSES += -U lfuse:w:0xff:m
FUSES += -U hfuse:w:0xd9:m
FUSES += -U efuse:w:0xff:m
upload: .upload
.upload: $(PROG).hex
avrdude $(AVDFLAGS) -U flash:w:$<
touch $@
fuses:
avrdude $(AVDFLAGS) $(FUSES)
main: main.o avr.o
$(PROG).hex: $(PROG)
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature $< $@
clean:
rm -f $(PROG) *.o *.hex .upload

View File

@ -1,42 +0,0 @@
PROG = main
MCU = attiny84
CC = avr-gcc
CFLAGS += -mmcu=$(MCU)
CFLAGS += -Os
CFLAGS += -w
LDFLAGS += -mmcu=$(MCU)
AVDFLAGS += -p $(MCU)
AVDFLAGS += -c usbtiny
FUSES += -U lfuse:w:0xff:m
FUSES += -U hfuse:w:0xd9:m
FUSES += -U efuse:w:0xff:m
upload: .upload
.upload: $(PROG).hex
avrdude $(AVDFLAGS) -U flash:w:$<
touch $@
fuses:
avrdude $(AVDFLAGS) $(FUSES)
$(PROG).hex: $(PROG)
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature $< $@
main: main.o avr.o
#main.o: avr.h
#avr.o: avr.h
clean:
rm -f $(PROG) *.o *.hex .upload

View File

@ -1,17 +0,0 @@
CC = msp430-gcc
LDFLAGS += -mmcu=msp430g2553
CFLAGS += -mmcu=msp430g2553
CFLAGS += -Wall
CFLAGS += -Os
CFLAGS += -w
upload: .upload
.upload: main
mspdebug rf2500 "prog $<"
touch $@
main: main.o ti.o
clean:
rm -f main *.o .upload

48
avr.c
View File

@ -4,49 +4,39 @@
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include "avr.h" #include "avr.h"
/* This only works out for a 16MHz or 8MHz clock */
#define CLOCK_HZ 16000000
#define TICKS_PER_SECOND (CLOCK_HZ / 256)
#define TICKS_PER_JIFFY (TICKS_PER_SECOND / 10)
#define cbi(byt, bit) (byt &= ~_BV(bit)) #define cbi(byt, bit) (byt &= ~_BV(bit))
#define sbi(byt, bit) (byt |= _BV(bit)) #define sbi(byt, bit) (byt |= _BV(bit))
extern volatile bool tick; extern volatile bool tick;
extern volatile uint32_t jiffies; extern volatile uint32_t jiffies;
// Count microseconds // Interrupt called every jiffy
volatile uint32_t micros = 0; ISR(TIM1_COMPA_vect)
// Interrupt called every 256 * 64 microseconds
ISR(TIM0_OVF_vect)
{ {
uint32_t m = micros; jiffies += 1;
tick = true;
m += (256 * 64);
if (m >= JIFFY_uS) {
m -= JIFFY_uS;
tick = true;
jiffies += 1;
}
micros = m;
} }
void void
init(void) init(void)
{ {
// Set prescaler to 16, so we get clock ticks at exactly 1MHz int i;
CLKPR = _BV(CLKPCE);
CLKPR = 0x04;
// Set timer 0 interrupt clock divider to 64
TCCR0B = _BV(CS01) + _BV(CS00);
// enable timer 0 overflow interrupt
TIMSK0 |= _BV(TOIE0); //enable compare match interrupt;
// Enable interrupts
sei();
DDRA = ~(_BV(NESOUT)); DDRA = ~(_BV(NESOUT));
DDRB = 0xff; DDRB = 0xff;
PORTA = 0; TCCR1A = 0;
PORTB = 0xff; TCCR1B = 0;
TCNT1 = 0;
OCR1A = TICKS_PER_JIFFY - 1;
TCCR1B |= (1 << WGM12);
TCCR1B |= (1 << CS12);
TIMSK1 |= (1 << OCIE1A);
sei();
} }

95
main.c
View File

@ -5,22 +5,25 @@
#include <avr/io.h> #include <avr/io.h>
#include <util/delay.h> #include <util/delay.h>
#if ARCH == avr #include "avr.h"
# include "avr.h"
#else
# include "ti.h"
#endif
// Number of shift registers in your scoreboard // Number of shift registers in your scoreboard
// If you want scores to go over 199, you need 8 // If you want scores to go over 199, you need 8
const int nsr = 6; const int nsr = 6;
// //
// Timing stuff // Timing stuff
// //
//
// 2**32 deciseconds = 13.610221 years
//
// As long as you unplug your scoreboard once every 10 years or so,
// you're good.
//
volatile uint32_t jiffies = 0; // Elapsed time in deciseconds
volatile bool tick = false; // Set high when jiffy clock ticks
volatile uint32_t jiffies = 0;
volatile bool tick = false; // Set high when jiffy clock ticks
// Clocks are in deciseconds // Clocks are in deciseconds
uint16_t score_a = 0; uint16_t score_a = 0;
@ -75,11 +78,11 @@ write(uint8_t number)
{ {
int i; int i;
int j; int j;
// MSB first // MSB first
for (i = 7; i >= 0; i -= 1) { for (i = 7; i >= 0; i -= 1) {
sin(number & (1 << i)); sin(number & (1 << i));
for (j = 0; j < 12; j += 1) { for (j = 0; j < 12; j += 1) {
pulse(); pulse();
} }
@ -94,7 +97,7 @@ write_num(uint16_t number, int digits)
for (i = 0; i < digits; i += 1) { for (i = 0; i < digits; i += 1) {
uint16_t n = (number / divisor) % 10; uint16_t n = (number / divisor) % 10;
write(seven_segment_digits[n]); write(seven_segment_digits[n]);
divisor *= 10; divisor *= 10;
} }
@ -108,11 +111,11 @@ draw()
{ {
uint16_t clk; uint16_t clk;
//XXX testing // XXX testing
write_num(score_b, 2); write_num(score_b, 2);
if (state == SETUP) { if (state == SETUP) {
write(setup_digits[2]); write(setup_digits[2]);
write(setup_digits[1]); write(setup_digits[1]);
@ -120,10 +123,10 @@ draw()
write(setup_digits[0]); write(setup_digits[0]);
} else { } else {
clk = (abs(jam_clock / 600) % 10) * 1000; clk = (abs(jam_clock / 600) % 10) * 1000;
clk += abs(jam_clock) % 600; clk += abs(jam_clock) % 600;
write_num(clk, 4); write_num(clk, 4);
} }
write_num(score_a, 2); write_num(score_a, 2);
@ -137,7 +140,7 @@ draw()
clk += abs(period_clock / 10) % 60; clk += abs(period_clock / 10) % 60;
write_num(clk, 4); write_num(clk, 4);
} }
latch(); latch();
pulse(); pulse();
} }
@ -153,7 +156,7 @@ nesprobe()
nesltch(true); nesltch(true);
nesltch(false); nesltch(false);
for (i = 0; i < 8; i += 1) { for (i = 0; i < 8; i += 1) {
state <<= 1; state <<= 1;
if (nesout()) { if (nesout()) {
@ -164,7 +167,7 @@ nesprobe()
nesclk(true); nesclk(true);
nesclk(false); nesclk(false);
} }
// Only report button down events. // Only report button down events.
return state; return state;
} }
@ -173,10 +176,10 @@ void
update_controller() update_controller()
{ {
static uint8_t last_val = 0; static uint8_t last_val = 0;
uint8_t cur; uint8_t cur;
uint8_t pressed; uint8_t pressed;
int inc = 1; int inc = 1;
cur = nesprobe(); cur = nesprobe();
pressed = (last_val ^ cur) & cur; pressed = (last_val ^ cur) & cur;
last_val = cur; last_val = cur;
@ -185,9 +188,9 @@ update_controller()
state = JAM; state = JAM;
jam_clock = jam_duration; jam_clock = jam_duration;
} }
if ((pressed & BTN_B) && ((state != LINEUP) || (jam_clock == 0))) { if ((pressed & BTN_B) && ((state != LINEUP) || (jam_clock == 0))) {
state = LINEUP; state = LINEUP;
jam_clock = lineup_duration; jam_clock = lineup_duration;
} }
@ -195,7 +198,7 @@ update_controller()
state = TIMEOUT; state = TIMEOUT;
jam_clock = 1; jam_clock = 1;
} }
if (cur & BTN_SELECT) { if (cur & BTN_SELECT) {
inc = -1; inc = -1;
@ -205,7 +208,7 @@ update_controller()
if (pressed & BTN_LEFT) { if (pressed & BTN_LEFT) {
score_a += inc; score_a += inc;
} }
if (pressed & BTN_RIGHT) { if (pressed & BTN_RIGHT) {
score_b += inc; score_b += inc;
} }
@ -223,7 +226,7 @@ setup()
{ {
int i; int i;
// Datasheet says you have to do this before DC initialization. // TLC5941 datasheet says you have to do this before DC initialization.
// In practice it doesn't seem to matter, but what the hey. // In practice it doesn't seem to matter, but what the hey.
draw(); draw();
@ -244,28 +247,29 @@ loop()
if (tick) { if (tick) {
tick = false; tick = false;
update_controller();
if (jiffies % 66 == 0) { update_controller();
if (jiffies % 10 == 0) {
PORTB ^= 0xff; PORTB ^= 0xff;
} }
if (jiffies % (JIFFIES_PER_SECOND / 10) == 0) {
if (jiffies == 0) {
switch (state) { switch (state) {
case SETUP: case SETUP:
break; break;
case JAM: case JAM:
case LINEUP: case LINEUP:
if (period_clock) { if (period_clock) {
period_clock += 1; period_clock += 1;
} }
// fall through // fall through
case TIMEOUT: case TIMEOUT:
if (jam_clock) { if (jam_clock) {
jam_clock += 1; jam_clock += 1;
} }
} }
draw(); draw();
} }
} }
@ -281,6 +285,3 @@ main(void)
} }
return 0; return 0;
} }

34
ti.c
View File

@ -1,34 +0,0 @@
#include <stdbool.h>
#include <stdint.h>
#include "ti.h"
extern volatile bool tick;
extern volatile uint32_t jiffies;
// Count microseconds
volatile uint32_t micros = 0;
// Interrupt called every 1024 µs
__attribute__((interrupt(TIMER0_A0_VECTOR)))
void
timer_a(void)
{
tick = true;
jiffies += 1;
}
void
init()
{
WDTCTL = WDTPW + WDTHOLD; // Disable Watchdog Timer
P1DIR = ~(_BV(NESOUT));
P1OUT = 0;
CCTL0 |= CCIE; // Trigger interrupt on A checkpoint
TACTL = TASSEL_2 + MC_1; // Set timer A to SMCLCK, up mode
TACCR0 = 0x4444; // Interrupt 60 times per second
__enable_interrupt();
}

28
ti.h
View File

@ -1,28 +0,0 @@
#ifndef TI_H
#define TI_H
#include <stdint.h>
#include <msp430.h>
#define _BV(x) (1 << x)
#define JIFFIES_PER_SECOND 60
#define bit(pin, bit, on) pin = (on ? (pin | bit) : (pin & ~bit))
#define mode(on) bit(P1OUT, _BV(0), on)
#define sin(on) bit(P1OUT, _BV(1), on)
#define sclk(on) bit(P1OUT, _BV(2), on)
#define xlat(on) bit(P1OUT, _BV(3), on)
// Connect GSCLK to SCLK
// Connect BLANK to XLAT
// TRUST ME, THIS TOTALLY WORKS
#define NESOUT 6
#define nesclk(on) bit(P1OUT, _BV(4), on)
#define nesltch(on) bit(P1OUT, _BV(5), on)
#define nesout() ((P1IN & _BV(NESOUT)) << NESOUT)
void init();
#endif