/* 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 }