/*
MeggyJr.cpp - Meggy Jr RGB library for Arduino
Version 1.4 - 4/17/2010
Copyright (c) 2010 Windell H. Oskay. All right reserved.
This library is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library. If not, see .
Thanks to Arthur J. Dahm III and Jay Clegg for code written for the Peggy 2.0,
which was adapted to make this library.
*/
/******************************************************************************
* Includes
******************************************************************************/
extern "C" {
#include
#include
#include
//#include
}
#include "MeggyJr.h"
byte MeggyJr::MeggyFrame[DISP_BUFFER_SIZE];
byte MeggyJr::AuxLEDs;
byte MeggyJr::SoundAllowed;
byte MeggyJr::SoundEnabled;
byte MeggyJr::currentCol;
byte MeggyJr::currentBrightness;
byte* MeggyJr::currentColPtr;
//unsigned long MeggyJr::SoundStopTime;
unsigned int MeggyJr::ToneTimeRemaining;
#ifdef timingtest
unsigned int MeggyJr::testTime;
#endif
/******************************************************************************
* Constructor
******************************************************************************/
MeggyJr::MeggyJr(void)
{
// Initialization routine for Meggy Jr RGB hardware
AuxLEDs = 0;
currentColPtr = MeggyFrame;
currentCol=0;
currentBrightness=0;
PORTC = 255U; // Pull-ups on Port C (for detecting button presses)
DDRC = 0; //All inputs
DDRD = 254U; // All D Output except for Rx
PORTD = 254U;
DDRB = 63U;
PORTB = 255;
//If a button is pressed at startup, turn sound off.
if ((PINC & 63) != 63)
{
SoundAllowed = 0;
}
else
{
SoundAllowed = 1;
}
SoundEnabled = 0;
MeggyJr::ToneTimeRemaining = 0;
//Turn display off:
PORTD |= 252U;
PORTB |= 17U;
ClearMeggy();
SPSR = (1<> 3) / 8 / 15 / FPS; // Frames per second * 15 passes for brightness * 8 rows
TIMSK2 = (1<= MAX_BRIGHTNESS)
{
MeggyJr::currentBrightness = 0;
if (++MeggyJr::currentCol > 7)
{
MeggyJr::currentCol = 0;
MeggyJr::currentColPtr = MeggyJr::MeggyFrame;
}
else
MeggyJr::currentColPtr += 24;
if (MeggyJr::ToneTimeRemaining > 0)
{
if (--MeggyJr::ToneTimeRemaining == 0)
{
TCCR1A = 0;
DDRB &= 253;
PORTB |= 2;
TCCR1B = 0; // High bit flags that the sound is done.
}
}
}
//////////////////// Parse a row of data and write out the bits via spi
byte *ptr = MeggyJr::currentColPtr + 23; // it is more convenient to work from right to left
byte p;
byte cb = MeggyJr::currentBrightness;
// Optimization: interleave waiting for SPI with other code, so the CPU can do something useful
// when waiting for each SPI transmission to complete
//Turn display off:
PORTD |= 252U;
PORTB |= 17U;
SPCR = 80;// i.e., (1 << SPE) | ( 1 << MSTR );
// First SPI word: Aux LED drive. Zero, except once per full screen redraw.
if ((cb + MeggyJr::currentCol ) == 0)
SPDR = MeggyJr::AuxLEDs;
else
SPDR = 0;
byte bits=0;
p = *ptr--;
if (p > cb)
bits |= 128;
p = *ptr--;
if (p > cb)
bits |= 64;
p = *ptr--;
if (p > cb)
bits |= 32;
p = *ptr--;
if (p > cb)
bits |= 16;
p = *ptr--;
if (p > cb)
bits |= 8;
p = *ptr--;
if (p > cb)
bits |= 4;
p = *ptr--;
if (p > cb)
bits |= 2;
p = *ptr--;
if (p > cb)
bits |= 1;
// while (!(SPSR & (1< cb)
bits |= 128;
p = *ptr--;
if (p > cb)
bits |= 64;
p = *ptr--;
if (p > cb)
bits |= 32;
p = *ptr--;
if (p > cb)
bits |= 16;
p = *ptr--;
if (p > cb)
bits |= 8;
p = *ptr--;
if (p > cb)
bits |= 4;
p = *ptr--;
if (p > cb)
bits |= 2;
p = *ptr--;
if (p > cb)
bits |= 1;
// while (!(SPSR & (1< cb)
bits |= 128;
p = *ptr--;
if (p > cb)
bits |= 64;
p = *ptr--;
if (p > cb)
bits |= 32;
p = *ptr--;
if (p > cb)
bits |= 16;
p = *ptr--;
if (p > cb)
bits |= 8;
p = *ptr--;
if (p > cb)
bits |= 4;
p = *ptr--;
if (p > cb)
bits |= 2;
p = *ptr--;
if (p > cb)
bits |= 1;
//asm("nop"); // short delay
while (!(SPSR & (1< 1)
PORTD &= portdTemp;
else
PORTB &= portbTemp;
PORTB &= 251; //End Latch Pulse
SPCR = 0; //turn off spi
#ifdef timingtest
if (TCNT1 > MeggyJr::testTime)
MeggyJr::testTime = TCNT1;
OCR1A = soundTemp;
#endif
}