Lab_interaccio/2012/Ecuavoley/Ecuavoley.ino

230 lines
7.7 KiB
Arduino
Raw Permalink Normal View History

2025-02-25 21:29:42 +01:00
#include "TimerOne.h"
// Serial data transfer rate
#define BAUD 115200
//TLC5940NT pin definitions
#define VPRG 2
#define SIN 11 // MOSI - Hardware SPI, can't be changed
#define SCLK 13 // SCK - Hardware SPI, can't be changed
#define XLAT 4
#define BLANK 5
#define DCPRG 6
#define GSCLK 7
/* These pins are from the Hardware SPI, but aren't connected to the TLC5940
These definitions are only here for clarity, and aren't used. MISO can not
be used for anything else, while SS can be used for any OUTPUT. It can NOT
be used for an input. Currently, it is used for INCLOCKPIN, the 165's clock
pin setting.
*/
//#define MISO 12 //MISO - Hardware SPI, can't be changed (not connected, can't be used for anything other than MISO)
//#define SS 10 //SS - Hardware SPI, not used and therefore can be used for something else, but ONLY AS AN OUTPUT!!
// Pin definitions for the 74HC164 SIPO shift register (drives button rows high)
#define DATAPIN 16 // aka analog pin 2 (what, you didn't know that analog pins 0-5 are also digital pins 14-19? Well, now you do!)
#define CLOCKPIN 3
// Keyboard times
#define KEY_DEBOUNCE_TIME 100 // debounce time (ms) to prevent flickering when pressing or releasing the button
#define KEY_HOLD_TIME 400 // holding period (ms) how long to wait for press+hold event
/*This is the mapping of the physical position of the boards to the correct
output of the TLC5940s. The left halves are rotated to correspond to the
orientation of the boards*/
const byte remap[64] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 15,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 };
// Holds the current colour level for each of the buttons
int level[64] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
byte puntos_local = 0;
byte puntos_visitante = 0;
byte sets_local = 0;
byte sets_visitante = 0;
const byte remap_puntos_local[16] = { 63, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0};
const byte remap_sets_local[4] = { 63, 32, 33, 34 };
const byte remap_puntos_visitante[16] = {63, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62};
const byte remap_sets_visitante[4] = { 63, 35, 36, 37 };
boolean flag_local = false;
boolean flag_visitante = false;
// For interrupt timing; needed only to do intermediate clock speeds
/* Divide interrupt frequency by a factor of FREQ. It is preferable to keep
FREQ as small as possible, and control the frequency of the interrupts
using the hardware clock. Setting it to 1 disables this entirely, which,
if it works, is ideal; this should be the same as commenting out the
"#define FREQ" statement entirely.
*/
void timerIsr()
{
makemagic();
}
// Transfer a character out over hardware SPI
char spi_transfer(volatile byte data)
{
SPDR = data; // Start the transmission
while (!(SPSR & (1<<SPIF))) // Wait the end of the transmission
{
};
return SPDR; // return the received byte
}
// Run this animation once at startup. Currently unfinished.
void startup(){
for(byte x = 0; x < 64; ++x){
level[remap[x]] = 4095;
}
}
void setup() {
//Setup data directions, and set everything to the correct initial levels,
// For TLC5940
DDRC |= B00100011; //Configuracion como pines de salida de los pines del puerto C
asm("cbi 0x08,5"); //pone a 0 el bit 5 del puerto C
pinMode(VPRG, OUTPUT);
pinMode(SIN, OUTPUT);
pinMode(SCLK, OUTPUT);
pinMode(XLAT, OUTPUT);
pinMode(BLANK, OUTPUT);
pinMode(DCPRG, OUTPUT);
pinMode(GSCLK, OUTPUT);
pinMode(MISO, INPUT);
pinMode(SS,OUTPUT);
pinMode(17, INPUT);
pinMode(18, INPUT);
digitalWrite(SS,HIGH); //disable device
digitalWrite(SIN, LOW);
digitalWrite(SCLK, LOW);
digitalWrite(XLAT, LOW);
digitalWrite(VPRG, LOW);
digitalWrite(BLANK, HIGH);
digitalWrite(GSCLK, HIGH);
digitalWrite(DCPRG, LOW); // USE EEPROM DC register if LOW
digitalWrite(17, HIGH);
digitalWrite(18, HIGH);
//Setup the Hardware SPI registers
// SPCR = 01010000
//interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
//sample on leading edge of clk,system clock/4 (fastest)
byte clr;
SPCR = (1<<SPE)|(1<<MSTR);
clr=SPSR;
clr=SPDR;
delay(10);
Timer1.initialize(4000); // set a timer of length 1000000 microseconds (or 1 sec - or 1Hz)
Timer1.attachInterrupt( timerIsr ); // attach the service routine here
// Start the serial port
Serial.begin(BAUD);
delay(10);
Serial.println("Reset!!");
//startup();
}
void loop () {
checkButtons();
}
void makemagic(){
setGreys();
feedPorts();
}
void setGreys() {
asm("sbi 0x0B,5"); //pone a 1 el bit 5 del puerto D (BLANK)
asm("cbi 0x0B,4"); //pone a 0 el bit 4 del puerto D (XLAT)
for(int i = 31; i>=0; i--){
spi_transfer( (level[2*i+1] & 0x0FF0) >> 4 );
spi_transfer( ((level[2*i+1] & 0xF) << 4) | ((level[2*i] & 0x0F00) >> 8) );
spi_transfer( level[2*i] & 0xFF);
}
asm("sbi 0x0B,4"); //pone a 1 el bit 4 del puerto D (XLAT)
asm("cbi 0x0B,4"); //pone a 0 el bit 4 del puerto D (XLAT)
asm("cbi 0x0B,5"); //pone a 0 el bit 5 del puerto D (BLANK)
}
void feedPorts() {
// Clock for TLC5940's PWM
asm("sbi 0x0B,5"); //pone a 1 el bit 5 del puerto D (BLANK)
asm("cbi 0x0B,5"); //pone a 0 el bit 5 del puerto D (BLANK)
for (int i=0; i<4096; i++) {
asm("sbi 0x0B,7"); //pone a 1 el bit 1 del puerto D (GSCLK)
asm("cbi 0x0B,7"); //pone a 0 el bit 1 del puerto D (GSCLK)
}
}
void checkButtons(){
if ((!digitalRead(18))&&(!flag_local))
{
flag_local=true;
if ((sets_local>2)||(sets_visitante>2))
{
sets_local = 0;
sets_visitante = 0;
puntos_visitante = 0;
puntos_local = 0;
for (int i=0; i<16; i++) level[remap_sets_local[i]] = 0;
for (int i=0; i<4; i++) level[remap_sets_visitante[i]] = 0;
for (int i=0; i<16; i++) level[remap_puntos_visitante[i]] = 0;
for (int i=0; i<16; i++) level[remap_puntos_local[i]] = 0;
}
puntos_local++;
if (puntos_local>15)
{
puntos_local = 0;
puntos_visitante = 0;
for (int i=0; i<16; i++) level[remap_puntos_local[i]] = 0;
for (int i=0; i<16; i++) level[remap_puntos_visitante[i]] = 0;
sets_local++;
}
level[remap_puntos_local[puntos_local]] = 4095;
level[remap_sets_local[sets_local]] = 4095;
delay(100);
} if ((digitalRead(18))&&(flag_local)) flag_local=false;
if ((!digitalRead(17))&&(!flag_visitante))
{
flag_visitante=true;
if ((sets_local>2)||(sets_visitante>2))
{
sets_visitante = 0;
sets_local = 0;
puntos_local = 0;
puntos_visitante = 0;
for (int i=0; i<16; i++) level[remap_sets_visitante[i]] = 0;
for (int i=0; i<4; i++) level[remap_sets_local[i]] = 0;
for (int i=0; i<16; i++) level[remap_puntos_local[i]] = 0;
for (int i=0; i<16; i++) level[remap_puntos_visitante[i]] = 0;
}
puntos_visitante++;
if (puntos_visitante>15)
{
puntos_visitante = 0;
puntos_local = 0;
for (int i=0; i<16; i++) level[remap_puntos_visitante[i]] = 0;
for (int i=0; i<16; i++) level[remap_puntos_local[i]] = 0;
sets_visitante++;
}
level[remap_puntos_visitante[puntos_visitante]] = 4095;
level[remap_sets_visitante[sets_visitante]] = 4095;
delay(100);
} if ((digitalRead(17))&&(flag_visitante)) flag_visitante=false;
}
//boolean flag_local = false;
//boolean flag_visitante = false;