diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/README.md b/README.md index 81e4e52..ecb615d 100644 --- a/README.md +++ b/README.md @@ -5,13 +5,41 @@ IJduino * Atmega328 * Button +http://ijhack.nl/project/ijduino + https://pad.ijhack.nl/p/ijduino -https://pad.ijhack.nl/p/20-projects-20-euro +https://github.com/IJHack/ijduino/blob/master/documentation/ijduino.pdf?raw=true Installing ---------- -Create a folder "ijduino" in the "variants" folder of the Arduino IDE and copy the file "pins_arduino.h" from the "hardware" folder there. +**Just copy the "hardware" and "libraries" folders into your "Arduino" sketches folder.** + +On most Linux and BSD this will be in your home folder. +``` +cp -r hardware ~/Arduino/ +cp -r libraries ~/Arduino/ +``` +On Mac OS X it's in the "Documents" folder. +``` +cp -r hardware ~/Documents/Arduino/ +cp -r libraries ~/Documents/Arduino/ +``` +On Windows you can find the "Arduino" folder inside your "My Documents" folder. + +USB-ASP Programmer +------------------ + +On Linux you probably need to add a udev rule to get this working. +Place the following at `/etc/udev/rules.d/99-usbasp.rules` + +``` +SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05dc", GROUP="users", MODE="0666" +``` +Then run `udevadm trigger` to reload the udev rules. + -Add the text from the "boards.txt" file in the "hardware" folder to the "boards.txt" file in the Arduino IDE. +Creating Animations +------------------- +http://ijhack.nl/page/led-matrix-generator diff --git a/documentation/INSTALL.md b/documentation/INSTALL.md new file mode 100644 index 0000000..8bdd20f --- /dev/null +++ b/documentation/INSTALL.md @@ -0,0 +1,28 @@ +Installing +---------- + +**Just copy the "hardware" and "libraries" folders into your "Arduino" sketches folder.** + +On most Linux and BSD this will be in your home folder. +``` +cp -r hardware ~/Arduino/ +cp -r libraries ~/Arduino/ +``` +On Mac OS X it's in the "Documents" folder. +``` +cp -r hardware ~/Documents/Arduino/ +cp -r libraries ~/Documents/Arduino/ +``` +On Windows you can find the "Arduino" folder inside your "My Documents" folder. + +USB-ASP Programmer +------------------ + +On Linux probably need to add a udev rule to get this working. +Place the following at `/etc/udev/rules.d/99-usbasp.rules` + +``` +SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05dc", GROUP="users", MODE="0666" +``` +Then run `udevadm trigger` to reload the udev rules. + diff --git a/documentation/ijduino.pdf b/documentation/ijduino.pdf new file mode 100644 index 0000000..a5d7c5b Binary files /dev/null and b/documentation/ijduino.pdf differ diff --git a/documentation/src/ijduino-kit-jinx.png b/documentation/src/ijduino-kit-jinx.png new file mode 100644 index 0000000..8f00b80 Binary files /dev/null and b/documentation/src/ijduino-kit-jinx.png differ diff --git a/documentation/src/ijduino-kit-jinx.xcf b/documentation/src/ijduino-kit-jinx.xcf new file mode 100644 index 0000000..213d781 Binary files /dev/null and b/documentation/src/ijduino-kit-jinx.xcf differ diff --git a/documentation/src/ijduino.odt b/documentation/src/ijduino.odt new file mode 100644 index 0000000..b1a1c48 Binary files /dev/null and b/documentation/src/ijduino.odt differ diff --git a/documentation/src/ijduino_bb.png b/documentation/src/ijduino_bb.png new file mode 100644 index 0000000..d4e2fe7 Binary files /dev/null and b/documentation/src/ijduino_bb.png differ diff --git a/documentation/src/ijduino_lol.png b/documentation/src/ijduino_lol.png new file mode 100644 index 0000000..29588bc Binary files /dev/null and b/documentation/src/ijduino_lol.png differ diff --git a/documentation/src/ijduino_minimal.png b/documentation/src/ijduino_minimal.png new file mode 100644 index 0000000..bc927b3 Binary files /dev/null and b/documentation/src/ijduino_minimal.png differ diff --git a/documentation/src/ijduino_sensors.png b/documentation/src/ijduino_sensors.png new file mode 100644 index 0000000..77c4af4 Binary files /dev/null and b/documentation/src/ijduino_sensors.png differ diff --git a/documentation/src/ijduino_sensors.xcf b/documentation/src/ijduino_sensors.xcf new file mode 100644 index 0000000..4f147fa Binary files /dev/null and b/documentation/src/ijduino_sensors.xcf differ diff --git a/documentation/src/ijduino_test_shoop.png b/documentation/src/ijduino_test_shoop.png new file mode 100644 index 0000000..bc9a1c8 Binary files /dev/null and b/documentation/src/ijduino_test_shoop.png differ diff --git a/documentation/src/ijduino_test_shoop.xcf b/documentation/src/ijduino_test_shoop.xcf new file mode 100644 index 0000000..0bc208d Binary files /dev/null and b/documentation/src/ijduino_test_shoop.xcf differ diff --git a/documentation/src/ijduino_wireup.png b/documentation/src/ijduino_wireup.png new file mode 100644 index 0000000..e3ddbae Binary files /dev/null and b/documentation/src/ijduino_wireup.png differ diff --git a/documentation/src/ijduino_wireup.xcf b/documentation/src/ijduino_wireup.xcf new file mode 100644 index 0000000..fa1633f Binary files /dev/null and b/documentation/src/ijduino_wireup.xcf differ diff --git a/documentation/src/ijphone.jpg b/documentation/src/ijphone.jpg new file mode 100644 index 0000000..b7b3c9c Binary files /dev/null and b/documentation/src/ijphone.jpg differ diff --git a/hardware/boards.txt b/hardware/ijhack/avr/boards.txt similarity index 83% rename from hardware/boards.txt rename to hardware/ijhack/avr/boards.txt index 92d659e..1c63350 100644 --- a/hardware/boards.txt +++ b/hardware/ijhack/avr/boards.txt @@ -1,6 +1,6 @@ ############################################################## -ijduino.name=IJduino (ATmega328 MHz internal) +ijduino.name=IJduino (ATmega328 8 MHz internal) ijduino.upload.protocol=stk500 ijduino.upload.maximum_size=30720 @@ -19,3 +19,6 @@ ijduino.build.f_cpu=8000000L ijduino.build.core=arduino ijduino.build.variant=ijduino +ijduino.bootloader.tool=avrdude +ijduino.upload.tool=avrdude + diff --git a/hardware/ijhack/avr/bootloaders/ATmegaBOOT_168_atmega328_pro_8MHz.hex b/hardware/ijhack/avr/bootloaders/ATmegaBOOT_168_atmega328_pro_8MHz.hex new file mode 100644 index 0000000..9753e2e --- /dev/null +++ b/hardware/ijhack/avr/bootloaders/ATmegaBOOT_168_atmega328_pro_8MHz.hex @@ -0,0 +1,124 @@ +:107800000C94343C0C94513C0C94513C0C94513CE1 +:107810000C94513C0C94513C0C94513C0C94513CB4 +:107820000C94513C0C94513C0C94513C0C94513CA4 +:107830000C94513C0C94513C0C94513C0C94513C94 +:107840000C94513C0C94513C0C94513C0C94513C84 +:107850000C94513C0C94513C0C94513C0C94513C74 +:107860000C94513C0C94513C11241FBECFEFD8E036 +:10787000DEBFCDBF11E0A0E0B1E0EAE8FFE702C063 +:1078800005900D92A230B107D9F712E0A2E0B1E065 +:1078900001C01D92AD30B107E1F70E942D3D0C945F +:1078A000C33F0C94003C982F95959595959595958B +:1078B000905D8F708A307CF0282F295A8091C0000B +:1078C00085FFFCCF9093C6008091C00085FFFCCF60 +:1078D0002093C6000895282F205DF0CF982F809127 +:1078E000C00085FFFCCF9093C6000895EF92FF92F1 +:1078F0000F931F93EE24FF2487018091C00087FD22 +:1079000017C00894E11CF11C011D111D81E2E8164D +:1079100081EAF80687E0080780E0180770F3E09135 +:107920000401F091050109958091C00087FFE9CF1E +:107930008091C6001F910F91FF90EF9008950E94D3 +:10794000763C982F8091C00085FFFCCF9093C600B5 +:1079500091362CF490330CF09053892F089597555D +:10796000892F08951F930E949F3C182F0E949F3CCF +:107970001295107F810F1F9108951F93182F882350 +:1079800021F00E94763C1150E1F71F9108951F935A +:10799000182F0E94763C803249F0809103018F5F5E +:1079A000809303018530C1F01F9108958091C0003C +:1079B00085FFFCCF84E18093C6008091C00085FFE5 +:1079C000FCCF1093C6008091C00085FFFCCF80E102 +:1079D0008093C6001F910895E0910401F091050184 +:1079E00009951F9108950E94763C803241F0809164 +:1079F00003018F5F80930301853081F008958091AA +:107A0000C00085FFFCCF84E18093C6008091C00058 +:107A100085FFFCCF80E18093C6000895E0910401CA +:107A2000F09105010995089548EC50E08823A1F0F4 +:107A30002D9A28EE33E0FA013197F1F721503040CA +:107A4000D1F72D9828EE33E0FA013197F1F7215064 +:107A50003040D1F7815061F708953F924F925F9285 +:107A60006F927F928F929F92AF92BF92CF92DF924E +:107A7000EF92FF920F931F93CF93DF93000082E06A +:107A80008093C00080E18093C4001092C50088E11B +:107A90008093C10086E08093C2005098589A259A3E +:107AA00081E00E94143D24E1F22E9EE1E92E85E959 +:107AB000D82E0FE0C02E10E1B12EAA24A394B1E479 +:107AC0009B2EA6E58A2EF2E57F2EE0E26E2E79E46B +:107AD000572E63E5462E50E5352E0E94763C8033C6 +:107AE000B1F18133B9F1803409F46FC0813409F404 +:107AF00076C0823409F485C0853409F488C08035A5 +:107B000031F1823521F1813511F1853509F485C0D6 +:107B1000863509F48DC0843609F496C0843709F49B +:107B200003C1853709F472C1863709F466C08091B4 +:107B300003018F5F80930301853079F6E0910401A2 +:107B4000F091050109950E94763C803351F60E9420 +:107B5000F33CC3CF0E94763C803249F78091C0004D +:107B600085FFFCCFF092C6008091C00085FFFCCF5E +:107B70009092C6008091C00085FFFCCF8092C60025 +:107B80008091C00085FFFCCF7092C6008091C0003C +:107B900085FFFCCF6092C6008091C00085FFFCCFBE +:107BA0005092C6008091C00085FFFCCF4092C60075 +:107BB0008091C00085FFFCCF3092C6008091C0004C +:107BC00085FFFCCFB092C60088CF0E94763C8638F5 +:107BD00008F4BDCF0E94763C0E94F33C7ECF0E9409 +:107BE000763C803809F49CC0813809F40BC1823896 +:107BF00009F430C1883909F48FC080E00E94C73C85 +:107C00006CCF84E10E94BD3C0E94F33C66CF85E0CE +:107C10000E94BD3C0E94F33C60CF0E94763C809362 +:107C200006010E94763C809307010E94F33C55CFE9 +:107C30000E94763C803309F411C183E00E94BD3C70 +:107C400080E00E94C73C49CF0E94763C80930902A5 +:107C50000E94763C8093080280910C028E7F809374 +:107C60000C020E94763C853409F409C18091080217 +:107C700090910902892B89F000E010E00E94763C87 +:107C8000F801E85FFE4F80830F5F1F4F809108026D +:107C9000909109020817190788F30E94763C8032F8 +:107CA00009F045CF80910C0280FFF5C0609106017C +:107CB00070910701660F771F7093070160930601AB +:107CC000A0910802B09109021097C9F0E8E0F1E034 +:107CD0009B01AD014E0F5F1FF999FECF32BD21BD53 +:107CE000819180BDFA9AF99A2F5F3F4FE417F5070B +:107CF00099F76A0F7B1F70930701609306018091CB +:107D0000C00085FFFCCFF092C6008091C00085FFC7 +:107D1000FCCFB092C600E1CE83E00E94C73CDDCE2E +:107D200082E00E94C73CD9CE0E94763C8093090233 +:107D30000E94763C80930802809106019091070191 +:107D4000880F991F90930701809306010E94763C4B +:107D5000853409F49AC080910C028E7F80930C02C6 +:107D60000E94763C803209F0B8CE8091C00085FF39 +:107D7000FCCFF092C600A0910802B09109021097C2 +:107D8000C1F180910C02082F0170182F1695117007 +:107D9000E0910601F0910701AF014F5F5F4FBA011B +:107DA00020E030E00023B1F4112339F49491809164 +:107DB000C00085FFFCCF9093C6002F5F3F4FCB01E3 +:107DC0000196FA012A173B0780F4BC014F5F5F4F11 +:107DD000002351F3F999FECFF2BDE1BDF89A90B5B9 +:107DE0008091C00085FFFCCFE6CF709307016093C0 +:107DF00006018091C00085FDE5CE8091C00085FF21 +:107E0000F8CFE0CE81E00E94C73C67CE0E94763C6E +:107E1000803209F08CCE8091C00085FFFCCFF092BB +:107E2000C6008091C00085FFFCCFE092C600809123 +:107E3000C00085FFFCCFD092C6008091C00085FFB6 +:107E4000FCCFC092C6008091C00085FFFCCFB092ED +:107E5000C60043CE80E10E94C73C3FCE0E94763CE4 +:107E60000E94763C182F0E94763C112309F483C0AF +:107E7000113009F484C08FE00E94C73C2ECE80915F +:107E80000C02816080930C02F1CE80910C02816023 +:107E900080930C0265CF809107018823880F880B9F +:107EA0008A2180930B028091060190910701880F2F +:107EB000991F90930701809306018091080280FF2B +:107EC00009C08091080290910902019690930902DD +:107ED00080930802F894F999FECF1127E0910601EA +:107EE000F0910701C8E0D1E0809108029091090269 +:107EF000103091F40091570001700130D9F303E084 +:107F000000935700E8950091570001700130D9F3B4 +:107F100001E100935700E8950990199000915700EE +:107F200001700130D9F301E000935700E8951395F3 +:107F3000103498F011270091570001700130D9F3E7 +:107F400005E000935700E89500915700017001305B +:107F5000D9F301E100935700E8953296029709F0B2 +:107F6000C7CF103011F00296E5CF11248091C000E8 +:107F700085FFC5CEC8CE8EE10E94C73CAECD85E957 +:0A7F80000E94C73CAACDF894FFCF81 +:027F8A00800075 +:040000030000780081 +:00000001FF diff --git a/hardware/ijhack/avr/bootloaders/atmega/ATmegaBOOT_168.c b/hardware/ijhack/avr/bootloaders/atmega/ATmegaBOOT_168.c new file mode 100644 index 0000000..880cf9b --- /dev/null +++ b/hardware/ijhack/avr/bootloaders/atmega/ATmegaBOOT_168.c @@ -0,0 +1,1054 @@ +/**********************************************************/ +/* Serial Bootloader for Atmel megaAVR Controllers */ +/* */ +/* tested with ATmega8, ATmega128 and ATmega168 */ +/* should work with other mega's, see code for details */ +/* */ +/* ATmegaBOOT.c */ +/* */ +/* */ +/* 20090308: integrated Mega changes into main bootloader */ +/* source by D. Mellis */ +/* 20080930: hacked for Arduino Mega (with the 1280 */ +/* processor, backwards compatible) */ +/* by D. Cuartielles */ +/* 20070626: hacked for Arduino Diecimila (which auto- */ +/* resets when a USB connection is made to it) */ +/* by D. Mellis */ +/* 20060802: hacked for Arduino by D. Cuartielles */ +/* based on a previous hack by D. Mellis */ +/* and D. Cuartielles */ +/* */ +/* Monitor and debug functions were added to the original */ +/* code by Dr. Erik Lins, chip45.com. (See below) */ +/* */ +/* Thanks to Karl Pitrich for fixing a bootloader pin */ +/* problem and more informative LED blinking! */ +/* */ +/* For the latest version see: */ +/* http://www.chip45.com/ */ +/* */ +/* ------------------------------------------------------ */ +/* */ +/* based on stk500boot.c */ +/* Copyright (c) 2003, Jason P. Kyle */ +/* All rights reserved. */ +/* see avr1.org for original file and information */ +/* */ +/* This program 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 2 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* This program 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 program; if not, write */ +/* to the Free Software Foundation, Inc., */ +/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/* */ +/* Licence can be viewed at */ +/* http://www.fsf.org/licenses/gpl.txt */ +/* */ +/* Target = Atmel AVR m128,m64,m32,m16,m8,m162,m163,m169, */ +/* m8515,m8535. ATmega161 has a very small boot block so */ +/* isn't supported. */ +/* */ +/* Tested with m168 */ +/**********************************************************/ + +/* $Id$ */ + + +/* some includes */ +#include +#include +#include +#include +#include +#include + +/* the current avr-libc eeprom functions do not support the ATmega168 */ +/* own eeprom write/read functions are used instead */ +#if !defined(__AVR_ATmega168__) || !defined(__AVR_ATmega328P__) +#include +#endif + +/* Use the F_CPU defined in Makefile */ + +/* 20060803: hacked by DojoCorp */ +/* 20070626: hacked by David A. Mellis to decrease waiting time for auto-reset */ +/* set the waiting time for the bootloader */ +/* get this from the Makefile instead */ +/* #define MAX_TIME_COUNT (F_CPU>>4) */ + +/* 20070707: hacked by David A. Mellis - after this many errors give up and launch application */ +#define MAX_ERROR_COUNT 5 + +/* set the UART baud rate */ +/* 20060803: hacked by DojoCorp */ +//#define BAUD_RATE 115200 +#ifndef BAUD_RATE +#define BAUD_RATE 19200 +#endif + + +/* SW_MAJOR and MINOR needs to be updated from time to time to avoid warning message from AVR Studio */ +/* never allow AVR Studio to do an update !!!! */ +#define HW_VER 0x02 +#define SW_MAJOR 0x01 +#define SW_MINOR 0x10 + + +/* Adjust to suit whatever pin your hardware uses to enter the bootloader */ +/* ATmega128 has two UARTS so two pins are used to enter bootloader and select UART */ +/* ATmega1280 has four UARTS, but for Arduino Mega, we will only use RXD0 to get code */ +/* BL0... means UART0, BL1... means UART1 */ +#ifdef __AVR_ATmega128__ +#define BL_DDR DDRF +#define BL_PORT PORTF +#define BL_PIN PINF +#define BL0 PINF7 +#define BL1 PINF6 +#elif defined __AVR_ATmega1280__ +/* we just don't do anything for the MEGA and enter bootloader on reset anyway*/ +#else +/* other ATmegas have only one UART, so only one pin is defined to enter bootloader */ +#define BL_DDR DDRD +#define BL_PORT PORTD +#define BL_PIN PIND +#define BL PIND6 +#endif + + +/* onboard LED is used to indicate, that the bootloader was entered (3x flashing) */ +/* if monitor functions are included, LED goes on after monitor was entered */ +#if defined __AVR_ATmega128__ || defined __AVR_ATmega1280__ +/* Onboard LED is connected to pin PB7 (e.g. Crumb128, PROBOmega128, Savvy128, Arduino Mega) */ +#define LED_DDR DDRB +#define LED_PORT PORTB +#define LED_PIN PINB +#define LED PINB7 +#else +/* Onboard LED is connected to pin PB5 in Arduino NG, Diecimila, and Duomilanuove */ +/* other boards like e.g. Crumb8, Crumb168 are using PB2 */ +#define LED_DDR DDRB +#define LED_PORT PORTB +#define LED_PIN PINB +#define LED PINB5 +#endif + + +/* monitor functions will only be compiled when using ATmega128, due to bootblock size constraints */ +#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) +#define MONITOR 1 +#endif + + +/* define various device id's */ +/* manufacturer byte is always the same */ +#define SIG1 0x1E // Yep, Atmel is the only manufacturer of AVR micros. Single source :( + +#if defined __AVR_ATmega1280__ +#define SIG2 0x97 +#define SIG3 0x03 +#define PAGE_SIZE 0x80U //128 words + +#elif defined __AVR_ATmega1281__ +#define SIG2 0x97 +#define SIG3 0x04 +#define PAGE_SIZE 0x80U //128 words + +#elif defined __AVR_ATmega128__ +#define SIG2 0x97 +#define SIG3 0x02 +#define PAGE_SIZE 0x80U //128 words + +#elif defined __AVR_ATmega64__ +#define SIG2 0x96 +#define SIG3 0x02 +#define PAGE_SIZE 0x80U //128 words + +#elif defined __AVR_ATmega32__ +#define SIG2 0x95 +#define SIG3 0x02 +#define PAGE_SIZE 0x40U //64 words + +#elif defined __AVR_ATmega16__ +#define SIG2 0x94 +#define SIG3 0x03 +#define PAGE_SIZE 0x40U //64 words + +#elif defined __AVR_ATmega8__ +#define SIG2 0x93 +#define SIG3 0x07 +#define PAGE_SIZE 0x20U //32 words + +#elif defined __AVR_ATmega88__ +#define SIG2 0x93 +#define SIG3 0x0a +#define PAGE_SIZE 0x20U //32 words + +#elif defined __AVR_ATmega168__ +#define SIG2 0x94 +#define SIG3 0x06 +#define PAGE_SIZE 0x40U //64 words + +#elif defined __AVR_ATmega328P__ +#define SIG2 0x95 +#define SIG3 0x0F +#define PAGE_SIZE 0x40U //64 words + +#elif defined __AVR_ATmega162__ +#define SIG2 0x94 +#define SIG3 0x04 +#define PAGE_SIZE 0x40U //64 words + +#elif defined __AVR_ATmega163__ +#define SIG2 0x94 +#define SIG3 0x02 +#define PAGE_SIZE 0x40U //64 words + +#elif defined __AVR_ATmega169__ +#define SIG2 0x94 +#define SIG3 0x05 +#define PAGE_SIZE 0x40U //64 words + +#elif defined __AVR_ATmega8515__ +#define SIG2 0x93 +#define SIG3 0x06 +#define PAGE_SIZE 0x20U //32 words + +#elif defined __AVR_ATmega8535__ +#define SIG2 0x93 +#define SIG3 0x08 +#define PAGE_SIZE 0x20U //32 words +#endif + + +/* function prototypes */ +void putch(char); +char getch(void); +void getNch(uint8_t); +void byte_response(uint8_t); +void nothing_response(void); +char gethex(void); +void puthex(char); +void flash_led(uint8_t); + +/* some variables */ +union address_union { + uint16_t word; + uint8_t byte[2]; +} address; + +union length_union { + uint16_t word; + uint8_t byte[2]; +} length; + +struct flags_struct { + unsigned eeprom : 1; + unsigned rampz : 1; +} flags; + +uint8_t buff[256]; +uint8_t address_high; + +uint8_t pagesz=0x80; + +uint8_t i; +uint8_t bootuart = 0; + +uint8_t error_count = 0; + +void (*app_start)(void) = 0x0000; + + +/* main program starts here */ +int main(void) +{ + uint8_t ch,ch2; + uint16_t w; + +#ifdef WATCHDOG_MODS + ch = MCUSR; + MCUSR = 0; + + WDTCSR |= _BV(WDCE) | _BV(WDE); + WDTCSR = 0; + + // Check if the WDT was used to reset, in which case we dont bootload and skip straight to the code. woot. + if (! (ch & _BV(EXTRF))) // if its a not an external reset... + app_start(); // skip bootloader +#else + asm volatile("nop\n\t"); +#endif + + /* set pin direction for bootloader pin and enable pullup */ + /* for ATmega128, two pins need to be initialized */ +#ifdef __AVR_ATmega128__ + BL_DDR &= ~_BV(BL0); + BL_DDR &= ~_BV(BL1); + BL_PORT |= _BV(BL0); + BL_PORT |= _BV(BL1); +#else + /* We run the bootloader regardless of the state of this pin. Thus, don't + put it in a different state than the other pins. --DAM, 070709 + This also applies to Arduino Mega -- DC, 080930 + BL_DDR &= ~_BV(BL); + BL_PORT |= _BV(BL); + */ +#endif + + +#ifdef __AVR_ATmega128__ + /* check which UART should be used for booting */ + if(bit_is_clear(BL_PIN, BL0)) { + bootuart = 1; + } + else if(bit_is_clear(BL_PIN, BL1)) { + bootuart = 2; + } +#endif + +#if defined __AVR_ATmega1280__ + /* the mega1280 chip has four serial ports ... we could eventually use any of them, or not? */ + /* however, we don't wanna confuse people, to avoid making a mess, we will stick to RXD0, TXD0 */ + bootuart = 1; +#endif + + /* check if flash is programmed already, if not start bootloader anyway */ + if(pgm_read_byte_near(0x0000) != 0xFF) { + +#ifdef __AVR_ATmega128__ + /* no UART was selected, start application */ + if(!bootuart) { + app_start(); + } +#else + /* check if bootloader pin is set low */ + /* we don't start this part neither for the m8, nor m168 */ + //if(bit_is_set(BL_PIN, BL)) { + // app_start(); + // } +#endif + } + +#ifdef __AVR_ATmega128__ + /* no bootuart was selected, default to uart 0 */ + if(!bootuart) { + bootuart = 1; + } +#endif + + + /* initialize UART(s) depending on CPU defined */ +#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) + if(bootuart == 1) { + UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1); + UBRR0H = (F_CPU/(BAUD_RATE*16L)-1) >> 8; + UCSR0A = 0x00; + UCSR0C = 0x06; + UCSR0B = _BV(TXEN0)|_BV(RXEN0); + } + if(bootuart == 2) { + UBRR1L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1); + UBRR1H = (F_CPU/(BAUD_RATE*16L)-1) >> 8; + UCSR1A = 0x00; + UCSR1C = 0x06; + UCSR1B = _BV(TXEN1)|_BV(RXEN1); + } +#elif defined __AVR_ATmega163__ + UBRR = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1); + UBRRHI = (F_CPU/(BAUD_RATE*16L)-1) >> 8; + UCSRA = 0x00; + UCSRB = _BV(TXEN)|_BV(RXEN); +#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) + +#ifdef DOUBLE_SPEED + UCSR0A = (1<> 8; +#else + UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1); + UBRR0H = (F_CPU/(BAUD_RATE*16L)-1) >> 8; +#endif + + UCSR0B = (1<>8; // set baud rate + UBRRL = (((F_CPU/BAUD_RATE)/16)-1); + UCSRB = (1<> 8; + UCSRA = 0x00; + UCSRC = 0x06; + UCSRB = _BV(TXEN)|_BV(RXEN); +#endif + +#if defined __AVR_ATmega1280__ + /* Enable internal pull-up resistor on pin D0 (RX), in order + to supress line noise that prevents the bootloader from + timing out (DAM: 20070509) */ + /* feature added to the Arduino Mega --DC: 080930 */ + DDRE &= ~_BV(PINE0); + PORTE |= _BV(PINE0); +#endif + + + /* set LED pin as output */ + LED_DDR |= _BV(LED); + + + /* flash onboard LED to signal entering of bootloader */ +#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) + // 4x for UART0, 5x for UART1 + flash_led(NUM_LED_FLASHES + bootuart); +#else + flash_led(NUM_LED_FLASHES); +#endif + + /* 20050803: by DojoCorp, this is one of the parts provoking the + system to stop listening, cancelled from the original */ + //putch('\0'); + + /* forever loop */ + for (;;) { + + /* get character from UART */ + ch = getch(); + + /* A bunch of if...else if... gives smaller code than switch...case ! */ + + /* Hello is anyone home ? */ + if(ch=='0') { + nothing_response(); + } + + + /* Request programmer ID */ + /* Not using PROGMEM string due to boot block in m128 being beyond 64kB boundry */ + /* Would need to selectively manipulate RAMPZ, and it's only 9 characters anyway so who cares. */ + else if(ch=='1') { + if (getch() == ' ') { + putch(0x14); + putch('A'); + putch('V'); + putch('R'); + putch(' '); + putch('I'); + putch('S'); + putch('P'); + putch(0x10); + } else { + if (++error_count == MAX_ERROR_COUNT) + app_start(); + } + } + + + /* AVR ISP/STK500 board commands DON'T CARE so default nothing_response */ + else if(ch=='@') { + ch2 = getch(); + if (ch2>0x85) getch(); + nothing_response(); + } + + + /* AVR ISP/STK500 board requests */ + else if(ch=='A') { + ch2 = getch(); + if(ch2==0x80) byte_response(HW_VER); // Hardware version + else if(ch2==0x81) byte_response(SW_MAJOR); // Software major version + else if(ch2==0x82) byte_response(SW_MINOR); // Software minor version + else if(ch2==0x98) byte_response(0x03); // Unknown but seems to be required by avr studio 3.56 + else byte_response(0x00); // Covers various unnecessary responses we don't care about + } + + + /* Device Parameters DON'T CARE, DEVICE IS FIXED */ + else if(ch=='B') { + getNch(20); + nothing_response(); + } + + + /* Parallel programming stuff DON'T CARE */ + else if(ch=='E') { + getNch(5); + nothing_response(); + } + + + /* P: Enter programming mode */ + /* R: Erase device, don't care as we will erase one page at a time anyway. */ + else if(ch=='P' || ch=='R') { + nothing_response(); + } + + + /* Leave programming mode */ + else if(ch=='Q') { + nothing_response(); +#ifdef WATCHDOG_MODS + // autoreset via watchdog (sneaky!) + WDTCSR = _BV(WDE); + while (1); // 16 ms +#endif + } + + + /* Set address, little endian. EEPROM in bytes, FLASH in words */ + /* Perhaps extra address bytes may be added in future to support > 128kB FLASH. */ + /* This might explain why little endian was used here, big endian used everywhere else. */ + else if(ch=='U') { + address.byte[0] = getch(); + address.byte[1] = getch(); + nothing_response(); + } + + + /* Universal SPI programming command, disabled. Would be used for fuses and lock bits. */ + else if(ch=='V') { + if (getch() == 0x30) { + getch(); + ch = getch(); + getch(); + if (ch == 0) { + byte_response(SIG1); + } else if (ch == 1) { + byte_response(SIG2); + } else { + byte_response(SIG3); + } + } else { + getNch(3); + byte_response(0x00); + } + } + + + /* Write memory, length is big endian and is in bytes */ + else if(ch=='d') { + length.byte[1] = getch(); + length.byte[0] = getch(); + flags.eeprom = 0; + if (getch() == 'E') flags.eeprom = 1; + for (w=0;w127) address_high = 0x01; //Only possible with m128, m256 will need 3rd address byte. FIXME + else address_high = 0x00; +#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__) + RAMPZ = address_high; +#endif + address.word = address.word << 1; //address * 2 -> byte location + /* if ((length.byte[0] & 0x01) == 0x01) length.word++; //Even up an odd number of bytes */ + if ((length.byte[0] & 0x01)) length.word++; //Even up an odd number of bytes + cli(); //Disable interrupts, just to be sure +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__) + while(bit_is_set(EECR,EEPE)); //Wait for previous EEPROM writes to complete +#else + while(bit_is_set(EECR,EEWE)); //Wait for previous EEPROM writes to complete +#endif + asm volatile( + "clr r17 \n\t" //page_word_count + "lds r30,address \n\t" //Address of FLASH location (in bytes) + "lds r31,address+1 \n\t" + "ldi r28,lo8(buff) \n\t" //Start of buffer array in RAM + "ldi r29,hi8(buff) \n\t" + "lds r24,length \n\t" //Length of data to be written (in bytes) + "lds r25,length+1 \n\t" + "length_loop: \n\t" //Main loop, repeat for number of words in block + "cpi r17,0x00 \n\t" //If page_word_count=0 then erase page + "brne no_page_erase \n\t" + "wait_spm1: \n\t" + "lds r16,%0 \n\t" //Wait for previous spm to complete + "andi r16,1 \n\t" + "cpi r16,1 \n\t" + "breq wait_spm1 \n\t" + "ldi r16,0x03 \n\t" //Erase page pointed to by Z + "sts %0,r16 \n\t" + "spm \n\t" +#ifdef __AVR_ATmega163__ + ".word 0xFFFF \n\t" + "nop \n\t" +#endif + "wait_spm2: \n\t" + "lds r16,%0 \n\t" //Wait for previous spm to complete + "andi r16,1 \n\t" + "cpi r16,1 \n\t" + "breq wait_spm2 \n\t" + + "ldi r16,0x11 \n\t" //Re-enable RWW section + "sts %0,r16 \n\t" + "spm \n\t" +#ifdef __AVR_ATmega163__ + ".word 0xFFFF \n\t" + "nop \n\t" +#endif + "no_page_erase: \n\t" + "ld r0,Y+ \n\t" //Write 2 bytes into page buffer + "ld r1,Y+ \n\t" + + "wait_spm3: \n\t" + "lds r16,%0 \n\t" //Wait for previous spm to complete + "andi r16,1 \n\t" + "cpi r16,1 \n\t" + "breq wait_spm3 \n\t" + "ldi r16,0x01 \n\t" //Load r0,r1 into FLASH page buffer + "sts %0,r16 \n\t" + "spm \n\t" + + "inc r17 \n\t" //page_word_count++ + "cpi r17,%1 \n\t" + "brlo same_page \n\t" //Still same page in FLASH + "write_page: \n\t" + "clr r17 \n\t" //New page, write current one first + "wait_spm4: \n\t" + "lds r16,%0 \n\t" //Wait for previous spm to complete + "andi r16,1 \n\t" + "cpi r16,1 \n\t" + "breq wait_spm4 \n\t" +#ifdef __AVR_ATmega163__ + "andi r30,0x80 \n\t" // m163 requires Z6:Z1 to be zero during page write +#endif + "ldi r16,0x05 \n\t" //Write page pointed to by Z + "sts %0,r16 \n\t" + "spm \n\t" +#ifdef __AVR_ATmega163__ + ".word 0xFFFF \n\t" + "nop \n\t" + "ori r30,0x7E \n\t" // recover Z6:Z1 state after page write (had to be zero during write) +#endif + "wait_spm5: \n\t" + "lds r16,%0 \n\t" //Wait for previous spm to complete + "andi r16,1 \n\t" + "cpi r16,1 \n\t" + "breq wait_spm5 \n\t" + "ldi r16,0x11 \n\t" //Re-enable RWW section + "sts %0,r16 \n\t" + "spm \n\t" +#ifdef __AVR_ATmega163__ + ".word 0xFFFF \n\t" + "nop \n\t" +#endif + "same_page: \n\t" + "adiw r30,2 \n\t" //Next word in FLASH + "sbiw r24,2 \n\t" //length-2 + "breq final_write \n\t" //Finished + "rjmp length_loop \n\t" + "final_write: \n\t" + "cpi r17,0 \n\t" + "breq block_done \n\t" + "adiw r24,2 \n\t" //length+2, fool above check on length after short page write + "rjmp write_page \n\t" + "block_done: \n\t" + "clr __zero_reg__ \n\t" //restore zero register +#if defined __AVR_ATmega168__ || __AVR_ATmega328P__ || __AVR_ATmega128__ || __AVR_ATmega1280__ || __AVR_ATmega1281__ + : "=m" (SPMCSR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31" +#else + : "=m" (SPMCR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31" +#endif + ); + /* Should really add a wait for RWW section to be enabled, don't actually need it since we never */ + /* exit the bootloader without a power cycle anyhow */ + } + putch(0x14); + putch(0x10); + } else { + if (++error_count == MAX_ERROR_COUNT) + app_start(); + } + } + + + /* Read memory block mode, length is big endian. */ + else if(ch=='t') { + length.byte[1] = getch(); + length.byte[0] = getch(); +#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) + if (address.word>0x7FFF) flags.rampz = 1; // No go with m256, FIXME + else flags.rampz = 0; +#endif + address.word = address.word << 1; // address * 2 -> byte location + if (getch() == 'E') flags.eeprom = 1; + else flags.eeprom = 0; + if (getch() == ' ') { // Command terminator + putch(0x14); + for (w=0;w < length.word;w++) { // Can handle odd and even lengths okay + if (flags.eeprom) { // Byte access EEPROM read +#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) + while(EECR & (1<= 'a') { + return (a - 'a' + 0x0a); + } else if(a >= '0') { + return(a - '0'); + } + return a; +} + + +char gethex(void) { + return (gethexnib() << 4) + gethexnib(); +} + + +void puthex(char ch) { + char ah; + + ah = ch >> 4; + if(ah >= 0x0a) { + ah = ah - 0x0a + 'a'; + } else { + ah += '0'; + } + + ch &= 0x0f; + if(ch >= 0x0a) { + ch = ch - 0x0a + 'a'; + } else { + ch += '0'; + } + + putch(ah); + putch(ch); +} + + +void putch(char ch) +{ +#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) + if(bootuart == 1) { + while (!(UCSR0A & _BV(UDRE0))); + UDR0 = ch; + } + else if (bootuart == 2) { + while (!(UCSR1A & _BV(UDRE1))); + UDR1 = ch; + } +#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) + while (!(UCSR0A & _BV(UDRE0))); + UDR0 = ch; +#else + /* m8,16,32,169,8515,8535,163 */ + while (!(UCSRA & _BV(UDRE))); + UDR = ch; +#endif +} + + +char getch(void) +{ +#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) + uint32_t count = 0; + if(bootuart == 1) { + while(!(UCSR0A & _BV(RXC0))) { + /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/ + /* HACKME:: here is a good place to count times*/ + count++; + if (count > MAX_TIME_COUNT) + app_start(); + } + + return UDR0; + } + else if(bootuart == 2) { + while(!(UCSR1A & _BV(RXC1))) { + /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/ + /* HACKME:: here is a good place to count times*/ + count++; + if (count > MAX_TIME_COUNT) + app_start(); + } + + return UDR1; + } + return 0; +#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) + uint32_t count = 0; + while(!(UCSR0A & _BV(RXC0))){ + /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/ + /* HACKME:: here is a good place to count times*/ + count++; + if (count > MAX_TIME_COUNT) + app_start(); + } + return UDR0; +#else + /* m8,16,32,169,8515,8535,163 */ + uint32_t count = 0; + while(!(UCSRA & _BV(RXC))){ + /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/ + /* HACKME:: here is a good place to count times*/ + count++; + if (count > MAX_TIME_COUNT) + app_start(); + } + return UDR; +#endif +} + + +void getNch(uint8_t count) +{ + while(count--) { +#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) + if(bootuart == 1) { + while(!(UCSR0A & _BV(RXC0))); + UDR0; + } + else if(bootuart == 2) { + while(!(UCSR1A & _BV(RXC1))); + UDR1; + } +#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) + getch(); +#else + /* m8,16,32,169,8515,8535,163 */ + /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/ + //while(!(UCSRA & _BV(RXC))); + //UDR; + getch(); // need to handle time out +#endif + } +} + + +void byte_response(uint8_t val) +{ + if (getch() == ' ') { + putch(0x14); + putch(val); + putch(0x10); + } else { + if (++error_count == MAX_ERROR_COUNT) + app_start(); + } +} + + +void nothing_response(void) +{ + if (getch() == ' ') { + putch(0x14); + putch(0x10); + } else { + if (++error_count == MAX_ERROR_COUNT) + app_start(); + } +} + +void flash_led(uint8_t count) +{ + while (count--) { + LED_PORT |= _BV(LED); + _delay_ms(100); + LED_PORT &= ~_BV(LED); + _delay_ms(100); + } +} + + +/* end of file ATmegaBOOT.c */ diff --git a/hardware/ijhack/avr/bootloaders/atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex b/hardware/ijhack/avr/bootloaders/atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex new file mode 100644 index 0000000..9753e2e --- /dev/null +++ b/hardware/ijhack/avr/bootloaders/atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex @@ -0,0 +1,124 @@ +:107800000C94343C0C94513C0C94513C0C94513CE1 +:107810000C94513C0C94513C0C94513C0C94513CB4 +:107820000C94513C0C94513C0C94513C0C94513CA4 +:107830000C94513C0C94513C0C94513C0C94513C94 +:107840000C94513C0C94513C0C94513C0C94513C84 +:107850000C94513C0C94513C0C94513C0C94513C74 +:107860000C94513C0C94513C11241FBECFEFD8E036 +:10787000DEBFCDBF11E0A0E0B1E0EAE8FFE702C063 +:1078800005900D92A230B107D9F712E0A2E0B1E065 +:1078900001C01D92AD30B107E1F70E942D3D0C945F +:1078A000C33F0C94003C982F95959595959595958B +:1078B000905D8F708A307CF0282F295A8091C0000B +:1078C00085FFFCCF9093C6008091C00085FFFCCF60 +:1078D0002093C6000895282F205DF0CF982F809127 +:1078E000C00085FFFCCF9093C6000895EF92FF92F1 +:1078F0000F931F93EE24FF2487018091C00087FD22 +:1079000017C00894E11CF11C011D111D81E2E8164D +:1079100081EAF80687E0080780E0180770F3E09135 +:107920000401F091050109958091C00087FFE9CF1E +:107930008091C6001F910F91FF90EF9008950E94D3 +:10794000763C982F8091C00085FFFCCF9093C600B5 +:1079500091362CF490330CF09053892F089597555D +:10796000892F08951F930E949F3C182F0E949F3CCF +:107970001295107F810F1F9108951F93182F882350 +:1079800021F00E94763C1150E1F71F9108951F935A +:10799000182F0E94763C803249F0809103018F5F5E +:1079A000809303018530C1F01F9108958091C0003C +:1079B00085FFFCCF84E18093C6008091C00085FFE5 +:1079C000FCCF1093C6008091C00085FFFCCF80E102 +:1079D0008093C6001F910895E0910401F091050184 +:1079E00009951F9108950E94763C803241F0809164 +:1079F00003018F5F80930301853081F008958091AA +:107A0000C00085FFFCCF84E18093C6008091C00058 +:107A100085FFFCCF80E18093C6000895E0910401CA +:107A2000F09105010995089548EC50E08823A1F0F4 +:107A30002D9A28EE33E0FA013197F1F721503040CA +:107A4000D1F72D9828EE33E0FA013197F1F7215064 +:107A50003040D1F7815061F708953F924F925F9285 +:107A60006F927F928F929F92AF92BF92CF92DF924E +:107A7000EF92FF920F931F93CF93DF93000082E06A +:107A80008093C00080E18093C4001092C50088E11B +:107A90008093C10086E08093C2005098589A259A3E +:107AA00081E00E94143D24E1F22E9EE1E92E85E959 +:107AB000D82E0FE0C02E10E1B12EAA24A394B1E479 +:107AC0009B2EA6E58A2EF2E57F2EE0E26E2E79E46B +:107AD000572E63E5462E50E5352E0E94763C8033C6 +:107AE000B1F18133B9F1803409F46FC0813409F404 +:107AF00076C0823409F485C0853409F488C08035A5 +:107B000031F1823521F1813511F1853509F485C0D6 +:107B1000863509F48DC0843609F496C0843709F49B +:107B200003C1853709F472C1863709F466C08091B4 +:107B300003018F5F80930301853079F6E0910401A2 +:107B4000F091050109950E94763C803351F60E9420 +:107B5000F33CC3CF0E94763C803249F78091C0004D +:107B600085FFFCCFF092C6008091C00085FFFCCF5E +:107B70009092C6008091C00085FFFCCF8092C60025 +:107B80008091C00085FFFCCF7092C6008091C0003C +:107B900085FFFCCF6092C6008091C00085FFFCCFBE +:107BA0005092C6008091C00085FFFCCF4092C60075 +:107BB0008091C00085FFFCCF3092C6008091C0004C +:107BC00085FFFCCFB092C60088CF0E94763C8638F5 +:107BD00008F4BDCF0E94763C0E94F33C7ECF0E9409 +:107BE000763C803809F49CC0813809F40BC1823896 +:107BF00009F430C1883909F48FC080E00E94C73C85 +:107C00006CCF84E10E94BD3C0E94F33C66CF85E0CE +:107C10000E94BD3C0E94F33C60CF0E94763C809362 +:107C200006010E94763C809307010E94F33C55CFE9 +:107C30000E94763C803309F411C183E00E94BD3C70 +:107C400080E00E94C73C49CF0E94763C80930902A5 +:107C50000E94763C8093080280910C028E7F809374 +:107C60000C020E94763C853409F409C18091080217 +:107C700090910902892B89F000E010E00E94763C87 +:107C8000F801E85FFE4F80830F5F1F4F809108026D +:107C9000909109020817190788F30E94763C8032F8 +:107CA00009F045CF80910C0280FFF5C0609106017C +:107CB00070910701660F771F7093070160930601AB +:107CC000A0910802B09109021097C9F0E8E0F1E034 +:107CD0009B01AD014E0F5F1FF999FECF32BD21BD53 +:107CE000819180BDFA9AF99A2F5F3F4FE417F5070B +:107CF00099F76A0F7B1F70930701609306018091CB +:107D0000C00085FFFCCFF092C6008091C00085FFC7 +:107D1000FCCFB092C600E1CE83E00E94C73CDDCE2E +:107D200082E00E94C73CD9CE0E94763C8093090233 +:107D30000E94763C80930802809106019091070191 +:107D4000880F991F90930701809306010E94763C4B +:107D5000853409F49AC080910C028E7F80930C02C6 +:107D60000E94763C803209F0B8CE8091C00085FF39 +:107D7000FCCFF092C600A0910802B09109021097C2 +:107D8000C1F180910C02082F0170182F1695117007 +:107D9000E0910601F0910701AF014F5F5F4FBA011B +:107DA00020E030E00023B1F4112339F49491809164 +:107DB000C00085FFFCCF9093C6002F5F3F4FCB01E3 +:107DC0000196FA012A173B0780F4BC014F5F5F4F11 +:107DD000002351F3F999FECFF2BDE1BDF89A90B5B9 +:107DE0008091C00085FFFCCFE6CF709307016093C0 +:107DF00006018091C00085FDE5CE8091C00085FF21 +:107E0000F8CFE0CE81E00E94C73C67CE0E94763C6E +:107E1000803209F08CCE8091C00085FFFCCFF092BB +:107E2000C6008091C00085FFFCCFE092C600809123 +:107E3000C00085FFFCCFD092C6008091C00085FFB6 +:107E4000FCCFC092C6008091C00085FFFCCFB092ED +:107E5000C60043CE80E10E94C73C3FCE0E94763CE4 +:107E60000E94763C182F0E94763C112309F483C0AF +:107E7000113009F484C08FE00E94C73C2ECE80915F +:107E80000C02816080930C02F1CE80910C02816023 +:107E900080930C0265CF809107018823880F880B9F +:107EA0008A2180930B028091060190910701880F2F +:107EB000991F90930701809306018091080280FF2B +:107EC00009C08091080290910902019690930902DD +:107ED00080930802F894F999FECF1127E0910601EA +:107EE000F0910701C8E0D1E0809108029091090269 +:107EF000103091F40091570001700130D9F303E084 +:107F000000935700E8950091570001700130D9F3B4 +:107F100001E100935700E8950990199000915700EE +:107F200001700130D9F301E000935700E8951395F3 +:107F3000103498F011270091570001700130D9F3E7 +:107F400005E000935700E89500915700017001305B +:107F5000D9F301E100935700E8953296029709F0B2 +:107F6000C7CF103011F00296E5CF11248091C000E8 +:107F700085FFC5CEC8CE8EE10E94C73CAECD85E957 +:0A7F80000E94C73CAACDF894FFCF81 +:027F8A00800075 +:040000030000780081 +:00000001FF diff --git a/hardware/ijhack/avr/bootloaders/atmega/Makefile b/hardware/ijhack/avr/bootloaders/atmega/Makefile new file mode 100644 index 0000000..0fd54db --- /dev/null +++ b/hardware/ijhack/avr/bootloaders/atmega/Makefile @@ -0,0 +1,224 @@ +# Makefile for ATmegaBOOT +# E.Lins, 18.7.2005 +# $Id$ +# +# Instructions +# +# To make bootloader .hex file: +# make diecimila +# make lilypad +# make ng +# etc... +# +# To burn bootloader .hex file: +# make diecimila_isp +# make lilypad_isp +# make ng_isp +# etc... + +# program name should not be changed... +PROGRAM = ATmegaBOOT_168 + +# enter the parameters for the avrdude isp tool +ISPTOOL = stk500v2 +ISPPORT = usb +ISPSPEED = -b 115200 + +MCU_TARGET = atmega168 +LDSECTION = --section-start=.text=0x3800 + +# the efuse should really be 0xf8; since, however, only the lower +# three bits of that byte are used on the atmega168, avrdude gets +# confused if you specify 1's for the higher bits, see: +# http://tinker.it/now/2007/02/24/the-tale-of-avrdude-atmega168-and-extended-bits-fuses/ +# +# similarly, the lock bits should be 0xff instead of 0x3f (to +# unlock the bootloader section) and 0xcf instead of 0x0f (to +# lock it), but since the high two bits of the lock byte are +# unused, avrdude would get confused. + +ISPFUSES = avrdude -c $(ISPTOOL) -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \ +-e -u -U lock:w:0x3f:m -U efuse:w:0x$(EFUSE):m -U hfuse:w:0x$(HFUSE):m -U lfuse:w:0x$(LFUSE):m +ISPFLASH = avrdude -c $(ISPTOOL) -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \ +-U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x0f:m + +STK500 = "C:\Program Files\Atmel\AVR Tools\STK500\Stk500.exe" +STK500-1 = $(STK500) -e -d$(MCU_TARGET) -pf -vf -if$(PROGRAM)_$(TARGET).hex \ +-lFF -LFF -f$(HFUSE)$(LFUSE) -EF8 -ms -q -cUSB -I200kHz -s -wt +STK500-2 = $(STK500) -d$(MCU_TARGET) -ms -q -lCF -LCF -cUSB -I200kHz -s -wt + + +OBJ = $(PROGRAM).o +OPTIMIZE = -O2 + +DEFS = +LIBS = + +CC = avr-gcc + +# Override is only needed by avr-lib build system. + +override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(AVR_FREQ) $(DEFS) +override LDFLAGS = -Wl,$(LDSECTION) +#override LDFLAGS = -Wl,-Map,$(PROGRAM).map,$(LDSECTION) + +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump + +all: + +lilypad: TARGET = lilypad +lilypad: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>1' '-DNUM_LED_FLASHES=3' +lilypad: AVR_FREQ = 8000000L +lilypad: $(PROGRAM)_lilypad.hex + +lilypad_isp: lilypad +lilypad_isp: TARGET = lilypad +lilypad_isp: HFUSE = DD +lilypad_isp: LFUSE = E2 +lilypad_isp: EFUSE = 00 +lilypad_isp: isp + +lilypad_resonator: TARGET = lilypad_resonator +lilypad_resonator: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=3' +lilypad_resonator: AVR_FREQ = 8000000L +lilypad_resonator: $(PROGRAM)_lilypad_resonator.hex + +lilypad_resonator_isp: lilypad_resonator +lilypad_resonator_isp: TARGET = lilypad_resonator +lilypad_resonator_isp: HFUSE = DD +lilypad_resonator_isp: LFUSE = C6 +lilypad_resonator_isp: EFUSE = 00 +lilypad_resonator_isp: isp + +pro8: TARGET = pro_8MHz +pro8: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' '-DWATCHDOG_MODS' +pro8: AVR_FREQ = 8000000L +pro8: $(PROGRAM)_pro_8MHz.hex + +pro8_isp: pro8 +pro8_isp: TARGET = pro_8MHz +pro8_isp: HFUSE = DD +pro8_isp: LFUSE = C6 +pro8_isp: EFUSE = 00 +pro8_isp: isp + +pro16: TARGET = pro_16MHz +pro16: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' '-DWATCHDOG_MODS' +pro16: AVR_FREQ = 16000000L +pro16: $(PROGRAM)_pro_16MHz.hex + +pro16_isp: pro16 +pro16_isp: TARGET = pro_16MHz +pro16_isp: HFUSE = DD +pro16_isp: LFUSE = C6 +pro16_isp: EFUSE = 00 +pro16_isp: isp + +pro20: TARGET = pro_20mhz +pro20: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' '-DWATCHDOG_MODS' +pro20: AVR_FREQ = 20000000L +pro20: $(PROGRAM)_pro_20mhz.hex + +pro20_isp: pro20 +pro20_isp: TARGET = pro_20mhz +pro20_isp: HFUSE = DD +pro20_isp: LFUSE = C6 +pro20_isp: EFUSE = 00 +pro20_isp: isp + +diecimila: TARGET = diecimila +diecimila: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' +diecimila: AVR_FREQ = 16000000L +diecimila: $(PROGRAM)_diecimila.hex + +diecimila_isp: diecimila +diecimila_isp: TARGET = diecimila +diecimila_isp: HFUSE = DD +diecimila_isp: LFUSE = FF +diecimila_isp: EFUSE = 00 +diecimila_isp: isp + +ng: TARGET = ng +ng: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>1' '-DNUM_LED_FLASHES=3' +ng: AVR_FREQ = 16000000L +ng: $(PROGRAM)_ng.hex + +ng_isp: ng +ng_isp: TARGET = ng +ng_isp: HFUSE = DD +ng_isp: LFUSE = FF +ng_isp: EFUSE = 00 +ng_isp: isp + +atmega328: TARGET = atmega328 +atmega328: MCU_TARGET = atmega328p +atmega328: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -DBAUD_RATE=57600 +atmega328: AVR_FREQ = 16000000L +atmega328: LDSECTION = --section-start=.text=0x7800 +atmega328: $(PROGRAM)_atmega328.hex + +atmega328_isp: atmega328 +atmega328_isp: TARGET = atmega328 +atmega328_isp: MCU_TARGET = atmega328p +atmega328_isp: HFUSE = DA +atmega328_isp: LFUSE = FF +atmega328_isp: EFUSE = 05 +atmega328_isp: isp + +atmega328_pro8: TARGET = atmega328_pro_8MHz +atmega328_pro8: MCU_TARGET = atmega328p +atmega328_pro8: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -DBAUD_RATE=57600 -DDOUBLE_SPEED +atmega328_pro8: AVR_FREQ = 8000000L +atmega328_pro8: LDSECTION = --section-start=.text=0x7800 +atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.hex + +atmega328_pro8_isp: atmega328_pro8 +atmega328_pro8_isp: TARGET = atmega328_pro_8MHz +atmega328_pro8_isp: MCU_TARGET = atmega328p +atmega328_pro8_isp: HFUSE = DA +atmega328_pro8_isp: LFUSE = FF +atmega328_pro8_isp: EFUSE = 05 +atmega328_pro8_isp: isp + +mega: TARGET = atmega1280 +mega: MCU_TARGET = atmega1280 +mega: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=0' -DBAUD_RATE=57600 +mega: AVR_FREQ = 16000000L +mega: LDSECTION = --section-start=.text=0x1F000 +mega: $(PROGRAM)_atmega1280.hex + +mega_isp: mega +mega_isp: TARGET = atmega1280 +mega_isp: MCU_TARGET = atmega1280 +mega_isp: HFUSE = DA +mega_isp: LFUSE = FF +mega_isp: EFUSE = F5 +mega_isp: isp + +isp: $(TARGET) + $(ISPFUSES) + $(ISPFLASH) + +isp-stk500: $(PROGRAM)_$(TARGET).hex + $(STK500-1) + $(STK500-2) + +%.elf: $(OBJ) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) + +clean: + rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex + +%.lst: %.elf + $(OBJDUMP) -h -S $< > $@ + +%.hex: %.elf + $(OBJCOPY) -j .text -j .data -O ihex $< $@ + +%.srec: %.elf + $(OBJCOPY) -j .text -j .data -O srec $< $@ + +%.bin: %.elf + $(OBJCOPY) -j .text -j .data -O binary $< $@ + diff --git a/hardware/ijhack/avr/cores/arduino/Arduino.h b/hardware/ijhack/avr/cores/arduino/Arduino.h new file mode 100644 index 0000000..16dd759 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/Arduino.h @@ -0,0 +1,249 @@ +/* + Arduino.h - Main include file for the Arduino SDK + Copyright (c) 2005-2013 Arduino Team. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Arduino_h +#define Arduino_h + +#include +#include +#include +#include + +#include +#include +#include + +#include "binary.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +void yield(void); + +#define HIGH 0x1 +#define LOW 0x0 + +#define INPUT 0x0 +#define OUTPUT 0x1 +#define INPUT_PULLUP 0x2 + +#define PI 3.1415926535897932384626433832795 +#define HALF_PI 1.5707963267948966192313216916398 +#define TWO_PI 6.283185307179586476925286766559 +#define DEG_TO_RAD 0.017453292519943295769236907684886 +#define RAD_TO_DEG 57.295779513082320876798154814105 +#define EULER 2.718281828459045235360287471352 + +#define SERIAL 0x0 +#define DISPLAY 0x1 + +#define LSBFIRST 0 +#define MSBFIRST 1 + +#define CHANGE 1 +#define FALLING 2 +#define RISING 3 + +#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) +#define DEFAULT 0 +#define EXTERNAL 1 +#define INTERNAL 2 +#else +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) +#define INTERNAL1V1 2 +#define INTERNAL2V56 3 +#else +#define INTERNAL 3 +#endif +#define DEFAULT 1 +#define EXTERNAL 0 +#endif + +// undefine stdlib's abs if encountered +#ifdef abs +#undef abs +#endif + +#define min(a,b) ((a)<(b)?(a):(b)) +#define max(a,b) ((a)>(b)?(a):(b)) +#define abs(x) ((x)>0?(x):-(x)) +#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) +#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) +#define radians(deg) ((deg)*DEG_TO_RAD) +#define degrees(rad) ((rad)*RAD_TO_DEG) +#define sq(x) ((x)*(x)) + +#define interrupts() sei() +#define noInterrupts() cli() + +#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) +#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) +#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() ) + +#define lowByte(w) ((uint8_t) ((w) & 0xff)) +#define highByte(w) ((uint8_t) ((w) >> 8)) + +#define bitRead(value, bit) (((value) >> (bit)) & 0x01) +#define bitSet(value, bit) ((value) |= (1UL << (bit))) +#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) +#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) + +// avr-libc defines _NOP() since 1.6.2 +#ifndef _NOP +#define _NOP() do { __asm__ volatile ("nop"); } while (0) +#endif + +typedef unsigned int word; + +#define bit(b) (1UL << (b)) + +typedef bool boolean; +typedef uint8_t byte; + +void init(void); +void initVariant(void); + +int atexit(void (*func)()) __attribute__((weak)); + +void pinMode(uint8_t, uint8_t); +void digitalWrite(uint8_t, uint8_t); +int digitalRead(uint8_t); +int analogRead(uint8_t); +void analogReference(uint8_t mode); +void analogWrite(uint8_t, int); + +unsigned long millis(void); +unsigned long micros(void); +void delay(unsigned long); +void delayMicroseconds(unsigned int us); +unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout); + +void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val); +uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder); + +void attachInterrupt(uint8_t, void (*)(void), int mode); +void detachInterrupt(uint8_t); + +void setup(void); +void loop(void); + +// Get the bit location within the hardware port of the given virtual pin. +// This comes from the pins_*.c file for the active board configuration. + +#define analogInPinToBit(P) (P) + +// On the ATmega1280, the addresses of some of the port registers are +// greater than 255, so we can't store them in uint8_t's. +extern const uint16_t PROGMEM port_to_mode_PGM[]; +extern const uint16_t PROGMEM port_to_input_PGM[]; +extern const uint16_t PROGMEM port_to_output_PGM[]; + +extern const uint8_t PROGMEM digital_pin_to_port_PGM[]; +// extern const uint8_t PROGMEM digital_pin_to_bit_PGM[]; +extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[]; +extern const uint8_t PROGMEM digital_pin_to_timer_PGM[]; + +// Get the bit location within the hardware port of the given virtual pin. +// This comes from the pins_*.c file for the active board configuration. +// +// These perform slightly better as macros compared to inline functions +// +#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) ) +#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) ) +#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) ) +#define analogInPinToBit(P) (P) +#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) ) +#define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) ) +#define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) ) + +#define NOT_A_PIN 0 +#define NOT_A_PORT 0 + +#define NOT_AN_INTERRUPT -1 + +#ifdef ARDUINO_MAIN +#define PA 1 +#define PB 2 +#define PC 3 +#define PD 4 +#define PE 5 +#define PF 6 +#define PG 7 +#define PH 8 +#define PJ 10 +#define PK 11 +#define PL 12 +#endif + +#define NOT_ON_TIMER 0 +#define TIMER0A 1 +#define TIMER0B 2 +#define TIMER1A 3 +#define TIMER1B 4 +#define TIMER1C 5 +#define TIMER2 6 +#define TIMER2A 7 +#define TIMER2B 8 + +#define TIMER3A 9 +#define TIMER3B 10 +#define TIMER3C 11 +#define TIMER4A 12 +#define TIMER4B 13 +#define TIMER4C 14 +#define TIMER4D 15 +#define TIMER5A 16 +#define TIMER5B 17 +#define TIMER5C 18 + +#ifdef __cplusplus +} // extern "C" +#endif + +#ifdef __cplusplus +#include "WCharacter.h" +#include "WString.h" +#include "HardwareSerial.h" +#include "USBAPI.h" +#if defined(HAVE_HWSERIAL0) && defined(HAVE_CDCSERIAL) +#error "Targets with both UART0 and CDC serial not supported" +#endif + +uint16_t makeWord(uint16_t w); +uint16_t makeWord(byte h, byte l); + +#define word(...) makeWord(__VA_ARGS__) + +unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); + +void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0); +void noTone(uint8_t _pin); + +// WMath prototypes +long random(long); +long random(long, long); +void randomSeed(unsigned int); +long map(long, long, long, long, long); + +#endif + +#include "pins_arduino.h" + +#endif diff --git a/hardware/ijhack/avr/cores/arduino/CDC.cpp b/hardware/ijhack/avr/cores/arduino/CDC.cpp new file mode 100644 index 0000000..5d4f2a0 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/CDC.cpp @@ -0,0 +1,211 @@ + + +/* Copyright (c) 2011, Peter Barrett +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#include "USBAPI.h" +#include + +#if defined(USBCON) +#ifdef CDC_ENABLED + +typedef struct +{ + u32 dwDTERate; + u8 bCharFormat; + u8 bParityType; + u8 bDataBits; + u8 lineState; +} LineInfo; + +static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 }; + +#define WEAK __attribute__ ((weak)) + +extern const CDCDescriptor _cdcInterface PROGMEM; +const CDCDescriptor _cdcInterface = +{ + D_IAD(0,2,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,1), + + // CDC communication interface + D_INTERFACE(CDC_ACM_INTERFACE,1,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,0), + D_CDCCS(CDC_HEADER,0x10,0x01), // Header (1.10 bcd) + D_CDCCS(CDC_CALL_MANAGEMENT,1,1), // Device handles call management (not) + D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported + D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0 + D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10,0x40), + + // CDC data interface + D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0), + D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,0x40,0), + D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,0x40,0) +}; + +int WEAK CDC_GetInterface(u8* interfaceNum) +{ + interfaceNum[0] += 2; // uses 2 + return USB_SendControl(TRANSFER_PGM,&_cdcInterface,sizeof(_cdcInterface)); +} + +bool WEAK CDC_Setup(Setup& setup) +{ + u8 r = setup.bRequest; + u8 requestType = setup.bmRequestType; + + if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType) + { + if (CDC_GET_LINE_CODING == r) + { + USB_SendControl(0,(void*)&_usbLineInfo,7); + return true; + } + } + + if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType) + { + if (CDC_SET_LINE_CODING == r) + { + USB_RecvControl((void*)&_usbLineInfo,7); + } + + if (CDC_SET_CONTROL_LINE_STATE == r) + { + _usbLineInfo.lineState = setup.wValueL; + } + + if (CDC_SET_LINE_CODING == r || CDC_SET_CONTROL_LINE_STATE == r) + { + // auto-reset into the bootloader is triggered when the port, already + // open at 1200 bps, is closed. this is the signal to start the watchdog + // with a relatively long period so it can finish housekeeping tasks + // like servicing endpoints before the sketch ends + + // We check DTR state to determine if host port is open (bit 0 of lineState). + if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0) + { + *(uint16_t *)0x0800 = 0x7777; + wdt_enable(WDTO_120MS); + } + else + { + // Most OSs do some intermediate steps when configuring ports and DTR can + // twiggle more than once before stabilizing. + // To avoid spurious resets we set the watchdog to 250ms and eventually + // cancel if DTR goes back high. + + wdt_disable(); + wdt_reset(); + *(uint16_t *)0x0800 = 0x0; + } + } + return true; + } + return false; +} + + +void Serial_::begin(unsigned long /* baud_count */) +{ + peek_buffer = -1; +} + +void Serial_::begin(unsigned long /* baud_count */, byte /* config */) +{ + peek_buffer = -1; +} + +void Serial_::end(void) +{ +} + +int Serial_::available(void) +{ + if (peek_buffer >= 0) { + return 1 + USB_Available(CDC_RX); + } + return USB_Available(CDC_RX); +} + +int Serial_::peek(void) +{ + if (peek_buffer < 0) + peek_buffer = USB_Recv(CDC_RX); + return peek_buffer; +} + +int Serial_::read(void) +{ + if (peek_buffer >= 0) { + int c = peek_buffer; + peek_buffer = -1; + return c; + } + return USB_Recv(CDC_RX); +} + +void Serial_::flush(void) +{ + USB_Flush(CDC_TX); +} + +size_t Serial_::write(uint8_t c) +{ + return write(&c, 1); +} + +size_t Serial_::write(const uint8_t *buffer, size_t size) +{ + /* only try to send bytes if the high-level CDC connection itself + is open (not just the pipe) - the OS should set lineState when the port + is opened and clear lineState when the port is closed. + bytes sent before the user opens the connection or after + the connection is closed are lost - just like with a UART. */ + + // TODO - ZE - check behavior on different OSes and test what happens if an + // open connection isn't broken cleanly (cable is yanked out, host dies + // or locks up, or host virtual serial port hangs) + if (_usbLineInfo.lineState > 0) { + int r = USB_Send(CDC_TX,buffer,size); + if (r > 0) { + return r; + } else { + setWriteError(); + return 0; + } + } + setWriteError(); + return 0; +} + +// This operator is a convenient way for a sketch to check whether the +// port has actually been configured and opened by the host (as opposed +// to just being connected to the host). It can be used, for example, in +// setup() before printing to ensure that an application on the host is +// actually ready to receive and display the data. +// We add a short delay before returning to fix a bug observed by Federico +// where the port is configured (lineState != 0) but not quite opened. +Serial_::operator bool() { + bool result = false; + if (_usbLineInfo.lineState > 0) + result = true; + delay(10); + return result; +} + +Serial_ Serial; + +#endif +#endif /* if defined(USBCON) */ diff --git a/hardware/ijhack/avr/cores/arduino/Client.h b/hardware/ijhack/avr/cores/arduino/Client.h new file mode 100644 index 0000000..b8e5d93 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/Client.h @@ -0,0 +1,45 @@ +/* + Client.h - Base class that provides Client + Copyright (c) 2011 Adrian McEwen. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef client_h +#define client_h +#include "Print.h" +#include "Stream.h" +#include "IPAddress.h" + +class Client : public Stream { + +public: + virtual int connect(IPAddress ip, uint16_t port) =0; + virtual int connect(const char *host, uint16_t port) =0; + virtual size_t write(uint8_t) =0; + virtual size_t write(const uint8_t *buf, size_t size) =0; + virtual int available() = 0; + virtual int read() = 0; + virtual int read(uint8_t *buf, size_t size) = 0; + virtual int peek() = 0; + virtual void flush() = 0; + virtual void stop() = 0; + virtual uint8_t connected() = 0; + virtual operator bool() = 0; +protected: + uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); }; +}; + +#endif diff --git a/hardware/ijhack/avr/cores/arduino/HID.cpp b/hardware/ijhack/avr/cores/arduino/HID.cpp new file mode 100644 index 0000000..75c37b2 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/HID.cpp @@ -0,0 +1,518 @@ + + +/* Copyright (c) 2011, Peter Barrett +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#include "USBAPI.h" + +#if defined(USBCON) +#ifdef HID_ENABLED + +//#define RAWHID_ENABLED + +// Singletons for mouse and keyboard + +Mouse_ Mouse; +Keyboard_ Keyboard; + +//================================================================================ +//================================================================================ + +// HID report descriptor + +#define LSB(_x) ((_x) & 0xFF) +#define MSB(_x) ((_x) >> 8) + +#define RAWHID_USAGE_PAGE 0xFFC0 +#define RAWHID_USAGE 0x0C00 +#define RAWHID_TX_SIZE 64 +#define RAWHID_RX_SIZE 64 + +extern const u8 _hidReportDescriptor[] PROGMEM; +const u8 _hidReportDescriptor[] = { + + // Mouse + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 54 + 0x09, 0x02, // USAGE (Mouse) + 0xa1, 0x01, // COLLECTION (Application) + 0x09, 0x01, // USAGE (Pointer) + 0xa1, 0x00, // COLLECTION (Physical) + 0x85, 0x01, // REPORT_ID (1) + 0x05, 0x09, // USAGE_PAGE (Button) + 0x19, 0x01, // USAGE_MINIMUM (Button 1) + 0x29, 0x03, // USAGE_MAXIMUM (Button 3) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x95, 0x03, // REPORT_COUNT (3) + 0x75, 0x01, // REPORT_SIZE (1) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x05, // REPORT_SIZE (5) + 0x81, 0x03, // INPUT (Cnst,Var,Abs) + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x30, // USAGE (X) + 0x09, 0x31, // USAGE (Y) + 0x09, 0x38, // USAGE (Wheel) + 0x15, 0x81, // LOGICAL_MINIMUM (-127) + 0x25, 0x7f, // LOGICAL_MAXIMUM (127) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x03, // REPORT_COUNT (3) + 0x81, 0x06, // INPUT (Data,Var,Rel) + 0xc0, // END_COLLECTION + 0xc0, // END_COLLECTION + + // Keyboard + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 47 + 0x09, 0x06, // USAGE (Keyboard) + 0xa1, 0x01, // COLLECTION (Application) + 0x85, 0x02, // REPORT_ID (2) + 0x05, 0x07, // USAGE_PAGE (Keyboard) + + 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) + 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x75, 0x01, // REPORT_SIZE (1) + + 0x95, 0x08, // REPORT_COUNT (8) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x08, // REPORT_SIZE (8) + 0x81, 0x03, // INPUT (Cnst,Var,Abs) + + 0x95, 0x06, // REPORT_COUNT (6) + 0x75, 0x08, // REPORT_SIZE (8) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x65, // LOGICAL_MAXIMUM (101) + 0x05, 0x07, // USAGE_PAGE (Keyboard) + + 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) + 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) + 0x81, 0x00, // INPUT (Data,Ary,Abs) + 0xc0, // END_COLLECTION + +#ifdef RAWHID_ENABLED + // RAW HID + 0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE), // 30 + 0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE), + + 0xA1, 0x01, // Collection 0x01 + 0x85, 0x03, // REPORT_ID (3) + 0x75, 0x08, // report size = 8 bits + 0x15, 0x00, // logical minimum = 0 + 0x26, 0xFF, 0x00, // logical maximum = 255 + + 0x95, 64, // report count TX + 0x09, 0x01, // usage + 0x81, 0x02, // Input (array) + + 0x95, 64, // report count RX + 0x09, 0x02, // usage + 0x91, 0x02, // Output (array) + 0xC0 // end collection +#endif +}; + +extern const HIDDescriptor _hidInterface PROGMEM; +const HIDDescriptor _hidInterface = +{ + D_INTERFACE(HID_INTERFACE,1,3,0,0), + D_HIDREPORT(sizeof(_hidReportDescriptor)), + D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,0x40,0x01) +}; + +//================================================================================ +//================================================================================ +// Driver + +u8 _hid_protocol = 1; +u8 _hid_idle = 1; + +#define WEAK __attribute__ ((weak)) + +int WEAK HID_GetInterface(u8* interfaceNum) +{ + interfaceNum[0] += 1; // uses 1 + return USB_SendControl(TRANSFER_PGM,&_hidInterface,sizeof(_hidInterface)); +} + +int WEAK HID_GetDescriptor(int /* i */) +{ + return USB_SendControl(TRANSFER_PGM,_hidReportDescriptor,sizeof(_hidReportDescriptor)); +} + +void WEAK HID_SendReport(u8 id, const void* data, int len) +{ + USB_Send(HID_TX, &id, 1); + USB_Send(HID_TX | TRANSFER_RELEASE,data,len); +} + +bool WEAK HID_Setup(Setup& setup) +{ + u8 r = setup.bRequest; + u8 requestType = setup.bmRequestType; + if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType) + { + if (HID_GET_REPORT == r) + { + //HID_GetReport(); + return true; + } + if (HID_GET_PROTOCOL == r) + { + //Send8(_hid_protocol); // TODO + return true; + } + } + + if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType) + { + if (HID_SET_PROTOCOL == r) + { + _hid_protocol = setup.wValueL; + return true; + } + + if (HID_SET_IDLE == r) + { + _hid_idle = setup.wValueL; + return true; + } + } + return false; +} + +//================================================================================ +//================================================================================ +// Mouse + +Mouse_::Mouse_(void) : _buttons(0) +{ +} + +void Mouse_::begin(void) +{ +} + +void Mouse_::end(void) +{ +} + +void Mouse_::click(uint8_t b) +{ + _buttons = b; + move(0,0,0); + _buttons = 0; + move(0,0,0); +} + +void Mouse_::move(signed char x, signed char y, signed char wheel) +{ + u8 m[4]; + m[0] = _buttons; + m[1] = x; + m[2] = y; + m[3] = wheel; + HID_SendReport(1,m,4); +} + +void Mouse_::buttons(uint8_t b) +{ + if (b != _buttons) + { + _buttons = b; + move(0,0,0); + } +} + +void Mouse_::press(uint8_t b) +{ + buttons(_buttons | b); +} + +void Mouse_::release(uint8_t b) +{ + buttons(_buttons & ~b); +} + +bool Mouse_::isPressed(uint8_t b) +{ + if ((b & _buttons) > 0) + return true; + return false; +} + +//================================================================================ +//================================================================================ +// Keyboard + +Keyboard_::Keyboard_(void) +{ +} + +void Keyboard_::begin(void) +{ +} + +void Keyboard_::end(void) +{ +} + +void Keyboard_::sendReport(KeyReport* keys) +{ + HID_SendReport(2,keys,sizeof(KeyReport)); +} + +extern +const uint8_t _asciimap[128] PROGMEM; + +#define SHIFT 0x80 +const uint8_t _asciimap[128] = +{ + 0x00, // NUL + 0x00, // SOH + 0x00, // STX + 0x00, // ETX + 0x00, // EOT + 0x00, // ENQ + 0x00, // ACK + 0x00, // BEL + 0x2a, // BS Backspace + 0x2b, // TAB Tab + 0x28, // LF Enter + 0x00, // VT + 0x00, // FF + 0x00, // CR + 0x00, // SO + 0x00, // SI + 0x00, // DEL + 0x00, // DC1 + 0x00, // DC2 + 0x00, // DC3 + 0x00, // DC4 + 0x00, // NAK + 0x00, // SYN + 0x00, // ETB + 0x00, // CAN + 0x00, // EM + 0x00, // SUB + 0x00, // ESC + 0x00, // FS + 0x00, // GS + 0x00, // RS + 0x00, // US + + 0x2c, // ' ' + 0x1e|SHIFT, // ! + 0x34|SHIFT, // " + 0x20|SHIFT, // # + 0x21|SHIFT, // $ + 0x22|SHIFT, // % + 0x24|SHIFT, // & + 0x34, // ' + 0x26|SHIFT, // ( + 0x27|SHIFT, // ) + 0x25|SHIFT, // * + 0x2e|SHIFT, // + + 0x36, // , + 0x2d, // - + 0x37, // . + 0x38, // / + 0x27, // 0 + 0x1e, // 1 + 0x1f, // 2 + 0x20, // 3 + 0x21, // 4 + 0x22, // 5 + 0x23, // 6 + 0x24, // 7 + 0x25, // 8 + 0x26, // 9 + 0x33|SHIFT, // : + 0x33, // ; + 0x36|SHIFT, // < + 0x2e, // = + 0x37|SHIFT, // > + 0x38|SHIFT, // ? + 0x1f|SHIFT, // @ + 0x04|SHIFT, // A + 0x05|SHIFT, // B + 0x06|SHIFT, // C + 0x07|SHIFT, // D + 0x08|SHIFT, // E + 0x09|SHIFT, // F + 0x0a|SHIFT, // G + 0x0b|SHIFT, // H + 0x0c|SHIFT, // I + 0x0d|SHIFT, // J + 0x0e|SHIFT, // K + 0x0f|SHIFT, // L + 0x10|SHIFT, // M + 0x11|SHIFT, // N + 0x12|SHIFT, // O + 0x13|SHIFT, // P + 0x14|SHIFT, // Q + 0x15|SHIFT, // R + 0x16|SHIFT, // S + 0x17|SHIFT, // T + 0x18|SHIFT, // U + 0x19|SHIFT, // V + 0x1a|SHIFT, // W + 0x1b|SHIFT, // X + 0x1c|SHIFT, // Y + 0x1d|SHIFT, // Z + 0x2f, // [ + 0x31, // bslash + 0x30, // ] + 0x23|SHIFT, // ^ + 0x2d|SHIFT, // _ + 0x35, // ` + 0x04, // a + 0x05, // b + 0x06, // c + 0x07, // d + 0x08, // e + 0x09, // f + 0x0a, // g + 0x0b, // h + 0x0c, // i + 0x0d, // j + 0x0e, // k + 0x0f, // l + 0x10, // m + 0x11, // n + 0x12, // o + 0x13, // p + 0x14, // q + 0x15, // r + 0x16, // s + 0x17, // t + 0x18, // u + 0x19, // v + 0x1a, // w + 0x1b, // x + 0x1c, // y + 0x1d, // z + 0x2f|SHIFT, // + 0x31|SHIFT, // | + 0x30|SHIFT, // } + 0x35|SHIFT, // ~ + 0 // DEL +}; + +uint8_t USBPutChar(uint8_t c); + +// press() adds the specified key (printing, non-printing, or modifier) +// to the persistent key report and sends the report. Because of the way +// USB HID works, the host acts like the key remains pressed until we +// call release(), releaseAll(), or otherwise clear the report and resend. +size_t Keyboard_::press(uint8_t k) +{ + uint8_t i; + if (k >= 136) { // it's a non-printing key (not a modifier) + k = k - 136; + } else if (k >= 128) { // it's a modifier key + _keyReport.modifiers |= (1<<(k-128)); + k = 0; + } else { // it's a printing key + k = pgm_read_byte(_asciimap + k); + if (!k) { + setWriteError(); + return 0; + } + if (k & 0x80) { // it's a capital letter or other character reached with shift + _keyReport.modifiers |= 0x02; // the left shift modifier + k &= 0x7F; + } + } + + // Add k to the key report only if it's not already present + // and if there is an empty slot. + if (_keyReport.keys[0] != k && _keyReport.keys[1] != k && + _keyReport.keys[2] != k && _keyReport.keys[3] != k && + _keyReport.keys[4] != k && _keyReport.keys[5] != k) { + + for (i=0; i<6; i++) { + if (_keyReport.keys[i] == 0x00) { + _keyReport.keys[i] = k; + break; + } + } + if (i == 6) { + setWriteError(); + return 0; + } + } + sendReport(&_keyReport); + return 1; +} + +// release() takes the specified key out of the persistent key report and +// sends the report. This tells the OS the key is no longer pressed and that +// it shouldn't be repeated any more. +size_t Keyboard_::release(uint8_t k) +{ + uint8_t i; + if (k >= 136) { // it's a non-printing key (not a modifier) + k = k - 136; + } else if (k >= 128) { // it's a modifier key + _keyReport.modifiers &= ~(1<<(k-128)); + k = 0; + } else { // it's a printing key + k = pgm_read_byte(_asciimap + k); + if (!k) { + return 0; + } + if (k & 0x80) { // it's a capital letter or other character reached with shift + _keyReport.modifiers &= ~(0x02); // the left shift modifier + k &= 0x7F; + } + } + + // Test the key report to see if k is present. Clear it if it exists. + // Check all positions in case the key is present more than once (which it shouldn't be) + for (i=0; i<6; i++) { + if (0 != k && _keyReport.keys[i] == k) { + _keyReport.keys[i] = 0x00; + } + } + + sendReport(&_keyReport); + return 1; +} + +void Keyboard_::releaseAll(void) +{ + _keyReport.keys[0] = 0; + _keyReport.keys[1] = 0; + _keyReport.keys[2] = 0; + _keyReport.keys[3] = 0; + _keyReport.keys[4] = 0; + _keyReport.keys[5] = 0; + _keyReport.modifiers = 0; + sendReport(&_keyReport); +} + +size_t Keyboard_::write(uint8_t c) +{ + uint8_t p = press(c); // Keydown + release(c); // Keyup + return p; // just return the result of press() since release() almost always returns 1 +} + +#endif + +#endif /* if defined(USBCON) */ diff --git a/hardware/ijhack/avr/cores/arduino/HardwareSerial.cpp b/hardware/ijhack/avr/cores/arduino/HardwareSerial.cpp new file mode 100644 index 0000000..41935e3 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/HardwareSerial.cpp @@ -0,0 +1,252 @@ +/* + HardwareSerial.cpp - Hardware serial library for Wiring + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 23 November 2006 by David A. Mellis + Modified 28 September 2010 by Mark Sproul + Modified 14 August 2012 by Alarus + Modified 3 December 2013 by Matthijs Kooijman +*/ + +#include +#include +#include +#include +#include "Arduino.h" + +#include "HardwareSerial.h" +#include "HardwareSerial_private.h" + +// this next line disables the entire HardwareSerial.cpp, +// this is so I can support Attiny series and any other chip without a uart +#if defined(HAVE_HWSERIAL0) || defined(HAVE_HWSERIAL1) || defined(HAVE_HWSERIAL2) || defined(HAVE_HWSERIAL3) + +// SerialEvent functions are weak, so when the user doesn't define them, +// the linker just sets their address to 0 (which is checked below). +// The Serialx_available is just a wrapper around Serialx.available(), +// but we can refer to it weakly so we don't pull in the entire +// HardwareSerial instance if the user doesn't also refer to it. +#if defined(HAVE_HWSERIAL0) + void serialEvent() __attribute__((weak)); + bool Serial0_available() __attribute__((weak)); +#endif + +#if defined(HAVE_HWSERIAL1) + void serialEvent1() __attribute__((weak)); + bool Serial1_available() __attribute__((weak)); +#endif + +#if defined(HAVE_HWSERIAL2) + void serialEvent2() __attribute__((weak)); + bool Serial2_available() __attribute__((weak)); +#endif + +#if defined(HAVE_HWSERIAL3) + void serialEvent3() __attribute__((weak)); + bool Serial3_available() __attribute__((weak)); +#endif + +void serialEventRun(void) +{ +#if defined(HAVE_HWSERIAL0) + if (Serial0_available && serialEvent && Serial0_available()) serialEvent(); +#endif +#if defined(HAVE_HWSERIAL1) + if (Serial1_available && serialEvent1 && Serial1_available()) serialEvent1(); +#endif +#if defined(HAVE_HWSERIAL2) + if (Serial2_available && serialEvent2 && Serial2_available()) serialEvent2(); +#endif +#if defined(HAVE_HWSERIAL3) + if (Serial3_available && serialEvent3 && Serial3_available()) serialEvent3(); +#endif +} + +// Actual interrupt handlers ////////////////////////////////////////////////////////////// + +void HardwareSerial::_tx_udr_empty_irq(void) +{ + // If interrupts are enabled, there must be more data in the output + // buffer. Send the next byte + unsigned char c = _tx_buffer[_tx_buffer_tail]; + _tx_buffer_tail = (_tx_buffer_tail + 1) % SERIAL_TX_BUFFER_SIZE; + + *_udr = c; + + // clear the TXC bit -- "can be cleared by writing a one to its bit + // location". This makes sure flush() won't return until the bytes + // actually got written + sbi(*_ucsra, TXC0); + + if (_tx_buffer_head == _tx_buffer_tail) { + // Buffer empty, so disable interrupts + cbi(*_ucsrb, UDRIE0); + } +} + +// Public Methods ////////////////////////////////////////////////////////////// + +void HardwareSerial::begin(unsigned long baud, byte config) +{ + // Try u2x mode first + uint16_t baud_setting = (F_CPU / 4 / baud - 1) / 2; + *_ucsra = 1 << U2X0; + + // hardcoded exception for 57600 for compatibility with the bootloader + // shipped with the Duemilanove and previous boards and the firmware + // on the 8U2 on the Uno and Mega 2560. Also, The baud_setting cannot + // be > 4095, so switch back to non-u2x mode if the baud rate is too + // low. + if (((F_CPU == 16000000UL) && (baud == 57600)) || (baud_setting >4095)) + { + *_ucsra = 0; + baud_setting = (F_CPU / 8 / baud - 1) / 2; + } + + // assign the baud_setting, a.k.a. ubrr (USART Baud Rate Register) + *_ubrrh = baud_setting >> 8; + *_ubrrl = baud_setting; + + _written = false; + + //set the data bits, parity, and stop bits +#if defined(__AVR_ATmega8__) + config |= 0x80; // select UCSRC register (shared with UBRRH) +#endif + *_ucsrc = config; + + sbi(*_ucsrb, RXEN0); + sbi(*_ucsrb, TXEN0); + sbi(*_ucsrb, RXCIE0); + cbi(*_ucsrb, UDRIE0); +} + +void HardwareSerial::end() +{ + // wait for transmission of outgoing data + while (_tx_buffer_head != _tx_buffer_tail) + ; + + cbi(*_ucsrb, RXEN0); + cbi(*_ucsrb, TXEN0); + cbi(*_ucsrb, RXCIE0); + cbi(*_ucsrb, UDRIE0); + + // clear any received data + _rx_buffer_head = _rx_buffer_tail; +} + +int HardwareSerial::available(void) +{ + return ((unsigned int)(SERIAL_RX_BUFFER_SIZE + _rx_buffer_head - _rx_buffer_tail)) % SERIAL_RX_BUFFER_SIZE; +} + +int HardwareSerial::peek(void) +{ + if (_rx_buffer_head == _rx_buffer_tail) { + return -1; + } else { + return _rx_buffer[_rx_buffer_tail]; + } +} + +int HardwareSerial::read(void) +{ + // if the head isn't ahead of the tail, we don't have any characters + if (_rx_buffer_head == _rx_buffer_tail) { + return -1; + } else { + unsigned char c = _rx_buffer[_rx_buffer_tail]; + _rx_buffer_tail = (rx_buffer_index_t)(_rx_buffer_tail + 1) % SERIAL_RX_BUFFER_SIZE; + return c; + } +} + +int HardwareSerial::availableForWrite(void) +{ +#if (SERIAL_TX_BUFFER_SIZE>256) + uint8_t oldSREG = SREG; + cli(); +#endif + tx_buffer_index_t head = _tx_buffer_head; + tx_buffer_index_t tail = _tx_buffer_tail; +#if (SERIAL_TX_BUFFER_SIZE>256) + SREG = oldSREG; +#endif + if (head >= tail) return SERIAL_TX_BUFFER_SIZE - 1 - head + tail; + return tail - head - 1; +} + +void HardwareSerial::flush() +{ + // If we have never written a byte, no need to flush. This special + // case is needed since there is no way to force the TXC (transmit + // complete) bit to 1 during initialization + if (!_written) + return; + + while (bit_is_set(*_ucsrb, UDRIE0) || bit_is_clear(*_ucsra, TXC0)) { + if (bit_is_clear(SREG, SREG_I) && bit_is_set(*_ucsrb, UDRIE0)) + // Interrupts are globally disabled, but the DR empty + // interrupt should be enabled, so poll the DR empty flag to + // prevent deadlock + if (bit_is_set(*_ucsra, UDRE0)) + _tx_udr_empty_irq(); + } + // If we get here, nothing is queued anymore (DRIE is disabled) and + // the hardware finished tranmission (TXC is set). +} + +size_t HardwareSerial::write(uint8_t c) +{ + // If the buffer and the data register is empty, just write the byte + // to the data register and be done. This shortcut helps + // significantly improve the effective datarate at high (> + // 500kbit/s) bitrates, where interrupt overhead becomes a slowdown. + if (_tx_buffer_head == _tx_buffer_tail && bit_is_set(*_ucsra, UDRE0)) { + *_udr = c; + sbi(*_ucsra, TXC0); + return 1; + } + tx_buffer_index_t i = (_tx_buffer_head + 1) % SERIAL_TX_BUFFER_SIZE; + + // If the output buffer is full, there's nothing for it other than to + // wait for the interrupt handler to empty it a bit + while (i == _tx_buffer_tail) { + if (bit_is_clear(SREG, SREG_I)) { + // Interrupts are disabled, so we'll have to poll the data + // register empty flag ourselves. If it is set, pretend an + // interrupt has happened and call the handler to free up + // space for us. + if(bit_is_set(*_ucsra, UDRE0)) + _tx_udr_empty_irq(); + } else { + // nop, the interrupt handler will free up space for us + } + } + + _tx_buffer[_tx_buffer_head] = c; + _tx_buffer_head = i; + + sbi(*_ucsrb, UDRIE0); + _written = true; + + return 1; +} + + +#endif // whole file diff --git a/hardware/ijhack/avr/cores/arduino/HardwareSerial.h b/hardware/ijhack/avr/cores/arduino/HardwareSerial.h new file mode 100644 index 0000000..7dc2aa9 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/HardwareSerial.h @@ -0,0 +1,151 @@ +/* + HardwareSerial.h - Hardware serial library for Wiring + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 28 September 2010 by Mark Sproul + Modified 14 August 2012 by Alarus + Modified 3 December 2013 by Matthijs Kooijman +*/ + +#ifndef HardwareSerial_h +#define HardwareSerial_h + +#include + +#include "Stream.h" + +// Define constants and variables for buffering incoming serial data. We're +// using a ring buffer (I think), in which head is the index of the location +// to which to write the next incoming character and tail is the index of the +// location from which to read. +// NOTE: a "power of 2" buffer size is reccomended to dramatically +// optimize all the modulo operations for ring buffers. +#if !(defined(SERIAL_TX_BUFFER_SIZE) && defined(SERIAL_RX_BUFFER_SIZE)) +#if (RAMEND < 1000) +#define SERIAL_TX_BUFFER_SIZE 16 +#define SERIAL_RX_BUFFER_SIZE 16 +#else +#define SERIAL_TX_BUFFER_SIZE 64 +#define SERIAL_RX_BUFFER_SIZE 64 +#endif +#endif +#if (SERIAL_TX_BUFFER_SIZE>256) +typedef uint16_t tx_buffer_index_t; +#else +typedef uint8_t tx_buffer_index_t; +#endif +#if (SERIAL_RX_BUFFER_SIZE>256) +typedef uint16_t rx_buffer_index_t; +#else +typedef uint8_t rx_buffer_index_t; +#endif + +// Define config for Serial.begin(baud, config); +#define SERIAL_5N1 0x00 +#define SERIAL_6N1 0x02 +#define SERIAL_7N1 0x04 +#define SERIAL_8N1 0x06 +#define SERIAL_5N2 0x08 +#define SERIAL_6N2 0x0A +#define SERIAL_7N2 0x0C +#define SERIAL_8N2 0x0E +#define SERIAL_5E1 0x20 +#define SERIAL_6E1 0x22 +#define SERIAL_7E1 0x24 +#define SERIAL_8E1 0x26 +#define SERIAL_5E2 0x28 +#define SERIAL_6E2 0x2A +#define SERIAL_7E2 0x2C +#define SERIAL_8E2 0x2E +#define SERIAL_5O1 0x30 +#define SERIAL_6O1 0x32 +#define SERIAL_7O1 0x34 +#define SERIAL_8O1 0x36 +#define SERIAL_5O2 0x38 +#define SERIAL_6O2 0x3A +#define SERIAL_7O2 0x3C +#define SERIAL_8O2 0x3E + +class HardwareSerial : public Stream +{ + protected: + volatile uint8_t * const _ubrrh; + volatile uint8_t * const _ubrrl; + volatile uint8_t * const _ucsra; + volatile uint8_t * const _ucsrb; + volatile uint8_t * const _ucsrc; + volatile uint8_t * const _udr; + // Has any byte been written to the UART since begin() + bool _written; + + volatile rx_buffer_index_t _rx_buffer_head; + volatile rx_buffer_index_t _rx_buffer_tail; + volatile tx_buffer_index_t _tx_buffer_head; + volatile tx_buffer_index_t _tx_buffer_tail; + + // Don't put any members after these buffers, since only the first + // 32 bytes of this struct can be accessed quickly using the ldd + // instruction. + unsigned char _rx_buffer[SERIAL_RX_BUFFER_SIZE]; + unsigned char _tx_buffer[SERIAL_TX_BUFFER_SIZE]; + + public: + inline HardwareSerial( + volatile uint8_t *ubrrh, volatile uint8_t *ubrrl, + volatile uint8_t *ucsra, volatile uint8_t *ucsrb, + volatile uint8_t *ucsrc, volatile uint8_t *udr); + void begin(unsigned long baud) { begin(baud, SERIAL_8N1); } + void begin(unsigned long, uint8_t); + void end(); + virtual int available(void); + virtual int peek(void); + virtual int read(void); + int availableForWrite(void); + virtual void flush(void); + virtual size_t write(uint8_t); + inline size_t write(unsigned long n) { return write((uint8_t)n); } + inline size_t write(long n) { return write((uint8_t)n); } + inline size_t write(unsigned int n) { return write((uint8_t)n); } + inline size_t write(int n) { return write((uint8_t)n); } + using Print::write; // pull in write(str) and write(buf, size) from Print + operator bool() { return true; } + + // Interrupt handlers - Not intended to be called externally + inline void _rx_complete_irq(void); + void _tx_udr_empty_irq(void); +}; + +#if defined(UBRRH) || defined(UBRR0H) + extern HardwareSerial Serial; + #define HAVE_HWSERIAL0 +#endif +#if defined(UBRR1H) + extern HardwareSerial Serial1; + #define HAVE_HWSERIAL1 +#endif +#if defined(UBRR2H) + extern HardwareSerial Serial2; + #define HAVE_HWSERIAL2 +#endif +#if defined(UBRR3H) + extern HardwareSerial Serial3; + #define HAVE_HWSERIAL3 +#endif + +extern void serialEventRun(void) __attribute__((weak)); + +#endif diff --git a/hardware/ijhack/avr/cores/arduino/HardwareSerial0.cpp b/hardware/ijhack/avr/cores/arduino/HardwareSerial0.cpp new file mode 100644 index 0000000..1146eeb --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/HardwareSerial0.cpp @@ -0,0 +1,79 @@ +/* + HardwareSerial0.cpp - Hardware serial library for Wiring + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 23 November 2006 by David A. Mellis + Modified 28 September 2010 by Mark Sproul + Modified 14 August 2012 by Alarus + Modified 3 December 2013 by Matthijs Kooijman +*/ + +#include "Arduino.h" +#include "HardwareSerial.h" +#include "HardwareSerial_private.h" + +// Each HardwareSerial is defined in its own file, sine the linker pulls +// in the entire file when any element inside is used. --gc-sections can +// additionally cause unused symbols to be dropped, but ISRs have the +// "used" attribute so are never dropped and they keep the +// HardwareSerial instance in as well. Putting each instance in its own +// file prevents the linker from pulling in any unused instances in the +// first place. + +#if defined(HAVE_HWSERIAL0) + +#if defined(USART_RX_vect) + ISR(USART_RX_vect) +#elif defined(USART0_RX_vect) + ISR(USART0_RX_vect) +#elif defined(USART_RXC_vect) + ISR(USART_RXC_vect) // ATmega8 +#else + #error "Don't know what the Data Received vector is called for Serial" +#endif + { + Serial._rx_complete_irq(); + } + +#if defined(UART0_UDRE_vect) +ISR(UART0_UDRE_vect) +#elif defined(UART_UDRE_vect) +ISR(UART_UDRE_vect) +#elif defined(USART0_UDRE_vect) +ISR(USART0_UDRE_vect) +#elif defined(USART_UDRE_vect) +ISR(USART_UDRE_vect) +#else + #error "Don't know what the Data Register Empty vector is called for Serial" +#endif +{ + Serial._tx_udr_empty_irq(); +} + +#if defined(UBRRH) && defined(UBRRL) + HardwareSerial Serial(&UBRRH, &UBRRL, &UCSRA, &UCSRB, &UCSRC, &UDR); +#else + HardwareSerial Serial(&UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UCSR0C, &UDR0); +#endif + +// Function that can be weakly referenced by serialEventRun to prevent +// pulling in this file if it's not otherwise used. +bool Serial0_available() { + return Serial.available(); +} + +#endif // HAVE_HWSERIAL0 diff --git a/hardware/ijhack/avr/cores/arduino/HardwareSerial1.cpp b/hardware/ijhack/avr/cores/arduino/HardwareSerial1.cpp new file mode 100644 index 0000000..19625e2 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/HardwareSerial1.cpp @@ -0,0 +1,69 @@ +/* + HardwareSerial1.cpp - Hardware serial library for Wiring + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 23 November 2006 by David A. Mellis + Modified 28 September 2010 by Mark Sproul + Modified 14 August 2012 by Alarus + Modified 3 December 2013 by Matthijs Kooijman +*/ + +#include "Arduino.h" +#include "HardwareSerial.h" +#include "HardwareSerial_private.h" + +// Each HardwareSerial is defined in its own file, sine the linker pulls +// in the entire file when any element inside is used. --gc-sections can +// additionally cause unused symbols to be dropped, but ISRs have the +// "used" attribute so are never dropped and they keep the +// HardwareSerial instance in as well. Putting each instance in its own +// file prevents the linker from pulling in any unused instances in the +// first place. + +#if defined(HAVE_HWSERIAL1) + +#if defined(UART1_RX_vect) +ISR(UART1_RX_vect) +#elif defined(USART1_RX_vect) +ISR(USART1_RX_vect) +#else +#error "Don't know what the Data Register Empty vector is called for Serial1" +#endif +{ + Serial1._rx_complete_irq(); +} + +#if defined(UART1_UDRE_vect) +ISR(UART1_UDRE_vect) +#elif defined(USART1_UDRE_vect) +ISR(USART1_UDRE_vect) +#else +#error "Don't know what the Data Register Empty vector is called for Serial1" +#endif +{ + Serial1._tx_udr_empty_irq(); +} + +HardwareSerial Serial1(&UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UCSR1C, &UDR1); + +// Function that can be weakly referenced by serialEventRun to prevent +// pulling in this file if it's not otherwise used. +bool Serial1_available() { + return Serial1.available(); +} + +#endif // HAVE_HWSERIAL1 diff --git a/hardware/ijhack/avr/cores/arduino/HardwareSerial2.cpp b/hardware/ijhack/avr/cores/arduino/HardwareSerial2.cpp new file mode 100644 index 0000000..fd334ae --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/HardwareSerial2.cpp @@ -0,0 +1,57 @@ +/* + HardwareSerial2.cpp - Hardware serial library for Wiring + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 23 November 2006 by David A. Mellis + Modified 28 September 2010 by Mark Sproul + Modified 14 August 2012 by Alarus + Modified 3 December 2013 by Matthijs Kooijman +*/ + +#include "Arduino.h" +#include "HardwareSerial.h" +#include "HardwareSerial_private.h" + +// Each HardwareSerial is defined in its own file, sine the linker pulls +// in the entire file when any element inside is used. --gc-sections can +// additionally cause unused symbols to be dropped, but ISRs have the +// "used" attribute so are never dropped and they keep the +// HardwareSerial instance in as well. Putting each instance in its own +// file prevents the linker from pulling in any unused instances in the +// first place. + +#if defined(HAVE_HWSERIAL2) + +ISR(USART2_RX_vect) +{ + Serial2._rx_complete_irq(); +} + +ISR(USART2_UDRE_vect) +{ + Serial2._tx_udr_empty_irq(); +} + +HardwareSerial Serial2(&UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UCSR2C, &UDR2); + +// Function that can be weakly referenced by serialEventRun to prevent +// pulling in this file if it's not otherwise used. +bool Serial2_available() { + return Serial2.available(); +} + +#endif // HAVE_HWSERIAL2 diff --git a/hardware/ijhack/avr/cores/arduino/HardwareSerial3.cpp b/hardware/ijhack/avr/cores/arduino/HardwareSerial3.cpp new file mode 100644 index 0000000..a68095b --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/HardwareSerial3.cpp @@ -0,0 +1,57 @@ +/* + HardwareSerial3.cpp - Hardware serial library for Wiring + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 23 November 2006 by David A. Mellis + Modified 28 September 2010 by Mark Sproul + Modified 14 August 2012 by Alarus + Modified 3 December 2013 by Matthijs Kooijman +*/ + +#include "Arduino.h" +#include "HardwareSerial.h" +#include "HardwareSerial_private.h" + +// Each HardwareSerial is defined in its own file, sine the linker pulls +// in the entire file when any element inside is used. --gc-sections can +// additionally cause unused symbols to be dropped, but ISRs have the +// "used" attribute so are never dropped and they keep the +// HardwareSerial instance in as well. Putting each instance in its own +// file prevents the linker from pulling in any unused instances in the +// first place. + +#if defined(HAVE_HWSERIAL3) + +ISR(USART3_RX_vect) +{ + Serial3._rx_complete_irq(); +} + +ISR(USART3_UDRE_vect) +{ + Serial3._tx_udr_empty_irq(); +} + +HardwareSerial Serial3(&UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UCSR3C, &UDR3); + +// Function that can be weakly referenced by serialEventRun to prevent +// pulling in this file if it's not otherwise used. +bool Serial3_available() { + return Serial3.available(); +} + +#endif // HAVE_HWSERIAL3 diff --git a/hardware/ijhack/avr/cores/arduino/HardwareSerial_private.h b/hardware/ijhack/avr/cores/arduino/HardwareSerial_private.h new file mode 100644 index 0000000..761a5e5 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/HardwareSerial_private.h @@ -0,0 +1,123 @@ +/* + HardwareSerial_private.h - Hardware serial library for Wiring + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 23 November 2006 by David A. Mellis + Modified 28 September 2010 by Mark Sproul + Modified 14 August 2012 by Alarus +*/ + +#include "wiring_private.h" + +// this next line disables the entire HardwareSerial.cpp, +// this is so I can support Attiny series and any other chip without a uart +#if defined(HAVE_HWSERIAL0) || defined(HAVE_HWSERIAL1) || defined(HAVE_HWSERIAL2) || defined(HAVE_HWSERIAL3) + +// Ensure that the various bit positions we use are available with a 0 +// postfix, so we can always use the values for UART0 for all UARTs. The +// alternative, passing the various values for each UART to the +// HardwareSerial constructor also works, but makes the code bigger and +// slower. +#if !defined(TXC0) +#if defined(TXC) +// Some chips like ATmega8 don't have UPE, only PE. The other bits are +// named as expected. +#if !defined(UPE) && defined(PE) +#define UPE PE +#endif +// On ATmega8, the uart and its bits are not numbered, so there is no TXC0 etc. +#define TXC0 TXC +#define RXEN0 RXEN +#define TXEN0 TXEN +#define RXCIE0 RXCIE +#define UDRIE0 UDRIE +#define U2X0 U2X +#define UPE0 UPE +#define UDRE0 UDRE +#elif defined(TXC1) +// Some devices have uart1 but no uart0 +#define TXC0 TXC1 +#define RXEN0 RXEN1 +#define TXEN0 TXEN1 +#define RXCIE0 RXCIE1 +#define UDRIE0 UDRIE1 +#define U2X0 U2X1 +#define UPE0 UPE1 +#define UDRE0 UDRE1 +#else +#error No UART found in HardwareSerial.cpp +#endif +#endif // !defined TXC0 + +// Check at compiletime that it is really ok to use the bit positions of +// UART0 for the other UARTs as well, in case these values ever get +// changed for future hardware. +#if defined(TXC1) && (TXC1 != TXC0 || RXEN1 != RXEN0 || RXCIE1 != RXCIE0 || \ + UDRIE1 != UDRIE0 || U2X1 != U2X0 || UPE1 != UPE0 || \ + UDRE1 != UDRE0) +#error "Not all bit positions for UART1 are the same as for UART0" +#endif +#if defined(TXC2) && (TXC2 != TXC0 || RXEN2 != RXEN0 || RXCIE2 != RXCIE0 || \ + UDRIE2 != UDRIE0 || U2X2 != U2X0 || UPE2 != UPE0 || \ + UDRE2 != UDRE0) +#error "Not all bit positions for UART2 are the same as for UART0" +#endif +#if defined(TXC3) && (TXC3 != TXC0 || RXEN3 != RXEN0 || RXCIE3 != RXCIE0 || \ + UDRIE3 != UDRIE0 || U3X3 != U3X0 || UPE3 != UPE0 || \ + UDRE3 != UDRE0) +#error "Not all bit positions for UART3 are the same as for UART0" +#endif + +// Constructors //////////////////////////////////////////////////////////////// + +HardwareSerial::HardwareSerial( + volatile uint8_t *ubrrh, volatile uint8_t *ubrrl, + volatile uint8_t *ucsra, volatile uint8_t *ucsrb, + volatile uint8_t *ucsrc, volatile uint8_t *udr) : + _ubrrh(ubrrh), _ubrrl(ubrrl), + _ucsra(ucsra), _ucsrb(ucsrb), _ucsrc(ucsrc), + _udr(udr), + _rx_buffer_head(0), _rx_buffer_tail(0), + _tx_buffer_head(0), _tx_buffer_tail(0) +{ +} + +// Actual interrupt handlers ////////////////////////////////////////////////////////////// + +void HardwareSerial::_rx_complete_irq(void) +{ + if (bit_is_clear(*_ucsra, UPE0)) { + // No Parity error, read byte and store it in the buffer if there is + // room + unsigned char c = *_udr; + rx_buffer_index_t i = (unsigned int)(_rx_buffer_head + 1) % SERIAL_RX_BUFFER_SIZE; + + // if we should be storing the received character into the location + // just before the tail (meaning that the head would advance to the + // current location of the tail), we're about to overflow the buffer + // and so we don't write the character or advance the head. + if (i != _rx_buffer_tail) { + _rx_buffer[_rx_buffer_head] = c; + _rx_buffer_head = i; + } + } else { + // Parity error, read byte but discard it + *_udr; + }; +} + +#endif // whole file diff --git a/hardware/ijhack/avr/cores/arduino/IPAddress.cpp b/hardware/ijhack/avr/cores/arduino/IPAddress.cpp new file mode 100644 index 0000000..899cbd4 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/IPAddress.cpp @@ -0,0 +1,74 @@ +/* + IPAddress.cpp - Base class that provides IPAddress + Copyright (c) 2011 Adrian McEwen. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include + +IPAddress::IPAddress() +{ + _address.dword = 0; +} + +IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) +{ + _address.bytes[0] = first_octet; + _address.bytes[1] = second_octet; + _address.bytes[2] = third_octet; + _address.bytes[3] = fourth_octet; +} + +IPAddress::IPAddress(uint32_t address) +{ + _address.dword = address; +} + +IPAddress::IPAddress(const uint8_t *address) +{ + memcpy(_address.bytes, address, sizeof(_address.bytes)); +} + +IPAddress& IPAddress::operator=(const uint8_t *address) +{ + memcpy(_address.bytes, address, sizeof(_address.bytes)); + return *this; +} + +IPAddress& IPAddress::operator=(uint32_t address) +{ + _address.dword = address; + return *this; +} + +bool IPAddress::operator==(const uint8_t* addr) const +{ + return memcmp(addr, _address.bytes, sizeof(_address.bytes)) == 0; +} + +size_t IPAddress::printTo(Print& p) const +{ + size_t n = 0; + for (int i =0; i < 3; i++) + { + n += p.print(_address.bytes[i], DEC); + n += p.print('.'); + } + n += p.print(_address.bytes[3], DEC); + return n; +} + diff --git a/hardware/ijhack/avr/cores/arduino/IPAddress.h b/hardware/ijhack/avr/cores/arduino/IPAddress.h new file mode 100644 index 0000000..94acdc4 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/IPAddress.h @@ -0,0 +1,75 @@ +/* + IPAddress.h - Base class that provides IPAddress + Copyright (c) 2011 Adrian McEwen. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef IPAddress_h +#define IPAddress_h + +#include +#include + +// A class to make it easier to handle and pass around IP addresses + +class IPAddress : public Printable { +private: + union { + uint8_t bytes[4]; // IPv4 address + uint32_t dword; + } _address; + + // Access the raw byte array containing the address. Because this returns a pointer + // to the internal structure rather than a copy of the address this function should only + // be used when you know that the usage of the returned uint8_t* will be transient and not + // stored. + uint8_t* raw_address() { return _address.bytes; }; + +public: + // Constructors + IPAddress(); + IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet); + IPAddress(uint32_t address); + IPAddress(const uint8_t *address); + + // Overloaded cast operator to allow IPAddress objects to be used where a pointer + // to a four-byte uint8_t array is expected + operator uint32_t() const { return _address.dword; }; + bool operator==(const IPAddress& addr) const { return _address.dword == addr._address.dword; }; + bool operator==(const uint8_t* addr) const; + + // Overloaded index operator to allow getting and setting individual octets of the address + uint8_t operator[](int index) const { return _address.bytes[index]; }; + uint8_t& operator[](int index) { return _address.bytes[index]; }; + + // Overloaded copy operators to allow initialisation of IPAddress objects from other types + IPAddress& operator=(const uint8_t *address); + IPAddress& operator=(uint32_t address); + + virtual size_t printTo(Print& p) const; + + friend class EthernetClass; + friend class UDP; + friend class Client; + friend class Server; + friend class DhcpClass; + friend class DNSClient; +}; + +const IPAddress INADDR_NONE(0,0,0,0); + + +#endif diff --git a/hardware/ijhack/avr/cores/arduino/Print.cpp b/hardware/ijhack/avr/cores/arduino/Print.cpp new file mode 100644 index 0000000..5df5630 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/Print.cpp @@ -0,0 +1,264 @@ +/* + Print.cpp - Base class that provides print() and println() + Copyright (c) 2008 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 23 November 2006 by David A. Mellis + */ + +#include +#include +#include +#include +#include "Arduino.h" + +#include "Print.h" + +// Public Methods ////////////////////////////////////////////////////////////// + +/* default implementation: may be overridden */ +size_t Print::write(const uint8_t *buffer, size_t size) +{ + size_t n = 0; + while (size--) { + n += write(*buffer++); + } + return n; +} + +size_t Print::print(const __FlashStringHelper *ifsh) +{ + PGM_P p = reinterpret_cast(ifsh); + size_t n = 0; + while (1) { + unsigned char c = pgm_read_byte(p++); + if (c == 0) break; + n += write(c); + } + return n; +} + +size_t Print::print(const String &s) +{ + return write(s.c_str(), s.length()); +} + +size_t Print::print(const char str[]) +{ + return write(str); +} + +size_t Print::print(char c) +{ + return write(c); +} + +size_t Print::print(unsigned char b, int base) +{ + return print((unsigned long) b, base); +} + +size_t Print::print(int n, int base) +{ + return print((long) n, base); +} + +size_t Print::print(unsigned int n, int base) +{ + return print((unsigned long) n, base); +} + +size_t Print::print(long n, int base) +{ + if (base == 0) { + return write(n); + } else if (base == 10) { + if (n < 0) { + int t = print('-'); + n = -n; + return printNumber(n, 10) + t; + } + return printNumber(n, 10); + } else { + return printNumber(n, base); + } +} + +size_t Print::print(unsigned long n, int base) +{ + if (base == 0) return write(n); + else return printNumber(n, base); +} + +size_t Print::print(double n, int digits) +{ + return printFloat(n, digits); +} + +size_t Print::println(const __FlashStringHelper *ifsh) +{ + size_t n = print(ifsh); + n += println(); + return n; +} + +size_t Print::print(const Printable& x) +{ + return x.printTo(*this); +} + +size_t Print::println(void) +{ + size_t n = print('\r'); + n += print('\n'); + return n; +} + +size_t Print::println(const String &s) +{ + size_t n = print(s); + n += println(); + return n; +} + +size_t Print::println(const char c[]) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(char c) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(unsigned char b, int base) +{ + size_t n = print(b, base); + n += println(); + return n; +} + +size_t Print::println(int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(double num, int digits) +{ + size_t n = print(num, digits); + n += println(); + return n; +} + +size_t Print::println(const Printable& x) +{ + size_t n = print(x); + n += println(); + return n; +} + +// Private Methods ///////////////////////////////////////////////////////////// + +size_t Print::printNumber(unsigned long n, uint8_t base) { + char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. + char *str = &buf[sizeof(buf) - 1]; + + *str = '\0'; + + // prevent crash if called with base == 1 + if (base < 2) base = 10; + + do { + unsigned long m = n; + n /= base; + char c = m - base * n; + *--str = c < 10 ? c + '0' : c + 'A' - 10; + } while(n); + + return write(str); +} + +size_t Print::printFloat(double number, uint8_t digits) +{ + size_t n = 0; + + if (isnan(number)) return print("nan"); + if (isinf(number)) return print("inf"); + if (number > 4294967040.0) return print ("ovf"); // constant determined empirically + if (number <-4294967040.0) return print ("ovf"); // constant determined empirically + + // Handle negative numbers + if (number < 0.0) + { + n += print('-'); + number = -number; + } + + // Round correctly so that print(1.999, 2) prints as "2.00" + double rounding = 0.5; + for (uint8_t i=0; i 0) { + n += print("."); + } + + // Extract digits from the remainder one at a time + while (digits-- > 0) + { + remainder *= 10.0; + int toPrint = int(remainder); + n += print(toPrint); + remainder -= toPrint; + } + + return n; +} diff --git a/hardware/ijhack/avr/cores/arduino/Print.h b/hardware/ijhack/avr/cores/arduino/Print.h new file mode 100644 index 0000000..7b53aa4 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/Print.h @@ -0,0 +1,84 @@ +/* + Print.h - Base class that provides print() and println() + Copyright (c) 2008 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Print_h +#define Print_h + +#include +#include // for size_t + +#include "WString.h" +#include "Printable.h" + +#define DEC 10 +#define HEX 16 +#define OCT 8 +#define BIN 2 + +class Print +{ + private: + int write_error; + size_t printNumber(unsigned long, uint8_t); + size_t printFloat(double, uint8_t); + protected: + void setWriteError(int err = 1) { write_error = err; } + public: + Print() : write_error(0) {} + + int getWriteError() { return write_error; } + void clearWriteError() { setWriteError(0); } + + virtual size_t write(uint8_t) = 0; + size_t write(const char *str) { + if (str == NULL) return 0; + return write((const uint8_t *)str, strlen(str)); + } + virtual size_t write(const uint8_t *buffer, size_t size); + size_t write(const char *buffer, size_t size) { + return write((const uint8_t *)buffer, size); + } + + size_t print(const __FlashStringHelper *); + size_t print(const String &); + size_t print(const char[]); + size_t print(char); + size_t print(unsigned char, int = DEC); + size_t print(int, int = DEC); + size_t print(unsigned int, int = DEC); + size_t print(long, int = DEC); + size_t print(unsigned long, int = DEC); + size_t print(double, int = 2); + size_t print(const Printable&); + + size_t println(const __FlashStringHelper *); + size_t println(const String &s); + size_t println(const char[]); + size_t println(char); + size_t println(unsigned char, int = DEC); + size_t println(int, int = DEC); + size_t println(unsigned int, int = DEC); + size_t println(long, int = DEC); + size_t println(unsigned long, int = DEC); + size_t println(double, int = 2); + size_t println(const Printable&); + size_t println(void); +}; + +#endif diff --git a/hardware/ijhack/avr/cores/arduino/Printable.h b/hardware/ijhack/avr/cores/arduino/Printable.h new file mode 100644 index 0000000..2a1b2e9 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/Printable.h @@ -0,0 +1,40 @@ +/* + Printable.h - Interface class that allows printing of complex types + Copyright (c) 2011 Adrian McEwen. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Printable_h +#define Printable_h + +#include + +class Print; + +/** The Printable class provides a way for new classes to allow themselves to be printed. + By deriving from Printable and implementing the printTo method, it will then be possible + for users to print out instances of this class by passing them into the usual + Print::print and Print::println methods. +*/ + +class Printable +{ + public: + virtual size_t printTo(Print& p) const = 0; +}; + +#endif + diff --git a/hardware/ijhack/avr/cores/arduino/Server.h b/hardware/ijhack/avr/cores/arduino/Server.h new file mode 100644 index 0000000..69e3e39 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/Server.h @@ -0,0 +1,30 @@ +/* + Server.h - Base class that provides Server + Copyright (c) 2011 Adrian McEwen. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef server_h +#define server_h + +#include "Print.h" + +class Server : public Print { +public: + virtual void begin() =0; +}; + +#endif diff --git a/hardware/ijhack/avr/cores/arduino/Stream.cpp b/hardware/ijhack/avr/cores/arduino/Stream.cpp new file mode 100644 index 0000000..b31942f --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/Stream.cpp @@ -0,0 +1,317 @@ +/* + Stream.cpp - adds parsing methods to Stream class + Copyright (c) 2008 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Created July 2011 + parsing functions based on TextFinder library by Michael Margolis + + findMulti/findUntil routines written by Jim Leonard/Xuth + */ + +#include "Arduino.h" +#include "Stream.h" + +#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait +#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field + +// private method to read stream with timeout +int Stream::timedRead() +{ + int c; + _startMillis = millis(); + do { + c = read(); + if (c >= 0) return c; + } while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// private method to peek stream with timeout +int Stream::timedPeek() +{ + int c; + _startMillis = millis(); + do { + c = peek(); + if (c >= 0) return c; + } while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// returns peek of the next digit in the stream or -1 if timeout +// discards non-numeric characters +int Stream::peekNextDigit() +{ + int c; + while (1) { + c = timedPeek(); + if (c < 0) return c; // timeout + if (c == '-') return c; + if (c >= '0' && c <= '9') return c; + read(); // discard non-numeric + } +} + +// Public Methods +////////////////////////////////////////////////////////////// + +void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait +{ + _timeout = timeout; +} + + // find returns true if the target string is found +bool Stream::find(char *target) +{ + return findUntil(target, strlen(target), NULL, 0); +} + +// reads data from the stream until the target string of given length is found +// returns true if target string is found, false if timed out +bool Stream::find(char *target, size_t length) +{ + return findUntil(target, length, NULL, 0); +} + +// as find but search ends if the terminator string is found +bool Stream::findUntil(char *target, char *terminator) +{ + return findUntil(target, strlen(target), terminator, strlen(terminator)); +} + +// reads data from the stream until the target string of the given length is found +// search terminated if the terminator string is found +// returns true if target string is found, false if terminated or timed out +bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen) +{ + if (terminator == NULL) { + MultiTarget t[1] = {{target, targetLen, 0}}; + return findMulti(t, 1) == 0 ? true : false; + } else { + MultiTarget t[2] = {{target, targetLen, 0}, {terminator, termLen, 0}}; + return findMulti(t, 2) == 0 ? true : false; + } +} + + +// returns the first valid (long) integer value from the current position. +// initial characters that are not digits (or the minus sign) are skipped +// function is terminated by the first character that is not a digit. +long Stream::parseInt() +{ + return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout) +} + +// as above but a given skipChar is ignored +// this allows format characters (typically commas) in values to be ignored +long Stream::parseInt(char skipChar) +{ + bool isNegative = false; + long value = 0; + int c; + + c = peekNextDigit(); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do{ + if(c == skipChar) + ; // ignore this charactor + else if(c == '-') + isNegative = true; + else if(c >= '0' && c <= '9') // is c a digit? + value = value * 10 + c - '0'; + read(); // consume the character we got with peek + c = timedPeek(); + } + while( (c >= '0' && c <= '9') || c == skipChar ); + + if(isNegative) + value = -value; + return value; +} + + +// as parseInt but returns a floating point value +float Stream::parseFloat() +{ + return parseFloat(NO_SKIP_CHAR); +} + +// as above but the given skipChar is ignored +// this allows format characters (typically commas) in values to be ignored +float Stream::parseFloat(char skipChar){ + bool isNegative = false; + bool isFraction = false; + long value = 0; + char c; + float fraction = 1.0; + + c = peekNextDigit(); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do{ + if(c == skipChar) + ; // ignore + else if(c == '-') + isNegative = true; + else if (c == '.') + isFraction = true; + else if(c >= '0' && c <= '9') { // is c a digit? + value = value * 10 + c - '0'; + if(isFraction) + fraction *= 0.1; + } + read(); // consume the character we got with peek + c = timedPeek(); + } + while( (c >= '0' && c <= '9') || c == '.' || c == skipChar ); + + if(isNegative) + value = -value; + if(isFraction) + return value * fraction; + else + return value; +} + +// read characters from stream into buffer +// terminates if length characters have been read, or timeout (see setTimeout) +// returns the number of characters placed in the buffer +// the buffer is NOT null terminated. +// +size_t Stream::readBytes(char *buffer, size_t length) +{ + size_t count = 0; + while (count < length) { + int c = timedRead(); + if (c < 0) break; + *buffer++ = (char)c; + count++; + } + return count; +} + + +// as readBytes with terminator character +// terminates if length characters have been read, timeout, or if the terminator character detected +// returns the number of characters placed in the buffer (0 means no valid data found) + +size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) +{ + if (length < 1) return 0; + size_t index = 0; + while (index < length) { + int c = timedRead(); + if (c < 0 || c == terminator) break; + *buffer++ = (char)c; + index++; + } + return index; // return number of characters, not including null terminator +} + +String Stream::readString() +{ + String ret; + int c = timedRead(); + while (c >= 0) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + +String Stream::readStringUntil(char terminator) +{ + String ret; + int c = timedRead(); + while (c >= 0 && c != terminator) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + +int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) { + // any zero length target string automatically matches and would make + // a mess of the rest of the algorithm. + for (struct MultiTarget *t = targets; t < targets+tCount; ++t) { + if (t->len <= 0) + return t - targets; + } + + while (1) { + int c = timedRead(); + if (c < 0) + return -1; + + for (struct MultiTarget *t = targets; t < targets+tCount; ++t) { + // the simple case is if we match, deal with that first. + if (c == t->str[t->index]) { + if (++t->index == t->len) + return t - targets; + else + continue; + } + + // if not we need to walk back and see if we could have matched further + // down the stream (ie '1112' doesn't match the first position in '11112' + // but it will match the second position so we can't just reset the current + // index to 0 when we find a mismatch. + if (t->index == 0) + continue; + + int origIndex = t->index; + do { + --t->index; + // first check if current char works against the new current index + if (c != t->str[t->index]) + continue; + + // if it's the only char then we're good, nothing more to check + if (t->index == 0) { + t->index++; + break; + } + + // otherwise we need to check the rest of the found string + int diff = origIndex - t->index; + size_t i; + for (i = 0; i < t->index; ++i) { + if (t->str[i] != t->str[i + diff]) + break; + } + + // if we successfully got through the previous loop then our current + // index is good. + if (i == t->index) { + t->index++; + break; + } + + // otherwise we just try the next index + } while (t->index); + } + } + // unreachable + return -1; +} diff --git a/hardware/ijhack/avr/cores/arduino/Stream.h b/hardware/ijhack/avr/cores/arduino/Stream.h new file mode 100644 index 0000000..a810132 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/Stream.h @@ -0,0 +1,113 @@ +/* + Stream.h - base class for character-based streams. + Copyright (c) 2010 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + parsing functions based on TextFinder library by Michael Margolis +*/ + +#ifndef Stream_h +#define Stream_h + +#include +#include "Print.h" + +// compatability macros for testing +/* +#define getInt() parseInt() +#define getInt(skipChar) parseInt(skipchar) +#define getFloat() parseFloat() +#define getFloat(skipChar) parseFloat(skipChar) +#define getString( pre_string, post_string, buffer, length) +readBytesBetween( pre_string, terminator, buffer, length) +*/ + +class Stream : public Print +{ + protected: + unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read + unsigned long _startMillis; // used for timeout measurement + int timedRead(); // private method to read stream with timeout + int timedPeek(); // private method to peek stream with timeout + int peekNextDigit(); // returns the next numeric digit in the stream or -1 if timeout + + public: + virtual int available() = 0; + virtual int read() = 0; + virtual int peek() = 0; + virtual void flush() = 0; + + Stream() {_timeout=1000;} + +// parsing methods + + void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second + + bool find(char *target); // reads data from the stream until the target string is found + bool find(uint8_t *target) { return find ((char *)target); } + // returns true if target string is found, false if timed out (see setTimeout) + + bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found + bool find(uint8_t *target, size_t length) { return find ((char *)target, length); } + // returns true if target string is found, false if timed out + + bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found + bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); } + + bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found + bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); } + + + long parseInt(); // returns the first valid (long) integer value from the current position. + // initial characters that are not digits (or the minus sign) are skipped + // integer is terminated by the first character that is not a digit. + + float parseFloat(); // float version of parseInt + + size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer + size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); } + // terminates if length characters have been read or timeout (see setTimeout) + // returns the number of characters placed in the buffer (0 means no valid data found) + + size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character + size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); } + // terminates if length characters have been read, timeout, or if the terminator character detected + // returns the number of characters placed in the buffer (0 means no valid data found) + + // Arduino String functions to be added here + String readString(); + String readStringUntil(char terminator); + + protected: + long parseInt(char skipChar); // as above but the given skipChar is ignored + // as above but the given skipChar is ignored + // this allows format characters (typically commas) in values to be ignored + + float parseFloat(char skipChar); // as above but the given skipChar is ignored + + struct MultiTarget { + const char *str; // string you're searching for + size_t len; // length of string you're searching for + size_t index; // index used by the search routine. + }; + + // This allows you to search for an arbitrary number of strings. + // Returns index of the target that is found first or -1 if timeout occurs. + int findMulti(struct MultiTarget *targets, int tCount); +}; + + +#endif diff --git a/hardware/ijhack/avr/cores/arduino/Tone.cpp b/hardware/ijhack/avr/cores/arduino/Tone.cpp new file mode 100644 index 0000000..7216219 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/Tone.cpp @@ -0,0 +1,618 @@ +/* Tone.cpp + + A Tone Generator Library + + Written by Brett Hagman + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Version Modified By Date Comments +------- ----------- -------- -------- +0001 B Hagman 09/08/02 Initial coding +0002 B Hagman 09/08/18 Multiple pins +0003 B Hagman 09/08/18 Moved initialization from constructor to begin() +0004 B Hagman 09/09/26 Fixed problems with ATmega8 +0005 B Hagman 09/11/23 Scanned prescalars for best fit on 8 bit timers + 09/11/25 Changed pin toggle method to XOR + 09/11/25 Fixed timer0 from being excluded +0006 D Mellis 09/12/29 Replaced objects with functions +0007 M Sproul 10/08/29 Changed #ifdefs from cpu to register +0008 S Kanemoto 12/06/22 Fixed for Leonardo by @maris_HY +0009 J Reucker 15/04/10 Issue #292 Fixed problems with ATmega8 (thanks to Pete62) +0010 jipp 15/04/13 added additional define check #2923 +*************************************************/ + +#include +#include +#include "Arduino.h" +#include "pins_arduino.h" + +#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega128__) +#define TCCR2A TCCR2 +#define TCCR2B TCCR2 +#define COM2A1 COM21 +#define COM2A0 COM20 +#define OCR2A OCR2 +#define TIMSK2 TIMSK +#define OCIE2A OCIE2 +#define TIMER2_COMPA_vect TIMER2_COMP_vect +#define TIMSK1 TIMSK +#endif + +// timerx_toggle_count: +// > 0 - duration specified +// = 0 - stopped +// < 0 - infinitely (until stop() method called, or new play() called) + +#if !defined(__AVR_ATmega8__) +volatile long timer0_toggle_count; +volatile uint8_t *timer0_pin_port; +volatile uint8_t timer0_pin_mask; +#endif + +volatile long timer1_toggle_count; +volatile uint8_t *timer1_pin_port; +volatile uint8_t timer1_pin_mask; +volatile long timer2_toggle_count; +volatile uint8_t *timer2_pin_port; +volatile uint8_t timer2_pin_mask; + +#if defined(TIMSK3) +volatile long timer3_toggle_count; +volatile uint8_t *timer3_pin_port; +volatile uint8_t timer3_pin_mask; +#endif + +#if defined(TIMSK4) +volatile long timer4_toggle_count; +volatile uint8_t *timer4_pin_port; +volatile uint8_t timer4_pin_mask; +#endif + +#if defined(TIMSK5) +volatile long timer5_toggle_count; +volatile uint8_t *timer5_pin_port; +volatile uint8_t timer5_pin_mask; +#endif + + +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + +#define AVAILABLE_TONE_PINS 1 +#define USE_TIMER2 + +const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 3, 4, 5, 1, 0 */ }; +static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255, 255, 255, 255 */ }; + +#elif defined(__AVR_ATmega8__) + +#define AVAILABLE_TONE_PINS 1 +#define USE_TIMER2 + +const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 1 */ }; +static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255 */ }; + +#elif defined(__AVR_ATmega32U4__) + +#define AVAILABLE_TONE_PINS 1 +#define USE_TIMER3 + +const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 3 /*, 1 */ }; +static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255 */ }; + +#else + +#define AVAILABLE_TONE_PINS 1 +#define USE_TIMER2 + +// Leave timer 0 to last. +const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 1, 0 */ }; +static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255 */ }; + +#endif + + + +static int8_t toneBegin(uint8_t _pin) +{ + int8_t _timer = -1; + + // if we're already using the pin, the timer should be configured. + for (int i = 0; i < AVAILABLE_TONE_PINS; i++) { + if (tone_pins[i] == _pin) { + return pgm_read_byte(tone_pin_to_timer_PGM + i); + } + } + + // search for an unused timer. + for (int i = 0; i < AVAILABLE_TONE_PINS; i++) { + if (tone_pins[i] == 255) { + tone_pins[i] = _pin; + _timer = pgm_read_byte(tone_pin_to_timer_PGM + i); + break; + } + } + + if (_timer != -1) + { + // Set timer specific stuff + // All timers in CTC mode + // 8 bit timers will require changing prescalar values, + // whereas 16 bit timers are set to either ck/1 or ck/64 prescalar + switch (_timer) + { + #if defined(TCCR0A) && defined(TCCR0B) && defined(WGM01) + case 0: + // 8 bit timer + TCCR0A = 0; + TCCR0B = 0; + bitWrite(TCCR0A, WGM01, 1); + bitWrite(TCCR0B, CS00, 1); + timer0_pin_port = portOutputRegister(digitalPinToPort(_pin)); + timer0_pin_mask = digitalPinToBitMask(_pin); + break; + #endif + + #if defined(TCCR1A) && defined(TCCR1B) && defined(WGM12) + case 1: + // 16 bit timer + TCCR1A = 0; + TCCR1B = 0; + bitWrite(TCCR1B, WGM12, 1); + bitWrite(TCCR1B, CS10, 1); + timer1_pin_port = portOutputRegister(digitalPinToPort(_pin)); + timer1_pin_mask = digitalPinToBitMask(_pin); + break; + #endif + + #if defined(TCCR2A) && defined(TCCR2B) + case 2: + // 8 bit timer + TCCR2A = 0; + TCCR2B = 0; + bitWrite(TCCR2A, WGM21, 1); + bitWrite(TCCR2B, CS20, 1); + timer2_pin_port = portOutputRegister(digitalPinToPort(_pin)); + timer2_pin_mask = digitalPinToBitMask(_pin); + break; + #endif + + #if defined(TCCR3A) && defined(TCCR3B) && defined(TIMSK3) + case 3: + // 16 bit timer + TCCR3A = 0; + TCCR3B = 0; + bitWrite(TCCR3B, WGM32, 1); + bitWrite(TCCR3B, CS30, 1); + timer3_pin_port = portOutputRegister(digitalPinToPort(_pin)); + timer3_pin_mask = digitalPinToBitMask(_pin); + break; + #endif + + #if defined(TCCR4A) && defined(TCCR4B) && defined(TIMSK4) + case 4: + // 16 bit timer + TCCR4A = 0; + TCCR4B = 0; + #if defined(WGM42) + bitWrite(TCCR4B, WGM42, 1); + #elif defined(CS43) + #warning this may not be correct + // atmega32u4 + bitWrite(TCCR4B, CS43, 1); + #endif + bitWrite(TCCR4B, CS40, 1); + timer4_pin_port = portOutputRegister(digitalPinToPort(_pin)); + timer4_pin_mask = digitalPinToBitMask(_pin); + break; + #endif + + #if defined(TCCR5A) && defined(TCCR5B) && defined(TIMSK5) + case 5: + // 16 bit timer + TCCR5A = 0; + TCCR5B = 0; + bitWrite(TCCR5B, WGM52, 1); + bitWrite(TCCR5B, CS50, 1); + timer5_pin_port = portOutputRegister(digitalPinToPort(_pin)); + timer5_pin_mask = digitalPinToBitMask(_pin); + break; + #endif + } + } + + return _timer; +} + + + +// frequency (in hertz) and duration (in milliseconds). + +void tone(uint8_t _pin, unsigned int frequency, unsigned long duration) +{ + uint8_t prescalarbits = 0b001; + long toggle_count = 0; + uint32_t ocr = 0; + int8_t _timer; + + _timer = toneBegin(_pin); + + if (_timer >= 0) + { + // Set the pinMode as OUTPUT + pinMode(_pin, OUTPUT); + + // if we are using an 8 bit timer, scan through prescalars to find the best fit + if (_timer == 0 || _timer == 2) + { + ocr = F_CPU / frequency / 2 - 1; + prescalarbits = 0b001; // ck/1: same for both timers + if (ocr > 255) + { + ocr = F_CPU / frequency / 2 / 8 - 1; + prescalarbits = 0b010; // ck/8: same for both timers + + if (_timer == 2 && ocr > 255) + { + ocr = F_CPU / frequency / 2 / 32 - 1; + prescalarbits = 0b011; + } + + if (ocr > 255) + { + ocr = F_CPU / frequency / 2 / 64 - 1; + prescalarbits = _timer == 0 ? 0b011 : 0b100; + + if (_timer == 2 && ocr > 255) + { + ocr = F_CPU / frequency / 2 / 128 - 1; + prescalarbits = 0b101; + } + + if (ocr > 255) + { + ocr = F_CPU / frequency / 2 / 256 - 1; + prescalarbits = _timer == 0 ? 0b100 : 0b110; + if (ocr > 255) + { + // can't do any better than /1024 + ocr = F_CPU / frequency / 2 / 1024 - 1; + prescalarbits = _timer == 0 ? 0b101 : 0b111; + } + } + } + } + +#if defined(TCCR0B) + if (_timer == 0) + { + TCCR0B = (TCCR0B & 0b11111000) | prescalarbits; + } + else +#endif +#if defined(TCCR2B) + { + TCCR2B = (TCCR2B & 0b11111000) | prescalarbits; + } +#else + { + // dummy place holder to make the above ifdefs work + } +#endif + } + else + { + // two choices for the 16 bit timers: ck/1 or ck/64 + ocr = F_CPU / frequency / 2 - 1; + + prescalarbits = 0b001; + if (ocr > 0xffff) + { + ocr = F_CPU / frequency / 2 / 64 - 1; + prescalarbits = 0b011; + } + + if (_timer == 1) + { +#if defined(TCCR1B) + TCCR1B = (TCCR1B & 0b11111000) | prescalarbits; +#endif + } +#if defined(TCCR3B) + else if (_timer == 3) + TCCR3B = (TCCR3B & 0b11111000) | prescalarbits; +#endif +#if defined(TCCR4B) + else if (_timer == 4) + TCCR4B = (TCCR4B & 0b11111000) | prescalarbits; +#endif +#if defined(TCCR5B) + else if (_timer == 5) + TCCR5B = (TCCR5B & 0b11111000) | prescalarbits; +#endif + + } + + + // Calculate the toggle count + if (duration > 0) + { + toggle_count = 2 * frequency * duration / 1000; + } + else + { + toggle_count = -1; + } + + // Set the OCR for the given timer, + // set the toggle count, + // then turn on the interrupts + switch (_timer) + { + +#if defined(OCR0A) && defined(TIMSK0) && defined(OCIE0A) + case 0: + OCR0A = ocr; + timer0_toggle_count = toggle_count; + bitWrite(TIMSK0, OCIE0A, 1); + break; +#endif + + case 1: +#if defined(OCR1A) && defined(TIMSK1) && defined(OCIE1A) + OCR1A = ocr; + timer1_toggle_count = toggle_count; + bitWrite(TIMSK1, OCIE1A, 1); +#elif defined(OCR1A) && defined(TIMSK) && defined(OCIE1A) + // this combination is for at least the ATmega32 + OCR1A = ocr; + timer1_toggle_count = toggle_count; + bitWrite(TIMSK, OCIE1A, 1); +#endif + break; + +#if defined(OCR2A) && defined(TIMSK2) && defined(OCIE2A) + case 2: + OCR2A = ocr; + timer2_toggle_count = toggle_count; + bitWrite(TIMSK2, OCIE2A, 1); + break; +#endif + +#if defined(OCR3A) && defined(TIMSK3) && defined(OCIE3A) + case 3: + OCR3A = ocr; + timer3_toggle_count = toggle_count; + bitWrite(TIMSK3, OCIE3A, 1); + break; +#endif + +#if defined(OCR4A) && defined(TIMSK4) && defined(OCIE4A) + case 4: + OCR4A = ocr; + timer4_toggle_count = toggle_count; + bitWrite(TIMSK4, OCIE4A, 1); + break; +#endif + +#if defined(OCR5A) && defined(TIMSK5) && defined(OCIE5A) + case 5: + OCR5A = ocr; + timer5_toggle_count = toggle_count; + bitWrite(TIMSK5, OCIE5A, 1); + break; +#endif + + } + } +} + + +// XXX: this function only works properly for timer 2 (the only one we use +// currently). for the others, it should end the tone, but won't restore +// proper PWM functionality for the timer. +void disableTimer(uint8_t _timer) +{ + switch (_timer) + { + case 0: + #if defined(TIMSK0) + TIMSK0 = 0; + #elif defined(TIMSK) + TIMSK = 0; // atmega32 + #endif + break; + +#if defined(TIMSK1) && defined(OCIE1A) + case 1: + bitWrite(TIMSK1, OCIE1A, 0); + break; +#endif + + case 2: + #if defined(TIMSK2) && defined(OCIE2A) + bitWrite(TIMSK2, OCIE2A, 0); // disable interrupt + #endif + #if defined(TCCR2A) && defined(WGM20) + TCCR2A = (1 << WGM20); + #endif + #if defined(TCCR2B) && defined(CS22) + TCCR2B = (TCCR2B & 0b11111000) | (1 << CS22); + #endif + #if defined(OCR2A) + OCR2A = 0; + #endif + break; + +#if defined(TIMSK3) && defined(OCIE3A) + case 3: + bitWrite(TIMSK3, OCIE3A, 0); + break; +#endif + +#if defined(TIMSK4) && defined(OCIE4A) + case 4: + bitWrite(TIMSK4, OCIE4A, 0); + break; +#endif + +#if defined(TIMSK5) && defined(OCIE5A) + case 5: + bitWrite(TIMSK5, OCIE5A, 0); + break; +#endif + } +} + + +void noTone(uint8_t _pin) +{ + int8_t _timer = -1; + + for (int i = 0; i < AVAILABLE_TONE_PINS; i++) { + if (tone_pins[i] == _pin) { + _timer = pgm_read_byte(tone_pin_to_timer_PGM + i); + tone_pins[i] = 255; + } + } + + disableTimer(_timer); + + digitalWrite(_pin, 0); +} + +#ifdef USE_TIMER0 +ISR(TIMER0_COMPA_vect) +{ + if (timer0_toggle_count != 0) + { + // toggle the pin + *timer0_pin_port ^= timer0_pin_mask; + + if (timer0_toggle_count > 0) + timer0_toggle_count--; + } + else + { + disableTimer(0); + *timer0_pin_port &= ~(timer0_pin_mask); // keep pin low after stop + } +} +#endif + + +#ifdef USE_TIMER1 +ISR(TIMER1_COMPA_vect) +{ + if (timer1_toggle_count != 0) + { + // toggle the pin + *timer1_pin_port ^= timer1_pin_mask; + + if (timer1_toggle_count > 0) + timer1_toggle_count--; + } + else + { + disableTimer(1); + *timer1_pin_port &= ~(timer1_pin_mask); // keep pin low after stop + } +} +#endif + + +#ifdef USE_TIMER2 +ISR(TIMER2_COMPA_vect) +{ + + if (timer2_toggle_count != 0) + { + // toggle the pin + *timer2_pin_port ^= timer2_pin_mask; + + if (timer2_toggle_count > 0) + timer2_toggle_count--; + } + else + { + // need to call noTone() so that the tone_pins[] entry is reset, so the + // timer gets initialized next time we call tone(). + // XXX: this assumes timer 2 is always the first one used. + noTone(tone_pins[0]); +// disableTimer(2); +// *timer2_pin_port &= ~(timer2_pin_mask); // keep pin low after stop + } +} +#endif + + +#ifdef USE_TIMER3 +ISR(TIMER3_COMPA_vect) +{ + if (timer3_toggle_count != 0) + { + // toggle the pin + *timer3_pin_port ^= timer3_pin_mask; + + if (timer3_toggle_count > 0) + timer3_toggle_count--; + } + else + { + disableTimer(3); + *timer3_pin_port &= ~(timer3_pin_mask); // keep pin low after stop + } +} +#endif + + +#ifdef USE_TIMER4 +ISR(TIMER4_COMPA_vect) +{ + if (timer4_toggle_count != 0) + { + // toggle the pin + *timer4_pin_port ^= timer4_pin_mask; + + if (timer4_toggle_count > 0) + timer4_toggle_count--; + } + else + { + disableTimer(4); + *timer4_pin_port &= ~(timer4_pin_mask); // keep pin low after stop + } +} +#endif + + +#ifdef USE_TIMER5 +ISR(TIMER5_COMPA_vect) +{ + if (timer5_toggle_count != 0) + { + // toggle the pin + *timer5_pin_port ^= timer5_pin_mask; + + if (timer5_toggle_count > 0) + timer5_toggle_count--; + } + else + { + disableTimer(5); + *timer5_pin_port &= ~(timer5_pin_mask); // keep pin low after stop + } +} +#endif diff --git a/hardware/ijhack/avr/cores/arduino/USBAPI.h b/hardware/ijhack/avr/cores/arduino/USBAPI.h new file mode 100644 index 0000000..2fab957 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/USBAPI.h @@ -0,0 +1,244 @@ +/* + USBAPI.h + Copyright (c) 2005-2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef __USBAPI__ +#define __USBAPI__ + +#include +#include +#include +#include +#include + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned long u32; + +#include "Arduino.h" + +#if defined(USBCON) + +#include "USBDesc.h" +#include "USBCore.h" + +//================================================================================ +//================================================================================ +// USB + +class USBDevice_ +{ +public: + USBDevice_(); + bool configured(); + + void attach(); + void detach(); // Serial port goes down too... + void poll(); +}; +extern USBDevice_ USBDevice; + +//================================================================================ +//================================================================================ +// Serial over CDC (Serial1 is the physical port) + +struct ring_buffer; + +#if (RAMEND < 1000) +#define SERIAL_BUFFER_SIZE 16 +#else +#define SERIAL_BUFFER_SIZE 64 +#endif + +class Serial_ : public Stream +{ +private: + int peek_buffer; +public: + Serial_() { peek_buffer = -1; }; + void begin(unsigned long); + void begin(unsigned long, uint8_t); + void end(void); + + virtual int available(void); + virtual int peek(void); + virtual int read(void); + virtual void flush(void); + virtual size_t write(uint8_t); + virtual size_t write(const uint8_t*, size_t); + using Print::write; // pull in write(str) and write(buf, size) from Print + operator bool(); + + volatile uint8_t _rx_buffer_head; + volatile uint8_t _rx_buffer_tail; + unsigned char _rx_buffer[SERIAL_BUFFER_SIZE]; +}; +extern Serial_ Serial; + +#define HAVE_CDCSERIAL + +//================================================================================ +//================================================================================ +// Mouse + +#define MOUSE_LEFT 1 +#define MOUSE_RIGHT 2 +#define MOUSE_MIDDLE 4 +#define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE) + +class Mouse_ +{ +private: + uint8_t _buttons; + void buttons(uint8_t b); +public: + Mouse_(void); + void begin(void); + void end(void); + void click(uint8_t b = MOUSE_LEFT); + void move(signed char x, signed char y, signed char wheel = 0); + void press(uint8_t b = MOUSE_LEFT); // press LEFT by default + void release(uint8_t b = MOUSE_LEFT); // release LEFT by default + bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default +}; +extern Mouse_ Mouse; + +//================================================================================ +//================================================================================ +// Keyboard + +#define KEY_LEFT_CTRL 0x80 +#define KEY_LEFT_SHIFT 0x81 +#define KEY_LEFT_ALT 0x82 +#define KEY_LEFT_GUI 0x83 +#define KEY_RIGHT_CTRL 0x84 +#define KEY_RIGHT_SHIFT 0x85 +#define KEY_RIGHT_ALT 0x86 +#define KEY_RIGHT_GUI 0x87 + +#define KEY_UP_ARROW 0xDA +#define KEY_DOWN_ARROW 0xD9 +#define KEY_LEFT_ARROW 0xD8 +#define KEY_RIGHT_ARROW 0xD7 +#define KEY_BACKSPACE 0xB2 +#define KEY_TAB 0xB3 +#define KEY_RETURN 0xB0 +#define KEY_ESC 0xB1 +#define KEY_INSERT 0xD1 +#define KEY_DELETE 0xD4 +#define KEY_PAGE_UP 0xD3 +#define KEY_PAGE_DOWN 0xD6 +#define KEY_HOME 0xD2 +#define KEY_END 0xD5 +#define KEY_CAPS_LOCK 0xC1 +#define KEY_F1 0xC2 +#define KEY_F2 0xC3 +#define KEY_F3 0xC4 +#define KEY_F4 0xC5 +#define KEY_F5 0xC6 +#define KEY_F6 0xC7 +#define KEY_F7 0xC8 +#define KEY_F8 0xC9 +#define KEY_F9 0xCA +#define KEY_F10 0xCB +#define KEY_F11 0xCC +#define KEY_F12 0xCD + +// Low level key report: up to 6 keys and shift, ctrl etc at once +typedef struct +{ + uint8_t modifiers; + uint8_t reserved; + uint8_t keys[6]; +} KeyReport; + +class Keyboard_ : public Print +{ +private: + KeyReport _keyReport; + void sendReport(KeyReport* keys); +public: + Keyboard_(void); + void begin(void); + void end(void); + virtual size_t write(uint8_t k); + virtual size_t press(uint8_t k); + virtual size_t release(uint8_t k); + virtual void releaseAll(void); +}; +extern Keyboard_ Keyboard; + +//================================================================================ +//================================================================================ +// Low level API + +typedef struct +{ + uint8_t bmRequestType; + uint8_t bRequest; + uint8_t wValueL; + uint8_t wValueH; + uint16_t wIndex; + uint16_t wLength; +} Setup; + +//================================================================================ +//================================================================================ +// HID 'Driver' + +int HID_GetInterface(uint8_t* interfaceNum); +int HID_GetDescriptor(int i); +bool HID_Setup(Setup& setup); +void HID_SendReport(uint8_t id, const void* data, int len); + +//================================================================================ +//================================================================================ +// MSC 'Driver' + +int MSC_GetInterface(uint8_t* interfaceNum); +int MSC_GetDescriptor(int i); +bool MSC_Setup(Setup& setup); +bool MSC_Data(uint8_t rx,uint8_t tx); + +//================================================================================ +//================================================================================ +// CSC 'Driver' + +int CDC_GetInterface(uint8_t* interfaceNum); +int CDC_GetDescriptor(int i); +bool CDC_Setup(Setup& setup); + +//================================================================================ +//================================================================================ + +#define TRANSFER_PGM 0x80 +#define TRANSFER_RELEASE 0x40 +#define TRANSFER_ZERO 0x20 + +int USB_SendControl(uint8_t flags, const void* d, int len); +int USB_RecvControl(void* d, int len); + +uint8_t USB_Available(uint8_t ep); +int USB_Send(uint8_t ep, const void* data, int len); // blocking +int USB_Recv(uint8_t ep, void* data, int len); // non-blocking +int USB_Recv(uint8_t ep); // non-blocking +void USB_Flush(uint8_t ep); + +#endif + +#endif /* if defined(USBCON) */ diff --git a/hardware/ijhack/avr/cores/arduino/USBCore.cpp b/hardware/ijhack/avr/cores/arduino/USBCore.cpp new file mode 100644 index 0000000..b4f7bed --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/USBCore.cpp @@ -0,0 +1,699 @@ + + +/* Copyright (c) 2010, Peter Barrett +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#include "USBAPI.h" + +#if defined(USBCON) + +#define EP_TYPE_CONTROL 0x00 +#define EP_TYPE_BULK_IN 0x81 +#define EP_TYPE_BULK_OUT 0x80 +#define EP_TYPE_INTERRUPT_IN 0xC1 +#define EP_TYPE_INTERRUPT_OUT 0xC0 +#define EP_TYPE_ISOCHRONOUS_IN 0x41 +#define EP_TYPE_ISOCHRONOUS_OUT 0x40 + +/** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */ +#define TX_RX_LED_PULSE_MS 100 +volatile u8 TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */ +volatile u8 RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */ + +//================================================================== +//================================================================== + +extern const u16 STRING_LANGUAGE[] PROGMEM; +extern const u8 STRING_PRODUCT[] PROGMEM; +extern const u8 STRING_MANUFACTURER[] PROGMEM; +extern const DeviceDescriptor USB_DeviceDescriptor PROGMEM; +extern const DeviceDescriptor USB_DeviceDescriptorA PROGMEM; + +const u16 STRING_LANGUAGE[2] = { + (3<<8) | (2+2), + 0x0409 // English +}; + +#ifndef USB_PRODUCT +// If no product is provided, use USB IO Board +#define USB_PRODUCT "USB IO Board" +#endif + +const u8 STRING_PRODUCT[] PROGMEM = USB_PRODUCT; + +#if USB_VID == 0x2341 +# if defined(USB_MANUFACTURER) +# undef USB_MANUFACTURER +# endif +# define USB_MANUFACTURER "Arduino LLC" +#elif USB_VID == 0x1b4f +# if defined(USB_MANUFACTURER) +# undef USB_MANUFACTURER +# endif +# define USB_MANUFACTURER "SparkFun" +#elif !defined(USB_MANUFACTURER) +// Fall through to unknown if no manufacturer name was provided in a macro +# define USB_MANUFACTURER "Unknown" +#endif + +const u8 STRING_MANUFACTURER[] PROGMEM = USB_MANUFACTURER; + + +#ifdef CDC_ENABLED +#define DEVICE_CLASS 0x02 +#else +#define DEVICE_CLASS 0x00 +#endif + +// DEVICE DESCRIPTOR +const DeviceDescriptor USB_DeviceDescriptor = + D_DEVICE(0x00,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1); + +const DeviceDescriptor USB_DeviceDescriptorA = + D_DEVICE(DEVICE_CLASS,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1); + +//================================================================== +//================================================================== + +volatile u8 _usbConfiguration = 0; + +static inline void WaitIN(void) +{ + while (!(UEINTX & (1< len) + n = len; + { + LockEP lock(ep); + // Frame may have been released by the SOF interrupt handler + if (!ReadWriteAllowed()) + continue; + len -= n; + if (ep & TRANSFER_ZERO) + { + while (n--) + Send8(0); + } + else if (ep & TRANSFER_PGM) + { + while (n--) + Send8(pgm_read_byte(data++)); + } + else + { + while (n--) + Send8(*data++); + } + if (!ReadWriteAllowed() || ((len == 0) && (ep & TRANSFER_RELEASE))) // Release full buffer + ReleaseTX(); + } + } + TXLED1; // light the TX LED + TxLEDPulse = TX_RX_LED_PULSE_MS; + return r; +} + +extern const u8 _initEndpoints[] PROGMEM; +const u8 _initEndpoints[] = +{ + 0, + +#ifdef CDC_ENABLED + EP_TYPE_INTERRUPT_IN, // CDC_ENDPOINT_ACM + EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT + EP_TYPE_BULK_IN, // CDC_ENDPOINT_IN +#endif + +#ifdef HID_ENABLED + EP_TYPE_INTERRUPT_IN // HID_ENDPOINT_INT +#endif +}; + +#define EP_SINGLE_64 0x32 // EP0 +#define EP_DOUBLE_64 0x36 // Other endpoints + +static +void InitEP(u8 index, u8 type, u8 size) +{ + UENUM = index; + UECONX = 1; + UECFG0X = type; + UECFG1X = size; +} + +static +void InitEndpoints() +{ + for (u8 i = 1; i < sizeof(_initEndpoints); i++) + { + UENUM = i; + UECONX = 1; + UECFG0X = pgm_read_byte(_initEndpoints+i); + UECFG1X = EP_DOUBLE_64; + } + UERST = 0x7E; // And reset them + UERST = 0; +} + +// Handle CLASS_INTERFACE requests +static +bool ClassInterfaceRequest(Setup& setup) +{ + u8 i = setup.wIndex; + +#ifdef CDC_ENABLED + if (CDC_ACM_INTERFACE == i) + return CDC_Setup(setup); +#endif + +#ifdef HID_ENABLED + if (HID_INTERFACE == i) + return HID_Setup(setup); +#endif + return false; +} + +int _cmark; +int _cend; +void InitControl(int end) +{ + SetEP(0); + _cmark = 0; + _cend = end; +} + +static +bool SendControl(u8 d) +{ + if (_cmark < _cend) + { + if (!WaitForINOrOUT()) + return false; + Send8(d); + if (!((_cmark + 1) & 0x3F)) + ClearIN(); // Fifo is full, release this packet + } + _cmark++; + return true; +}; + +// Clipped by _cmark/_cend +int USB_SendControl(u8 flags, const void* d, int len) +{ + int sent = len; + const u8* data = (const u8*)d; + bool pgm = flags & TRANSFER_PGM; + while (len--) + { + u8 c = pgm ? pgm_read_byte(data++) : *data++; + if (!SendControl(c)) + return -1; + } + return sent; +} + +// Send a USB descriptor string. The string is stored in PROGMEM as a +// plain ASCII string but is sent out as UTF-16 with the correct 2-byte +// prefix +static bool USB_SendStringDescriptor(const u8*string_P, u8 string_len) { + SendControl(2 + string_len * 2); + SendControl(3); + for(u8 i = 0; i < string_len; i++) { + bool r = SendControl(pgm_read_byte(&string_P[i])); + r &= SendControl(0); // high byte + if(!r) { + return false; + } + } + return true; +} + +// Does not timeout or cross fifo boundaries +// Will only work for transfers <= 64 bytes +// TODO +int USB_RecvControl(void* d, int len) +{ + WaitOUT(); + Recv((u8*)d,len); + ClearOUT(); + return len; +} + +int SendInterfaces() +{ + int total = 0; + u8 interfaces = 0; + +#ifdef CDC_ENABLED + total = CDC_GetInterface(&interfaces); +#endif + +#ifdef HID_ENABLED + total += HID_GetInterface(&interfaces); +#endif + + return interfaces; +} + +// Construct a dynamic configuration descriptor +// This really needs dynamic endpoint allocation etc +// TODO +static +bool SendConfiguration(int maxlen) +{ + // Count and measure interfaces + InitControl(0); + int interfaces = SendInterfaces(); + ConfigDescriptor config = D_CONFIG(_cmark + sizeof(ConfigDescriptor),interfaces); + + // Now send them + InitControl(maxlen); + USB_SendControl(0,&config,sizeof(ConfigDescriptor)); + SendInterfaces(); + return true; +} + +u8 _cdcComposite = 0; + +static +bool SendDescriptor(Setup& setup) +{ + u8 t = setup.wValueH; + if (USB_CONFIGURATION_DESCRIPTOR_TYPE == t) + return SendConfiguration(setup.wLength); + + InitControl(setup.wLength); +#ifdef HID_ENABLED + if (HID_REPORT_DESCRIPTOR_TYPE == t) + return HID_GetDescriptor(t); +#endif + + const u8* desc_addr = 0; + if (USB_DEVICE_DESCRIPTOR_TYPE == t) + { + if (setup.wLength == 8) + _cdcComposite = 1; + desc_addr = _cdcComposite ? (const u8*)&USB_DeviceDescriptorA : (const u8*)&USB_DeviceDescriptor; + } + else if (USB_STRING_DESCRIPTOR_TYPE == t) + { + if (setup.wValueL == 0) { + desc_addr = (const u8*)&STRING_LANGUAGE; + } + else if (setup.wValueL == IPRODUCT) { + return USB_SendStringDescriptor(STRING_PRODUCT, strlen(USB_PRODUCT)); + } + else if (setup.wValueL == IMANUFACTURER) { + return USB_SendStringDescriptor(STRING_MANUFACTURER, strlen(USB_MANUFACTURER)); + } + else + return false; + } + + if (desc_addr == 0) + return false; + u8 desc_length = pgm_read_byte(desc_addr); + + USB_SendControl(TRANSFER_PGM,desc_addr,desc_length); + return true; +} + +// Endpoint 0 interrupt +ISR(USB_COM_vect) +{ + SetEP(0); + if (!ReceivedSetupInt()) + return; + + Setup setup; + Recv((u8*)&setup,8); + ClearSetupInt(); + + u8 requestType = setup.bmRequestType; + if (requestType & REQUEST_DEVICETOHOST) + WaitIN(); + else + ClearIN(); + + bool ok = true; + if (REQUEST_STANDARD == (requestType & REQUEST_TYPE)) + { + // Standard Requests + u8 r = setup.bRequest; + if (GET_STATUS == r) + { + Send8(0); // TODO + Send8(0); + } + else if (CLEAR_FEATURE == r) + { + } + else if (SET_FEATURE == r) + { + } + else if (SET_ADDRESS == r) + { + WaitIN(); + UDADDR = setup.wValueL | (1<> 8) & 0xFF) + +#define CDC_V1_10 0x0110 +#define CDC_COMMUNICATION_INTERFACE_CLASS 0x02 + +#define CDC_CALL_MANAGEMENT 0x01 +#define CDC_ABSTRACT_CONTROL_MODEL 0x02 +#define CDC_HEADER 0x00 +#define CDC_ABSTRACT_CONTROL_MANAGEMENT 0x02 +#define CDC_UNION 0x06 +#define CDC_CS_INTERFACE 0x24 +#define CDC_CS_ENDPOINT 0x25 +#define CDC_DATA_INTERFACE_CLASS 0x0A + +#define MSC_SUBCLASS_SCSI 0x06 +#define MSC_PROTOCOL_BULK_ONLY 0x50 + +#define HID_HID_DESCRIPTOR_TYPE 0x21 +#define HID_REPORT_DESCRIPTOR_TYPE 0x22 +#define HID_PHYSICAL_DESCRIPTOR_TYPE 0x23 + + +// Device +typedef struct { + u8 len; // 18 + u8 dtype; // 1 USB_DEVICE_DESCRIPTOR_TYPE + u16 usbVersion; // 0x200 + u8 deviceClass; + u8 deviceSubClass; + u8 deviceProtocol; + u8 packetSize0; // Packet 0 + u16 idVendor; + u16 idProduct; + u16 deviceVersion; // 0x100 + u8 iManufacturer; + u8 iProduct; + u8 iSerialNumber; + u8 bNumConfigurations; +} DeviceDescriptor; + +// Config +typedef struct { + u8 len; // 9 + u8 dtype; // 2 + u16 clen; // total length + u8 numInterfaces; + u8 config; + u8 iconfig; + u8 attributes; + u8 maxPower; +} ConfigDescriptor; + +// String + +// Interface +typedef struct +{ + u8 len; // 9 + u8 dtype; // 4 + u8 number; + u8 alternate; + u8 numEndpoints; + u8 interfaceClass; + u8 interfaceSubClass; + u8 protocol; + u8 iInterface; +} InterfaceDescriptor; + +// Endpoint +typedef struct +{ + u8 len; // 7 + u8 dtype; // 5 + u8 addr; + u8 attr; + u16 packetSize; + u8 interval; +} EndpointDescriptor; + +// Interface Association Descriptor +// Used to bind 2 interfaces together in CDC compostite device +typedef struct +{ + u8 len; // 8 + u8 dtype; // 11 + u8 firstInterface; + u8 interfaceCount; + u8 functionClass; + u8 funtionSubClass; + u8 functionProtocol; + u8 iInterface; +} IADDescriptor; + +// CDC CS interface descriptor +typedef struct +{ + u8 len; // 5 + u8 dtype; // 0x24 + u8 subtype; + u8 d0; + u8 d1; +} CDCCSInterfaceDescriptor; + +typedef struct +{ + u8 len; // 4 + u8 dtype; // 0x24 + u8 subtype; + u8 d0; +} CDCCSInterfaceDescriptor4; + +typedef struct +{ + u8 len; + u8 dtype; // 0x24 + u8 subtype; // 1 + u8 bmCapabilities; + u8 bDataInterface; +} CMFunctionalDescriptor; + +typedef struct +{ + u8 len; + u8 dtype; // 0x24 + u8 subtype; // 1 + u8 bmCapabilities; +} ACMFunctionalDescriptor; + +typedef struct +{ + // IAD + IADDescriptor iad; // Only needed on compound device + + // Control + InterfaceDescriptor cif; // + CDCCSInterfaceDescriptor header; + CMFunctionalDescriptor callManagement; // Call Management + ACMFunctionalDescriptor controlManagement; // ACM + CDCCSInterfaceDescriptor functionalDescriptor; // CDC_UNION + EndpointDescriptor cifin; + + // Data + InterfaceDescriptor dif; + EndpointDescriptor in; + EndpointDescriptor out; +} CDCDescriptor; + +typedef struct +{ + InterfaceDescriptor msc; + EndpointDescriptor in; + EndpointDescriptor out; +} MSCDescriptor; + +typedef struct +{ + u8 len; // 9 + u8 dtype; // 0x21 + u8 addr; + u8 versionL; // 0x101 + u8 versionH; // 0x101 + u8 country; + u8 desctype; // 0x22 report + u8 descLenL; + u8 descLenH; +} HIDDescDescriptor; + +typedef struct +{ + InterfaceDescriptor hid; + HIDDescDescriptor desc; + EndpointDescriptor in; +} HIDDescriptor; + + +#define D_DEVICE(_class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs) \ + { 18, 1, 0x200, _class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs } + +#define D_CONFIG(_totalLength,_interfaces) \ + { 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_BUS_POWERED, USB_CONFIG_POWER_MA(500) } + +#define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \ + { 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 } + +#define D_ENDPOINT(_addr,_attr,_packetSize, _interval) \ + { 7, 5, _addr,_attr,_packetSize, _interval } + +#define D_IAD(_firstInterface, _count, _class, _subClass, _protocol) \ + { 8, 11, _firstInterface, _count, _class, _subClass, _protocol, 0 } + +#define D_HIDREPORT(_descriptorLength) \ + { 9, 0x21, 0x1, 0x1, 0, 1, 0x22, _descriptorLength, 0 } + +#define D_CDCCS(_subtype,_d0,_d1) { 5, 0x24, _subtype, _d0, _d1 } +#define D_CDCCS4(_subtype,_d0) { 4, 0x24, _subtype, _d0 } + + +#endif \ No newline at end of file diff --git a/hardware/ijhack/avr/cores/arduino/USBDesc.h b/hardware/ijhack/avr/cores/arduino/USBDesc.h new file mode 100644 index 0000000..900713e --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/USBDesc.h @@ -0,0 +1,63 @@ + + +/* Copyright (c) 2011, Peter Barrett +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#define CDC_ENABLED +#define HID_ENABLED + + +#ifdef CDC_ENABLED +#define CDC_INTERFACE_COUNT 2 +#define CDC_ENPOINT_COUNT 3 +#else +#define CDC_INTERFACE_COUNT 0 +#define CDC_ENPOINT_COUNT 0 +#endif + +#ifdef HID_ENABLED +#define HID_INTERFACE_COUNT 1 +#define HID_ENPOINT_COUNT 1 +#else +#define HID_INTERFACE_COUNT 0 +#define HID_ENPOINT_COUNT 0 +#endif + +#define CDC_ACM_INTERFACE 0 // CDC ACM +#define CDC_DATA_INTERFACE 1 // CDC Data +#define CDC_FIRST_ENDPOINT 1 +#define CDC_ENDPOINT_ACM (CDC_FIRST_ENDPOINT) // CDC First +#define CDC_ENDPOINT_OUT (CDC_FIRST_ENDPOINT+1) +#define CDC_ENDPOINT_IN (CDC_FIRST_ENDPOINT+2) + +#define HID_INTERFACE (CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT) // HID Interface +#define HID_FIRST_ENDPOINT (CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT) +#define HID_ENDPOINT_INT (HID_FIRST_ENDPOINT) + +#define INTERFACE_COUNT (MSC_INTERFACE + MSC_INTERFACE_COUNT) + +#ifdef CDC_ENABLED +#define CDC_RX CDC_ENDPOINT_OUT +#define CDC_TX CDC_ENDPOINT_IN +#endif + +#ifdef HID_ENABLED +#define HID_TX HID_ENDPOINT_INT +#endif + +#define IMANUFACTURER 1 +#define IPRODUCT 2 + diff --git a/hardware/ijhack/avr/cores/arduino/Udp.h b/hardware/ijhack/avr/cores/arduino/Udp.h new file mode 100644 index 0000000..dc5644b --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/Udp.h @@ -0,0 +1,88 @@ +/* + * Udp.cpp: Library to send/receive UDP packets. + * + * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these) + * 1) UDP does not guarantee the order in which assembled UDP packets are received. This + * might not happen often in practice, but in larger network topologies, a UDP + * packet can be received out of sequence. + * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being + * aware of it. Again, this may not be a concern in practice on small local networks. + * For more information, see http://www.cafeaulait.org/course/week12/35.html + * + * MIT License: + * Copyright (c) 2008 Bjoern Hartmann + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * bjoern@cs.stanford.edu 12/30/2008 + */ + +#ifndef udp_h +#define udp_h + +#include +#include + +class UDP : public Stream { + +public: + virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use + virtual void stop() =0; // Finish with the UDP socket + + // Sending UDP packets + + // Start building up a packet to send to the remote host specific in ip and port + // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port + virtual int beginPacket(IPAddress ip, uint16_t port) =0; + // Start building up a packet to send to the remote host specific in host and port + // Returns 1 if successful, 0 if there was a problem resolving the hostname or port + virtual int beginPacket(const char *host, uint16_t port) =0; + // Finish off this packet and send it + // Returns 1 if the packet was sent successfully, 0 if there was an error + virtual int endPacket() =0; + // Write a single byte into the packet + virtual size_t write(uint8_t) =0; + // Write size bytes from buffer into the packet + virtual size_t write(const uint8_t *buffer, size_t size) =0; + + // Start processing the next available incoming packet + // Returns the size of the packet in bytes, or 0 if no packets are available + virtual int parsePacket() =0; + // Number of bytes remaining in the current packet + virtual int available() =0; + // Read a single byte from the current packet + virtual int read() =0; + // Read up to len bytes from the current packet and place them into buffer + // Returns the number of bytes read, or 0 if none are available + virtual int read(unsigned char* buffer, size_t len) =0; + // Read up to len characters from the current packet and place them into buffer + // Returns the number of characters read, or 0 if none are available + virtual int read(char* buffer, size_t len) =0; + // Return the next byte from the current packet without moving on to the next byte + virtual int peek() =0; + virtual void flush() =0; // Finish reading the current packet + + // Return the IP address of the host who sent the current incoming packet + virtual IPAddress remoteIP() =0; + // Return the port of the host who sent the current incoming packet + virtual uint16_t remotePort() =0; +protected: + uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); }; +}; + +#endif diff --git a/hardware/ijhack/avr/cores/arduino/WCharacter.h b/hardware/ijhack/avr/cores/arduino/WCharacter.h new file mode 100644 index 0000000..79733b5 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/WCharacter.h @@ -0,0 +1,168 @@ +/* + WCharacter.h - Character utility functions for Wiring & Arduino + Copyright (c) 2010 Hernando Barragan. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef Character_h +#define Character_h + +#include + +// WCharacter.h prototypes +inline boolean isAlphaNumeric(int c) __attribute__((always_inline)); +inline boolean isAlpha(int c) __attribute__((always_inline)); +inline boolean isAscii(int c) __attribute__((always_inline)); +inline boolean isWhitespace(int c) __attribute__((always_inline)); +inline boolean isControl(int c) __attribute__((always_inline)); +inline boolean isDigit(int c) __attribute__((always_inline)); +inline boolean isGraph(int c) __attribute__((always_inline)); +inline boolean isLowerCase(int c) __attribute__((always_inline)); +inline boolean isPrintable(int c) __attribute__((always_inline)); +inline boolean isPunct(int c) __attribute__((always_inline)); +inline boolean isSpace(int c) __attribute__((always_inline)); +inline boolean isUpperCase(int c) __attribute__((always_inline)); +inline boolean isHexadecimalDigit(int c) __attribute__((always_inline)); +inline int toAscii(int c) __attribute__((always_inline)); +inline int toLowerCase(int c) __attribute__((always_inline)); +inline int toUpperCase(int c)__attribute__((always_inline)); + + +// Checks for an alphanumeric character. +// It is equivalent to (isalpha(c) || isdigit(c)). +inline boolean isAlphaNumeric(int c) +{ + return ( isalnum(c) == 0 ? false : true); +} + + +// Checks for an alphabetic character. +// It is equivalent to (isupper(c) || islower(c)). +inline boolean isAlpha(int c) +{ + return ( isalpha(c) == 0 ? false : true); +} + + +// Checks whether c is a 7-bit unsigned char value +// that fits into the ASCII character set. +inline boolean isAscii(int c) +{ + return ( isascii (c) == 0 ? false : true); +} + + +// Checks for a blank character, that is, a space or a tab. +inline boolean isWhitespace(int c) +{ + return ( isblank (c) == 0 ? false : true); +} + + +// Checks for a control character. +inline boolean isControl(int c) +{ + return ( iscntrl (c) == 0 ? false : true); +} + + +// Checks for a digit (0 through 9). +inline boolean isDigit(int c) +{ + return ( isdigit (c) == 0 ? false : true); +} + + +// Checks for any printable character except space. +inline boolean isGraph(int c) +{ + return ( isgraph (c) == 0 ? false : true); +} + + +// Checks for a lower-case character. +inline boolean isLowerCase(int c) +{ + return (islower (c) == 0 ? false : true); +} + + +// Checks for any printable character including space. +inline boolean isPrintable(int c) +{ + return ( isprint (c) == 0 ? false : true); +} + + +// Checks for any printable character which is not a space +// or an alphanumeric character. +inline boolean isPunct(int c) +{ + return ( ispunct (c) == 0 ? false : true); +} + + +// Checks for white-space characters. For the avr-libc library, +// these are: space, formfeed ('\f'), newline ('\n'), carriage +// return ('\r'), horizontal tab ('\t'), and vertical tab ('\v'). +inline boolean isSpace(int c) +{ + return ( isspace (c) == 0 ? false : true); +} + + +// Checks for an uppercase letter. +inline boolean isUpperCase(int c) +{ + return ( isupper (c) == 0 ? false : true); +} + + +// Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7 +// 8 9 a b c d e f A B C D E F. +inline boolean isHexadecimalDigit(int c) +{ + return ( isxdigit (c) == 0 ? false : true); +} + + +// Converts c to a 7-bit unsigned char value that fits into the +// ASCII character set, by clearing the high-order bits. +inline int toAscii(int c) +{ + return toascii (c); +} + + +// Warning: +// Many people will be unhappy if you use this function. +// This function will convert accented letters into random +// characters. + +// Converts the letter c to lower case, if possible. +inline int toLowerCase(int c) +{ + return tolower (c); +} + + +// Converts the letter c to upper case, if possible. +inline int toUpperCase(int c) +{ + return toupper (c); +} + +#endif \ No newline at end of file diff --git a/hardware/ijhack/avr/cores/arduino/WInterrupts.c b/hardware/ijhack/avr/cores/arduino/WInterrupts.c new file mode 100644 index 0000000..d3fbf10 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/WInterrupts.c @@ -0,0 +1,334 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Wiring project - http://wiring.uniandes.edu.co + + Copyright (c) 2004-05 Hernando Barragan + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + Modified 24 November 2006 by David A. Mellis + Modified 1 August 2010 by Mark Sproul +*/ + +#include +#include +#include +#include +#include + +#include "wiring_private.h" + +static volatile voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS]; +// volatile static voidFuncPtr twiIntFunc; + +void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) { + if(interruptNum < EXTERNAL_NUM_INTERRUPTS) { + intFunc[interruptNum] = userFunc; + + // Configure the interrupt mode (trigger on low input, any change, rising + // edge, or falling edge). The mode constants were chosen to correspond + // to the configuration bits in the hardware register, so we simply shift + // the mode into place. + + // Enable the interrupt. + + switch (interruptNum) { +#if defined(__AVR_ATmega32U4__) + // I hate doing this, but the register assignment differs between the 1280/2560 + // and the 32U4. Since avrlib defines registers PCMSK1 and PCMSK2 that aren't + // even present on the 32U4 this is the only way to distinguish between them. + case 0: + EICRA = (EICRA & ~((1<= howbig) { + return howsmall; + } + long diff = howbig - howsmall; + return random(diff) + howsmall; +} + +long map(long x, long in_min, long in_max, long out_min, long out_max) +{ + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} + +unsigned int makeWord(unsigned int w) { return w; } +unsigned int makeWord(unsigned char h, unsigned char l) { return (h << 8) | l; } \ No newline at end of file diff --git a/hardware/ijhack/avr/cores/arduino/WString.cpp b/hardware/ijhack/avr/cores/arduino/WString.cpp new file mode 100644 index 0000000..dcd469d --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/WString.cpp @@ -0,0 +1,745 @@ +/* + WString.cpp - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All rights reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "WString.h" + +/*********************************************/ +/* Constructors */ +/*********************************************/ + +String::String(const char *cstr) +{ + init(); + if (cstr) copy(cstr, strlen(cstr)); +} + +String::String(const String &value) +{ + init(); + *this = value; +} + +String::String(const __FlashStringHelper *pstr) +{ + init(); + *this = pstr; +} + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +String::String(String &&rval) +{ + init(); + move(rval); +} +String::String(StringSumHelper &&rval) +{ + init(); + move(rval); +} +#endif + +String::String(char c) +{ + init(); + char buf[2]; + buf[0] = c; + buf[1] = 0; + *this = buf; +} + +String::String(unsigned char value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned char)]; + utoa(value, buf, base); + *this = buf; +} + +String::String(int value, unsigned char base) +{ + init(); + char buf[2 + 8 * sizeof(int)]; + itoa(value, buf, base); + *this = buf; +} + +String::String(unsigned int value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned int)]; + utoa(value, buf, base); + *this = buf; +} + +String::String(long value, unsigned char base) +{ + init(); + char buf[2 + 8 * sizeof(long)]; + ltoa(value, buf, base); + *this = buf; +} + +String::String(unsigned long value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned long)]; + ultoa(value, buf, base); + *this = buf; +} + +String::String(float value, unsigned char decimalPlaces) +{ + init(); + char buf[33]; + *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); +} + +String::String(double value, unsigned char decimalPlaces) +{ + init(); + char buf[33]; + *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); +} + +String::~String() +{ + free(buffer); +} + +/*********************************************/ +/* Memory Management */ +/*********************************************/ + +inline void String::init(void) +{ + buffer = NULL; + capacity = 0; + len = 0; +} + +void String::invalidate(void) +{ + if (buffer) free(buffer); + buffer = NULL; + capacity = len = 0; +} + +unsigned char String::reserve(unsigned int size) +{ + if (buffer && capacity >= size) return 1; + if (changeBuffer(size)) { + if (len == 0) buffer[0] = 0; + return 1; + } + return 0; +} + +unsigned char String::changeBuffer(unsigned int maxStrLen) +{ + char *newbuffer = (char *)realloc(buffer, maxStrLen + 1); + if (newbuffer) { + buffer = newbuffer; + capacity = maxStrLen; + return 1; + } + return 0; +} + +/*********************************************/ +/* Copy and Move */ +/*********************************************/ + +String & String::copy(const char *cstr, unsigned int length) +{ + if (!reserve(length)) { + invalidate(); + return *this; + } + len = length; + strcpy(buffer, cstr); + return *this; +} + +String & String::copy(const __FlashStringHelper *pstr, unsigned int length) +{ + if (!reserve(length)) { + invalidate(); + return *this; + } + len = length; + strcpy_P(buffer, (PGM_P)pstr); + return *this; +} + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +void String::move(String &rhs) +{ + if (buffer) { + if (capacity >= rhs.len) { + strcpy(buffer, rhs.buffer); + len = rhs.len; + rhs.len = 0; + return; + } else { + free(buffer); + } + } + buffer = rhs.buffer; + capacity = rhs.capacity; + len = rhs.len; + rhs.buffer = NULL; + rhs.capacity = 0; + rhs.len = 0; +} +#endif + +String & String::operator = (const String &rhs) +{ + if (this == &rhs) return *this; + + if (rhs.buffer) copy(rhs.buffer, rhs.len); + else invalidate(); + + return *this; +} + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +String & String::operator = (String &&rval) +{ + if (this != &rval) move(rval); + return *this; +} + +String & String::operator = (StringSumHelper &&rval) +{ + if (this != &rval) move(rval); + return *this; +} +#endif + +String & String::operator = (const char *cstr) +{ + if (cstr) copy(cstr, strlen(cstr)); + else invalidate(); + + return *this; +} + +String & String::operator = (const __FlashStringHelper *pstr) +{ + if (pstr) copy(pstr, strlen_P((PGM_P)pstr)); + else invalidate(); + + return *this; +} + +/*********************************************/ +/* concat */ +/*********************************************/ + +unsigned char String::concat(const String &s) +{ + return concat(s.buffer, s.len); +} + +unsigned char String::concat(const char *cstr, unsigned int length) +{ + unsigned int newlen = len + length; + if (!cstr) return 0; + if (length == 0) return 1; + if (!reserve(newlen)) return 0; + strcpy(buffer + len, cstr); + len = newlen; + return 1; +} + +unsigned char String::concat(const char *cstr) +{ + if (!cstr) return 0; + return concat(cstr, strlen(cstr)); +} + +unsigned char String::concat(char c) +{ + char buf[2]; + buf[0] = c; + buf[1] = 0; + return concat(buf, 1); +} + +unsigned char String::concat(unsigned char num) +{ + char buf[1 + 3 * sizeof(unsigned char)]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(int num) +{ + char buf[2 + 3 * sizeof(int)]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(unsigned int num) +{ + char buf[1 + 3 * sizeof(unsigned int)]; + utoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(long num) +{ + char buf[2 + 3 * sizeof(long)]; + ltoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(unsigned long num) +{ + char buf[1 + 3 * sizeof(unsigned long)]; + ultoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(float num) +{ + char buf[20]; + char* string = dtostrf(num, 4, 2, buf); + return concat(string, strlen(string)); +} + +unsigned char String::concat(double num) +{ + char buf[20]; + char* string = dtostrf(num, 4, 2, buf); + return concat(string, strlen(string)); +} + +unsigned char String::concat(const __FlashStringHelper * str) +{ + if (!str) return 0; + int length = strlen_P((const char *) str); + if (length == 0) return 1; + unsigned int newlen = len + length; + if (!reserve(newlen)) return 0; + strcpy_P(buffer + len, (const char *) str); + len = newlen; + return 1; +} + +/*********************************************/ +/* Concatenate */ +/*********************************************/ + +StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs.buffer, rhs.len)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr) +{ + StringSumHelper &a = const_cast(lhs); + if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, char c) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(c)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, int num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, long num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, float num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, double num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs)) a.invalidate(); + return a; +} + +/*********************************************/ +/* Comparison */ +/*********************************************/ + +int String::compareTo(const String &s) const +{ + if (!buffer || !s.buffer) { + if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer; + if (buffer && len > 0) return *(unsigned char *)buffer; + return 0; + } + return strcmp(buffer, s.buffer); +} + +unsigned char String::equals(const String &s2) const +{ + return (len == s2.len && compareTo(s2) == 0); +} + +unsigned char String::equals(const char *cstr) const +{ + if (len == 0) return (cstr == NULL || *cstr == 0); + if (cstr == NULL) return buffer[0] == 0; + return strcmp(buffer, cstr) == 0; +} + +unsigned char String::operator<(const String &rhs) const +{ + return compareTo(rhs) < 0; +} + +unsigned char String::operator>(const String &rhs) const +{ + return compareTo(rhs) > 0; +} + +unsigned char String::operator<=(const String &rhs) const +{ + return compareTo(rhs) <= 0; +} + +unsigned char String::operator>=(const String &rhs) const +{ + return compareTo(rhs) >= 0; +} + +unsigned char String::equalsIgnoreCase( const String &s2 ) const +{ + if (this == &s2) return 1; + if (len != s2.len) return 0; + if (len == 0) return 1; + const char *p1 = buffer; + const char *p2 = s2.buffer; + while (*p1) { + if (tolower(*p1++) != tolower(*p2++)) return 0; + } + return 1; +} + +unsigned char String::startsWith( const String &s2 ) const +{ + if (len < s2.len) return 0; + return startsWith(s2, 0); +} + +unsigned char String::startsWith( const String &s2, unsigned int offset ) const +{ + if (offset > len - s2.len || !buffer || !s2.buffer) return 0; + return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0; +} + +unsigned char String::endsWith( const String &s2 ) const +{ + if ( len < s2.len || !buffer || !s2.buffer) return 0; + return strcmp(&buffer[len - s2.len], s2.buffer) == 0; +} + +/*********************************************/ +/* Character Access */ +/*********************************************/ + +char String::charAt(unsigned int loc) const +{ + return operator[](loc); +} + +void String::setCharAt(unsigned int loc, char c) +{ + if (loc < len) buffer[loc] = c; +} + +char & String::operator[](unsigned int index) +{ + static char dummy_writable_char; + if (index >= len || !buffer) { + dummy_writable_char = 0; + return dummy_writable_char; + } + return buffer[index]; +} + +char String::operator[]( unsigned int index ) const +{ + if (index >= len || !buffer) return 0; + return buffer[index]; +} + +void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const +{ + if (!bufsize || !buf) return; + if (index >= len) { + buf[0] = 0; + return; + } + unsigned int n = bufsize - 1; + if (n > len - index) n = len - index; + strncpy((char *)buf, buffer + index, n); + buf[n] = 0; +} + +/*********************************************/ +/* Search */ +/*********************************************/ + +int String::indexOf(char c) const +{ + return indexOf(c, 0); +} + +int String::indexOf( char ch, unsigned int fromIndex ) const +{ + if (fromIndex >= len) return -1; + const char* temp = strchr(buffer + fromIndex, ch); + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::indexOf(const String &s2) const +{ + return indexOf(s2, 0); +} + +int String::indexOf(const String &s2, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + const char *found = strstr(buffer + fromIndex, s2.buffer); + if (found == NULL) return -1; + return found - buffer; +} + +int String::lastIndexOf( char theChar ) const +{ + return lastIndexOf(theChar, len - 1); +} + +int String::lastIndexOf(char ch, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + char tempchar = buffer[fromIndex + 1]; + buffer[fromIndex + 1] = '\0'; + char* temp = strrchr( buffer, ch ); + buffer[fromIndex + 1] = tempchar; + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::lastIndexOf(const String &s2) const +{ + return lastIndexOf(s2, len - s2.len); +} + +int String::lastIndexOf(const String &s2, unsigned int fromIndex) const +{ + if (s2.len == 0 || len == 0 || s2.len > len) return -1; + if (fromIndex >= len) fromIndex = len - 1; + int found = -1; + for (char *p = buffer; p <= buffer + fromIndex; p++) { + p = strstr(p, s2.buffer); + if (!p) break; + if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer; + } + return found; +} + +String String::substring(unsigned int left, unsigned int right) const +{ + if (left > right) { + unsigned int temp = right; + right = left; + left = temp; + } + String out; + if (left >= len) return out; + if (right > len) right = len; + char temp = buffer[right]; // save the replaced character + buffer[right] = '\0'; + out = buffer + left; // pointer arithmetic + buffer[right] = temp; //restore character + return out; +} + +/*********************************************/ +/* Modification */ +/*********************************************/ + +void String::replace(char find, char replace) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + if (*p == find) *p = replace; + } +} + +void String::replace(const String& find, const String& replace) +{ + if (len == 0 || find.len == 0) return; + int diff = replace.len - find.len; + char *readFrom = buffer; + char *foundAt; + if (diff == 0) { + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + memcpy(foundAt, replace.buffer, replace.len); + readFrom = foundAt + replace.len; + } + } else if (diff < 0) { + char *writeTo = buffer; + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + unsigned int n = foundAt - readFrom; + memcpy(writeTo, readFrom, n); + writeTo += n; + memcpy(writeTo, replace.buffer, replace.len); + writeTo += replace.len; + readFrom = foundAt + find.len; + len += diff; + } + strcpy(writeTo, readFrom); + } else { + unsigned int size = len; // compute size needed for result + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + readFrom = foundAt + find.len; + size += diff; + } + if (size == len) return; + if (size > capacity && !changeBuffer(size)) return; // XXX: tell user! + int index = len - 1; + while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) { + readFrom = buffer + index + find.len; + memmove(readFrom + diff, readFrom, len - (readFrom - buffer)); + len += diff; + buffer[len] = 0; + memcpy(buffer + index, replace.buffer, replace.len); + index--; + } + } +} + +void String::remove(unsigned int index){ + // Pass the biggest integer as the count. The remove method + // below will take care of truncating it at the end of the + // string. + remove(index, (unsigned int)-1); +} + +void String::remove(unsigned int index, unsigned int count){ + if (index >= len) { return; } + if (count <= 0) { return; } + if (count > len - index) { count = len - index; } + char *writeTo = buffer + index; + len = len - count; + strncpy(writeTo, buffer + index + count,len - index); + buffer[len] = 0; +} + +void String::toLowerCase(void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = tolower(*p); + } +} + +void String::toUpperCase(void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = toupper(*p); + } +} + +void String::trim(void) +{ + if (!buffer || len == 0) return; + char *begin = buffer; + while (isspace(*begin)) begin++; + char *end = buffer + len - 1; + while (isspace(*end) && end >= begin) end--; + len = end + 1 - begin; + if (begin > buffer) memcpy(buffer, begin, len); + buffer[len] = 0; +} + +/*********************************************/ +/* Parsing / Conversion */ +/*********************************************/ + +long String::toInt(void) const +{ + if (buffer) return atol(buffer); + return 0; +} + +float String::toFloat(void) const +{ + if (buffer) return float(atof(buffer)); + return 0; +} diff --git a/hardware/ijhack/avr/cores/arduino/WString.h b/hardware/ijhack/avr/cores/arduino/WString.h new file mode 100644 index 0000000..7402430 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/WString.h @@ -0,0 +1,224 @@ +/* + WString.h - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All right reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef String_class_h +#define String_class_h +#ifdef __cplusplus + +#include +#include +#include +#include + +// When compiling programs with this class, the following gcc parameters +// dramatically increase performance and memory (RAM) efficiency, typically +// with little or no increase in code size. +// -felide-constructors +// -std=c++0x + +class __FlashStringHelper; +#define F(string_literal) (reinterpret_cast(PSTR(string_literal))) + +// An inherited class for holding the result of a concatenation. These +// result objects are assumed to be writable by subsequent concatenations. +class StringSumHelper; + +// The string class +class String +{ + // use a function pointer to allow for "if (s)" without the + // complications of an operator bool(). for more information, see: + // http://www.artima.com/cppsource/safebool.html + typedef void (String::*StringIfHelperType)() const; + void StringIfHelper() const {} + +public: + // constructors + // creates a copy of the initial value. + // if the initial value is null or invalid, or if memory allocation + // fails, the string will be marked as invalid (i.e. "if (s)" will + // be false). + String(const char *cstr = ""); + String(const String &str); + String(const __FlashStringHelper *str); + #ifdef __GXX_EXPERIMENTAL_CXX0X__ + String(String &&rval); + String(StringSumHelper &&rval); + #endif + explicit String(char c); + explicit String(unsigned char, unsigned char base=10); + explicit String(int, unsigned char base=10); + explicit String(unsigned int, unsigned char base=10); + explicit String(long, unsigned char base=10); + explicit String(unsigned long, unsigned char base=10); + explicit String(float, unsigned char decimalPlaces=2); + explicit String(double, unsigned char decimalPlaces=2); + ~String(void); + + // memory management + // return true on success, false on failure (in which case, the string + // is left unchanged). reserve(0), if successful, will validate an + // invalid string (i.e., "if (s)" will be true afterwards) + unsigned char reserve(unsigned int size); + inline unsigned int length(void) const {return len;} + + // creates a copy of the assigned value. if the value is null or + // invalid, or if the memory allocation fails, the string will be + // marked as invalid ("if (s)" will be false). + String & operator = (const String &rhs); + String & operator = (const char *cstr); + String & operator = (const __FlashStringHelper *str); + #ifdef __GXX_EXPERIMENTAL_CXX0X__ + String & operator = (String &&rval); + String & operator = (StringSumHelper &&rval); + #endif + + // concatenate (works w/ built-in types) + + // returns true on success, false on failure (in which case, the string + // is left unchanged). if the argument is null or invalid, the + // concatenation is considered unsucessful. + unsigned char concat(const String &str); + unsigned char concat(const char *cstr); + unsigned char concat(char c); + unsigned char concat(unsigned char c); + unsigned char concat(int num); + unsigned char concat(unsigned int num); + unsigned char concat(long num); + unsigned char concat(unsigned long num); + unsigned char concat(float num); + unsigned char concat(double num); + unsigned char concat(const __FlashStringHelper * str); + + // if there's not enough memory for the concatenated value, the string + // will be left unchanged (but this isn't signalled in any way) + String & operator += (const String &rhs) {concat(rhs); return (*this);} + String & operator += (const char *cstr) {concat(cstr); return (*this);} + String & operator += (char c) {concat(c); return (*this);} + String & operator += (unsigned char num) {concat(num); return (*this);} + String & operator += (int num) {concat(num); return (*this);} + String & operator += (unsigned int num) {concat(num); return (*this);} + String & operator += (long num) {concat(num); return (*this);} + String & operator += (unsigned long num) {concat(num); return (*this);} + String & operator += (float num) {concat(num); return (*this);} + String & operator += (double num) {concat(num); return (*this);} + String & operator += (const __FlashStringHelper *str){concat(str); return (*this);} + + friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr); + friend StringSumHelper & operator + (const StringSumHelper &lhs, char c); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, float num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, double num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs); + + // comparison (only works w/ Strings and "strings") + operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; } + int compareTo(const String &s) const; + unsigned char equals(const String &s) const; + unsigned char equals(const char *cstr) const; + unsigned char operator == (const String &rhs) const {return equals(rhs);} + unsigned char operator == (const char *cstr) const {return equals(cstr);} + unsigned char operator != (const String &rhs) const {return !equals(rhs);} + unsigned char operator != (const char *cstr) const {return !equals(cstr);} + unsigned char operator < (const String &rhs) const; + unsigned char operator > (const String &rhs) const; + unsigned char operator <= (const String &rhs) const; + unsigned char operator >= (const String &rhs) const; + unsigned char equalsIgnoreCase(const String &s) const; + unsigned char startsWith( const String &prefix) const; + unsigned char startsWith(const String &prefix, unsigned int offset) const; + unsigned char endsWith(const String &suffix) const; + + // character acccess + char charAt(unsigned int index) const; + void setCharAt(unsigned int index, char c); + char operator [] (unsigned int index) const; + char& operator [] (unsigned int index); + void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const; + void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const + {getBytes((unsigned char *)buf, bufsize, index);} + const char * c_str() const { return buffer; } + + // search + int indexOf( char ch ) const; + int indexOf( char ch, unsigned int fromIndex ) const; + int indexOf( const String &str ) const; + int indexOf( const String &str, unsigned int fromIndex ) const; + int lastIndexOf( char ch ) const; + int lastIndexOf( char ch, unsigned int fromIndex ) const; + int lastIndexOf( const String &str ) const; + int lastIndexOf( const String &str, unsigned int fromIndex ) const; + String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); }; + String substring( unsigned int beginIndex, unsigned int endIndex ) const; + + // modification + void replace(char find, char replace); + void replace(const String& find, const String& replace); + void remove(unsigned int index); + void remove(unsigned int index, unsigned int count); + void toLowerCase(void); + void toUpperCase(void); + void trim(void); + + // parsing/conversion + long toInt(void) const; + float toFloat(void) const; + +protected: + char *buffer; // the actual char array + unsigned int capacity; // the array length minus one (for the '\0') + unsigned int len; // the String length (not counting the '\0') +protected: + void init(void); + void invalidate(void); + unsigned char changeBuffer(unsigned int maxStrLen); + unsigned char concat(const char *cstr, unsigned int length); + + // copy and move + String & copy(const char *cstr, unsigned int length); + String & copy(const __FlashStringHelper *pstr, unsigned int length); + #ifdef __GXX_EXPERIMENTAL_CXX0X__ + void move(String &rhs); + #endif +}; + +class StringSumHelper : public String +{ +public: + StringSumHelper(const String &s) : String(s) {} + StringSumHelper(const char *p) : String(p) {} + StringSumHelper(char c) : String(c) {} + StringSumHelper(unsigned char num) : String(num) {} + StringSumHelper(int num) : String(num) {} + StringSumHelper(unsigned int num) : String(num) {} + StringSumHelper(long num) : String(num) {} + StringSumHelper(unsigned long num) : String(num) {} + StringSumHelper(float num) : String(num) {} + StringSumHelper(double num) : String(num) {} +}; + +#endif // __cplusplus +#endif // String_class_h diff --git a/hardware/ijhack/avr/cores/arduino/abi.cpp b/hardware/ijhack/avr/cores/arduino/abi.cpp new file mode 100644 index 0000000..8d719b8 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/abi.cpp @@ -0,0 +1,35 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +extern "C" void __cxa_pure_virtual(void) __attribute__ ((__noreturn__)); +extern "C" void __cxa_deleted_virtual(void) __attribute__ ((__noreturn__)); + +void __cxa_pure_virtual(void) { + // We might want to write some diagnostics to uart in this case + //std::terminate(); + abort(); +} + +void __cxa_deleted_virtual(void) { + // We might want to write some diagnostics to uart in this case + //std::terminate(); + abort(); +} + diff --git a/hardware/ijhack/avr/cores/arduino/binary.h b/hardware/ijhack/avr/cores/arduino/binary.h new file mode 100644 index 0000000..aec4c73 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/binary.h @@ -0,0 +1,534 @@ +/* + binary.h - Definitions for binary constants + Copyright (c) 2006 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Binary_h +#define Binary_h + +#define B0 0 +#define B00 0 +#define B000 0 +#define B0000 0 +#define B00000 0 +#define B000000 0 +#define B0000000 0 +#define B00000000 0 +#define B1 1 +#define B01 1 +#define B001 1 +#define B0001 1 +#define B00001 1 +#define B000001 1 +#define B0000001 1 +#define B00000001 1 +#define B10 2 +#define B010 2 +#define B0010 2 +#define B00010 2 +#define B000010 2 +#define B0000010 2 +#define B00000010 2 +#define B11 3 +#define B011 3 +#define B0011 3 +#define B00011 3 +#define B000011 3 +#define B0000011 3 +#define B00000011 3 +#define B100 4 +#define B0100 4 +#define B00100 4 +#define B000100 4 +#define B0000100 4 +#define B00000100 4 +#define B101 5 +#define B0101 5 +#define B00101 5 +#define B000101 5 +#define B0000101 5 +#define B00000101 5 +#define B110 6 +#define B0110 6 +#define B00110 6 +#define B000110 6 +#define B0000110 6 +#define B00000110 6 +#define B111 7 +#define B0111 7 +#define B00111 7 +#define B000111 7 +#define B0000111 7 +#define B00000111 7 +#define B1000 8 +#define B01000 8 +#define B001000 8 +#define B0001000 8 +#define B00001000 8 +#define B1001 9 +#define B01001 9 +#define B001001 9 +#define B0001001 9 +#define B00001001 9 +#define B1010 10 +#define B01010 10 +#define B001010 10 +#define B0001010 10 +#define B00001010 10 +#define B1011 11 +#define B01011 11 +#define B001011 11 +#define B0001011 11 +#define B00001011 11 +#define B1100 12 +#define B01100 12 +#define B001100 12 +#define B0001100 12 +#define B00001100 12 +#define B1101 13 +#define B01101 13 +#define B001101 13 +#define B0001101 13 +#define B00001101 13 +#define B1110 14 +#define B01110 14 +#define B001110 14 +#define B0001110 14 +#define B00001110 14 +#define B1111 15 +#define B01111 15 +#define B001111 15 +#define B0001111 15 +#define B00001111 15 +#define B10000 16 +#define B010000 16 +#define B0010000 16 +#define B00010000 16 +#define B10001 17 +#define B010001 17 +#define B0010001 17 +#define B00010001 17 +#define B10010 18 +#define B010010 18 +#define B0010010 18 +#define B00010010 18 +#define B10011 19 +#define B010011 19 +#define B0010011 19 +#define B00010011 19 +#define B10100 20 +#define B010100 20 +#define B0010100 20 +#define B00010100 20 +#define B10101 21 +#define B010101 21 +#define B0010101 21 +#define B00010101 21 +#define B10110 22 +#define B010110 22 +#define B0010110 22 +#define B00010110 22 +#define B10111 23 +#define B010111 23 +#define B0010111 23 +#define B00010111 23 +#define B11000 24 +#define B011000 24 +#define B0011000 24 +#define B00011000 24 +#define B11001 25 +#define B011001 25 +#define B0011001 25 +#define B00011001 25 +#define B11010 26 +#define B011010 26 +#define B0011010 26 +#define B00011010 26 +#define B11011 27 +#define B011011 27 +#define B0011011 27 +#define B00011011 27 +#define B11100 28 +#define B011100 28 +#define B0011100 28 +#define B00011100 28 +#define B11101 29 +#define B011101 29 +#define B0011101 29 +#define B00011101 29 +#define B11110 30 +#define B011110 30 +#define B0011110 30 +#define B00011110 30 +#define B11111 31 +#define B011111 31 +#define B0011111 31 +#define B00011111 31 +#define B100000 32 +#define B0100000 32 +#define B00100000 32 +#define B100001 33 +#define B0100001 33 +#define B00100001 33 +#define B100010 34 +#define B0100010 34 +#define B00100010 34 +#define B100011 35 +#define B0100011 35 +#define B00100011 35 +#define B100100 36 +#define B0100100 36 +#define B00100100 36 +#define B100101 37 +#define B0100101 37 +#define B00100101 37 +#define B100110 38 +#define B0100110 38 +#define B00100110 38 +#define B100111 39 +#define B0100111 39 +#define B00100111 39 +#define B101000 40 +#define B0101000 40 +#define B00101000 40 +#define B101001 41 +#define B0101001 41 +#define B00101001 41 +#define B101010 42 +#define B0101010 42 +#define B00101010 42 +#define B101011 43 +#define B0101011 43 +#define B00101011 43 +#define B101100 44 +#define B0101100 44 +#define B00101100 44 +#define B101101 45 +#define B0101101 45 +#define B00101101 45 +#define B101110 46 +#define B0101110 46 +#define B00101110 46 +#define B101111 47 +#define B0101111 47 +#define B00101111 47 +#define B110000 48 +#define B0110000 48 +#define B00110000 48 +#define B110001 49 +#define B0110001 49 +#define B00110001 49 +#define B110010 50 +#define B0110010 50 +#define B00110010 50 +#define B110011 51 +#define B0110011 51 +#define B00110011 51 +#define B110100 52 +#define B0110100 52 +#define B00110100 52 +#define B110101 53 +#define B0110101 53 +#define B00110101 53 +#define B110110 54 +#define B0110110 54 +#define B00110110 54 +#define B110111 55 +#define B0110111 55 +#define B00110111 55 +#define B111000 56 +#define B0111000 56 +#define B00111000 56 +#define B111001 57 +#define B0111001 57 +#define B00111001 57 +#define B111010 58 +#define B0111010 58 +#define B00111010 58 +#define B111011 59 +#define B0111011 59 +#define B00111011 59 +#define B111100 60 +#define B0111100 60 +#define B00111100 60 +#define B111101 61 +#define B0111101 61 +#define B00111101 61 +#define B111110 62 +#define B0111110 62 +#define B00111110 62 +#define B111111 63 +#define B0111111 63 +#define B00111111 63 +#define B1000000 64 +#define B01000000 64 +#define B1000001 65 +#define B01000001 65 +#define B1000010 66 +#define B01000010 66 +#define B1000011 67 +#define B01000011 67 +#define B1000100 68 +#define B01000100 68 +#define B1000101 69 +#define B01000101 69 +#define B1000110 70 +#define B01000110 70 +#define B1000111 71 +#define B01000111 71 +#define B1001000 72 +#define B01001000 72 +#define B1001001 73 +#define B01001001 73 +#define B1001010 74 +#define B01001010 74 +#define B1001011 75 +#define B01001011 75 +#define B1001100 76 +#define B01001100 76 +#define B1001101 77 +#define B01001101 77 +#define B1001110 78 +#define B01001110 78 +#define B1001111 79 +#define B01001111 79 +#define B1010000 80 +#define B01010000 80 +#define B1010001 81 +#define B01010001 81 +#define B1010010 82 +#define B01010010 82 +#define B1010011 83 +#define B01010011 83 +#define B1010100 84 +#define B01010100 84 +#define B1010101 85 +#define B01010101 85 +#define B1010110 86 +#define B01010110 86 +#define B1010111 87 +#define B01010111 87 +#define B1011000 88 +#define B01011000 88 +#define B1011001 89 +#define B01011001 89 +#define B1011010 90 +#define B01011010 90 +#define B1011011 91 +#define B01011011 91 +#define B1011100 92 +#define B01011100 92 +#define B1011101 93 +#define B01011101 93 +#define B1011110 94 +#define B01011110 94 +#define B1011111 95 +#define B01011111 95 +#define B1100000 96 +#define B01100000 96 +#define B1100001 97 +#define B01100001 97 +#define B1100010 98 +#define B01100010 98 +#define B1100011 99 +#define B01100011 99 +#define B1100100 100 +#define B01100100 100 +#define B1100101 101 +#define B01100101 101 +#define B1100110 102 +#define B01100110 102 +#define B1100111 103 +#define B01100111 103 +#define B1101000 104 +#define B01101000 104 +#define B1101001 105 +#define B01101001 105 +#define B1101010 106 +#define B01101010 106 +#define B1101011 107 +#define B01101011 107 +#define B1101100 108 +#define B01101100 108 +#define B1101101 109 +#define B01101101 109 +#define B1101110 110 +#define B01101110 110 +#define B1101111 111 +#define B01101111 111 +#define B1110000 112 +#define B01110000 112 +#define B1110001 113 +#define B01110001 113 +#define B1110010 114 +#define B01110010 114 +#define B1110011 115 +#define B01110011 115 +#define B1110100 116 +#define B01110100 116 +#define B1110101 117 +#define B01110101 117 +#define B1110110 118 +#define B01110110 118 +#define B1110111 119 +#define B01110111 119 +#define B1111000 120 +#define B01111000 120 +#define B1111001 121 +#define B01111001 121 +#define B1111010 122 +#define B01111010 122 +#define B1111011 123 +#define B01111011 123 +#define B1111100 124 +#define B01111100 124 +#define B1111101 125 +#define B01111101 125 +#define B1111110 126 +#define B01111110 126 +#define B1111111 127 +#define B01111111 127 +#define B10000000 128 +#define B10000001 129 +#define B10000010 130 +#define B10000011 131 +#define B10000100 132 +#define B10000101 133 +#define B10000110 134 +#define B10000111 135 +#define B10001000 136 +#define B10001001 137 +#define B10001010 138 +#define B10001011 139 +#define B10001100 140 +#define B10001101 141 +#define B10001110 142 +#define B10001111 143 +#define B10010000 144 +#define B10010001 145 +#define B10010010 146 +#define B10010011 147 +#define B10010100 148 +#define B10010101 149 +#define B10010110 150 +#define B10010111 151 +#define B10011000 152 +#define B10011001 153 +#define B10011010 154 +#define B10011011 155 +#define B10011100 156 +#define B10011101 157 +#define B10011110 158 +#define B10011111 159 +#define B10100000 160 +#define B10100001 161 +#define B10100010 162 +#define B10100011 163 +#define B10100100 164 +#define B10100101 165 +#define B10100110 166 +#define B10100111 167 +#define B10101000 168 +#define B10101001 169 +#define B10101010 170 +#define B10101011 171 +#define B10101100 172 +#define B10101101 173 +#define B10101110 174 +#define B10101111 175 +#define B10110000 176 +#define B10110001 177 +#define B10110010 178 +#define B10110011 179 +#define B10110100 180 +#define B10110101 181 +#define B10110110 182 +#define B10110111 183 +#define B10111000 184 +#define B10111001 185 +#define B10111010 186 +#define B10111011 187 +#define B10111100 188 +#define B10111101 189 +#define B10111110 190 +#define B10111111 191 +#define B11000000 192 +#define B11000001 193 +#define B11000010 194 +#define B11000011 195 +#define B11000100 196 +#define B11000101 197 +#define B11000110 198 +#define B11000111 199 +#define B11001000 200 +#define B11001001 201 +#define B11001010 202 +#define B11001011 203 +#define B11001100 204 +#define B11001101 205 +#define B11001110 206 +#define B11001111 207 +#define B11010000 208 +#define B11010001 209 +#define B11010010 210 +#define B11010011 211 +#define B11010100 212 +#define B11010101 213 +#define B11010110 214 +#define B11010111 215 +#define B11011000 216 +#define B11011001 217 +#define B11011010 218 +#define B11011011 219 +#define B11011100 220 +#define B11011101 221 +#define B11011110 222 +#define B11011111 223 +#define B11100000 224 +#define B11100001 225 +#define B11100010 226 +#define B11100011 227 +#define B11100100 228 +#define B11100101 229 +#define B11100110 230 +#define B11100111 231 +#define B11101000 232 +#define B11101001 233 +#define B11101010 234 +#define B11101011 235 +#define B11101100 236 +#define B11101101 237 +#define B11101110 238 +#define B11101111 239 +#define B11110000 240 +#define B11110001 241 +#define B11110010 242 +#define B11110011 243 +#define B11110100 244 +#define B11110101 245 +#define B11110110 246 +#define B11110111 247 +#define B11111000 248 +#define B11111001 249 +#define B11111010 250 +#define B11111011 251 +#define B11111100 252 +#define B11111101 253 +#define B11111110 254 +#define B11111111 255 + +#endif diff --git a/hardware/ijhack/avr/cores/arduino/hooks.c b/hardware/ijhack/avr/cores/arduino/hooks.c new file mode 100644 index 0000000..641eabc --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/hooks.c @@ -0,0 +1,31 @@ +/* + Copyright (c) 2012 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/** + * Empty yield() hook. + * + * This function is intended to be used by library writers to build + * libraries or sketches that supports cooperative threads. + * + * Its defined as a weak symbol and it can be redefined to implement a + * real cooperative scheduler. + */ +static void __empty() { + // Empty +} +void yield(void) __attribute__ ((weak, alias("__empty"))); diff --git a/hardware/ijhack/avr/cores/arduino/main.cpp b/hardware/ijhack/avr/cores/arduino/main.cpp new file mode 100644 index 0000000..a60980d --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/main.cpp @@ -0,0 +1,49 @@ +/* + main.cpp - Main loop for Arduino sketches + Copyright (c) 2005-2013 Arduino Team. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +//Declared weak in Arduino.h to allow user redefinitions. +int atexit(void (*func)()) { return 0; } + +// Weak empty variant initialization function. +// May be redefined by variant files. +void initVariant() __attribute__((weak)); +void initVariant() { } + +int main(void) +{ + init(); + + initVariant(); + +#if defined(USBCON) + USBDevice.attach(); +#endif + + setup(); + + for (;;) { + loop(); + if (serialEventRun) serialEventRun(); + } + + return 0; +} + diff --git a/hardware/ijhack/avr/cores/arduino/new.cpp b/hardware/ijhack/avr/cores/arduino/new.cpp new file mode 100644 index 0000000..cf6f89c --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/new.cpp @@ -0,0 +1,36 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +void *operator new(size_t size) { + return malloc(size); +} + +void *operator new[](size_t size) { + return malloc(size); +} + +void operator delete(void * ptr) { + free(ptr); +} + +void operator delete[](void * ptr) { + free(ptr); +} + diff --git a/hardware/ijhack/avr/cores/arduino/new.h b/hardware/ijhack/avr/cores/arduino/new.h new file mode 100644 index 0000000..6e1b68f --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/new.h @@ -0,0 +1,30 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef NEW_H +#define NEW_H + +#include + +void * operator new(size_t size); +void * operator new[](size_t size); +void operator delete(void * ptr); +void operator delete[](void * ptr); + +#endif + diff --git a/hardware/ijhack/avr/cores/arduino/wiring.c b/hardware/ijhack/avr/cores/arduino/wiring.c new file mode 100644 index 0000000..5cbe241 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/wiring.c @@ -0,0 +1,325 @@ +/* + wiring.c - Partial implementation of the Wiring API for the ATmega8. + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2005-2006 David A. Mellis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + $Id$ +*/ + +#include "wiring_private.h" + +// the prescaler is set so that timer0 ticks every 64 clock cycles, and the +// the overflow handler is called every 256 ticks. +#define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256)) + +// the whole number of milliseconds per timer0 overflow +#define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000) + +// the fractional number of milliseconds per timer0 overflow. we shift right +// by three to fit these numbers into a byte. (for the clock speeds we care +// about - 8 and 16 MHz - this doesn't lose precision.) +#define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3) +#define FRACT_MAX (1000 >> 3) + +volatile unsigned long timer0_overflow_count = 0; +volatile unsigned long timer0_millis = 0; +static unsigned char timer0_fract = 0; + +#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) +ISR(TIM0_OVF_vect) +#else +ISR(TIMER0_OVF_vect) +#endif +{ + // copy these to local variables so they can be stored in registers + // (volatile variables must be read from memory on every access) + unsigned long m = timer0_millis; + unsigned char f = timer0_fract; + + m += MILLIS_INC; + f += FRACT_INC; + if (f >= FRACT_MAX) { + f -= FRACT_MAX; + m += 1; + } + + timer0_fract = f; + timer0_millis = m; + timer0_overflow_count++; +} + +unsigned long millis() +{ + unsigned long m; + uint8_t oldSREG = SREG; + + // disable interrupts while we read timer0_millis or we might get an + // inconsistent value (e.g. in the middle of a write to timer0_millis) + cli(); + m = timer0_millis; + SREG = oldSREG; + + return m; +} + +unsigned long micros() { + unsigned long m; + uint8_t oldSREG = SREG, t; + + cli(); + m = timer0_overflow_count; +#if defined(TCNT0) + t = TCNT0; +#elif defined(TCNT0L) + t = TCNT0L; +#else + #error TIMER 0 not defined +#endif + + +#ifdef TIFR0 + if ((TIFR0 & _BV(TOV0)) && (t < 255)) + m++; +#else + if ((TIFR & _BV(TOV0)) && (t < 255)) + m++; +#endif + + SREG = oldSREG; + + return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond()); +} + +void delay(unsigned long ms) +{ + uint16_t start = (uint16_t)micros(); + + while (ms > 0) { + yield(); + if (((uint16_t)micros() - start) >= 1000) { + ms--; + start += 1000; + } + } +} + +/* Delay for the given number of microseconds. Assumes a 8 or 16 MHz clock. */ +void delayMicroseconds(unsigned int us) +{ + // calling avrlib's delay_us() function with low values (e.g. 1 or + // 2 microseconds) gives delays longer than desired. + //delay_us(us); +#if F_CPU >= 20000000L + // for the 20 MHz clock on rare Arduino boards + + // for a one-microsecond delay, simply wait 2 cycle and return. The overhead + // of the function call yields a delay of exactly a one microsecond. + __asm__ __volatile__ ( + "nop" "\n\t" + "nop"); //just waiting 2 cycle + if (--us == 0) + return; + + // the following loop takes a 1/5 of a microsecond (4 cycles) + // per iteration, so execute it five times for each microsecond of + // delay requested. + us = (us<<2) + us; // x5 us + + // account for the time taken in the preceeding commands. + us -= 2; + +#elif F_CPU >= 16000000L + // for the 16 MHz clock on most Arduino boards + + // for a one-microsecond delay, simply return. the overhead + // of the function call yields a delay of approximately 1 1/8 us. + if (--us == 0) + return; + + // the following loop takes a quarter of a microsecond (4 cycles) + // per iteration, so execute it four times for each microsecond of + // delay requested. + us <<= 2; + + // account for the time taken in the preceeding commands. + us -= 2; +#else + // for the 8 MHz internal clock on the ATmega168 + + // for a one- or two-microsecond delay, simply return. the overhead of + // the function calls takes more than two microseconds. can't just + // subtract two, since us is unsigned; we'd overflow. + if (--us == 0) + return; + if (--us == 0) + return; + + // the following loop takes half of a microsecond (4 cycles) + // per iteration, so execute it twice for each microsecond of + // delay requested. + us <<= 1; + + // partially compensate for the time taken by the preceeding commands. + // we can't subtract any more than this or we'd overflow w/ small delays. + us--; +#endif + + // busy wait + __asm__ __volatile__ ( + "1: sbiw %0,1" "\n\t" // 2 cycles + "brne 1b" : "=w" (us) : "0" (us) // 2 cycles + ); +} + +void init() +{ + // this needs to be called before setup() or some functions won't + // work there + sei(); + + // on the ATmega168, timer 0 is also used for fast hardware pwm + // (using phase-correct PWM would mean that timer 0 overflowed half as often + // resulting in different millis() behavior on the ATmega8 and ATmega168) +#if defined(TCCR0A) && defined(WGM01) + sbi(TCCR0A, WGM01); + sbi(TCCR0A, WGM00); +#endif + + // set timer 0 prescale factor to 64 +#if defined(__AVR_ATmega128__) + // CPU specific: different values for the ATmega128 + sbi(TCCR0, CS02); +#elif defined(TCCR0) && defined(CS01) && defined(CS00) + // this combination is for the standard atmega8 + sbi(TCCR0, CS01); + sbi(TCCR0, CS00); +#elif defined(TCCR0B) && defined(CS01) && defined(CS00) + // this combination is for the standard 168/328/1280/2560 + sbi(TCCR0B, CS01); + sbi(TCCR0B, CS00); +#elif defined(TCCR0A) && defined(CS01) && defined(CS00) + // this combination is for the __AVR_ATmega645__ series + sbi(TCCR0A, CS01); + sbi(TCCR0A, CS00); +#else + #error Timer 0 prescale factor 64 not set correctly +#endif + + // enable timer 0 overflow interrupt +#if defined(TIMSK) && defined(TOIE0) + sbi(TIMSK, TOIE0); +#elif defined(TIMSK0) && defined(TOIE0) + sbi(TIMSK0, TOIE0); +#else + #error Timer 0 overflow interrupt not set correctly +#endif + + // timers 1 and 2 are used for phase-correct hardware pwm + // this is better for motors as it ensures an even waveform + // note, however, that fast pwm mode can achieve a frequency of up + // 8 MHz (with a 16 MHz clock) at 50% duty cycle + +#if defined(TCCR1B) && defined(CS11) && defined(CS10) + TCCR1B = 0; + + // set timer 1 prescale factor to 64 + sbi(TCCR1B, CS11); +#if F_CPU >= 8000000L + sbi(TCCR1B, CS10); +#endif +#elif defined(TCCR1) && defined(CS11) && defined(CS10) + sbi(TCCR1, CS11); +#if F_CPU >= 8000000L + sbi(TCCR1, CS10); +#endif +#endif + // put timer 1 in 8-bit phase correct pwm mode +#if defined(TCCR1A) && defined(WGM10) + sbi(TCCR1A, WGM10); +#elif defined(TCCR1) + #warning this needs to be finished +#endif + + // set timer 2 prescale factor to 64 +#if defined(TCCR2) && defined(CS22) + sbi(TCCR2, CS22); +#elif defined(TCCR2B) && defined(CS22) + sbi(TCCR2B, CS22); +#else + #warning Timer 2 not finished (may not be present on this CPU) +#endif + + // configure timer 2 for phase correct pwm (8-bit) +#if defined(TCCR2) && defined(WGM20) + sbi(TCCR2, WGM20); +#elif defined(TCCR2A) && defined(WGM20) + sbi(TCCR2A, WGM20); +#else + #warning Timer 2 not finished (may not be present on this CPU) +#endif + +#if defined(TCCR3B) && defined(CS31) && defined(WGM30) + sbi(TCCR3B, CS31); // set timer 3 prescale factor to 64 + sbi(TCCR3B, CS30); + sbi(TCCR3A, WGM30); // put timer 3 in 8-bit phase correct pwm mode +#endif + +#if defined(TCCR4A) && defined(TCCR4B) && defined(TCCR4D) /* beginning of timer4 block for 32U4 and similar */ + sbi(TCCR4B, CS42); // set timer4 prescale factor to 64 + sbi(TCCR4B, CS41); + sbi(TCCR4B, CS40); + sbi(TCCR4D, WGM40); // put timer 4 in phase- and frequency-correct PWM mode + sbi(TCCR4A, PWM4A); // enable PWM mode for comparator OCR4A + sbi(TCCR4C, PWM4D); // enable PWM mode for comparator OCR4D +#else /* beginning of timer4 block for ATMEGA1280 and ATMEGA2560 */ +#if defined(TCCR4B) && defined(CS41) && defined(WGM40) + sbi(TCCR4B, CS41); // set timer 4 prescale factor to 64 + sbi(TCCR4B, CS40); + sbi(TCCR4A, WGM40); // put timer 4 in 8-bit phase correct pwm mode +#endif +#endif /* end timer4 block for ATMEGA1280/2560 and similar */ + +#if defined(TCCR5B) && defined(CS51) && defined(WGM50) + sbi(TCCR5B, CS51); // set timer 5 prescale factor to 64 + sbi(TCCR5B, CS50); + sbi(TCCR5A, WGM50); // put timer 5 in 8-bit phase correct pwm mode +#endif + +#if defined(ADCSRA) + // set a2d prescale factor to 128 + // 16 MHz / 128 = 125 KHz, inside the desired 50-200 KHz range. + // XXX: this will not work properly for other clock speeds, and + // this code should use F_CPU to determine the prescale factor. + sbi(ADCSRA, ADPS2); + sbi(ADCSRA, ADPS1); + sbi(ADCSRA, ADPS0); + + // enable a2d conversions + sbi(ADCSRA, ADEN); +#endif + + // the bootloader connects pins 0 and 1 to the USART; disconnect them + // here so they can be used as normal digital i/o; they will be + // reconnected in Serial.begin() +#if defined(UCSRB) + UCSRB = 0; +#elif defined(UCSR0B) + UCSR0B = 0; +#endif +} diff --git a/hardware/ijhack/avr/cores/arduino/wiring_analog.c b/hardware/ijhack/avr/cores/arduino/wiring_analog.c new file mode 100644 index 0000000..48a9ef5 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/wiring_analog.c @@ -0,0 +1,292 @@ +/* + wiring_analog.c - analog input and output + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2005-2006 David A. Mellis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + Modified 28 September 2010 by Mark Sproul + + $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ +*/ + +#include "wiring_private.h" +#include "pins_arduino.h" + +uint8_t analog_reference = DEFAULT; + +void analogReference(uint8_t mode) +{ + // can't actually set the register here because the default setting + // will connect AVCC and the AREF pin, which would cause a short if + // there's something connected to AREF. + analog_reference = mode; +} + +int analogRead(uint8_t pin) +{ + uint8_t low, high; + +#if defined(analogPinToChannel) +#if defined(__AVR_ATmega32U4__) + if (pin >= 18) pin -= 18; // allow for channel or pin numbers +#endif + pin = analogPinToChannel(pin); +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + if (pin >= 54) pin -= 54; // allow for channel or pin numbers +#elif defined(__AVR_ATmega32U4__) + if (pin >= 18) pin -= 18; // allow for channel or pin numbers +#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) + if (pin >= 24) pin -= 24; // allow for channel or pin numbers +#else + if (pin >= 14) pin -= 14; // allow for channel or pin numbers +#endif + +#if defined(ADCSRB) && defined(MUX5) + // the MUX5 bit of ADCSRB selects whether we're reading from channels + // 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high). + ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5); +#endif + + // set the analog reference (high two bits of ADMUX) and select the + // channel (low 4 bits). this also sets ADLAR (left-adjust result) + // to 0 (the default). +#if defined(ADMUX) + ADMUX = (analog_reference << 6) | (pin & 0x07); +#endif + + // without a delay, we seem to read from the wrong channel + //delay(1); + +#if defined(ADCSRA) && defined(ADCL) + // start the conversion + sbi(ADCSRA, ADSC); + + // ADSC is cleared when the conversion finishes + while (bit_is_set(ADCSRA, ADSC)); + + // we have to read ADCL first; doing so locks both ADCL + // and ADCH until ADCH is read. reading ADCL second would + // cause the results of each conversion to be discarded, + // as ADCL and ADCH would be locked when it completed. + low = ADCL; + high = ADCH; +#else + // we dont have an ADC, return 0 + low = 0; + high = 0; +#endif + + // combine the two bytes + return (high << 8) | low; +} + +// Right now, PWM output only works on the pins with +// hardware support. These are defined in the appropriate +// pins_*.c file. For the rest of the pins, we default +// to digital output. +void analogWrite(uint8_t pin, int val) +{ + // We need to make sure the PWM output is enabled for those pins + // that support it, as we turn it off when digitally reading or + // writing with them. Also, make sure the pin is in output mode + // for consistenty with Wiring, which doesn't require a pinMode + // call for the analog output pins. + pinMode(pin, OUTPUT); + if (val == 0) + { + digitalWrite(pin, LOW); + } + else if (val == 255) + { + digitalWrite(pin, HIGH); + } + else + { + switch(digitalPinToTimer(pin)) + { + // XXX fix needed for atmega8 + #if defined(TCCR0) && defined(COM00) && !defined(__AVR_ATmega8__) + case TIMER0A: + // connect pwm to pin on timer 0 + sbi(TCCR0, COM00); + OCR0 = val; // set pwm duty + break; + #endif + + #if defined(TCCR0A) && defined(COM0A1) + case TIMER0A: + // connect pwm to pin on timer 0, channel A + sbi(TCCR0A, COM0A1); + OCR0A = val; // set pwm duty + break; + #endif + + #if defined(TCCR0A) && defined(COM0B1) + case TIMER0B: + // connect pwm to pin on timer 0, channel B + sbi(TCCR0A, COM0B1); + OCR0B = val; // set pwm duty + break; + #endif + + #if defined(TCCR1A) && defined(COM1A1) + case TIMER1A: + // connect pwm to pin on timer 1, channel A + sbi(TCCR1A, COM1A1); + OCR1A = val; // set pwm duty + break; + #endif + + #if defined(TCCR1A) && defined(COM1B1) + case TIMER1B: + // connect pwm to pin on timer 1, channel B + sbi(TCCR1A, COM1B1); + OCR1B = val; // set pwm duty + break; + #endif + + #if defined(TCCR1A) && defined(COM1C1) + case TIMER1C: + // connect pwm to pin on timer 1, channel B + sbi(TCCR1A, COM1C1); + OCR1C = val; // set pwm duty + break; + #endif + + #if defined(TCCR2) && defined(COM21) + case TIMER2: + // connect pwm to pin on timer 2 + sbi(TCCR2, COM21); + OCR2 = val; // set pwm duty + break; + #endif + + #if defined(TCCR2A) && defined(COM2A1) + case TIMER2A: + // connect pwm to pin on timer 2, channel A + sbi(TCCR2A, COM2A1); + OCR2A = val; // set pwm duty + break; + #endif + + #if defined(TCCR2A) && defined(COM2B1) + case TIMER2B: + // connect pwm to pin on timer 2, channel B + sbi(TCCR2A, COM2B1); + OCR2B = val; // set pwm duty + break; + #endif + + #if defined(TCCR3A) && defined(COM3A1) + case TIMER3A: + // connect pwm to pin on timer 3, channel A + sbi(TCCR3A, COM3A1); + OCR3A = val; // set pwm duty + break; + #endif + + #if defined(TCCR3A) && defined(COM3B1) + case TIMER3B: + // connect pwm to pin on timer 3, channel B + sbi(TCCR3A, COM3B1); + OCR3B = val; // set pwm duty + break; + #endif + + #if defined(TCCR3A) && defined(COM3C1) + case TIMER3C: + // connect pwm to pin on timer 3, channel C + sbi(TCCR3A, COM3C1); + OCR3C = val; // set pwm duty + break; + #endif + + #if defined(TCCR4A) + case TIMER4A: + //connect pwm to pin on timer 4, channel A + sbi(TCCR4A, COM4A1); + #if defined(COM4A0) // only used on 32U4 + cbi(TCCR4A, COM4A0); + #endif + OCR4A = val; // set pwm duty + break; + #endif + + #if defined(TCCR4A) && defined(COM4B1) + case TIMER4B: + // connect pwm to pin on timer 4, channel B + sbi(TCCR4A, COM4B1); + OCR4B = val; // set pwm duty + break; + #endif + + #if defined(TCCR4A) && defined(COM4C1) + case TIMER4C: + // connect pwm to pin on timer 4, channel C + sbi(TCCR4A, COM4C1); + OCR4C = val; // set pwm duty + break; + #endif + + #if defined(TCCR4C) && defined(COM4D1) + case TIMER4D: + // connect pwm to pin on timer 4, channel D + sbi(TCCR4C, COM4D1); + #if defined(COM4D0) // only used on 32U4 + cbi(TCCR4C, COM4D0); + #endif + OCR4D = val; // set pwm duty + break; + #endif + + + #if defined(TCCR5A) && defined(COM5A1) + case TIMER5A: + // connect pwm to pin on timer 5, channel A + sbi(TCCR5A, COM5A1); + OCR5A = val; // set pwm duty + break; + #endif + + #if defined(TCCR5A) && defined(COM5B1) + case TIMER5B: + // connect pwm to pin on timer 5, channel B + sbi(TCCR5A, COM5B1); + OCR5B = val; // set pwm duty + break; + #endif + + #if defined(TCCR5A) && defined(COM5C1) + case TIMER5C: + // connect pwm to pin on timer 5, channel C + sbi(TCCR5A, COM5C1); + OCR5C = val; // set pwm duty + break; + #endif + + case NOT_ON_TIMER: + default: + if (val < 128) { + digitalWrite(pin, LOW); + } else { + digitalWrite(pin, HIGH); + } + } + } +} + diff --git a/hardware/ijhack/avr/cores/arduino/wiring_digital.c b/hardware/ijhack/avr/cores/arduino/wiring_digital.c new file mode 100644 index 0000000..df94cc1 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/wiring_digital.c @@ -0,0 +1,181 @@ +/* + wiring_digital.c - digital input and output functions + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2005-2006 David A. Mellis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + Modified 28 September 2010 by Mark Sproul + + $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ +*/ + +#define ARDUINO_MAIN +#include "wiring_private.h" +#include "pins_arduino.h" + +void pinMode(uint8_t pin, uint8_t mode) +{ + uint8_t bit = digitalPinToBitMask(pin); + uint8_t port = digitalPinToPort(pin); + volatile uint8_t *reg, *out; + + if (port == NOT_A_PIN) return; + + // JWS: can I let the optimizer do this? + reg = portModeRegister(port); + out = portOutputRegister(port); + + if (mode == INPUT) { + uint8_t oldSREG = SREG; + cli(); + *reg &= ~bit; + *out &= ~bit; + SREG = oldSREG; + } else if (mode == INPUT_PULLUP) { + uint8_t oldSREG = SREG; + cli(); + *reg &= ~bit; + *out |= bit; + SREG = oldSREG; + } else { + uint8_t oldSREG = SREG; + cli(); + *reg |= bit; + SREG = oldSREG; + } +} + +// Forcing this inline keeps the callers from having to push their own stuff +// on the stack. It is a good performance win and only takes 1 more byte per +// user than calling. (It will take more bytes on the 168.) +// +// But shouldn't this be moved into pinMode? Seems silly to check and do on +// each digitalread or write. +// +// Mark Sproul: +// - Removed inline. Save 170 bytes on atmega1280 +// - changed to a switch statment; added 32 bytes but much easier to read and maintain. +// - Added more #ifdefs, now compiles for atmega645 +// +//static inline void turnOffPWM(uint8_t timer) __attribute__ ((always_inline)); +//static inline void turnOffPWM(uint8_t timer) +static void turnOffPWM(uint8_t timer) +{ + switch (timer) + { + #if defined(TCCR1A) && defined(COM1A1) + case TIMER1A: cbi(TCCR1A, COM1A1); break; + #endif + #if defined(TCCR1A) && defined(COM1B1) + case TIMER1B: cbi(TCCR1A, COM1B1); break; + #endif + #if defined(TCCR1A) && defined(COM1C1) + case TIMER1C: cbi(TCCR1A, COM1C1); break; + #endif + + #if defined(TCCR2) && defined(COM21) + case TIMER2: cbi(TCCR2, COM21); break; + #endif + + #if defined(TCCR0A) && defined(COM0A1) + case TIMER0A: cbi(TCCR0A, COM0A1); break; + #endif + + #if defined(TIMER0B) && defined(COM0B1) + case TIMER0B: cbi(TCCR0A, COM0B1); break; + #endif + #if defined(TCCR2A) && defined(COM2A1) + case TIMER2A: cbi(TCCR2A, COM2A1); break; + #endif + #if defined(TCCR2A) && defined(COM2B1) + case TIMER2B: cbi(TCCR2A, COM2B1); break; + #endif + + #if defined(TCCR3A) && defined(COM3A1) + case TIMER3A: cbi(TCCR3A, COM3A1); break; + #endif + #if defined(TCCR3A) && defined(COM3B1) + case TIMER3B: cbi(TCCR3A, COM3B1); break; + #endif + #if defined(TCCR3A) && defined(COM3C1) + case TIMER3C: cbi(TCCR3A, COM3C1); break; + #endif + + #if defined(TCCR4A) && defined(COM4A1) + case TIMER4A: cbi(TCCR4A, COM4A1); break; + #endif + #if defined(TCCR4A) && defined(COM4B1) + case TIMER4B: cbi(TCCR4A, COM4B1); break; + #endif + #if defined(TCCR4A) && defined(COM4C1) + case TIMER4C: cbi(TCCR4A, COM4C1); break; + #endif + #if defined(TCCR4C) && defined(COM4D1) + case TIMER4D: cbi(TCCR4C, COM4D1); break; + #endif + + #if defined(TCCR5A) + case TIMER5A: cbi(TCCR5A, COM5A1); break; + case TIMER5B: cbi(TCCR5A, COM5B1); break; + case TIMER5C: cbi(TCCR5A, COM5C1); break; + #endif + } +} + +void digitalWrite(uint8_t pin, uint8_t val) +{ + uint8_t timer = digitalPinToTimer(pin); + uint8_t bit = digitalPinToBitMask(pin); + uint8_t port = digitalPinToPort(pin); + volatile uint8_t *out; + + if (port == NOT_A_PIN) return; + + // If the pin that support PWM output, we need to turn it off + // before doing a digital write. + if (timer != NOT_ON_TIMER) turnOffPWM(timer); + + out = portOutputRegister(port); + + uint8_t oldSREG = SREG; + cli(); + + if (val == LOW) { + *out &= ~bit; + } else { + *out |= bit; + } + + SREG = oldSREG; +} + +int digitalRead(uint8_t pin) +{ + uint8_t timer = digitalPinToTimer(pin); + uint8_t bit = digitalPinToBitMask(pin); + uint8_t port = digitalPinToPort(pin); + + if (port == NOT_A_PIN) return LOW; + + // If the pin that support PWM output, we need to turn it off + // before getting a digital reading. + if (timer != NOT_ON_TIMER) turnOffPWM(timer); + + if (*portInputRegister(port) & bit) return HIGH; + return LOW; +} diff --git a/hardware/ijhack/avr/cores/arduino/wiring_private.h b/hardware/ijhack/avr/cores/arduino/wiring_private.h new file mode 100644 index 0000000..5dc7d4b --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/wiring_private.h @@ -0,0 +1,71 @@ +/* + wiring_private.h - Internal header file. + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2005-2006 David A. Mellis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + $Id: wiring.h 239 2007-01-12 17:58:39Z mellis $ +*/ + +#ifndef WiringPrivate_h +#define WiringPrivate_h + +#include +#include +#include +#include + +#include "Arduino.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#ifndef cbi +#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) +#endif +#ifndef sbi +#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) +#endif + +#define EXTERNAL_INT_0 0 +#define EXTERNAL_INT_1 1 +#define EXTERNAL_INT_2 2 +#define EXTERNAL_INT_3 3 +#define EXTERNAL_INT_4 4 +#define EXTERNAL_INT_5 5 +#define EXTERNAL_INT_6 6 +#define EXTERNAL_INT_7 7 + +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega256RFR2__) +#define EXTERNAL_NUM_INTERRUPTS 8 +#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) +#define EXTERNAL_NUM_INTERRUPTS 3 +#elif defined(__AVR_ATmega32U4__) +#define EXTERNAL_NUM_INTERRUPTS 5 +#else +#define EXTERNAL_NUM_INTERRUPTS 2 +#endif + +typedef void (*voidFuncPtr)(void); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/hardware/ijhack/avr/cores/arduino/wiring_pulse.c b/hardware/ijhack/avr/cores/arduino/wiring_pulse.c new file mode 100644 index 0000000..830c454 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/wiring_pulse.c @@ -0,0 +1,85 @@ +/* + wiring_pulse.c - pulseIn() function + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2005-2006 David A. Mellis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ +*/ + +#include "wiring_private.h" +#include "pins_arduino.h" + +/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH + * or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds + * to 3 minutes in length, but must be called at least a few dozen microseconds + * before the start of the pulse. */ +unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout) +{ + // cache the port and bit of the pin in order to speed up the + // pulse width measuring loop and achieve finer resolution. calling + // digitalRead() instead yields much coarser resolution. + uint8_t bit = digitalPinToBitMask(pin); + uint8_t port = digitalPinToPort(pin); + uint8_t stateMask = (state ? bit : 0); + unsigned long width = 0; // keep initialization out of time critical area + + // convert the timeout from microseconds to a number of times through + // the initial loop; it takes 16 clock cycles per iteration. + unsigned long numloops = 0; + unsigned long maxloops = microsecondsToClockCycles(timeout) / 16; + + // wait for any previous pulse to end + while ((*portInputRegister(port) & bit) == stateMask) + if (numloops++ == maxloops) + return 0; + + // wait for the pulse to start + while ((*portInputRegister(port) & bit) != stateMask) + if (numloops++ == maxloops) + return 0; + + // wait for the pulse to stop + while ((*portInputRegister(port) & bit) == stateMask) { + if (numloops++ == maxloops) + return 0; + width++; + } + + // convert the reading to microseconds. There will be some error introduced by + // the interrupt handlers. + + // Conversion constants are compiler-dependent, different compiler versions + // have different levels of optimization. +#if __GNUC__==4 && __GNUC_MINOR__==3 && __GNUC_PATCHLEVEL__==2 + // avr-gcc 4.3.2 + return clockCyclesToMicroseconds(width * 21 + 16); +#elif __GNUC__==4 && __GNUC_MINOR__==8 && __GNUC_PATCHLEVEL__==1 + // avr-gcc 4.8.1 + return clockCyclesToMicroseconds(width * 24 + 16); +#elif __GNUC__<=4 && __GNUC_MINOR__<=3 + // avr-gcc <=4.3.x + #warning "pulseIn() results may not be accurate" + return clockCyclesToMicroseconds(width * 21 + 16); +#else + // avr-gcc >4.3.x + #warning "pulseIn() results may not be accurate" + return clockCyclesToMicroseconds(width * 24 + 16); +#endif + +} diff --git a/hardware/ijhack/avr/cores/arduino/wiring_shift.c b/hardware/ijhack/avr/cores/arduino/wiring_shift.c new file mode 100644 index 0000000..cfe7867 --- /dev/null +++ b/hardware/ijhack/avr/cores/arduino/wiring_shift.c @@ -0,0 +1,55 @@ +/* + wiring_shift.c - shiftOut() function + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2005-2006 David A. Mellis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ +*/ + +#include "wiring_private.h" + +uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) { + uint8_t value = 0; + uint8_t i; + + for (i = 0; i < 8; ++i) { + digitalWrite(clockPin, HIGH); + if (bitOrder == LSBFIRST) + value |= digitalRead(dataPin) << i; + else + value |= digitalRead(dataPin) << (7 - i); + digitalWrite(clockPin, LOW); + } + return value; +} + +void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val) +{ + uint8_t i; + + for (i = 0; i < 8; i++) { + if (bitOrder == LSBFIRST) + digitalWrite(dataPin, !!(val & (1 << i))); + else + digitalWrite(dataPin, !!(val & (1 << (7 - i)))); + + digitalWrite(clockPin, HIGH); + digitalWrite(clockPin, LOW); + } +} diff --git a/hardware/ijhack/avr/platform.txt b/hardware/ijhack/avr/platform.txt new file mode 100644 index 0000000..454aec9 --- /dev/null +++ b/hardware/ijhack/avr/platform.txt @@ -0,0 +1,109 @@ + +# Arduino AVR Core and platform. +# ------------------------------ +# +# For more info: +# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification + +name=IJhack Boards +version=0.1.3 + +# AVR compile variables +# --------------------- + +compiler.warning_flags=-w +compiler.warning_flags.none=-w +compiler.warning_flags.default= +compiler.warning_flags.more=-Wall +compiler.warning_flags.all=-Wall -Wextra + +# Default "compiler.path" is correct, change only if you want to overidde the initial value +compiler.path={runtime.tools.avr-gcc.path}/bin/ +compiler.c.cmd=avr-gcc +compiler.c.flags=-c -g -Os {compiler.warning_flags} -ffunction-sections -fdata-sections -MMD +# -w flag added to avoid printing a wrong warning http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59396 +# This is fixed in gcc 4.8.3 and will be removed as soon as we update the toolchain +compiler.c.elf.flags={compiler.warning_flags} -Os -Wl,--gc-sections +compiler.c.elf.cmd=avr-gcc +compiler.S.flags=-c -g -x assembler-with-cpp +compiler.cpp.cmd=avr-g++ +compiler.cpp.flags=-c -g -Os {compiler.warning_flags} -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD +compiler.ar.cmd=avr-ar +compiler.ar.flags=rcs +compiler.objcopy.cmd=avr-objcopy +compiler.objcopy.eep.flags=-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 +compiler.elf2hex.flags=-O ihex -R .eeprom +compiler.elf2hex.cmd=avr-objcopy +compiler.ldflags= +compiler.size.cmd=avr-size + +# This can be overriden in boards.txt +build.extra_flags= + +# These can be overridden in platform.local.txt +compiler.c.extra_flags= +compiler.c.elf.extra_flags= +compiler.S.extra_flags= +compiler.cpp.extra_flags= +compiler.ar.extra_flags= +compiler.objcopy.eep.extra_flags= +compiler.elf2hex.extra_flags= + +# AVR compile patterns +# -------------------- + +## Compile c files +recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" + +## Compile c++ files +recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" + +## Compile S files +recipe.S.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.S.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" + +## Create archives +recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{build.path}/{archive_file}" "{object_file}" + +## Combine gc-sections, archives, and objects +recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mmcu={build.mcu} {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -lm + +## Create output files (.eep and .hex) +recipe.objcopy.eep.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.objcopy.eep.flags} {compiler.objcopy.eep.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.eep" +recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex" + +## Compute size +recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" +recipe.size.regex=^(?:\.text|\.data|\.bootloader)\s+([0-9]+).* +recipe.size.regex.data=^(?:\.data|\.bss|\.noinit)\s+([0-9]+).* +recipe.size.regex.eeprom=^(?:\.eeprom)\s+([0-9]+).* + + +# AVR Uploader/Programmers tools +# ------------------------------ + +tools.avrdude.path={runtime.tools.avrdude.path} +tools.avrdude.cmd.path={path}/bin/avrdude +tools.avrdude.config.path={path}/etc/avrdude.conf + +tools.avrdude.upload.params.verbose=-v +tools.avrdude.upload.params.quiet=-q -q +tools.avrdude.upload.pattern="{cmd.path}" "-C{config.path}" {upload.verbose} -p{build.mcu} -c{upload.protocol} -P{serial.port} -b{upload.speed} -D "-Uflash:w:{build.path}/{build.project_name}.hex:i" + +tools.avrdude.program.params.verbose=-v +tools.avrdude.program.params.quiet=-q -q +tools.avrdude.program.pattern="{cmd.path}" "-C{config.path}" {program.verbose} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{build.path}/{build.project_name}.hex:i" + +tools.avrdude.erase.params.verbose=-v +tools.avrdude.erase.params.quiet=-q -q +tools.avrdude.erase.pattern="{cmd.path}" "-C{config.path}" {erase.verbose} -p{build.mcu} -c{protocol} {program.extra_params} -e -Ulock:w:{bootloader.unlock_bits}:m -Uefuse:w:{bootloader.extended_fuses}:m -Uhfuse:w:{bootloader.high_fuses}:m -Ulfuse:w:{bootloader.low_fuses}:m + +tools.avrdude.bootloader.params.verbose=-v +tools.avrdude.bootloader.params.quiet=-q -q +tools.avrdude.bootloader.pattern="{cmd.path}" "-C{config.path}" {bootloader.verbose} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{runtime.platform.path}/bootloaders/{bootloader.file}:i" -Ulock:w:{bootloader.lock_bits}:m + + +# USB Default Flags +# Default blank usb manufacturer will be filled it at compile time +# - from numeric vendor ID, set to Unknown otherwise +build.usb_manufacturer="Unknown" +build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' diff --git a/hardware/pins_arduino.h b/hardware/ijhack/avr/variants/ijduino/pins_arduino.h similarity index 100% rename from hardware/pins_arduino.h rename to hardware/ijhack/avr/variants/ijduino/pins_arduino.h diff --git a/libraries/DallasTemperature/DallasTemperature.cpp b/libraries/DallasTemperature/DallasTemperature.cpp new file mode 100644 index 0000000..1409701 --- /dev/null +++ b/libraries/DallasTemperature/DallasTemperature.cpp @@ -0,0 +1,738 @@ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. + +// Version 3.7.2 modified on Dec 6, 2011 to support Arduino 1.0 +// See Includes... +// Modified by Jordan Hochenbaum + +#include "DallasTemperature.h" + +#if ARDUINO >= 100 + #include "Arduino.h" +#else +extern "C" { + #include "WConstants.h" +} +#endif + +DallasTemperature::DallasTemperature(OneWire* _oneWire) + #if REQUIRESALARMS + : _AlarmHandler(&defaultAlarmHandler) + #endif +{ + _wire = _oneWire; + devices = 0; + parasite = false; + bitResolution = 9; + waitForConversion = true; + checkForConversion = true; +} + +// initialise the bus +void DallasTemperature::begin(void) +{ + DeviceAddress deviceAddress; + + _wire->reset_search(); + devices = 0; // Reset the number of devices when we enumerate wire devices + + while (_wire->search(deviceAddress)) + { + if (validAddress(deviceAddress)) + { + if (!parasite && readPowerSupply(deviceAddress)) parasite = true; + + ScratchPad scratchPad; + + readScratchPad(deviceAddress, scratchPad); + + bitResolution = max(bitResolution, getResolution(deviceAddress)); + + devices++; + } + } +} + +// returns the number of devices found on the bus +uint8_t DallasTemperature::getDeviceCount(void) +{ + return devices; +} + +// returns true if address is valid +bool DallasTemperature::validAddress(uint8_t* deviceAddress) +{ + return (_wire->crc8(deviceAddress, 7) == deviceAddress[7]); +} + +// finds an address at a given index on the bus +// returns true if the device was found +bool DallasTemperature::getAddress(uint8_t* deviceAddress, uint8_t index) +{ + uint8_t depth = 0; + + _wire->reset_search(); + + while (depth <= index && _wire->search(deviceAddress)) + { + if (depth == index && validAddress(deviceAddress)) return true; + depth++; + } + + return false; +} + +// attempt to determine if the device at the given address is connected to the bus +bool DallasTemperature::isConnected(uint8_t* deviceAddress) +{ + ScratchPad scratchPad; + return isConnected(deviceAddress, scratchPad); +} + +// attempt to determine if the device at the given address is connected to the bus +// also allows for updating the read scratchpad +bool DallasTemperature::isConnected(uint8_t* deviceAddress, uint8_t* scratchPad) +{ + readScratchPad(deviceAddress, scratchPad); + return (_wire->crc8(scratchPad, 8) == scratchPad[SCRATCHPAD_CRC]); +} + +// read device's scratch pad +void DallasTemperature::readScratchPad(uint8_t* deviceAddress, uint8_t* scratchPad) +{ + // send the command + _wire->reset(); + _wire->select(deviceAddress); + _wire->write(READSCRATCH); + + // TODO => collect all comments & use simple loop + // byte 0: temperature LSB + // byte 1: temperature MSB + // byte 2: high alarm temp + // byte 3: low alarm temp + // byte 4: DS18S20: store for crc + // DS18B20 & DS1822: configuration register + // byte 5: internal use & crc + // byte 6: DS18S20: COUNT_REMAIN + // DS18B20 & DS1822: store for crc + // byte 7: DS18S20: COUNT_PER_C + // DS18B20 & DS1822: store for crc + // byte 8: SCRATCHPAD_CRC + // + // for(int i=0; i<9; i++) + // { + // scratchPad[i] = _wire->read(); + // } + + + // read the response + + // byte 0: temperature LSB + scratchPad[TEMP_LSB] = _wire->read(); + + // byte 1: temperature MSB + scratchPad[TEMP_MSB] = _wire->read(); + + // byte 2: high alarm temp + scratchPad[HIGH_ALARM_TEMP] = _wire->read(); + + // byte 3: low alarm temp + scratchPad[LOW_ALARM_TEMP] = _wire->read(); + + // byte 4: + // DS18S20: store for crc + // DS18B20 & DS1822: configuration register + scratchPad[CONFIGURATION] = _wire->read(); + + // byte 5: + // internal use & crc + scratchPad[INTERNAL_BYTE] = _wire->read(); + + // byte 6: + // DS18S20: COUNT_REMAIN + // DS18B20 & DS1822: store for crc + scratchPad[COUNT_REMAIN] = _wire->read(); + + // byte 7: + // DS18S20: COUNT_PER_C + // DS18B20 & DS1822: store for crc + scratchPad[COUNT_PER_C] = _wire->read(); + + // byte 8: + // SCTRACHPAD_CRC + scratchPad[SCRATCHPAD_CRC] = _wire->read(); + + _wire->reset(); +} + +// writes device's scratch pad +void DallasTemperature::writeScratchPad(uint8_t* deviceAddress, const uint8_t* scratchPad) +{ + _wire->reset(); + _wire->select(deviceAddress); + _wire->write(WRITESCRATCH); + _wire->write(scratchPad[HIGH_ALARM_TEMP]); // high alarm temp + _wire->write(scratchPad[LOW_ALARM_TEMP]); // low alarm temp + // DS18S20 does not use the configuration register + if (deviceAddress[0] != DS18S20MODEL) _wire->write(scratchPad[CONFIGURATION]); // configuration + _wire->reset(); + // save the newly written values to eeprom + _wire->write(COPYSCRATCH, parasite); + if (parasite) delay(10); // 10ms delay + _wire->reset(); +} + +// reads the device's power requirements +bool DallasTemperature::readPowerSupply(uint8_t* deviceAddress) +{ + bool ret = false; + _wire->reset(); + _wire->select(deviceAddress); + _wire->write(READPOWERSUPPLY); + if (_wire->read_bit() == 0) ret = true; + _wire->reset(); + return ret; +} + + +// set resolution of all devices to 9, 10, 11, or 12 bits +// if new resolution is out of range, it is constrained. +void DallasTemperature::setResolution(uint8_t newResolution) +{ + bitResolution = constrain(newResolution, 9, 12); + DeviceAddress deviceAddress; + for (int i=0; ireset(); + _wire->skip(); + _wire->write(STARTCONVO, parasite); + + // ASYNC mode? + if (!waitForConversion) return; + blockTillConversionComplete(&bitResolution, 0); + + return; +} + +// sends command for one device to perform a temperature by address +// returns FALSE if device is disconnected +// returns TRUE otherwise +bool DallasTemperature::requestTemperaturesByAddress(uint8_t* deviceAddress) +{ + + _wire->reset(); + _wire->select(deviceAddress); + _wire->write(STARTCONVO, parasite); + + // check device + ScratchPad scratchPad; + if (!isConnected(deviceAddress, scratchPad)) return false; + + + // ASYNC mode? + if (!waitForConversion) return true; + uint8_t bitResolution = getResolution(deviceAddress); + blockTillConversionComplete(&bitResolution, deviceAddress); + + return true; +} + + +void DallasTemperature::blockTillConversionComplete(uint8_t* bitResolution, uint8_t* deviceAddress) +{ + if(deviceAddress != 0 && checkForConversion && !parasite) + { + // Continue to check if the IC has responded with a temperature + // NB: Could cause issues with multiple devices (one device may respond faster) + unsigned long start = millis(); + while(!isConversionAvailable(0) && ((millis() - start) < 750)); + } + + // Wait a fix number of cycles till conversion is complete (based on IC datasheet) + switch (*bitResolution) + { + case 9: + delay(94); + break; + case 10: + delay(188); + break; + case 11: + delay(375); + break; + case 12: + default: + delay(750); + break; + } + +} + +// sends command for one device to perform a temp conversion by index +bool DallasTemperature::requestTemperaturesByIndex(uint8_t deviceIndex) +{ + DeviceAddress deviceAddress; + getAddress(deviceAddress, deviceIndex); + return requestTemperaturesByAddress(deviceAddress); +} + +// Fetch temperature for device index +float DallasTemperature::getTempCByIndex(uint8_t deviceIndex) +{ + DeviceAddress deviceAddress; + getAddress(deviceAddress, deviceIndex); + return getTempC((uint8_t*)deviceAddress); +} + +// Fetch temperature for device index +float DallasTemperature::getTempFByIndex(uint8_t deviceIndex) +{ + return toFahrenheit(getTempCByIndex(deviceIndex)); +} + +// reads scratchpad and returns the temperature in degrees C +float DallasTemperature::calculateTemperature(uint8_t* deviceAddress, uint8_t* scratchPad) +{ + int16_t rawTemperature = (((int16_t)scratchPad[TEMP_MSB]) << 8) | scratchPad[TEMP_LSB]; + + switch (deviceAddress[0]) + { + case DS18B20MODEL: + case DS1822MODEL: + switch (scratchPad[CONFIGURATION]) + { + case TEMP_12_BIT: + return (float)rawTemperature * 0.0625; + break; + case TEMP_11_BIT: + return (float)(rawTemperature >> 1) * 0.125; + break; + case TEMP_10_BIT: + return (float)(rawTemperature >> 2) * 0.25; + break; + case TEMP_9_BIT: + return (float)(rawTemperature >> 3) * 0.5; + break; + } + break; + case DS18S20MODEL: + /* + + Resolutions greater than 9 bits can be calculated using the data from + the temperature, COUNT REMAIN and COUNT PER �C registers in the + scratchpad. Note that the COUNT PER �C register is hard-wired to 16 + (10h). After reading the scratchpad, the TEMP_READ value is obtained + by truncating the 0.5�C bit (bit 0) from the temperature data. The + extended resolution temperature can then be calculated using the + following equation: + + COUNT_PER_C - COUNT_REMAIN + TEMPERATURE = TEMP_READ - 0.25 + -------------------------- + COUNT_PER_C + */ + + // Good spot. Thanks Nic Johns for your contribution + return (float)(rawTemperature >> 1) - 0.25 +((float)(scratchPad[COUNT_PER_C] - scratchPad[COUNT_REMAIN]) / (float)scratchPad[COUNT_PER_C] ); + break; + } +} + +// returns temperature in degrees C or DEVICE_DISCONNECTED if the +// device's scratch pad cannot be read successfully. +// the numeric value of DEVICE_DISCONNECTED is defined in +// DallasTemperature.h. It is a large negative number outside the +// operating range of the device +float DallasTemperature::getTempC(uint8_t* deviceAddress) +{ + // TODO: Multiple devices (up to 64) on the same bus may take + // some time to negotiate a response + // What happens in case of collision? + + ScratchPad scratchPad; + if (isConnected(deviceAddress, scratchPad)) return calculateTemperature(deviceAddress, scratchPad); + return DEVICE_DISCONNECTED; +} + +// returns temperature in degrees F +// TODO: - when getTempC returns DEVICE_DISCONNECTED +// -127 gets converted to -196.6 F +float DallasTemperature::getTempF(uint8_t* deviceAddress) +{ + return toFahrenheit(getTempC(deviceAddress)); +} + +// returns true if the bus requires parasite power +bool DallasTemperature::isParasitePowerMode(void) +{ + return parasite; +} + +#if REQUIRESALARMS + +/* + +ALARMS: + +TH and TL Register Format + +BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0 + S 2^6 2^5 2^4 2^3 2^2 2^1 2^0 + +Only bits 11 through 4 of the temperature register are used +in the TH and TL comparison since TH and TL are 8-bit +registers. If the measured temperature is lower than or equal +to TL or higher than or equal to TH, an alarm condition exists +and an alarm flag is set inside the DS18B20. This flag is +updated after every temperature measurement; therefore, if the +alarm condition goes away, the flag will be turned off after +the next temperature conversion. + +*/ + +// sets the high alarm temperature for a device in degrees celsius +// accepts a float, but the alarm resolution will ignore anything +// after a decimal point. valid range is -55C - 125C +void DallasTemperature::setHighAlarmTemp(uint8_t* deviceAddress, char celsius) +{ + // make sure the alarm temperature is within the device's range + if (celsius > 125) celsius = 125; + else if (celsius < -55) celsius = -55; + + ScratchPad scratchPad; + if (isConnected(deviceAddress, scratchPad)) + { + scratchPad[HIGH_ALARM_TEMP] = (uint8_t)celsius; + writeScratchPad(deviceAddress, scratchPad); + } +} + +// sets the low alarm temperature for a device in degreed celsius +// accepts a float, but the alarm resolution will ignore anything +// after a decimal point. valid range is -55C - 125C +void DallasTemperature::setLowAlarmTemp(uint8_t* deviceAddress, char celsius) +{ + // make sure the alarm temperature is within the device's range + if (celsius > 125) celsius = 125; + else if (celsius < -55) celsius = -55; + + ScratchPad scratchPad; + if (isConnected(deviceAddress, scratchPad)) + { + scratchPad[LOW_ALARM_TEMP] = (uint8_t)celsius; + writeScratchPad(deviceAddress, scratchPad); + } +} + +// returns a char with the current high alarm temperature or +// DEVICE_DISCONNECTED for an address +char DallasTemperature::getHighAlarmTemp(uint8_t* deviceAddress) +{ + ScratchPad scratchPad; + if (isConnected(deviceAddress, scratchPad)) return (char)scratchPad[HIGH_ALARM_TEMP]; + return DEVICE_DISCONNECTED; +} + +// returns a char with the current low alarm temperature or +// DEVICE_DISCONNECTED for an address +char DallasTemperature::getLowAlarmTemp(uint8_t* deviceAddress) +{ + ScratchPad scratchPad; + if (isConnected(deviceAddress, scratchPad)) return (char)scratchPad[LOW_ALARM_TEMP]; + return DEVICE_DISCONNECTED; +} + +// resets internal variables used for the alarm search +void DallasTemperature::resetAlarmSearch() +{ + alarmSearchJunction = -1; + alarmSearchExhausted = 0; + for(uint8_t i = 0; i < 7; i++) + alarmSearchAddress[i] = 0; +} + +// This is a modified version of the OneWire::search method. +// +// Also added the OneWire search fix documented here: +// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295 +// +// Perform an alarm search. If this function returns a '1' then it has +// enumerated the next device and you may retrieve the ROM from the +// OneWire::address variable. If there are no devices, no further +// devices, or something horrible happens in the middle of the +// enumeration then a 0 is returned. If a new device is found then +// its address is copied to newAddr. Use +// DallasTemperature::resetAlarmSearch() to start over. +bool DallasTemperature::alarmSearch(uint8_t* newAddr) +{ + uint8_t i; + char lastJunction = -1; + uint8_t done = 1; + + if (alarmSearchExhausted) return false; + if (!_wire->reset()) return false; + + // send the alarm search command + _wire->write(0xEC, 0); + + for(i = 0; i < 64; i++) + { + uint8_t a = _wire->read_bit( ); + uint8_t nota = _wire->read_bit( ); + uint8_t ibyte = i / 8; + uint8_t ibit = 1 << (i & 7); + + // I don't think this should happen, this means nothing responded, but maybe if + // something vanishes during the search it will come up. + if (a && nota) return false; + + if (!a && !nota) + { + if (i == alarmSearchJunction) + { + // this is our time to decide differently, we went zero last time, go one. + a = 1; + alarmSearchJunction = lastJunction; + } + else if (i < alarmSearchJunction) + { + // take whatever we took last time, look in address + if (alarmSearchAddress[ibyte] & ibit) a = 1; + else + { + // Only 0s count as pending junctions, we've already exhasuted the 0 side of 1s + a = 0; + done = 0; + lastJunction = i; + } + } + else + { + // we are blazing new tree, take the 0 + a = 0; + alarmSearchJunction = i; + done = 0; + } + // OneWire search fix + // See: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295 + } + + if (a) alarmSearchAddress[ibyte] |= ibit; + else alarmSearchAddress[ibyte] &= ~ibit; + + _wire->write_bit(a); + } + + if (done) alarmSearchExhausted = 1; + for (i = 0; i < 8; i++) newAddr[i] = alarmSearchAddress[i]; + return true; +} + +// returns true if device address has an alarm condition +// TODO: can this be done with only TEMP_MSB REGISTER (faster) +// if ((char) scratchPad[TEMP_MSB] <= (char) scratchPad[LOW_ALARM_TEMP]) return true; +// if ((char) scratchPad[TEMP_MSB] >= (char) scratchPad[HIGH_ALARM_TEMP]) return true; +bool DallasTemperature::hasAlarm(uint8_t* deviceAddress) +{ + ScratchPad scratchPad; + if (isConnected(deviceAddress, scratchPad)) + { + float temp = calculateTemperature(deviceAddress, scratchPad); + + // check low alarm + if ((char)temp <= (char)scratchPad[LOW_ALARM_TEMP]) return true; + + // check high alarm + if ((char)temp >= (char)scratchPad[HIGH_ALARM_TEMP]) return true; + } + + // no alarm + return false; +} + +// returns true if any device is reporting an alarm condition on the bus +bool DallasTemperature::hasAlarm(void) +{ + DeviceAddress deviceAddress; + resetAlarmSearch(); + return alarmSearch(deviceAddress); +} + +// runs the alarm handler for all devices returned by alarmSearch() +void DallasTemperature::processAlarms(void) +{ + resetAlarmSearch(); + DeviceAddress alarmAddr; + + while (alarmSearch(alarmAddr)) + { + if (validAddress(alarmAddr)) + _AlarmHandler(alarmAddr); + } +} + +// sets the alarm handler +void DallasTemperature::setAlarmHandler(AlarmHandler *handler) +{ + _AlarmHandler = handler; +} + +// The default alarm handler +void DallasTemperature::defaultAlarmHandler(uint8_t* deviceAddress) +{ +} + +#endif + +// Convert float celsius to fahrenheit +float DallasTemperature::toFahrenheit(float celsius) +{ + return (celsius * 1.8) + 32; +} + +// Convert float fahrenheit to celsius +float DallasTemperature::toCelsius(float fahrenheit) +{ + return (fahrenheit - 32) / 1.8; +} + +#if REQUIRESNEW + +// MnetCS - Allocates memory for DallasTemperature. Allows us to instance a new object +void* DallasTemperature::operator new(unsigned int size) // Implicit NSS obj size +{ + void * p; // void pointer + p = malloc(size); // Allocate memory + memset((DallasTemperature*)p,0,size); // Initalise memory + + //!!! CANT EXPLICITLY CALL CONSTRUCTOR - workaround by using an init() methodR - workaround by using an init() method + return (DallasTemperature*) p; // Cast blank region to NSS pointer +} + +// MnetCS 2009 - Unallocates the memory used by this instance +void DallasTemperature::operator delete(void* p) +{ + DallasTemperature* pNss = (DallasTemperature*) p; // Cast to NSS pointer + pNss->~DallasTemperature(); // Destruct the object + + free(p); // Free the memory +} + +#endif diff --git a/libraries/DallasTemperature/DallasTemperature.h b/libraries/DallasTemperature/DallasTemperature.h new file mode 100644 index 0000000..ff8262f --- /dev/null +++ b/libraries/DallasTemperature/DallasTemperature.h @@ -0,0 +1,242 @@ +#ifndef DallasTemperature_h +#define DallasTemperature_h + +#define DALLASTEMPLIBVERSION "3.7.2" + +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. + +// set to true to include code for new and delete operators +#ifndef REQUIRESNEW +#define REQUIRESNEW false +#endif + +// set to true to include code implementing alarm search functions +#ifndef REQUIRESALARMS +#define REQUIRESALARMS true +#endif + +#include +#include + +// Model IDs +#define DS18S20MODEL 0x10 +#define DS18B20MODEL 0x28 +#define DS1822MODEL 0x22 + +// OneWire commands +#define STARTCONVO 0x44 // Tells device to take a temperature reading and put it on the scratchpad +#define COPYSCRATCH 0x48 // Copy EEPROM +#define READSCRATCH 0xBE // Read EEPROM +#define WRITESCRATCH 0x4E // Write to EEPROM +#define RECALLSCRATCH 0xB8 // Reload from last known +#define READPOWERSUPPLY 0xB4 // Determine if device needs parasite power +#define ALARMSEARCH 0xEC // Query bus for devices with an alarm condition + +// Scratchpad locations +#define TEMP_LSB 0 +#define TEMP_MSB 1 +#define HIGH_ALARM_TEMP 2 +#define LOW_ALARM_TEMP 3 +#define CONFIGURATION 4 +#define INTERNAL_BYTE 5 +#define COUNT_REMAIN 6 +#define COUNT_PER_C 7 +#define SCRATCHPAD_CRC 8 + +// Device resolution +#define TEMP_9_BIT 0x1F // 9 bit +#define TEMP_10_BIT 0x3F // 10 bit +#define TEMP_11_BIT 0x5F // 11 bit +#define TEMP_12_BIT 0x7F // 12 bit + +// Error Codes +#define DEVICE_DISCONNECTED -127 + +typedef uint8_t DeviceAddress[8]; + +class DallasTemperature +{ + public: + + DallasTemperature(OneWire*); + + // initalise bus + void begin(void); + + // returns the number of devices found on the bus + uint8_t getDeviceCount(void); + + // Is a conversion complete on the wire? + bool isConversionComplete(void); + + // returns true if address is valid + bool validAddress(uint8_t*); + + // finds an address at a given index on the bus + bool getAddress(uint8_t*, const uint8_t); + + // attempt to determine if the device at the given address is connected to the bus + bool isConnected(uint8_t*); + + // attempt to determine if the device at the given address is connected to the bus + // also allows for updating the read scratchpad + bool isConnected(uint8_t*, uint8_t*); + + // read device's scratchpad + void readScratchPad(uint8_t*, uint8_t*); + + // write device's scratchpad + void writeScratchPad(uint8_t*, const uint8_t*); + + // read device's power requirements + bool readPowerSupply(uint8_t*); + + // get global resolution + uint8_t getResolution(); + + // set global resolution to 9, 10, 11, or 12 bits + void setResolution(uint8_t); + + // returns the device resolution, 9-12 + uint8_t getResolution(uint8_t*); + + // set resolution of a device to 9, 10, 11, or 12 bits + bool setResolution(uint8_t*, uint8_t); + + // sets/gets the waitForConversion flag + void setWaitForConversion(bool); + bool getWaitForConversion(void); + + // sets/gets the checkForConversion flag + void setCheckForConversion(bool); + bool getCheckForConversion(void); + + // sends command for all devices on the bus to perform a temperature conversion + void requestTemperatures(void); + + // sends command for one device to perform a temperature conversion by address + bool requestTemperaturesByAddress(uint8_t*); + + // sends command for one device to perform a temperature conversion by index + bool requestTemperaturesByIndex(uint8_t); + + // returns temperature in degrees C + float getTempC(uint8_t*); + + // returns temperature in degrees F + float getTempF(uint8_t*); + + // Get temperature for device index (slow) + float getTempCByIndex(uint8_t); + + // Get temperature for device index (slow) + float getTempFByIndex(uint8_t); + + // returns true if the bus requires parasite power + bool isParasitePowerMode(void); + + bool isConversionAvailable(uint8_t*); + + #if REQUIRESALARMS + + typedef void AlarmHandler(uint8_t*); + + // sets the high alarm temperature for a device + // accepts a char. valid range is -55C - 125C + void setHighAlarmTemp(uint8_t*, const char); + + // sets the low alarm temperature for a device + // accepts a char. valid range is -55C - 125C + void setLowAlarmTemp(uint8_t*, const char); + + // returns a signed char with the current high alarm temperature for a device + // in the range -55C - 125C + char getHighAlarmTemp(uint8_t*); + + // returns a signed char with the current low alarm temperature for a device + // in the range -55C - 125C + char getLowAlarmTemp(uint8_t*); + + // resets internal variables used for the alarm search + void resetAlarmSearch(void); + + // search the wire for devices with active alarms + bool alarmSearch(uint8_t*); + + // returns true if ia specific device has an alarm + bool hasAlarm(uint8_t*); + + // returns true if any device is reporting an alarm on the bus + bool hasAlarm(void); + + // runs the alarm handler for all devices returned by alarmSearch() + void processAlarms(void); + + // sets the alarm handler + void setAlarmHandler(AlarmHandler *); + + // The default alarm handler + static void defaultAlarmHandler(uint8_t*); + + #endif + + // convert from celcius to farenheit + static float toFahrenheit(const float); + + // convert from farenheit to celsius + static float toCelsius(const float); + + #if REQUIRESNEW + + // initalize memory area + void* operator new (unsigned int); + + // delete memory reference + void operator delete(void*); + + #endif + + private: + typedef uint8_t ScratchPad[9]; + + // parasite power on or off + bool parasite; + + // used to determine the delay amount needed to allow for the + // temperature conversion to take place + uint8_t bitResolution; + + // used to requestTemperature with or without delay + bool waitForConversion; + + // used to requestTemperature to dynamically check if a conversion is complete + bool checkForConversion; + + // count of devices on the bus + uint8_t devices; + + // Take a pointer to one wire instance + OneWire* _wire; + + // reads scratchpad and returns the temperature in degrees C + float calculateTemperature(uint8_t*, uint8_t*); + + void blockTillConversionComplete(uint8_t*,uint8_t*); + + #if REQUIRESALARMS + + // required for alarmSearch + uint8_t alarmSearchAddress[8]; + char alarmSearchJunction; + uint8_t alarmSearchExhausted; + + // the alarm handler function pointer + AlarmHandler *_AlarmHandler; + + #endif + +}; +#endif diff --git a/libraries/DallasTemperature/README.TXT b/libraries/DallasTemperature/README.TXT new file mode 100644 index 0000000..764bdd7 --- /dev/null +++ b/libraries/DallasTemperature/README.TXT @@ -0,0 +1,53 @@ +Arduino Library for Dallas Temperature ICs +========================================== + +Usage +----- + +This library supports the following devices: + DS18B20 + DS18S20 - Please note there appears to be an issue with this series. + DS1822 + +You will need a pull-up resistor of about 5 KOhm between the 1-Wire data line +and your 5V power. If you are using the DS18B20, ground pins 1 and 3. The +centre pin is the data line '1-wire'. + +We have included a "REQUIRESNEW" and "REQUIRESALARMS" definition. If you +want to slim down the code feel free to use either of these by including +#define REQUIRESNEW or #define REQUIRESALARMS a the top of DallasTemperature.h + +Credits +------- + +The OneWire code has been derived from +http://www.arduino.cc/playground/Learning/OneWire. +Miles Burton originally developed this library. +Tim Newsome added support for multiple sensors on +the same bus. +Guil Barros [gfbarros@bappos.com] added getTempByAddress (v3.5) +Rob Tillaart [rob.tillaart@gmail.com] added async modus (v3.7.0) + + +Website +------- + +You can find the latest version of the library at +http://milesburton.com/index.php?title=Dallas_Temperature_Control_Library + +License +------- + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA diff --git a/libraries/DallasTemperature/change.txt b/libraries/DallasTemperature/change.txt new file mode 100644 index 0000000..42564ca --- /dev/null +++ b/libraries/DallasTemperature/change.txt @@ -0,0 +1,85 @@ + +This file contains the change history of the Dallas Temperature Control Library. + +VERSION 3.7.2 BETA +=================== +DATE: 6 DEC 2011 + +- Jordan Hochenbaum [jhochenbaum@gmail.com] updated library for compatibility with Arduino 1.0. + +VERSION 3.7.0 BETA +=================== +DATE: 11 JAN 2011 + +- Rob Tillaart [rob.tillaart@gmail.com] added async modus (v3.7.0) + The library is backwards compatible with version 3.6.0 + + MAJOR: async modus + ------------------ +- Added - private bool waitForConversion. +This boolean is default set to true in the Constructor to keep the library backwards compatible. If this flag is true calls to requestTemperatures(), requestTemperaturesByAddress() et al, will be blocking with the appropiate time specified (in datasheet) for the resolution used. If the flag is set to false, requestTemperatures() et al, will return immediately after the conversion command is send over the 1-wire interface. The programmer is responsible to wait long enough before reading the temperature values. This enables the application to do other things while waiting for a new reading, like calculations, update LCD, read/write other IO lines etc. See examples. + +- Added - void setWaitForConversion(bool); +To set the flag to true or false, depending on the modus needed. + +- Added - bool getWaitForConversion(void); +To get the current value of the flag. + +- Changed - void requestTemperatures(void); +Added a test (false == waitForConversion) to return immediately after the conversion command instead of waiting until the conversion is ready. + +- Changed - bool requestTemperaturesByAddress(uint8_t*); +Added a test (false == waitForConversion) to return immediately after the conversion command instead of waiting until the conversion is ready. + + + MINOR version number + -------------------- +- Added - #define DALLASTEMPLIBVERSION "3.7.0" +To indicate the version number in .h file + + + MINOR internal var bitResolution + ---------------------------- +- Changed - private int conversionDelay - is renamed to - private int bitResolution +As this variable holds the resolution. The delay for the conversion is derived from it. + +- Changed - uint8_t getResolution(uint8_t* deviceAddress); +If the device is not connected, it returns 0, otherwise it returns the resolution of the device. + +- Changed - bool setResolution(uint8_t* deviceAddress, uint8_t newResolution); +If the device is not connected, it returns FALSE (fail), otherwise it returns TRUE (succes). + +- Added - uint8_t getResolution(); +Returns bitResolution. + +- Added - void setResolution(uint8_t newResolution) +Sets the internal variable bitResolution, and all devices to this value + + + MINOR check connected state + ---------------------------- +- Changed - bool requestTemperaturesByIndex(deviceIndex) +Changed return type from void to bool. The function returns false if the device identified with [deviceIndex] is not found on the bus and true otherwise. + +- Changed - bool requestTemperaturesByAddress(deviceAddress) +Changed return type from void to bool. The function returns false if the device identified with [deviceAddress] is not found on the bus and true otherwise. +Added code to handle the DS18S20 which has a 9 bit resolution separately. +Changed code so the blocking delay matches the bitResolution set in the device with deviceAddress. + +- Changed - bool requestTemperaturesByIndex(uint8_t deviceIndex) +Changed return type from void to bool. The function returns false if the device identified with [deviceIndex] is not found on the bus and true otherwise. + + + +VERSION 3.6.0 +============== +DATE: 2010-10-10 + +- no detailed change history known except: + +- The OneWire code has been derived from +http://www.arduino.cc/playground/Learning/OneWire. +- Miles Burton originally developed this library. +- Tim Newsome added support for multiple sensors on +the same bus. +- Guil Barros [gfbarros@bappos.com] added getTempByAddress (v3.5) diff --git a/libraries/DallasTemperature/examples/Alarm/Alarm.pde b/libraries/DallasTemperature/examples/Alarm/Alarm.pde new file mode 100644 index 0000000..d9c6e6c --- /dev/null +++ b/libraries/DallasTemperature/examples/Alarm/Alarm.pde @@ -0,0 +1,162 @@ +#include +#include + +// Data wire is plugged into port 2 on the Arduino +#define ONE_WIRE_BUS 2 + +// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) +OneWire oneWire(ONE_WIRE_BUS); + +// Pass our oneWire reference to Dallas Temperature. +DallasTemperature sensors(&oneWire); + +// arrays to hold device addresses +DeviceAddress insideThermometer, outsideThermometer; + +void setup(void) +{ + // start serial port + Serial.begin(9600); + Serial.println("Dallas Temperature IC Control Library Demo"); + + // Start up the library + sensors.begin(); + + // locate devices on the bus + Serial.print("Found "); + Serial.print(sensors.getDeviceCount(), DEC); + Serial.println(" devices."); + + // search for devices on the bus and assign based on an index. + if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0"); + if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1"); + + // show the addresses we found on the bus + Serial.print("Device 0 Address: "); + printAddress(insideThermometer); + Serial.println(); + + Serial.print("Device 0 Alarms: "); + printAlarms(insideThermometer); + Serial.println(); + + Serial.print("Device 1 Address: "); + printAddress(outsideThermometer); + Serial.println(); + + Serial.print("Device 1 Alarms: "); + printAlarms(outsideThermometer); + Serial.println(); + + Serial.println("Setting alarm temps..."); + + // alarm when temp is higher than 30C + sensors.setHighAlarmTemp(insideThermometer, 30); + + // alarm when temp is lower than -10C + sensors.setLowAlarmTemp(insideThermometer, -10); + + // alarm when temp is higher than 31C + sensors.setHighAlarmTemp(outsideThermometer, 31); + + // alarn when temp is lower than 27C + sensors.setLowAlarmTemp(outsideThermometer, 27); + + Serial.print("New Device 0 Alarms: "); + printAlarms(insideThermometer); + Serial.println(); + + Serial.print("New Device 1 Alarms: "); + printAlarms(outsideThermometer); + Serial.println(); +} + +// function to print a device address +void printAddress(DeviceAddress deviceAddress) +{ + for (uint8_t i = 0; i < 8; i++) + { + if (deviceAddress[i] < 16) Serial.print("0"); + Serial.print(deviceAddress[i], HEX); + } +} + +// function to print the temperature for a device +void printTemperature(DeviceAddress deviceAddress) +{ + float tempC = sensors.getTempC(deviceAddress); + Serial.print("Temp C: "); + Serial.print(tempC); + Serial.print(" Temp F: "); + Serial.print(DallasTemperature::toFahrenheit(tempC)); +} + +void printAlarms(uint8_t deviceAddress[]) +{ + char temp; + temp = sensors.getHighAlarmTemp(deviceAddress); + Serial.print("High Alarm: "); + Serial.print(temp, DEC); + Serial.print("C/"); + Serial.print(DallasTemperature::toFahrenheit(temp)); + Serial.print("F | Low Alarm: "); + temp = sensors.getLowAlarmTemp(deviceAddress); + Serial.print(temp, DEC); + Serial.print("C/"); + Serial.print(DallasTemperature::toFahrenheit(temp)); + Serial.print("F"); +} + +// main function to print information about a device +void printData(DeviceAddress deviceAddress) +{ + Serial.print("Device Address: "); + printAddress(deviceAddress); + Serial.print(" "); + printTemperature(deviceAddress); + Serial.println(); +} + +void checkAlarm(DeviceAddress deviceAddress) +{ + if (sensors.hasAlarm(deviceAddress)) + { + Serial.print("ALARM: "); + printData(deviceAddress); + } +} + +void loop(void) +{ + // call sensors.requestTemperatures() to issue a global temperature + // request to all devices on the bus + Serial.print("Requesting temperatures..."); + sensors.requestTemperatures(); + Serial.println("DONE"); + + // Method 1: + // check each address individually for an alarm condition + checkAlarm(insideThermometer); + checkAlarm(outsideThermometer); +/* + // Alternate method: + // Search the bus and iterate through addresses of devices with alarms + + // space for the alarm device's address + DeviceAddress alarmAddr; + + Serial.println("Searching for alarms..."); + + // resetAlarmSearch() must be called before calling alarmSearch() + sensors.resetAlarmSearch(); + + // alarmSearch() returns 0 when there are no devices with alarms + while (sensors.alarmSearch(alarmAddr)) + { + Serial.print("ALARM: "); + printData(alarmAddr); + } +*/ + +} + diff --git a/libraries/DallasTemperature/examples/AlarmHandler/AlarmHandler.pde b/libraries/DallasTemperature/examples/AlarmHandler/AlarmHandler.pde new file mode 100644 index 0000000..4b72962 --- /dev/null +++ b/libraries/DallasTemperature/examples/AlarmHandler/AlarmHandler.pde @@ -0,0 +1,144 @@ +#include +#include + +// Data wire is plugged into port 2 on the Arduino +#define ONE_WIRE_BUS 2 + +// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) +OneWire oneWire(ONE_WIRE_BUS); + +// Pass our oneWire reference to Dallas Temperature. +DallasTemperature sensors(&oneWire); + +// arrays to hold device addresses +DeviceAddress insideThermometer, outsideThermometer; + +// function that will be called when an alarm condition exists during DallasTemperatures::processAlarms(); +void newAlarmHandler(uint8_t* deviceAddress) +{ + Serial.println("Alarm Handler Start"); + printAlarmInfo(deviceAddress); + printTemp(deviceAddress); + Serial.println(); + Serial.println("Alarm Handler Finish"); +} + +void printCurrentTemp(DeviceAddress deviceAddress) +{ + printAddress(deviceAddress); + printTemp(deviceAddress); + Serial.println(); +} + +void printAddress(DeviceAddress deviceAddress) +{ + Serial.print("Address: "); + for (uint8_t i = 0; i < 8; i++) + { + if (deviceAddress[i] < 16) Serial.print("0"); + Serial.print(deviceAddress[i], HEX); + } + Serial.print(" "); +} + +void printTemp(DeviceAddress deviceAddress) +{ + float tempC = sensors.getTempC(deviceAddress); + if (tempC != DEVICE_DISCONNECTED) + { + Serial.print("Current Temp C: "); + Serial.print(tempC); + } + else Serial.print("DEVICE DISCONNECTED"); + Serial.print(" "); +} + +void printAlarmInfo(DeviceAddress deviceAddress) +{ + char temp; + printAddress(deviceAddress); + temp = sensors.getHighAlarmTemp(deviceAddress); + Serial.print("High Alarm: "); + Serial.print(temp, DEC); + Serial.print("C"); + Serial.print(" Low Alarm: "); + temp = sensors.getLowAlarmTemp(deviceAddress); + Serial.print(temp, DEC); + Serial.print("C"); + Serial.print(" "); +} + +void setup(void) +{ + // start serial port + Serial.begin(9600); + Serial.println("Dallas Temperature IC Control Library Demo"); + + // Start up the library + sensors.begin(); + + // locate devices on the bus + Serial.print("Found "); + Serial.print(sensors.getDeviceCount(), DEC); + Serial.println(" devices."); + + // search for devices on the bus and assign based on an index + if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0"); + if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1"); + + Serial.print("Device insideThermometer "); + printAlarmInfo(insideThermometer); + Serial.println(); + + Serial.print("Device outsideThermometer "); + printAlarmInfo(outsideThermometer); + Serial.println(); + + // set alarm ranges + Serial.println("Setting alarm temps..."); + sensors.setHighAlarmTemp(insideThermometer, 26); + sensors.setLowAlarmTemp(insideThermometer, 22); + sensors.setHighAlarmTemp(outsideThermometer, 25); + sensors.setLowAlarmTemp(outsideThermometer, 21); + + Serial.print("New insideThermometer "); + printAlarmInfo(insideThermometer); + Serial.println(); + + Serial.print("New outsideThermometer "); + printAlarmInfo(outsideThermometer); + Serial.println(); + + // attach alarm handler + sensors.setAlarmHandler(&newAlarmHandler); + +} + +void loop(void) +{ + // ask the devices to measure the temperature + sensors.requestTemperatures(); + + // if an alarm condition exists as a result of the most recent + // requestTemperatures() request, it exists until the next time + // requestTemperatures() is called AND there isn't an alarm condition + // on the device + if (sensors.hasAlarm()) + { + Serial.println("Oh noes! There is at least one alarm on the bus."); + } + + // call alarm handler function defined by sensors.setAlarmHandler + // for each device reporting an alarm + sensors.processAlarms(); + + if (!sensors.hasAlarm()) + { + // just print out the current temperature + printCurrentTemp(insideThermometer); + printCurrentTemp(outsideThermometer); + } + + delay(1000); +} + diff --git a/libraries/DallasTemperature/examples/Multiple/Multiple.pde b/libraries/DallasTemperature/examples/Multiple/Multiple.pde new file mode 100644 index 0000000..37e7ba6 --- /dev/null +++ b/libraries/DallasTemperature/examples/Multiple/Multiple.pde @@ -0,0 +1,140 @@ +#include +#include + +// Data wire is plugged into port 2 on the Arduino +#define ONE_WIRE_BUS 2 +#define TEMPERATURE_PRECISION 9 + +// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) +OneWire oneWire(ONE_WIRE_BUS); + +// Pass our oneWire reference to Dallas Temperature. +DallasTemperature sensors(&oneWire); + +// arrays to hold device addresses +DeviceAddress insideThermometer, outsideThermometer; + +void setup(void) +{ + // start serial port + Serial.begin(9600); + Serial.println("Dallas Temperature IC Control Library Demo"); + + // Start up the library + sensors.begin(); + + // locate devices on the bus + Serial.print("Locating devices..."); + Serial.print("Found "); + Serial.print(sensors.getDeviceCount(), DEC); + Serial.println(" devices."); + + // report parasite power requirements + Serial.print("Parasite power is: "); + if (sensors.isParasitePowerMode()) Serial.println("ON"); + else Serial.println("OFF"); + + // assign address manually. the addresses below will beed to be changed + // to valid device addresses on your bus. device address can be retrieved + // by using either oneWire.search(deviceAddress) or individually via + // sensors.getAddress(deviceAddress, index) + //insideThermometer = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 }; + //outsideThermometer = { 0x28, 0x3F, 0x1C, 0x31, 0x2, 0x0, 0x0, 0x2 }; + + // search for devices on the bus and assign based on an index. ideally, + // you would do this to initially discover addresses on the bus and then + // use those addresses and manually assign them (see above) once you know + // the devices on your bus (and assuming they don't change). + // + // method 1: by index + if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0"); + if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1"); + + // method 2: search() + // search() looks for the next device. Returns 1 if a new address has been + // returned. A zero might mean that the bus is shorted, there are no devices, + // or you have already retrieved all of them. It might be a good idea to + // check the CRC to make sure you didn't get garbage. The order is + // deterministic. You will always get the same devices in the same order + // + // Must be called before search() + //oneWire.reset_search(); + // assigns the first address found to insideThermometer + //if (!oneWire.search(insideThermometer)) Serial.println("Unable to find address for insideThermometer"); + // assigns the seconds address found to outsideThermometer + //if (!oneWire.search(outsideThermometer)) Serial.println("Unable to find address for outsideThermometer"); + + // show the addresses we found on the bus + Serial.print("Device 0 Address: "); + printAddress(insideThermometer); + Serial.println(); + + Serial.print("Device 1 Address: "); + printAddress(outsideThermometer); + Serial.println(); + + // set the resolution to 9 bit + sensors.setResolution(insideThermometer, TEMPERATURE_PRECISION); + sensors.setResolution(outsideThermometer, TEMPERATURE_PRECISION); + + Serial.print("Device 0 Resolution: "); + Serial.print(sensors.getResolution(insideThermometer), DEC); + Serial.println(); + + Serial.print("Device 1 Resolution: "); + Serial.print(sensors.getResolution(outsideThermometer), DEC); + Serial.println(); +} + +// function to print a device address +void printAddress(DeviceAddress deviceAddress) +{ + for (uint8_t i = 0; i < 8; i++) + { + // zero pad the address if necessary + if (deviceAddress[i] < 16) Serial.print("0"); + Serial.print(deviceAddress[i], HEX); + } +} + +// function to print the temperature for a device +void printTemperature(DeviceAddress deviceAddress) +{ + float tempC = sensors.getTempC(deviceAddress); + Serial.print("Temp C: "); + Serial.print(tempC); + Serial.print(" Temp F: "); + Serial.print(DallasTemperature::toFahrenheit(tempC)); +} + +// function to print a device's resolution +void printResolution(DeviceAddress deviceAddress) +{ + Serial.print("Resolution: "); + Serial.print(sensors.getResolution(deviceAddress)); + Serial.println(); +} + +// main function to print information about a device +void printData(DeviceAddress deviceAddress) +{ + Serial.print("Device Address: "); + printAddress(deviceAddress); + Serial.print(" "); + printTemperature(deviceAddress); + Serial.println(); +} + +void loop(void) +{ + // call sensors.requestTemperatures() to issue a global temperature + // request to all devices on the bus + Serial.print("Requesting temperatures..."); + sensors.requestTemperatures(); + Serial.println("DONE"); + + // print the device information + printData(insideThermometer); + printData(outsideThermometer); +} + diff --git a/libraries/DallasTemperature/examples/Simple/Simple.pde b/libraries/DallasTemperature/examples/Simple/Simple.pde new file mode 100644 index 0000000..5b2954d --- /dev/null +++ b/libraries/DallasTemperature/examples/Simple/Simple.pde @@ -0,0 +1,33 @@ +#include +#include + +// Data wire is plugged into port 2 on the Arduino +#define ONE_WIRE_BUS 2 + +// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) +OneWire oneWire(ONE_WIRE_BUS); + +// Pass our oneWire reference to Dallas Temperature. +DallasTemperature sensors(&oneWire); + +void setup(void) +{ + // start serial port + Serial.begin(9600); + Serial.println("Dallas Temperature IC Control Library Demo"); + + // Start up the library + sensors.begin(); +} + +void loop(void) +{ + // call sensors.requestTemperatures() to issue a global temperature + // request to all devices on the bus + Serial.print("Requesting temperatures..."); + sensors.requestTemperatures(); // Send the command to get temperatures + Serial.println("DONE"); + + Serial.print("Temperature for the device 1 (index 0) is: "); + Serial.println(sensors.getTempCByIndex(0)); +} diff --git a/libraries/DallasTemperature/examples/Single/Single.pde b/libraries/DallasTemperature/examples/Single/Single.pde new file mode 100644 index 0000000..7336859 --- /dev/null +++ b/libraries/DallasTemperature/examples/Single/Single.pde @@ -0,0 +1,109 @@ +#include +#include + +// Data wire is plugged into port 2 on the Arduino +#define ONE_WIRE_BUS 2 + +// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) +OneWire oneWire(ONE_WIRE_BUS); + +// Pass our oneWire reference to Dallas Temperature. +DallasTemperature sensors(&oneWire); + +// arrays to hold device address +DeviceAddress insideThermometer; + +void setup(void) +{ + // start serial port + Serial.begin(9600); + Serial.println("Dallas Temperature IC Control Library Demo"); + + // locate devices on the bus + Serial.print("Locating devices..."); + sensors.begin(); + Serial.print("Found "); + Serial.print(sensors.getDeviceCount(), DEC); + Serial.println(" devices."); + + // report parasite power requirements + Serial.print("Parasite power is: "); + if (sensors.isParasitePowerMode()) Serial.println("ON"); + else Serial.println("OFF"); + + // assign address manually. the addresses below will beed to be changed + // to valid device addresses on your bus. device address can be retrieved + // by using either oneWire.search(deviceAddress) or individually via + // sensors.getAddress(deviceAddress, index) + //insideThermometer = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 }; + + // Method 1: + // search for devices on the bus and assign based on an index. ideally, + // you would do this to initially discover addresses on the bus and then + // use those addresses and manually assign them (see above) once you know + // the devices on your bus (and assuming they don't change). + if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0"); + + // method 2: search() + // search() looks for the next device. Returns 1 if a new address has been + // returned. A zero might mean that the bus is shorted, there are no devices, + // or you have already retrieved all of them. It might be a good idea to + // check the CRC to make sure you didn't get garbage. The order is + // deterministic. You will always get the same devices in the same order + // + // Must be called before search() + //oneWire.reset_search(); + // assigns the first address found to insideThermometer + //if (!oneWire.search(insideThermometer)) Serial.println("Unable to find address for insideThermometer"); + + // show the addresses we found on the bus + Serial.print("Device 0 Address: "); + printAddress(insideThermometer); + Serial.println(); + + // set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions) + sensors.setResolution(insideThermometer, 9); + + Serial.print("Device 0 Resolution: "); + Serial.print(sensors.getResolution(insideThermometer), DEC); + Serial.println(); +} + +// function to print the temperature for a device +void printTemperature(DeviceAddress deviceAddress) +{ + // method 1 - slower + //Serial.print("Temp C: "); + //Serial.print(sensors.getTempC(deviceAddress)); + //Serial.print(" Temp F: "); + //Serial.print(sensors.getTempF(deviceAddress)); // Makes a second call to getTempC and then converts to Fahrenheit + + // method 2 - faster + float tempC = sensors.getTempC(deviceAddress); + Serial.print("Temp C: "); + Serial.print(tempC); + Serial.print(" Temp F: "); + Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit +} + +void loop(void) +{ + // call sensors.requestTemperatures() to issue a global temperature + // request to all devices on the bus + Serial.print("Requesting temperatures..."); + sensors.requestTemperatures(); // Send the command to get temperatures + Serial.println("DONE"); + + // It responds almost immediately. Let's print out the data + printTemperature(insideThermometer); // Use a simple function to print out the data +} + +// function to print a device address +void printAddress(DeviceAddress deviceAddress) +{ + for (uint8_t i = 0; i < 8; i++) + { + if (deviceAddress[i] < 16) Serial.print("0"); + Serial.print(deviceAddress[i], HEX); + } +} diff --git a/libraries/DallasTemperature/examples/Tester/Tester.pde b/libraries/DallasTemperature/examples/Tester/Tester.pde new file mode 100644 index 0000000..33ca9ba --- /dev/null +++ b/libraries/DallasTemperature/examples/Tester/Tester.pde @@ -0,0 +1,124 @@ +#include +#include + +// Data wire is plugged into port 2 on the Arduino +#define ONE_WIRE_BUS 2 +#define TEMPERATURE_PRECISION 9 + +// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) +OneWire oneWire(ONE_WIRE_BUS); + +// Pass our oneWire reference to Dallas Temperature. +DallasTemperature sensors(&oneWire); + +int numberOfDevices; // Number of temperature devices found + +DeviceAddress tempDeviceAddress; // We'll use this variable to store a found device address + +void setup(void) +{ + // start serial port + Serial.begin(9600); + Serial.println("Dallas Temperature IC Control Library Demo"); + + // Start up the library + sensors.begin(); + + // Grab a count of devices on the wire + numberOfDevices = sensors.getDeviceCount(); + + // locate devices on the bus + Serial.print("Locating devices..."); + + Serial.print("Found "); + Serial.print(numberOfDevices, DEC); + Serial.println(" devices."); + + // report parasite power requirements + Serial.print("Parasite power is: "); + if (sensors.isParasitePowerMode()) Serial.println("ON"); + else Serial.println("OFF"); + + // Loop through each device, print out address + for(int i=0;i +#include + +// Data wire is plugged into port 2 on the Arduino +#define ONE_WIRE_BUS 2 + +// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) +OneWire oneWire(ONE_WIRE_BUS); + +// Pass our oneWire reference to Dallas Temperature. +DallasTemperature sensors(&oneWire); + +void setup(void) +{ + // start serial port + Serial.begin(115200); + Serial.println("Dallas Temperature Control Library - Async Demo"); + Serial.println("\nDemo shows the difference in length of the call\n\n"); + + // Start up the library + sensors.begin(); +} + +void loop(void) +{ + // Request temperature conversion (traditional) + Serial.println("Before blocking requestForConversion"); + unsigned long start = millis(); + + sensors.requestTemperatures(); + + unsigned long stop = millis(); + Serial.println("After blocking requestForConversion"); + Serial.print("Time used: "); + Serial.println(stop - start); + + // get temperature + Serial.print("Temperature: "); + Serial.println(sensors.getTempCByIndex(0)); + Serial.println("\n"); + + // Request temperature conversion - non-blocking / async + Serial.println("Before NON-blocking/async requestForConversion"); + start = millis(); + sensors.setWaitForConversion(false); // makes it async + sensors.requestTemperatures(); + sensors.setWaitForConversion(true); + stop = millis(); + Serial.println("After NON-blocking/async requestForConversion"); + Serial.print("Time used: "); + Serial.println(stop - start); + + + // 9 bit resolution by default + // Note the programmer is responsible for the right delay + // we could do something usefull here instead of the delay + int resolution = 9; + delay(750/ (1 << (12-resolution))); + + // get temperature + Serial.print("Temperature: "); + Serial.println(sensors.getTempCByIndex(0)); + Serial.println("\n\n\n\n"); + + delay(5000); +} diff --git a/libraries/DallasTemperature/examples/WaitForConversion2/WaitForConversion2.pde b/libraries/DallasTemperature/examples/WaitForConversion2/WaitForConversion2.pde new file mode 100644 index 0000000..4322330 --- /dev/null +++ b/libraries/DallasTemperature/examples/WaitForConversion2/WaitForConversion2.pde @@ -0,0 +1,80 @@ +// +// Sample of using Async reading of Dallas Temperature Sensors +// +#include +#include + +// Data wire is plugged into port 2 on the Arduino +#define ONE_WIRE_BUS 2 + +// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) +OneWire oneWire(ONE_WIRE_BUS); + +// Pass our oneWire reference to Dallas Temperature. +DallasTemperature sensors(&oneWire); + +DeviceAddress tempDeviceAddress; + +int resolution = 12; +unsigned long lastTempRequest = 0; +int delayInMillis = 0; +float temperature = 0.0; +int idle = 0; +// +// SETUP +// +void setup(void) +{ + Serial.begin(115200); + Serial.println("Dallas Temperature Control Library - Async Demo"); + Serial.print("Library Version: "); + Serial.println(DALLASTEMPLIBVERSION); + Serial.println("\n"); + + sensors.begin(); + sensors.getAddress(tempDeviceAddress, 0); + sensors.setResolution(tempDeviceAddress, resolution); + + sensors.setWaitForConversion(false); + sensors.requestTemperatures(); + delayInMillis = 750 / (1 << (12 - resolution)); + lastTempRequest = millis(); + + pinMode(13, OUTPUT); +} + +void loop(void) +{ + + if (millis() - lastTempRequest >= delayInMillis) // waited long enough?? + { + digitalWrite(13, LOW); + Serial.print(" Temperature: "); + temperature = sensors.getTempCByIndex(0); + Serial.println(temperature, resolution - 8); + Serial.print(" Resolution: "); + Serial.println(resolution); + Serial.print("Idle counter: "); + Serial.println(idle); + Serial.println(); + + idle = 0; + + // immediately after fetching the temperature we request a new sample + // in the async modus + // for the demo we let the resolution change to show differences + resolution++; + if (resolution > 12) resolution = 9; + + sensors.setResolution(tempDeviceAddress, resolution); + sensors.requestTemperatures(); + delayInMillis = 750 / (1 << (12 - resolution)); + lastTempRequest = millis(); + } + + digitalWrite(13, HIGH); + // we can do usefull things here + // for the demo we just count the idle time in millis + delay(1); + idle++; +} diff --git a/libraries/DallasTemperature/keywords.txt b/libraries/DallasTemperature/keywords.txt new file mode 100644 index 0000000..0212d44 --- /dev/null +++ b/libraries/DallasTemperature/keywords.txt @@ -0,0 +1,54 @@ +####################################### +# Syntax Coloring Map For Ultrasound +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### +DallasTemperature KEYWORD1 +OneWire KEYWORD1 +AlarmHandler KEYWORD1 +DeviceAddress KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +setResolution KEYWORD2 +getResolution KEYWORD2 +getTempC KEYWORD2 +toFahrenheit KEYWORD2 +getTempF KEYWORD2 +getTempCByIndex KEYWORD2 +getTempFByIndex KEYWORD2 +setWaitForConversion KEYWORD2 +getWaitForConversion KEYWORD2 +requestTemperatures KEYWORD2 +requestTemperaturesByAddress KEYWORD2 +requestTemperaturesByIndex KEYWORD2 +isParasitePowerMode KEYWORD2 +begin KEYWORD2 +getDeviceCount KEYWORD2 +getAddress KEYWORD2 +validAddress KEYWORD2 +isConnected KEYWORD2 +readScratchPad KEYWORD2 +writeScratchPad KEYWORD2 +readPowerSupply KEYWORD2 +setHighAlarmTemp KEYWORD2 +setLowAlarmTemp KEYWORD2 +getHighAlarmTemp KEYWORD2 +getLowAlarmTemp KEYWORD2 +resetAlarmSearch KEYWORD2 +alarmSearch KEYWORD2 +hasAlarm KEYWORD2 +toCelsius KEYWORD2 +processAlarmss KEYWORD2 +setAlarmHandlers KEYWORD2 +defaultAlarmHandler KEYWORD2 +calculateTemperature KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/software/LedControl/LedControl.cpp b/libraries/LedControl/LedControl.cpp similarity index 100% rename from software/LedControl/LedControl.cpp rename to libraries/LedControl/LedControl.cpp diff --git a/software/LedControl/LedControl.h b/libraries/LedControl/LedControl.h similarity index 100% rename from software/LedControl/LedControl.h rename to libraries/LedControl/LedControl.h diff --git a/software/LedControl/examples/LCDemo7Segment.pde b/libraries/LedControl/examples/LCDemo7Segment.pde similarity index 100% rename from software/LedControl/examples/LCDemo7Segment.pde rename to libraries/LedControl/examples/LCDemo7Segment.pde diff --git a/software/LedControl/examples/LCDemoCascadedDevices.pde b/libraries/LedControl/examples/LCDemoCascadedDevices.pde similarity index 100% rename from software/LedControl/examples/LCDemoCascadedDevices.pde rename to libraries/LedControl/examples/LCDemoCascadedDevices.pde diff --git a/software/LedControl/examples/LCDemoMatrix/LCDemoMatrix.pde b/libraries/LedControl/examples/LCDemoMatrix/LCDemoMatrix.pde similarity index 100% rename from software/LedControl/examples/LCDemoMatrix/LCDemoMatrix.pde rename to libraries/LedControl/examples/LCDemoMatrix/LCDemoMatrix.pde diff --git a/software/LedControl/examples/LCDemoMatrix/myledmatrixdemo/myledmatrixdemo.ino b/libraries/LedControl/examples/LCDemoMatrix/myledmatrixdemo/myledmatrixdemo.ino similarity index 100% rename from software/LedControl/examples/LCDemoMatrix/myledmatrixdemo/myledmatrixdemo.ino rename to libraries/LedControl/examples/LCDemoMatrix/myledmatrixdemo/myledmatrixdemo.ino diff --git a/libraries/LedControlMS/LedControlMS.cpp b/libraries/LedControlMS/LedControlMS.cpp new file mode 100644 index 0000000..91d1f52 --- /dev/null +++ b/libraries/LedControlMS/LedControlMS.cpp @@ -0,0 +1,245 @@ +/* + * LedControl.cpp - A library for controling Leds with a MAX7219/MAX7221 + * Copyright (c) 2007 Eberhard Fahle + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * This permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + + +#include "LedControlMS.h" + +//the opcodes for the MAX7221 and MAX7219 +#define OP_NOOP 0 +#define OP_DIGIT0 1 +#define OP_DIGIT1 2 +#define OP_DIGIT2 3 +#define OP_DIGIT3 4 +#define OP_DIGIT4 5 +#define OP_DIGIT5 6 +#define OP_DIGIT6 7 +#define OP_DIGIT7 8 +#define OP_DECODEMODE 9 +#define OP_INTENSITY 10 +#define OP_SCANLIMIT 11 +#define OP_SHUTDOWN 12 +#define OP_DISPLAYTEST 15 + +LedControl::LedControl(int dataPin, int clkPin, int csPin, int numDevices) { + LEDCONTROL_SPI_MOSI=dataPin; + LEDCONTROL_SPI_CLK=clkPin; + LEDCONTROL_SPI_CS=csPin; + if(numDevices<=0 || numDevices>8 ) + numDevices=8; + maxDevices=numDevices; + pinMode(LEDCONTROL_SPI_MOSI,OUTPUT); + pinMode(LEDCONTROL_SPI_CLK,OUTPUT); + pinMode(LEDCONTROL_SPI_CS,OUTPUT); + digitalWrite(LEDCONTROL_SPI_CS,HIGH); + LEDCONTROL_SPI_MOSI=dataPin; + for(int i=0;i<64;i++) + status[i]=0x00; + for(int i=0;i=maxDevices) + return; + if(b) + spiTransfer(addr, OP_SHUTDOWN,0); + else + spiTransfer(addr, OP_SHUTDOWN,1); +} + +void LedControl::setScanLimit(int addr, int limit) { + if(addr<0 || addr>=maxDevices) + return; + if(limit>=0 || limit<8) + spiTransfer(addr, OP_SCANLIMIT,limit); +} + +void LedControl::setIntensity(int addr, int intensity) { + if(addr<0 || addr>=maxDevices) + return; + if(intensity>=0 || intensity<16) + spiTransfer(addr, OP_INTENSITY,intensity); + +} + +void LedControl::clearDisplay(int addr) { + int offset; + + if(addr<0 || addr>=maxDevices) + return; + offset=addr*8; + for(int i=0;i<8;i++) { + status[offset+i]=0; + spiTransfer(addr, i+1,status[offset+i]); + } +} + +void LedControl::clearAll() { + for (int i=0;i=maxDevices) + return; + if(row<0 || row>7 || column<0 || column>7) + return; + offset=addr*8; + val=B10000000 >> column; + if(state) + status[offset+row]=status[offset+row]|val; + else { + val=~val; + status[offset+row]=status[offset+row]&val; + } + spiTransfer(addr, row+1,status[offset+row]); +} + +void LedControl::setRow(int addr, int row, byte value) { + int offset; + if(addr<0 || addr>=maxDevices) + return; + if(row<0 || row>7) + return; + offset=addr*8; + status[offset+row]=value; + spiTransfer(addr, row+1,status[offset+row]); +} + +void LedControl::setColumn(int addr, int col, byte value) { + byte val; + + if(addr<0 || addr>=maxDevices) + return; + if(col<0 || col>7) + return; + for(int row=0;row<8;row++) { + val=value >> (7-row); + val=val & 0x01; + setLed(addr,row,col,val); + } +} + +void LedControl::setDigit(int addr, int digit, byte value, boolean dp) { + int offset; + byte v; + + if(addr<0 || addr>=maxDevices) + return; + if(digit<0 || digit>7 || value>15) + return; + offset=addr*8; + v=charTable[value]; + if(dp) + v|=B10000000; + status[offset+digit]=v; + spiTransfer(addr, digit+1,v); + +} + +void LedControl::setChar(int addr, int digit, char value, boolean dp) { + int offset; + byte index,v; + + if(addr<0 || addr>=maxDevices) + return; + if(digit<0 || digit>7) + return; + offset=addr*8; + index=(byte)value; + if(index >127) { + //nothing define we use the space char + value=32; + } + v=charTable[index]; + if(dp) + v|=B10000000; + status[offset+digit]=v; + spiTransfer(addr, digit+1,v); +} + +void LedControl::spiTransfer(int addr, volatile byte opcode, volatile byte data) { + //Create an array with the data to shift out + int offset=addr*2; + int maxbytes=maxDevices*2; + + for(int i=0;i0;i--) + shiftOut(LEDCONTROL_SPI_MOSI,LEDCONTROL_SPI_CLK,MSBFIRST,spidata[i-1]); + //latch the data onto the display + digitalWrite(LEDCONTROL_SPI_CS,HIGH); +} + +int LedControl::getCharArrayPosition(char input){ + if ((input==' ')||(input=='+')) return 10; + if (input==':') return 11; + if (input=='-') return 12; + if (input=='.') return 13; + if ((input =='(')) return 14; //replace by 'ñ' + if ((input >='0')&&(input <='9')) return (input-'0'); + if ((input >='A')&&(input <='Z')) return (input-'A' + 15); + if ((input >='a')&&(input <='z')) return (input-'a' + 15); + return 13; +} + +void LedControl::writeString(int mtx, char * displayString) { + while ( displayString[0]!=0) { + char c =displayString[0]; + int pos= getCharArrayPosition( c); + displayChar(mtx,pos); + delay(300); + clearAll(); + displayString++; + } +} + + +void LedControl::displayChar(int matrix, int charIndex) { + for (int i=0; i<6;i++) { + setRow(matrix,i, alphabetBitmap[charIndex][i]); + } +} \ No newline at end of file diff --git a/libraries/LedControlMS/LedControlMS.h b/libraries/LedControlMS/LedControlMS.h new file mode 100644 index 0000000..7c0831a --- /dev/null +++ b/libraries/LedControlMS/LedControlMS.h @@ -0,0 +1,242 @@ +/* + * LedControl.h - A library for controling Leds with a MAX7219/MAX7221 + * Copyright (c) 2007 Eberhard Fahle + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * This permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef LedControl_h +#define LedControl_h + +#if (ARDUINO >= 100) +#include +#else +#include +#endif + +/* + * Segments to be switched on for characters and digits on + * 7-Segment Displays + */ +const static byte charTable[128] = { + B01111110,B00110000,B01101101,B01111001,B00110011,B01011011,B01011111,B01110000, + B01111111,B01111011,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, + B00000000,B00000000,B00000000,B00000000,B10000000,B00000001,B10000000,B00000000, + B01111110,B00110000,B01101101,B01111001,B00110011,B01011011,B01011111,B01110000, + B01111111,B01111011,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, + B00000000,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111,B00000000, + B00110111,B00000000,B00000000,B00000000,B00001110,B00000000,B00000000,B00000000, + B01100111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001000, + B00000000,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111,B00000000, + B00110111,B00000000,B00000000,B00000000,B00001110,B00000000,B00000000,B00000000, + B01100111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000 +}; + + +const static byte alphabetBitmap[41][6]={ + {0x7E,0x81,0x81,0x81,0x7E,0x0}, //0 + {0x4,0x82,0xFF,0x80,0x0,0x0}, //1 + {0xE2,0x91,0x91,0x91,0x8E,0x0},//2 + {0x42,0x89,0x89,0x89,0x76,0x0},//3 + {0x1F,0x10,0x10,0xFF,0x10,0x0},//4 + {0x8F,0x89,0x89,0x89,0x71,0x0},//5 + {0x7E,0x89,0x89,0x89,0x71,0x0},//6 + {0x1,0x1,0xF9,0x5,0x3,0x0},//7 + {0x76,0x89,0x89,0x89,0x76,0x0},//8 + {0x8E,0x91,0x91,0x91,0x7E,0x0},//9 + {0x0,0x0,0x0,0x0,0x0,0x0},// blank space + {0x0,0x0,0x90,0x0,0x0,0x0}, //: + {0x0,0x10,0x10,0x10,0x10,0x0},// - + {0x0,0x0,0x80,0x0,0x0,0x0},// . + {0xFC,0x9,0x11,0x21,0xFC,0x0},//Ñ + {0xFE,0x11,0x11,0x11,0xFE,0x0},//A + {0xFF,0x89,0x89,0x89,0x76,0x0},//B + {0x7E,0x81,0x81,0x81,0x42,0x0},//C + {0xFF,0x81,0x81,0x81,0x7E,0x0},//D + {0xFF,0x89,0x89,0x89,0x81,0x0},//E + {0xFF,0x9,0x9,0x9,0x1,0x0},//F + {0x7E,0x81,0x81,0x91,0x72,0x0},//G + {0xFF,0x8,0x8,0x8,0xFF,0x0},//H + {0x0,0x81,0xFF,0x81,0x0,0x0},//I + {0x60,0x80,0x80,0x80,0x7F,0x0},//J + {0xFF,0x18,0x24,0x42,0x81,0x0},//K + {0xFF,0x80,0x80,0x80,0x80,0x0},//L + {0xFF,0x2,0x4,0x2,0xFF,0x0},//M + {0xFF,0x2,0x4,0x8,0xFF,0x0},//N + {0x7E,0x81,0x81,0x81,0x7E,0x0},//O + {0xFF,0x11,0x11,0x11,0xE,0x0},//P + {0x7E,0x81,0x81,0xA1,0x7E,0x80},//Q + {0xFF,0x11,0x31,0x51,0x8E,0x0},//R + {0x46,0x89,0x89,0x89,0x72,0x0},//S + {0x1,0x1,0xFF,0x1,0x1,0x0},//T + {0x7F,0x80,0x80,0x80,0x7F,0x0},//U + {0x3F,0x40,0x80,0x40,0x3F,0x0},//V + {0x7F,0x80,0x60,0x80,0x7F,0x0},//W + {0xE3,0x14,0x8,0x14,0xE3,0x0},//X + {0x3,0x4,0xF8,0x4,0x3,0x0},//Y + {0xE1,0x91,0x89,0x85,0x83,0x0}//Z +}; + +class LedControl { + private : + /* The array for shifting the data to the devices */ + byte spidata[16]; + /* Send out a single command to the device */ + void spiTransfer(int addr, byte opcode, byte data); + + /* We keep track of the led-status for all 8 devices in this array */ + byte status[64]; + /* Data is shifted out of this pin*/ + int LEDCONTROL_SPI_MOSI; + /* The clock is signaled on this pin */ + int LEDCONTROL_SPI_CLK; + /* This one is driven LOW for chip selectzion */ + int LEDCONTROL_SPI_CS; + /* The maximum number of devices we use */ + int maxDevices; + + + public: + /* + * Create a new controler + * Params : + * dataPin pin on the Arduino where data gets shifted out + * clockPin pin for the clock + * csPin pin for selecting the device + * numDevices maximum number of devices that can be controled + */ + LedControl(int dataPin, int clkPin, int csPin, int numDevices=1); + + /* + * Gets the number of devices attached to this LedControl. + * Returns : + * int the number of devices on this LedControl + */ + int getDeviceCount(); + + /* + * Set the shutdown (power saving) mode for the device + * Params : + * addr The address of the display to control + * status If true the device goes into power-down mode. Set to false + * for normal operation. + */ + void shutdown(int addr, bool status); + + /* + * Set the number of digits (or rows) to be displayed. + * See datasheet for sideeffects of the scanlimit on the brightness + * of the display. + * Params : + * addr address of the display to control + * limit number of digits to be displayed (1..8) + */ + void setScanLimit(int addr, int limit); + + /* + * Set the brightness of the display. + * Params: + * addr the address of the display to control + * intensity the brightness of the display. (0..15) + */ + void setIntensity(int addr, int intensity); + + /* + * Switch all Leds on the display off. + * Params: + * addr address of the display to control + */ + void clearDisplay(int addr); + + void clearAll(); + + /* + * Set the status of a single Led. + * Params : + * addr address of the display + * row the row of the Led (0..7) + * col the column of the Led (0..7) + * state If true the led is switched on, + * if false it is switched off + */ + void setLed(int addr, int row, int col, boolean state); + + /* + * Set all 8 Led's in a row to a new state + * Params: + * addr address of the display + * row row which is to be set (0..7) + * value each bit set to 1 will light up the + * corresponding Led. + */ + void setRow(int addr, int row, byte value); + + /* + * Set all 8 Led's in a column to a new state + * Params: + * addr address of the display + * col column which is to be set (0..7) + * value each bit set to 1 will light up the + * corresponding Led. + */ + void setColumn(int addr, int col, byte value); + + /* + * Display a hexadecimal digit on a 7-Segment Display + * Params: + * addr address of the display + * digit the position of the digit on the display (0..7) + * value the value to be displayed. (0x00..0x0F) + * dp sets the decimal point. + */ + void setDigit(int addr, int digit, byte value, boolean dp); + + /* + * Display a character on a 7-Segment display. + * There are only a few characters that make sense here : + * '0','1','2','3','4','5','6','7','8','9','0', + * 'A','b','c','d','E','F','H','L','P', + * '.','-','_',' ' + * Params: + * addr address of the display + * digit the position of the character on the display (0..7) + * value the character to be displayed. + * dp sets the decimal point. + */ + void setChar(int addr, int digit, char value, boolean dp); + + //Returns the array number in the alphabetBitmap array + int getCharArrayPosition(char c); + + void writeString(int mtx, char * displayString); + void displayChar(int matrix, int charIndex); +}; + +#endif //LedControl.h + + + diff --git a/libraries/LedControlMS/examples/LCDemo7Segment/LCDemo7Segment.ino b/libraries/LedControlMS/examples/LCDemo7Segment/LCDemo7Segment.ino new file mode 100644 index 0000000..190ac28 --- /dev/null +++ b/libraries/LedControlMS/examples/LCDemo7Segment/LCDemo7Segment.ino @@ -0,0 +1,73 @@ +//We always have to include the library +#include "LedControlMS.h" + +/* + Now we need a LedControl to work with. + ***** These pin numbers will probably not work with your hardware ***** + pin 12 is connected to the DataIn + pin 11 is connected to the CLK + pin 10 is connected to LOAD + We have only a single MAX72XX. + */ +LedControl lc=LedControl(12,11,10,1); + +/* we always wait a bit between updates of the display */ +unsigned long delaytime=250; + +void setup() { + /* + The MAX72XX is in power-saving mode on startup, + we have to do a wakeup call + */ + lc.shutdown(0,false); + /* Set the brightness to a medium values */ + lc.setIntensity(0,8); + /* and clear the display */ + lc.clearDisplay(0); +} + + +/* + This method will display the characters for the + word "Arduino" one after the other on digit 0. + */ +void writeArduinoOn7Segment() { + lc.setChar(0,0,'a',false); + delay(delaytime); + lc.setRow(0,0,0x05); + delay(delaytime); + lc.setChar(0,0,'d',false); + delay(delaytime); + lc.setRow(0,0,0x1c); + delay(delaytime); + lc.setRow(0,0,B00010000); + delay(delaytime); + lc.setRow(0,0,0x15); + delay(delaytime); + lc.setRow(0,0,0x1D); + delay(delaytime); + lc.clearDisplay(0); + delay(delaytime); +} + +/* + This method will scroll all the hexa-decimal + numbers and letters on the display. You will need at least + four 7-Segment digits. otherwise it won't really look that good. + */ +void scrollDigits() { + for(int i=0;i<13;i++) { + lc.setDigit(0,3,i,false); + lc.setDigit(0,2,i+1,false); + lc.setDigit(0,1,i+2,false); + lc.setDigit(0,0,i+3,false); + delay(delaytime); + } + lc.clearDisplay(0); + delay(delaytime); +} + +void loop() { + writeArduinoOn7Segment(); + scrollDigits(); +} diff --git a/libraries/LedControlMS/examples/LCDemoCascadedDevices/LCDemoCascadedDevices.ino b/libraries/LedControlMS/examples/LCDemoCascadedDevices/LCDemoCascadedDevices.ino new file mode 100644 index 0000000..69c2d80 --- /dev/null +++ b/libraries/LedControlMS/examples/LCDemoCascadedDevices/LCDemoCascadedDevices.ino @@ -0,0 +1,52 @@ +//We always have to include the library +#include "LedControlMS.h" + +/* + Now we need a LedControl to work with. + ***** These pin numbers will probably not work with your hardware ***** + pin 12 is connected to the DataIn + pin 11 is connected to the CLK + pin 10 is connected to LOAD + ***** Please set the number of devices you have ***** + But the maximum default of 8 MAX72XX wil also work. + */ +LedControl lc=LedControl(12,11,10,8); + +/* we always wait a bit between updates of the display */ +unsigned long delaytime=500; + +/* + This time we have more than one device. + But all of them have to be initialized + individually. + */ +void setup() { + //we have already set the number of devices when we created the LedControl + int devices=lc.getDeviceCount(); + //we have to init all devices in a loop + for(int address=0;address9) digitCounter=0; + lc.displayChar(0, lc.getCharArrayPosition(ch)); + delay(1000); + lc.clearAll(); + delay(200); +} + + +void scrollLeft(char ch){ + int pos =lc.getCharArrayPosition(ch); + for (int scroll =0; scroll<6; scroll++) { + for (int i=scroll; i<6;i++) { + lc.setRow(0,i-scroll, alphabetBitmap[pos][i]); + } + delay(300); + lc.clearDisplay(0); + } +} + +void scrollRight(char ch){ + int pos =lc.getCharArrayPosition(ch); + for (int scroll =0; scroll<8; scroll++) { + for (int i=0; i<6;i++) { + if (scroll+i<8) lc.setRow(0, scroll+i, alphabetBitmap[pos][i]); + } + delay(300); + lc.clearDisplay(0); + } +} diff --git a/libraries/LedControlMS/keywords.txt b/libraries/LedControlMS/keywords.txt new file mode 100644 index 0000000..9d2a94f --- /dev/null +++ b/libraries/LedControlMS/keywords.txt @@ -0,0 +1,28 @@ +####################################### +# Syntax Coloring Map For LedControl +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +LedControl KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +shutdown KEYWORD2 +setScanLimit KEYWORD2 +setIntensity KEYWORD2 +clearDisplay KEYWORD2 +setLed KEYWORD2 +setRow KEYWORD2 +setColumn KEYWORD2 +setDigit KEYWORD2 +setChar KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/libraries/OneWire/OneWire.cpp b/libraries/OneWire/OneWire.cpp new file mode 100644 index 0000000..631813f --- /dev/null +++ b/libraries/OneWire/OneWire.cpp @@ -0,0 +1,557 @@ +/* +Copyright (c) 2007, Jim Studt (original old version - many contributors since) + +The latest version of this library may be found at: + http://www.pjrc.com/teensy/td_libs_OneWire.html + +OneWire has been maintained by Paul Stoffregen (paul@pjrc.com) since +January 2010. At the time, it was in need of many bug fixes, but had +been abandoned the original author (Jim Studt). None of the known +contributors were interested in maintaining OneWire. Paul typically +works on OneWire every 6 to 12 months. Patches usually wait that +long. If anyone is interested in more actively maintaining OneWire, +please contact Paul. + +Version 2.2: + Teensy 3.0 compatibility, Paul Stoffregen, paul@pjrc.com + Arduino Due compatibility, http://arduino.cc/forum/index.php?topic=141030 + Fix DS18B20 example negative temperature + Fix DS18B20 example's low res modes, Ken Butcher + Improve reset timing, Mark Tillotson + Add const qualifiers, Bertrik Sikken + Add initial value input to crc16, Bertrik Sikken + Add target_search() function, Scott Roberts + +Version 2.1: + Arduino 1.0 compatibility, Paul Stoffregen + Improve temperature example, Paul Stoffregen + DS250x_PROM example, Guillermo Lovato + PIC32 (chipKit) compatibility, Jason Dangel, dangel.jason AT gmail.com + Improvements from Glenn Trewitt: + - crc16() now works + - check_crc16() does all of calculation/checking work. + - Added read_bytes() and write_bytes(), to reduce tedious loops. + - Added ds2408 example. + Delete very old, out-of-date readme file (info is here) + +Version 2.0: Modifications by Paul Stoffregen, January 2010: +http://www.pjrc.com/teensy/td_libs_OneWire.html + Search fix from Robin James + http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295/27#27 + Use direct optimized I/O in all cases + Disable interrupts during timing critical sections + (this solves many random communication errors) + Disable interrupts during read-modify-write I/O + Reduce RAM consumption by eliminating unnecessary + variables and trimming many to 8 bits + Optimize both crc8 - table version moved to flash + +Modified to work with larger numbers of devices - avoids loop. +Tested in Arduino 11 alpha with 12 sensors. +26 Sept 2008 -- Robin James +http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295/27#27 + +Updated to work with arduino-0008 and to include skip() as of +2007/07/06. --RJL20 + +Modified to calculate the 8-bit CRC directly, avoiding the need for +the 256-byte lookup table to be loaded in RAM. Tested in arduino-0010 +-- Tom Pollard, Jan 23, 2008 + +Jim Studt's original library was modified by Josh Larios. + +Tom Pollard, pollard@alum.mit.edu, contributed around May 20, 2008 + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Much of the code was inspired by Derek Yerger's code, though I don't +think much of that remains. In any event that was.. + (copyleft) 2006 by Derek Yerger - Free to distribute freely. + +The CRC code was excerpted and inspired by the Dallas Semiconductor +sample code bearing this copyright. +//--------------------------------------------------------------------------- +// Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES +// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +// Except as contained in this notice, the name of Dallas Semiconductor +// shall not be used except as stated in the Dallas Semiconductor +// Branding Policy. +//-------------------------------------------------------------------------- +*/ + +#include "OneWire.h" + + +OneWire::OneWire(uint8_t pin) +{ + pinMode(pin, INPUT); + bitmask = PIN_TO_BITMASK(pin); + baseReg = PIN_TO_BASEREG(pin); +#if ONEWIRE_SEARCH + reset_search(); +#endif +} + + +// Perform the onewire reset function. We will wait up to 250uS for +// the bus to come high, if it doesn't then it is broken or shorted +// and we return a 0; +// +// Returns 1 if a device asserted a presence pulse, 0 otherwise. +// +uint8_t OneWire::reset(void) +{ + IO_REG_TYPE mask = bitmask; + volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg; + uint8_t r; + uint8_t retries = 125; + + noInterrupts(); + DIRECT_MODE_INPUT(reg, mask); + interrupts(); + // wait until the wire is high... just in case + do { + if (--retries == 0) return 0; + delayMicroseconds(2); + } while ( !DIRECT_READ(reg, mask)); + + noInterrupts(); + DIRECT_WRITE_LOW(reg, mask); + DIRECT_MODE_OUTPUT(reg, mask); // drive output low + interrupts(); + delayMicroseconds(480); + noInterrupts(); + DIRECT_MODE_INPUT(reg, mask); // allow it to float + delayMicroseconds(70); + r = !DIRECT_READ(reg, mask); + interrupts(); + delayMicroseconds(410); + return r; +} + +// +// Write a bit. Port and bit is used to cut lookup time and provide +// more certain timing. +// +void OneWire::write_bit(uint8_t v) +{ + IO_REG_TYPE mask=bitmask; + volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg; + + if (v & 1) { + noInterrupts(); + DIRECT_WRITE_LOW(reg, mask); + DIRECT_MODE_OUTPUT(reg, mask); // drive output low + delayMicroseconds(10); + DIRECT_WRITE_HIGH(reg, mask); // drive output high + interrupts(); + delayMicroseconds(55); + } else { + noInterrupts(); + DIRECT_WRITE_LOW(reg, mask); + DIRECT_MODE_OUTPUT(reg, mask); // drive output low + delayMicroseconds(65); + DIRECT_WRITE_HIGH(reg, mask); // drive output high + interrupts(); + delayMicroseconds(5); + } +} + +// +// Read a bit. Port and bit is used to cut lookup time and provide +// more certain timing. +// +uint8_t OneWire::read_bit(void) +{ + IO_REG_TYPE mask=bitmask; + volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg; + uint8_t r; + + noInterrupts(); + DIRECT_MODE_OUTPUT(reg, mask); + DIRECT_WRITE_LOW(reg, mask); + delayMicroseconds(3); + DIRECT_MODE_INPUT(reg, mask); // let pin float, pull up will raise + delayMicroseconds(10); + r = DIRECT_READ(reg, mask); + interrupts(); + delayMicroseconds(53); + return r; +} + +// +// Write a byte. The writing code uses the active drivers to raise the +// pin high, if you need power after the write (e.g. DS18S20 in +// parasite power mode) then set 'power' to 1, otherwise the pin will +// go tri-state at the end of the write to avoid heating in a short or +// other mishap. +// +void OneWire::write(uint8_t v, uint8_t power /* = 0 */) { + uint8_t bitMask; + + for (bitMask = 0x01; bitMask; bitMask <<= 1) { + OneWire::write_bit( (bitMask & v)?1:0); + } + if ( !power) { + noInterrupts(); + DIRECT_MODE_INPUT(baseReg, bitmask); + DIRECT_WRITE_LOW(baseReg, bitmask); + interrupts(); + } +} + +void OneWire::write_bytes(const uint8_t *buf, uint16_t count, bool power /* = 0 */) { + for (uint16_t i = 0 ; i < count ; i++) + write(buf[i]); + if (!power) { + noInterrupts(); + DIRECT_MODE_INPUT(baseReg, bitmask); + DIRECT_WRITE_LOW(baseReg, bitmask); + interrupts(); + } +} + +// +// Read a byte +// +uint8_t OneWire::read() { + uint8_t bitMask; + uint8_t r = 0; + + for (bitMask = 0x01; bitMask; bitMask <<= 1) { + if ( OneWire::read_bit()) r |= bitMask; + } + return r; +} + +void OneWire::read_bytes(uint8_t *buf, uint16_t count) { + for (uint16_t i = 0 ; i < count ; i++) + buf[i] = read(); +} + +// +// Do a ROM select +// +void OneWire::select(const uint8_t rom[8]) +{ + uint8_t i; + + write(0x55); // Choose ROM + + for (i = 0; i < 8; i++) write(rom[i]); +} + +// +// Do a ROM skip +// +void OneWire::skip() +{ + write(0xCC); // Skip ROM +} + +void OneWire::depower() +{ + noInterrupts(); + DIRECT_MODE_INPUT(baseReg, bitmask); + interrupts(); +} + +#if ONEWIRE_SEARCH + +// +// You need to use this function to start a search again from the beginning. +// You do not need to do it for the first search, though you could. +// +void OneWire::reset_search() +{ + // reset the search state + LastDiscrepancy = 0; + LastDeviceFlag = FALSE; + LastFamilyDiscrepancy = 0; + for(int i = 7; ; i--) { + ROM_NO[i] = 0; + if ( i == 0) break; + } +} + +// Setup the search to find the device type 'family_code' on the next call +// to search(*newAddr) if it is present. +// +void OneWire::target_search(uint8_t family_code) +{ + // set the search state to find SearchFamily type devices + ROM_NO[0] = family_code; + for (uint8_t i = 1; i < 8; i++) + ROM_NO[i] = 0; + LastDiscrepancy = 64; + LastFamilyDiscrepancy = 0; + LastDeviceFlag = FALSE; +} + +// +// Perform a search. If this function returns a '1' then it has +// enumerated the next device and you may retrieve the ROM from the +// OneWire::address variable. If there are no devices, no further +// devices, or something horrible happens in the middle of the +// enumeration then a 0 is returned. If a new device is found then +// its address is copied to newAddr. Use OneWire::reset_search() to +// start over. +// +// --- Replaced by the one from the Dallas Semiconductor web site --- +//-------------------------------------------------------------------------- +// Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing +// search state. +// Return TRUE : device found, ROM number in ROM_NO buffer +// FALSE : device not found, end of search +// +uint8_t OneWire::search(uint8_t *newAddr) +{ + uint8_t id_bit_number; + uint8_t last_zero, rom_byte_number, search_result; + uint8_t id_bit, cmp_id_bit; + + unsigned char rom_byte_mask, search_direction; + + // initialize for search + id_bit_number = 1; + last_zero = 0; + rom_byte_number = 0; + rom_byte_mask = 1; + search_result = 0; + + // if the last call was not the last one + if (!LastDeviceFlag) + { + // 1-Wire reset + if (!reset()) + { + // reset the search + LastDiscrepancy = 0; + LastDeviceFlag = FALSE; + LastFamilyDiscrepancy = 0; + return FALSE; + } + + // issue the search command + write(0xF0); + + // loop to do the search + do + { + // read a bit and its complement + id_bit = read_bit(); + cmp_id_bit = read_bit(); + + // check for no devices on 1-wire + if ((id_bit == 1) && (cmp_id_bit == 1)) + break; + else + { + // all devices coupled have 0 or 1 + if (id_bit != cmp_id_bit) + search_direction = id_bit; // bit write value for search + else + { + // if this discrepancy if before the Last Discrepancy + // on a previous next then pick the same as last time + if (id_bit_number < LastDiscrepancy) + search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0); + else + // if equal to last pick 1, if not then pick 0 + search_direction = (id_bit_number == LastDiscrepancy); + + // if 0 was picked then record its position in LastZero + if (search_direction == 0) + { + last_zero = id_bit_number; + + // check for Last discrepancy in family + if (last_zero < 9) + LastFamilyDiscrepancy = last_zero; + } + } + + // set or clear the bit in the ROM byte rom_byte_number + // with mask rom_byte_mask + if (search_direction == 1) + ROM_NO[rom_byte_number] |= rom_byte_mask; + else + ROM_NO[rom_byte_number] &= ~rom_byte_mask; + + // serial number search direction write bit + write_bit(search_direction); + + // increment the byte counter id_bit_number + // and shift the mask rom_byte_mask + id_bit_number++; + rom_byte_mask <<= 1; + + // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask + if (rom_byte_mask == 0) + { + rom_byte_number++; + rom_byte_mask = 1; + } + } + } + while(rom_byte_number < 8); // loop until through all ROM bytes 0-7 + + // if the search was successful then + if (!(id_bit_number < 65)) + { + // search successful so set LastDiscrepancy,LastDeviceFlag,search_result + LastDiscrepancy = last_zero; + + // check for last device + if (LastDiscrepancy == 0) + LastDeviceFlag = TRUE; + + search_result = TRUE; + } + } + + // if no device found then reset counters so next 'search' will be like a first + if (!search_result || !ROM_NO[0]) + { + LastDiscrepancy = 0; + LastDeviceFlag = FALSE; + LastFamilyDiscrepancy = 0; + search_result = FALSE; + } + for (int i = 0; i < 8; i++) newAddr[i] = ROM_NO[i]; + return search_result; + } + +#endif + +#if ONEWIRE_CRC +// The 1-Wire CRC scheme is described in Maxim Application Note 27: +// "Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products" +// + +#if ONEWIRE_CRC8_TABLE +// This table comes from Dallas sample code where it is freely reusable, +// though Copyright (C) 2000 Dallas Semiconductor Corporation +static const uint8_t PROGMEM dscrc_table[] = { + 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, + 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220, + 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98, + 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, + 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, + 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, + 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, + 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, + 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, + 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, + 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, + 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, + 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, + 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, + 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, + 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53}; + +// +// Compute a Dallas Semiconductor 8 bit CRC. These show up in the ROM +// and the registers. (note: this might better be done without to +// table, it would probably be smaller and certainly fast enough +// compared to all those delayMicrosecond() calls. But I got +// confused, so I use this table from the examples.) +// +uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len) +{ + uint8_t crc = 0; + + while (len--) { + crc = pgm_read_byte(dscrc_table + (crc ^ *addr++)); + } + return crc; +} +#else +// +// Compute a Dallas Semiconductor 8 bit CRC directly. +// this is much slower, but much smaller, than the lookup table. +// +uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len) +{ + uint8_t crc = 0; + + while (len--) { + uint8_t inbyte = *addr++; + for (uint8_t i = 8; i; i--) { + uint8_t mix = (crc ^ inbyte) & 0x01; + crc >>= 1; + if (mix) crc ^= 0x8C; + inbyte >>= 1; + } + } + return crc; +} +#endif + +#if ONEWIRE_CRC16 +bool OneWire::check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc) +{ + crc = ~crc16(input, len, crc); + return (crc & 0xFF) == inverted_crc[0] && (crc >> 8) == inverted_crc[1]; +} + +uint16_t OneWire::crc16(const uint8_t* input, uint16_t len, uint16_t crc) +{ + static const uint8_t oddparity[16] = + { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; + + for (uint16_t i = 0 ; i < len ; i++) { + // Even though we're just copying a byte from the input, + // we'll be doing 16-bit computation with it. + uint16_t cdata = input[i]; + cdata = (cdata ^ crc) & 0xff; + crc >>= 8; + + if (oddparity[cdata & 0x0F] ^ oddparity[cdata >> 4]) + crc ^= 0xC001; + + cdata <<= 6; + crc ^= cdata; + cdata <<= 1; + crc ^= cdata; + } + return crc; +} +#endif + +#endif diff --git a/libraries/OneWire/OneWire.h b/libraries/OneWire/OneWire.h new file mode 100644 index 0000000..916c529 --- /dev/null +++ b/libraries/OneWire/OneWire.h @@ -0,0 +1,229 @@ +#ifndef OneWire_h +#define OneWire_h + +#include + +#if ARDUINO >= 100 +#include "Arduino.h" // for delayMicroseconds, digitalPinToBitMask, etc +#else +#include "WProgram.h" // for delayMicroseconds +#include "pins_arduino.h" // for digitalPinToBitMask, etc +#endif + +// You can exclude certain features from OneWire. In theory, this +// might save some space. In practice, the compiler automatically +// removes unused code (technically, the linker, using -fdata-sections +// and -ffunction-sections when compiling, and Wl,--gc-sections +// when linking), so most of these will not result in any code size +// reduction. Well, unless you try to use the missing features +// and redesign your program to not need them! ONEWIRE_CRC8_TABLE +// is the exception, because it selects a fast but large algorithm +// or a small but slow algorithm. + +// you can exclude onewire_search by defining that to 0 +#ifndef ONEWIRE_SEARCH +#define ONEWIRE_SEARCH 1 +#endif + +// You can exclude CRC checks altogether by defining this to 0 +#ifndef ONEWIRE_CRC +#define ONEWIRE_CRC 1 +#endif + +// Select the table-lookup method of computing the 8-bit CRC +// by setting this to 1. The lookup table enlarges code size by +// about 250 bytes. It does NOT consume RAM (but did in very +// old versions of OneWire). If you disable this, a slower +// but very compact algorithm is used. +#ifndef ONEWIRE_CRC8_TABLE +#define ONEWIRE_CRC8_TABLE 1 +#endif + +// You can allow 16-bit CRC checks by defining this to 1 +// (Note that ONEWIRE_CRC must also be 1.) +#ifndef ONEWIRE_CRC16 +#define ONEWIRE_CRC16 1 +#endif + +#define FALSE 0 +#define TRUE 1 + +// Platform specific I/O definitions + +#if defined(__AVR__) +#define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin))) +#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) +#define IO_REG_TYPE uint8_t +#define IO_REG_ASM asm("r30") +#define DIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0) +#define DIRECT_MODE_INPUT(base, mask) ((*((base)+1)) &= ~(mask)) +#define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+1)) |= (mask)) +#define DIRECT_WRITE_LOW(base, mask) ((*((base)+2)) &= ~(mask)) +#define DIRECT_WRITE_HIGH(base, mask) ((*((base)+2)) |= (mask)) + +#elif defined(__MK20DX128__) +#define PIN_TO_BASEREG(pin) (portOutputRegister(pin)) +#define PIN_TO_BITMASK(pin) (1) +#define IO_REG_TYPE uint8_t +#define IO_REG_ASM +#define DIRECT_READ(base, mask) (*((base)+512)) +#define DIRECT_MODE_INPUT(base, mask) (*((base)+640) = 0) +#define DIRECT_MODE_OUTPUT(base, mask) (*((base)+640) = 1) +#define DIRECT_WRITE_LOW(base, mask) (*((base)+256) = 1) +#define DIRECT_WRITE_HIGH(base, mask) (*((base)+128) = 1) + +#elif defined(__SAM3X8E__) +// Arduino 1.5.1 may have a bug in delayMicroseconds() on Arduino Due. +// http://arduino.cc/forum/index.php/topic,141030.msg1076268.html#msg1076268 +// If you have trouble with OneWire on Arduino Due, please check the +// status of delayMicroseconds() before reporting a bug in OneWire! +#define PIN_TO_BASEREG(pin) (&(digitalPinToPort(pin)->PIO_PER)) +#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) +#define IO_REG_TYPE uint32_t +#define IO_REG_ASM +#define DIRECT_READ(base, mask) (((*((base)+15)) & (mask)) ? 1 : 0) +#define DIRECT_MODE_INPUT(base, mask) ((*((base)+5)) = (mask)) +#define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+4)) = (mask)) +#define DIRECT_WRITE_LOW(base, mask) ((*((base)+13)) = (mask)) +#define DIRECT_WRITE_HIGH(base, mask) ((*((base)+12)) = (mask)) +#ifndef PROGMEM +#define PROGMEM +#endif +#ifndef pgm_read_byte +#define pgm_read_byte(addr) (*(const uint8_t *)(addr)) +#endif + +#elif defined(__PIC32MX__) +#define PIN_TO_BASEREG(pin) (portModeRegister(digitalPinToPort(pin))) +#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) +#define IO_REG_TYPE uint32_t +#define IO_REG_ASM +#define DIRECT_READ(base, mask) (((*(base+4)) & (mask)) ? 1 : 0) //PORTX + 0x10 +#define DIRECT_MODE_INPUT(base, mask) ((*(base+2)) = (mask)) //TRISXSET + 0x08 +#define DIRECT_MODE_OUTPUT(base, mask) ((*(base+1)) = (mask)) //TRISXCLR + 0x04 +#define DIRECT_WRITE_LOW(base, mask) ((*(base+8+1)) = (mask)) //LATXCLR + 0x24 +#define DIRECT_WRITE_HIGH(base, mask) ((*(base+8+2)) = (mask)) //LATXSET + 0x28 + +#else +#error "Please define I/O register types here" +#endif + + +class OneWire +{ + private: + IO_REG_TYPE bitmask; + volatile IO_REG_TYPE *baseReg; + +#if ONEWIRE_SEARCH + // global search state + unsigned char ROM_NO[8]; + uint8_t LastDiscrepancy; + uint8_t LastFamilyDiscrepancy; + uint8_t LastDeviceFlag; +#endif + + public: + OneWire( uint8_t pin); + + // Perform a 1-Wire reset cycle. Returns 1 if a device responds + // with a presence pulse. Returns 0 if there is no device or the + // bus is shorted or otherwise held low for more than 250uS + uint8_t reset(void); + + // Issue a 1-Wire rom select command, you do the reset first. + void select(const uint8_t rom[8]); + + // Issue a 1-Wire rom skip command, to address all on bus. + void skip(void); + + // Write a byte. If 'power' is one then the wire is held high at + // the end for parasitically powered devices. You are responsible + // for eventually depowering it by calling depower() or doing + // another read or write. + void write(uint8_t v, uint8_t power = 0); + + void write_bytes(const uint8_t *buf, uint16_t count, bool power = 0); + + // Read a byte. + uint8_t read(void); + + void read_bytes(uint8_t *buf, uint16_t count); + + // Write a bit. The bus is always left powered at the end, see + // note in write() about that. + void write_bit(uint8_t v); + + // Read a bit. + uint8_t read_bit(void); + + // Stop forcing power onto the bus. You only need to do this if + // you used the 'power' flag to write() or used a write_bit() call + // and aren't about to do another read or write. You would rather + // not leave this powered if you don't have to, just in case + // someone shorts your bus. + void depower(void); + +#if ONEWIRE_SEARCH + // Clear the search state so that if will start from the beginning again. + void reset_search(); + + // Setup the search to find the device type 'family_code' on the next call + // to search(*newAddr) if it is present. + void target_search(uint8_t family_code); + + // Look for the next device. Returns 1 if a new address has been + // returned. A zero might mean that the bus is shorted, there are + // no devices, or you have already retrieved all of them. It + // might be a good idea to check the CRC to make sure you didn't + // get garbage. The order is deterministic. You will always get + // the same devices in the same order. + uint8_t search(uint8_t *newAddr); +#endif + +#if ONEWIRE_CRC + // Compute a Dallas Semiconductor 8 bit CRC, these are used in the + // ROM and scratchpad registers. + static uint8_t crc8(const uint8_t *addr, uint8_t len); + +#if ONEWIRE_CRC16 + // Compute the 1-Wire CRC16 and compare it against the received CRC. + // Example usage (reading a DS2408): + // // Put everything in a buffer so we can compute the CRC easily. + // uint8_t buf[13]; + // buf[0] = 0xF0; // Read PIO Registers + // buf[1] = 0x88; // LSB address + // buf[2] = 0x00; // MSB address + // WriteBytes(net, buf, 3); // Write 3 cmd bytes + // ReadBytes(net, buf+3, 10); // Read 6 data bytes, 2 0xFF, 2 CRC16 + // if (!CheckCRC16(buf, 11, &buf[11])) { + // // Handle error. + // } + // + // @param input - Array of bytes to checksum. + // @param len - How many bytes to use. + // @param inverted_crc - The two CRC16 bytes in the received data. + // This should just point into the received data, + // *not* at a 16-bit integer. + // @param crc - The crc starting value (optional) + // @return True, iff the CRC matches. + static bool check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc = 0); + + // Compute a Dallas Semiconductor 16 bit CRC. This is required to check + // the integrity of data received from many 1-Wire devices. Note that the + // CRC computed here is *not* what you'll get from the 1-Wire network, + // for two reasons: + // 1) The CRC is transmitted bitwise inverted. + // 2) Depending on the endian-ness of your processor, the binary + // representation of the two-byte return value may have a different + // byte order than the two bytes you get from 1-Wire. + // @param input - Array of bytes to checksum. + // @param len - How many bytes to use. + // @param crc - The crc starting value (optional) + // @return The CRC16, as defined by Dallas Semiconductor. + static uint16_t crc16(const uint8_t* input, uint16_t len, uint16_t crc = 0); +#endif +#endif +}; + +#endif diff --git a/libraries/OneWire/examples/DS18x20_Temperature/DS18x20_Temperature.pde b/libraries/OneWire/examples/DS18x20_Temperature/DS18x20_Temperature.pde new file mode 100644 index 0000000..68ca194 --- /dev/null +++ b/libraries/OneWire/examples/DS18x20_Temperature/DS18x20_Temperature.pde @@ -0,0 +1,112 @@ +#include + +// OneWire DS18S20, DS18B20, DS1822 Temperature Example +// +// http://www.pjrc.com/teensy/td_libs_OneWire.html +// +// The DallasTemperature library can do all this work for you! +// http://milesburton.com/Dallas_Temperature_Control_Library + +OneWire ds(10); // on pin 10 (a 4.7K resistor is necessary) + +void setup(void) { + Serial.begin(9600); +} + +void loop(void) { + byte i; + byte present = 0; + byte type_s; + byte data[12]; + byte addr[8]; + float celsius, fahrenheit; + + if ( !ds.search(addr)) { + Serial.println("No more addresses."); + Serial.println(); + ds.reset_search(); + delay(250); + return; + } + + Serial.print("ROM ="); + for( i = 0; i < 8; i++) { + Serial.write(' '); + Serial.print(addr[i], HEX); + } + + if (OneWire::crc8(addr, 7) != addr[7]) { + Serial.println("CRC is not valid!"); + return; + } + Serial.println(); + + // the first ROM byte indicates which chip + switch (addr[0]) { + case 0x10: + Serial.println(" Chip = DS18S20"); // or old DS1820 + type_s = 1; + break; + case 0x28: + Serial.println(" Chip = DS18B20"); + type_s = 0; + break; + case 0x22: + Serial.println(" Chip = DS1822"); + type_s = 0; + break; + default: + Serial.println("Device is not a DS18x20 family device."); + return; + } + + ds.reset(); + ds.select(addr); + ds.write(0x44, 1); // start conversion, with parasite power on at the end + + delay(1000); // maybe 750ms is enough, maybe not + // we might do a ds.depower() here, but the reset will take care of it. + + present = ds.reset(); + ds.select(addr); + ds.write(0xBE); // Read Scratchpad + + Serial.print(" Data = "); + Serial.print(present, HEX); + Serial.print(" "); + for ( i = 0; i < 9; i++) { // we need 9 bytes + data[i] = ds.read(); + Serial.print(data[i], HEX); + Serial.print(" "); + } + Serial.print(" CRC="); + Serial.print(OneWire::crc8(data, 8), HEX); + Serial.println(); + + // Convert the data to actual temperature + // because the result is a 16 bit signed integer, it should + // be stored to an "int16_t" type, which is always 16 bits + // even when compiled on a 32 bit processor. + int16_t raw = (data[1] << 8) | data[0]; + if (type_s) { + raw = raw << 3; // 9 bit resolution default + if (data[7] == 0x10) { + // "count remain" gives full 12 bit resolution + raw = (raw & 0xFFF0) + 12 - data[6]; + } + } else { + byte cfg = (data[4] & 0x60); + // at lower res, the low bits are undefined, so let's zero them + if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms + else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms + else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms + //// default is 12 bit resolution, 750 ms conversion time + } + celsius = (float)raw / 16.0; + fahrenheit = celsius * 1.8 + 32.0; + Serial.print(" Temperature = "); + Serial.print(celsius); + Serial.print(" Celsius, "); + Serial.print(fahrenheit); + Serial.println(" Fahrenheit"); +} diff --git a/libraries/OneWire/examples/DS2408_Switch/DS2408_Switch.pde b/libraries/OneWire/examples/DS2408_Switch/DS2408_Switch.pde new file mode 100644 index 0000000..d171f9b --- /dev/null +++ b/libraries/OneWire/examples/DS2408_Switch/DS2408_Switch.pde @@ -0,0 +1,77 @@ +#include + +/* + * DS2408 8-Channel Addressable Switch + * + * Writte by Glenn Trewitt, glenn at trewitt dot org + * + * Some notes about the DS2408: + * - Unlike most input/output ports, the DS2408 doesn't have mode bits to + * set whether the pins are input or output. If you issue a read command, + * they're inputs. If you write to them, they're outputs. + * - For reading from a switch, you should use 10K pull-up resisters. + */ + +void PrintBytes(uint8_t* addr, uint8_t count, bool newline=0) { + for (uint8_t i = 0; i < count; i++) { + Serial.print(addr[i]>>4, HEX); + Serial.print(addr[i]&0x0f, HEX); + } + if (newline) + Serial.println(); +} + +void ReadAndReport(OneWire* net, uint8_t* addr) { + Serial.print(" Reading DS2408 "); + PrintBytes(addr, 8); + Serial.println(); + + uint8_t buf[13]; // Put everything in the buffer so we can compute CRC easily. + buf[0] = 0xF0; // Read PIO Registers + buf[1] = 0x88; // LSB address + buf[2] = 0x00; // MSB address + net->write_bytes(buf, 3); + net->read_bytes(buf+3, 10); // 3 cmd bytes, 6 data bytes, 2 0xFF, 2 CRC16 + net->reset(); + + if (!OneWire::check_crc16(buf, 11, &buf[11])) { + Serial.print("CRC failure in DS2408 at "); + PrintBytes(addr, 8, true); + return; + } + Serial.print(" DS2408 data = "); + // First 3 bytes contain command, register address. + Serial.println(buf[3], BIN); +} + +OneWire net(10); // on pin 10 + +void setup(void) { + Serial.begin(9600); +} + +void loop(void) { + byte i; + byte present = 0; + byte addr[8]; + + if (!net.search(addr)) { + Serial.print("No more addresses.\n"); + net.reset_search(); + delay(1000); + return; + } + + if (OneWire::crc8(addr, 7) != addr[7]) { + Serial.print("CRC is not valid!\n"); + return; + } + + if (addr[0] != 0x29) { + PrintBytes(addr, 8); + Serial.print(" is not a DS2408.\n"); + return; + } + + ReadAndReport(&net, addr); +} diff --git a/libraries/OneWire/examples/DS250x_PROM/DS250x_PROM.pde b/libraries/OneWire/examples/DS250x_PROM/DS250x_PROM.pde new file mode 100644 index 0000000..baa51c8 --- /dev/null +++ b/libraries/OneWire/examples/DS250x_PROM/DS250x_PROM.pde @@ -0,0 +1,90 @@ +/* +DS250x add-only programmable memory reader w/SKIP ROM. + + The DS250x is a 512/1024bit add-only PROM(you can add data but cannot change the old one) that's used mainly for device identification purposes + like serial number, mfgr data, unique identifiers, etc. It uses the Maxim 1-wire bus. + + This sketch will use the SKIP ROM function that skips the 1-Wire search phase since we only have one device connected in the bus on digital pin 6. + If more than one device is connected to the bus, it will fail. + Sketch will not verify if device connected is from the DS250x family since the skip rom function effectively skips the family-id byte readout. + thus it is possible to run this sketch with any Maxim OneWire device in which case the command CRC will most likely fail. + Sketch will only read the first page of memory(32bits) starting from the lower address(0000h), if more than 1 device is present, then use the sketch with search functions. + Remember to put a 4.7K pullup resistor between pin 6 and +Vcc + + To change the range or ammount of data to read, simply change the data array size, LSB/MSB addresses and for loop iterations + + This example code is in the public domain and is provided AS-IS. + + Built with Arduino 0022 and PJRC OneWire 2.0 library http://www.pjrc.com/teensy/td_libs_OneWire.html + + created by Guillermo Lovato + march/2011 + + */ + +#include +OneWire ds(6); // OneWire bus on digital pin 6 +void setup() { + Serial.begin (9600); +} + +void loop() { + byte i; // This is for the for loops + boolean present; // device present var + byte data[32]; // container for the data from device + byte leemem[3] = { // array with the commands to initiate a read, DS250x devices expect 3 bytes to start a read: command,LSB&MSB adresses + 0xF0 , 0x00 , 0x00 }; // 0xF0 is the Read Data command, followed by 00h 00h as starting address(the beginning, 0000h) + byte ccrc; // Variable to store the command CRC + byte ccrc_calc; + + present = ds.reset(); // OneWire bus reset, always needed to start operation on the bus, returns a 1/TRUE if there's a device present. + ds.skip(); // Skip ROM search + + if (present == TRUE){ // We only try to read the data if there's a device present + Serial.println("DS250x device present"); + ds.write(leemem[0],1); // Read data command, leave ghost power on + ds.write(leemem[1],1); // LSB starting address, leave ghost power on + ds.write(leemem[2],1); // MSB starting address, leave ghost power on + + ccrc = ds.read(); // DS250x generates a CRC for the command we sent, we assign a read slot and store it's value + ccrc_calc = OneWire::crc8(leemem, 3); // We calculate the CRC of the commands we sent using the library function and store it + + if ( ccrc_calc != ccrc) { // Then we compare it to the value the ds250x calculated, if it fails, we print debug messages and abort + Serial.println("Invalid command CRC!"); + Serial.print("Calculated CRC:"); + Serial.println(ccrc_calc,HEX); // HEX makes it easier to observe and compare + Serial.print("DS250x readback CRC:"); + Serial.println(ccrc,HEX); + return; // Since CRC failed, we abort the rest of the loop and start over + } + Serial.println("Data is: "); // For the printout of the data + for ( i = 0; i < 32; i++) { // Now it's time to read the PROM data itself, each page is 32 bytes so we need 32 read commands + data[i] = ds.read(); // we store each read byte to a different position in the data array + Serial.print(data[i]); // printout in ASCII + Serial.print(" "); // blank space + } + Serial.println(); + delay(5000); // Delay so we don't saturate the serial output + } + else { // Nothing is connected in the bus + Serial.println("Nothing connected"); + delay(3000); + } +} + + + + + + + + + + + + + + + + + diff --git a/libraries/OneWire/keywords.txt b/libraries/OneWire/keywords.txt new file mode 100644 index 0000000..bee5d90 --- /dev/null +++ b/libraries/OneWire/keywords.txt @@ -0,0 +1,38 @@ +####################################### +# Syntax Coloring Map For OneWire +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +OneWire KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +reset KEYWORD2 +write_bit KEYWORD2 +read_bit KEYWORD2 +write KEYWORD2 +write_bytes KEYWORD2 +read KEYWORD2 +read_bytes KEYWORD2 +select KEYWORD2 +skip KEYWORD2 +depower KEYWORD2 +reset_search KEYWORD2 +search KEYWORD2 +crc8 KEYWORD2 +crc16 KEYWORD2 +check_crc16 KEYWORD2 + +####################################### +# Instances (KEYWORD2) +####################################### + + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/libraries/Pong/Ball.cpp b/libraries/Pong/Ball.cpp new file mode 100644 index 0000000..06ac8fe --- /dev/null +++ b/libraries/Pong/Ball.cpp @@ -0,0 +1,73 @@ +#include + +#include "Ball.h" + +int Ball::randomAngle(int row) +{ + int angle = random(1, 4) * 45; + + if ((row == 0 && angle < 90) || + (row == 7 && angle > 90)) + angle = 90; + + return angle; +} + +unsigned long Ball::accelerate(unsigned long delay) +{ + if (MIN_DELAY + DELAY_STEP <= delay) + delay -= DELAY_STEP; + + return delay; +} + +bool Ball::move(Paddle& paddle0, Paddle& paddle1, unsigned long& delay, int &startPlayer) +{ + bool carryOn = true; + + if (angle_ > 0) { + col_++; + } else { + col_--; + } + + if (col_ == MAX_COLUMN) { + if (paddle1.hit(row_, col_)) { + col_ = MAX_COLUMN - 2; + angle_ = -randomAngle(row_); + delay = accelerate(delay); + } else { + carryOn = false; + startPlayer = 0; + } + } else if (col_ == MIN_COLUMN) { + if (paddle0.hit(row_, col_)) { + col_ = MIN_COLUMN + 2; + angle_ = randomAngle(row_); + delay = accelerate(delay); + } else { + carryOn = false; + startPlayer = 1; + } + } else if (row_ == MIN_ROW) { + if (abs(angle_) < 90) { + angle_ *= 3; + } + } else if (row_ == MAX_ROW) { + if (abs(angle_) > 90) { + angle_ /= 3; + } + } + + if (abs(angle_) > 90) { + row_++; + } else if (abs(angle_) < 90) { + row_--; + } + + return carryOn; +} + +// Local variables: +// mode: c++ +// End: diff --git a/libraries/Pong/Ball.h b/libraries/Pong/Ball.h new file mode 100644 index 0000000..55f5fe0 --- /dev/null +++ b/libraries/Pong/Ball.h @@ -0,0 +1,45 @@ +#ifndef BALL_H +#define BALL_H + +#include "Paddle.h" + +class Ball { +public: + Ball(int rows, int cols) : + MIN_ROW(0), + MIN_COLUMN(0), + MAX_ROW(rows - 1), + MAX_COLUMN(cols - 1) {} + + static const unsigned long MIN_DELAY = 50; + static const unsigned long MAX_DELAY = 300; + static const unsigned long DELAY_STEP = 10; + + int row() const { return row_; } + int col() const { return col_; } + + void setPosition(int row, int col, int angle) { + row_ = row; + col_ = col; + angle_ = angle; + } + + bool move(Paddle& paddle0, Paddle& paddle1, unsigned long& delay, int &startPlayer); + +private: + const int MIN_ROW, MIN_COLUMN; + const int MAX_ROW, MAX_COLUMN; + + int randomAngle(int row); + unsigned long accelerate(unsigned long delay); + + int row_; + int col_; + int angle_; +}; + +#endif // BALL_H + +// Local variables: +// mode: c++ +// End: diff --git a/libraries/Pong/Paddle.h b/libraries/Pong/Paddle.h new file mode 100644 index 0000000..bc1a300 --- /dev/null +++ b/libraries/Pong/Paddle.h @@ -0,0 +1,29 @@ +#ifndef PADDLE_H +#define PADDLE_H + +class Paddle { +public: + Paddle(int pin, int row, int col) : + pin_(pin), row_(row), col_(col) {} + + void row(int row) { row_ = row; } + + bool hit(int row, int col) const { + return col == col_ && (row == row_ || row == row_ + 1); + } + + int pin() const { return pin_; } + int row() const { return row_; } + int col() const { return col_; } + +private: + int pin_; + int row_; + const int col_; +}; + +#endif // PADDLE_H + +// Local variables: +// mode: c++ +// End: diff --git a/libraries/Pong/Pong.cpp b/libraries/Pong/Pong.cpp new file mode 100644 index 0000000..881d067 --- /dev/null +++ b/libraries/Pong/Pong.cpp @@ -0,0 +1,76 @@ +#include + +#include "Pong.h" + +void Pong::start() +{ + if (startPlayer_ == 0) { + ball_.setPosition(4, 1, 90); + } else { + ball_.setPosition(4, MAX_COLUMN - 1, -90); + } + + showBall(ball_); + t_ = t0_ = millis(); + delay_ = Ball::MAX_DELAY; +} + +void Pong::update() +{ + movePaddle(paddle0_); + movePaddle(paddle1_); + + if ((t_ = millis()) - t0_ > delay_) { + if (!moveBall()) { + if (gameOver()) { + startGame(); + } else { + showScore(); + start(); + } + } else { + t0_ = t_; + } + } +} + +void Pong::movePaddle(Paddle& p) +{ + int row1 = map(analogRead(p.pin()), 0, 1000, 0, MAX_ROW - 1); + int row2 = map(analogRead(p.pin()), 0, 1000, 0, MAX_ROW - 1); + + int row = (row1 + row2) / 2; + + if (row != p.row()) { + hidePaddle(p); + p.row(row); + } + showPaddle(p); +} + +bool Pong::moveBall() +{ + hideBall(ball_); + + bool carryOn = ball_.move(paddle0_, paddle1_, delay_, startPlayer_); + + if (carryOn) { + showBall(ball_); + } else { + score_[startPlayer_]++; + } + + return carryOn; +} + +bool Pong::gameOver() +{ + if (score_[0] > 9 || score_[1] > 9) { + // show winner + score_[0] = 0; + score_[1] = 0; + return true; + } + + return false; +} diff --git a/libraries/Pong/Pong.h b/libraries/Pong/Pong.h new file mode 100644 index 0000000..686202f --- /dev/null +++ b/libraries/Pong/Pong.h @@ -0,0 +1,51 @@ +#ifndef PONG_H +#define PONG_H + +#include "Ball.h" +#include "Paddle.h" + +class Pong +{ +public: + Pong(int rows, int cols, int paddle0_pin, int paddle1_pin) : + MAX_ROW(rows - 1), + MAX_COLUMN(cols - 1), + paddle0_(paddle0_pin, (MAX_ROW / 2) - 1, 0), + paddle1_(paddle1_pin, (MAX_ROW / 2) - 1, MAX_COLUMN), + ball_(rows, cols), + startPlayer_(0) { + score_[0] = 0; + score_[1] = 0; + } + + void start(); + void update(); + +protected: + const int MAX_ROW; + const int MAX_COLUMN; + + void movePaddle(Paddle& p); + bool moveBall(); + bool gameOver(); + + virtual void showPaddle(Paddle& p) = 0; + virtual void hidePaddle(Paddle& p) = 0; + virtual void showBall(Ball& b) = 0; + virtual void hideBall(Ball& b) = 0; + virtual void showScore() = 0; + virtual void startGame() = 0; + + Paddle paddle0_; + Paddle paddle1_; + Ball ball_; + int startPlayer_; + int score_[2]; + unsigned long t_, t0_, delay_; +}; + +#endif // PONG_H + +// Local variables: +// mode: c++ +// End: diff --git a/libraries/Pong/README.md b/libraries/Pong/README.md new file mode 100644 index 0000000..88d3a2f --- /dev/null +++ b/libraries/Pong/README.md @@ -0,0 +1,4 @@ +PONG +==== + +Arduino Pong for an 8x8 LED Matrix and the LoLShield. diff --git a/libraries/Pong/examples/LoLPong/.gitignore b/libraries/Pong/examples/LoLPong/.gitignore new file mode 100644 index 0000000..d83325f --- /dev/null +++ b/libraries/Pong/examples/LoLPong/.gitignore @@ -0,0 +1,2 @@ +build-* +libraries diff --git a/libraries/Pong/examples/LoLPong/LoLPong.ino b/libraries/Pong/examples/LoLPong/LoLPong.ino new file mode 100644 index 0000000..752e00c --- /dev/null +++ b/libraries/Pong/examples/LoLPong/LoLPong.ino @@ -0,0 +1,125 @@ +#include "Pong.h" + +// LoLShield library: +// +// https://code.google.com/p/lolshield/ + +#include "Charliplexing.h" +#include "Myfont.h" + +static const int PADDLE0_PIN = 4; +static const int PADDLE1_PIN = 5; + +int digit[][7] = { + { 0b01110, 0b10001, 0b10001, 0b10001, 0b10001, 0b10001, 0b01110 }, + { 0b00100, 0b00110, 0b00100, 0b00100, 0b00100, 0b00100, 0b01110 }, + { 0b01110, 0b10001, 0b10000, 0b01110, 0b00001, 0b00001, 0b11111 }, + { 0b01110, 0b10001, 0b10000, 0b01110, 0b10000, 0b10001, 0b01110 }, + { 0b01000, 0b01100, 0b01010, 0b01001, 0b11111, 0b01000, 0b01000 }, + { 0b11111, 0b00001, 0b00001, 0b01111, 0b10000, 0b10000, 0b01111 }, + { 0b01110, 0b10001, 0b00001, 0b01111, 0b10001, 0b10001, 0b01110 }, + { 0b11111, 0b10000, 0b01000, 0b01000, 0b00100, 0b00100, 0b00100 }, + { 0b01110, 0b10001, 0b10001, 0b01110, 0b10001, 0b10001, 0b01110 }, + { 0b01110, 0b10001, 0b10001, 0b11110, 0b10000, 0b10000, 0b01111 }, +}; + +class LoLShieldPong : public Pong +{ +public: + LoLShieldPong(int paddle0_pin, int paddle1_pin) : + Pong(DISPLAY_ROWS, DISPLAY_COLS, paddle0_pin, paddle1_pin) {} + + void showPaddle(Paddle& p) { setPaddle(p, true); } + void hidePaddle(Paddle& p) { setPaddle(p, false); } + + void showBall(Ball& b) { LedSign::Set(b.col(), b.row(), true); } + void hideBall(Ball& b) { LedSign::Set(b.col(), b.row(), false); } + + void startGame(); + void showScore(); + +private: + static const unsigned char banner[]; + static const int bannerlength; + + void setPaddle(const Paddle& p, bool state); +}; + +const unsigned char LoLShieldPong::banner[] = "Play PONG!"; +const int LoLShieldPong::bannerlength = 10; + +void LoLShieldPong::startGame() +{ + LedSign::Clear(); + LedSign::SetBrightness(50); + + Myfont::Banner(bannerlength, const_cast(banner)); + start(); +} + +void LoLShieldPong::showScore() +{ + int i, j, ps1, ps2; + + // From the LoLShield example pong2.pde + // + // Author : Benjamin Sonntag http://benjamin.sonntag.fr + // Modified: Matt Mets http://cibomahto.com + + for (ps1 = 0; ps1 < 8; ps1++) { + LedSign::Clear(); // Clear the active screen + + LedSign::Set(6, 4, 1); // dash between the scores + LedSign::Set(7, 4, 1); + + // Fill it with both scores : + // Left score goes up > down + i = ps1; + j = 6; + while (i >= 0 && j >= 0) { + for (uint8_t k = 0; k < 5; k++) { + LedSign::Set(k, i, (digit[score_[0]][j] >> k) & 1); + } + i--; j--; + } + + // Right score goes down > up + ps2 = 8 - ps1; + i = ps2; + j = 0; + while (i <= 8 && j <= 6) { + for (uint8_t k = 0; k < 5; k++) { + LedSign::Set(k + 9, i, (digit[score_[1]][j] >> k) & 1); + } + i++; j++; + } + + delay(200); + } + + delay(1500); + LedSign::Clear(0); +} + +void LoLShieldPong::setPaddle(const Paddle& p, bool state) +{ + LedSign::Set(p.col(), p.row(), state); + LedSign::Set(p.col(), p.row() + 1, state); +} + +LoLShieldPong pong(PADDLE0_PIN, PADDLE1_PIN); + +void setup() +{ + LedSign::Init(); + pong.startGame(); +} + +void loop() +{ + pong.update(); +} + +// Local variables: +// mode: c++ +// End: diff --git a/libraries/Pong/examples/LoLPong/Makefile b/libraries/Pong/examples/LoLPong/Makefile new file mode 100644 index 0000000..b010f17 --- /dev/null +++ b/libraries/Pong/examples/LoLPong/Makefile @@ -0,0 +1,9 @@ +BOARD_TAG = atmega328 + +ARDUINO_SKETCHBOOK = $(PWD) + +ARDUINO_PORT = /dev/tty.usbserial-A* +ARDUINO_LIBS = LoLShield Pong + +include ../../../lib/mk/Common.mk +include ../../../lib/mk/Arduino.mk diff --git a/libraries/Pong/examples/MatrixPong/.gitignore b/libraries/Pong/examples/MatrixPong/.gitignore new file mode 100644 index 0000000..d83325f --- /dev/null +++ b/libraries/Pong/examples/MatrixPong/.gitignore @@ -0,0 +1,2 @@ +build-* +libraries diff --git a/libraries/Pong/examples/MatrixPong/Makefile b/libraries/Pong/examples/MatrixPong/Makefile new file mode 100644 index 0000000..acd4b69 --- /dev/null +++ b/libraries/Pong/examples/MatrixPong/Makefile @@ -0,0 +1,9 @@ +BOARD_TAG = uno + +ARDUINO_SKETCHBOOK = $(PWD) + +ARDUINO_PORT = /dev/tty.usbmodem* +ARDUINO_LIBS = LedControl Pong + +include ../../../lib/mk/Common.mk +include ../../../lib/mk/Arduino.mk diff --git a/libraries/Pong/examples/MatrixPong/MatrixPong.ino b/libraries/Pong/examples/MatrixPong/MatrixPong.ino new file mode 100644 index 0000000..241095e --- /dev/null +++ b/libraries/Pong/examples/MatrixPong/MatrixPong.ino @@ -0,0 +1,149 @@ +#include "Pong.h" + +// LedControl library: +// +// http://playground.arduino.cc/Main/LedControl +// http://www.wayoda.org/arduino/ledcontrol/index.html + +#include "LedControl.h" + +static const int DATA_PIN = 12; +static const int CLK_PIN = 11; +static const int CS_PIN = 10; + +static const int PADDLE0_PIN = 0; +static const int PADDLE1_PIN = 1; + +static char pongchars[][8] = { + { 0b00000000, 0b01111100, 0b01000010, 0b01000010, + 0b01111100, 0b01000000, 0b01000000, 0b00000000, }, // P + { 0b00000000, 0b00111100, 0b01000010, 0b01000010, + 0b01000010, 0b01000010, 0b00111100, 0b00000000, }, // O + { 0b00000000, 0b01000010, 0b01100010, 0b01010010, + 0b01001010, 0b01000110, 0b01000010, 0b00000000, }, // N + { 0b00000000, 0b00111100, 0b01000000, 0b01000000, + 0b01111100, 0b01000010, 0b00111100, 0b00000000, }, // G +}; + +static char digit[][5] = { + { 0b111, 0b101, 0b101, 0b101, 0b111 }, + { 0b001, 0b001, 0b001, 0b001, 0b001 }, + { 0b111, 0b001, 0b111, 0b100, 0b111 }, + { 0b111, 0b001, 0b111, 0b001, 0b111 }, + { 0b101, 0b101, 0b111, 0b001, 0b001 }, + { 0b111, 0b100, 0b111, 0b001, 0b111 }, + { 0b111, 0b100, 0b111, 0b101, 0b111 }, + { 0b111, 0b001, 0b001, 0b001, 0b001 }, + { 0b111, 0b101, 0b111, 0b101, 0b111 }, + { 0b111, 0b101, 0b111, 0b001, 0b111 }, +}; + +class LedMatrixPong : public Pong +{ +public: + LedMatrixPong(LedControl& ledControl, int paddle0_pin, int paddle1_pin) : + ledControl_(ledControl), + Pong(ROWS, COLS, paddle0_pin, paddle1_pin) {} + + void showPaddle(Paddle& p) { setPaddle(p, true); } + void hidePaddle(Paddle& p) { setPaddle(p, false); } + + void showBall(Ball& b) { ledControl_.setLed(0, b.row(), b.col(), true); } + void hideBall(Ball& b) { ledControl_.setLed(0, b.row(), b.col(), false); } + + void startGame(); + void showScore(); + +private: + static const int ROWS = 8; + static const int COLS = 8; + + void sayPong(int delay_ms); + void setPaddle(const Paddle& p, bool state); + + LedControl& ledControl_; +}; + +void LedMatrixPong::startGame() +{ + ledControl_.clearDisplay(0); + sayPong(500); + + for (int row = MAX_ROW; row >= 0; row--) { + ledControl_.setRow(0, row, 0xff); + delay(100); + ledControl_.setRow(0, row, 0); + } + + start(); +} + +void LedMatrixPong::sayPong(int delay_ms) +{ + for (int c = 0; c < 4; c++) { + for (int r = 0; r <= MAX_ROW; r++) { + ledControl_.setRow(0, r, pongchars[c][r]); + } + delay(delay_ms); + } +} + +void LedMatrixPong::showScore() +{ + for (int step = 0; step < 10; step++) { + ledControl_.clearDisplay(0); + ledControl_.setLed(0, 3, 3, true); + ledControl_.setLed(0, 3, 4, true); + + int i = (step < 8) ? step : 14 - step; + int j = 4; + while (i >= 0 && j >= 0) { + for (int k = 0; k < 3; k++) { + ledControl_.setLed(0, i, 2 - k, digit[score_[0]][j] & (1<= 100 +#include "Arduino.h" +#else +#include "WProgram.h" +#endif + +#include "Event.h" + +Event::Event(void) +{ + eventType = EVENT_NONE; +} + +void Event::update(void) +{ + unsigned long now = millis(); + update(now); +} + +void Event::update(unsigned long now) +{ + if (now - lastEventTime >= period) + { + switch (eventType) + { + case EVENT_EVERY: + (*callback)(); + break; + + case EVENT_OSCILLATE: + pinState = ! pinState; + digitalWrite(pin, pinState); + break; + } + lastEventTime = now; + count++; + } + if (repeatCount > -1 && count >= repeatCount) + { + eventType = EVENT_NONE; + } +} diff --git a/libraries/Timer/Event.h b/libraries/Timer/Event.h new file mode 100755 index 0000000..2f64d3f --- /dev/null +++ b/libraries/Timer/Event.h @@ -0,0 +1,49 @@ +/* + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * + Code by Simon Monk + http://www.simonmonk.org +* * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef Event_h +#define Event_h + +#include + +#define EVENT_NONE 0 +#define EVENT_EVERY 1 +#define EVENT_OSCILLATE 2 + +class Event +{ + +public: + Event(void); + void update(void); + void update(unsigned long now); + int8_t eventType; + unsigned long period; + int repeatCount; + uint8_t pin; + uint8_t pinState; + void (*callback)(void); + unsigned long lastEventTime; + int count; +}; + +#endif diff --git a/libraries/Timer/ReadMe.txt b/libraries/Timer/ReadMe.txt new file mode 100755 index 0000000..5b08895 --- /dev/null +++ b/libraries/Timer/ReadMe.txt @@ -0,0 +1,29 @@ +1.0 by Simon Monk +Library as downloaded 02Feb2012 22:55 UTC from http://srmonk.blogspot.com/2012/01/arduino-timer-library.html + +1.1 by Jack Christensen +Changed data types of variables and functions: + o event types and indexes changed from int to int8_t. + o periods and durations changed from lon to unsigned long. + o update() and stop() functions typed as void, since they return nothing. + o pin numbers and pin values changed from int to uint8_t, this agrees with digitalWrite(). + o added return values to Timer::pulse() and Timer::oscillate(uint8_t, unsigned long, uint8_t). + o changed test in Event::update() to use subtraction to avoid rollover issues. + o Updated keywords.txt file to include all functions. + +1.2 by Damian Philipp + o Added a range check to Timer::stop() to avoid memory corruption. + o Added constants to : + - NO_TIMER_AVAILABLE: Signals that while an event was to be queued, no free timer could be found. + - TIMER_NOT_AN_EVENT: Can be used to flag a variable that *might* contain a timer ID as + *not* containing a timer ID + o Replaced a bunch of magic numbers in by the above constants + o Added several comments + o Added Timer::pulseImmediate(). pulseImmediate sets the pin to the specified value for the given + duration. After the duration, the pin is set to !value. + +1.3 by Jack Christensen + o Added "blink2" example illustrating flashing two LEDs at different rates. + o 19Oct2013: This is the last v1.x release. It will continue to be available on GitHub + as a branch named v1.3. Future development will continue with Sandy Walsh's v2.0 which + can pass context (timer ID, etc.) to the callback functions. \ No newline at end of file diff --git a/libraries/Timer/Timer.cpp b/libraries/Timer/Timer.cpp new file mode 100755 index 0000000..9c8b889 --- /dev/null +++ b/libraries/Timer/Timer.cpp @@ -0,0 +1,138 @@ +/* + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * + Code by Simon Monk + http://www.simonmonk.org +* * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +// For Arduino 1.0 and earlier +#if defined(ARDUINO) && ARDUINO >= 100 +#include "Arduino.h" +#else +#include "WProgram.h" +#endif + +#include "Timer.h" + +Timer::Timer(void) +{ +} + +int8_t Timer::every(unsigned long period, void (*callback)(), int repeatCount) +{ + int8_t i = findFreeEventIndex(); + if (i == -1) return -1; + + _events[i].eventType = EVENT_EVERY; + _events[i].period = period; + _events[i].repeatCount = repeatCount; + _events[i].callback = callback; + _events[i].lastEventTime = millis(); + _events[i].count = 0; + return i; +} + +int8_t Timer::every(unsigned long period, void (*callback)()) +{ + return every(period, callback, -1); // - means forever +} + +int8_t Timer::after(unsigned long period, void (*callback)()) +{ + return every(period, callback, 1); +} + +int8_t Timer::oscillate(uint8_t pin, unsigned long period, uint8_t startingValue, int repeatCount) +{ + int8_t i = findFreeEventIndex(); + if (i == NO_TIMER_AVAILABLE) return NO_TIMER_AVAILABLE; + + _events[i].eventType = EVENT_OSCILLATE; + _events[i].pin = pin; + _events[i].period = period; + _events[i].pinState = startingValue; + digitalWrite(pin, startingValue); + _events[i].repeatCount = repeatCount * 2; // full cycles not transitions + _events[i].lastEventTime = millis(); + _events[i].count = 0; + return i; +} + +int8_t Timer::oscillate(uint8_t pin, unsigned long period, uint8_t startingValue) +{ + return oscillate(pin, period, startingValue, -1); // forever +} + +/** + * This method will generate a pulse of !startingValue, occuring period after the + * call of this method and lasting for period. The Pin will be left in !startingValue. + */ +int8_t Timer::pulse(uint8_t pin, unsigned long period, uint8_t startingValue) +{ + return oscillate(pin, period, startingValue, 1); // once +} + +/** + * This method will generate a pulse of startingValue, starting immediately and of + * length period. The pin will be left in the !startingValue state + */ +int8_t Timer::pulseImmediate(uint8_t pin, unsigned long period, uint8_t pulseValue) +{ + int8_t id(oscillate(pin, period, pulseValue, 1)); + // now fix the repeat count + if (id >= 0 && id < MAX_NUMBER_OF_EVENTS) { + _events[id].repeatCount = 1; + } + return id; +} + + +void Timer::stop(int8_t id) +{ + if (id >= 0 && id < MAX_NUMBER_OF_EVENTS) { + _events[id].eventType = EVENT_NONE; + } +} + +void Timer::update(void) +{ + unsigned long now = millis(); + update(now); +} + +void Timer::update(unsigned long now) +{ + for (int8_t i = 0; i < MAX_NUMBER_OF_EVENTS; i++) + { + if (_events[i].eventType != EVENT_NONE) + { + _events[i].update(now); + } + } +} +int8_t Timer::findFreeEventIndex(void) +{ + for (int8_t i = 0; i < MAX_NUMBER_OF_EVENTS; i++) + { + if (_events[i].eventType == EVENT_NONE) + { + return i; + } + } + return NO_TIMER_AVAILABLE; +} diff --git a/libraries/Timer/Timer.h b/libraries/Timer/Timer.h new file mode 100755 index 0000000..dd5ce93 --- /dev/null +++ b/libraries/Timer/Timer.h @@ -0,0 +1,67 @@ +/* + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * + Code by Simon Monk + http://www.simonmonk.org +* * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef Timer_h +#define Timer_h + +#include +#include "Event.h" + +#define MAX_NUMBER_OF_EVENTS (10) + +#define TIMER_NOT_AN_EVENT (-2) +#define NO_TIMER_AVAILABLE (-1) + +class Timer +{ + +public: + Timer(void); + + int8_t every(unsigned long period, void (*callback)(void)); + int8_t every(unsigned long period, void (*callback)(void), int repeatCount); + int8_t after(unsigned long duration, void (*callback)(void)); + int8_t oscillate(uint8_t pin, unsigned long period, uint8_t startingValue); + int8_t oscillate(uint8_t pin, unsigned long period, uint8_t startingValue, int repeatCount); + + /** + * This method will generate a pulse of !startingValue, occuring period after the + * call of this method and lasting for period. The Pin will be left in !startingValue. + */ + int8_t pulse(uint8_t pin, unsigned long period, uint8_t startingValue); + + /** + * This method will generate a pulse of pulseValue, starting immediately and of + * length period. The pin will be left in the !pulseValue state + */ + int8_t pulseImmediate(uint8_t pin, unsigned long period, uint8_t pulseValue); + void stop(int8_t id); + void update(void); + void update(unsigned long now); + +protected: + Event _events[MAX_NUMBER_OF_EVENTS]; + int8_t findFreeEventIndex(void); + +}; + +#endif diff --git a/libraries/Timer/examples/blink2/blink2.ino b/libraries/Timer/examples/blink2/blink2.ino new file mode 100755 index 0000000..e9080a4 --- /dev/null +++ b/libraries/Timer/examples/blink2/blink2.ino @@ -0,0 +1,29 @@ +//Flash two LEDs at different rates using Simon Monk's Timer library +//http://www.doctormonk.com/2012/01/arduino-timer-library.html +// +//Jack Christensen 30Sep2013 +// +//Beerware license: Free for any and all purposes, but if you find it +//useful AND we actually meet someday, you can buy me a beer! + +#include "Timer.h" //http://github.com/JChristensen/Timer + +const int LED1 = 8; //connect one LED to this pin (with appropriate current-limiting resistor of course) +const int LED2 = 9; //connect another LED to this pin (don't forget the resistor) +const unsigned long PERIOD1 = 1000; //one second +const unsigned long PERIOD2 = 10000; //ten seconds +Timer t; //instantiate the timer object + +void setup(void) +{ + pinMode(LED1, OUTPUT); + pinMode(LED2, OUTPUT); + t.oscillate(LED1, PERIOD1, HIGH); + t.oscillate(LED2, PERIOD2, HIGH); +} + +void loop(void) +{ + t.update(); +} + diff --git a/libraries/Timer/examples/kitchen_sink/kitchen_sink.pde b/libraries/Timer/examples/kitchen_sink/kitchen_sink.pde new file mode 100755 index 0000000..991bcb4 --- /dev/null +++ b/libraries/Timer/examples/kitchen_sink/kitchen_sink.pde @@ -0,0 +1,42 @@ +#include "Timer.h" + +Timer t; + +int ledEvent; + +void setup() +{ + Serial.begin(9600); + int tickEvent = t.every(2000, doSomething); + Serial.print("2 second tick started id="); + Serial.println(tickEvent); + + pinMode(13, OUTPUT); + ledEvent = t.oscillate(13, 50, HIGH); + Serial.print("LED event started id="); + Serial.println(ledEvent); + + int afterEvent = t.after(10000, doAfter); + Serial.print("After event started id="); + Serial.println(afterEvent); + +} + +void loop() +{ + t.update(); +} + +void doSomething() +{ + Serial.print("2 second tick: millis()="); + Serial.println(millis()); +} + + +void doAfter() +{ + Serial.println("stop the led event"); + t.stop(ledEvent); + t.oscillate(13, 500, HIGH, 5); +} diff --git a/libraries/Timer/examples/pin_high_10_mins/pin_high_10_mins.pde b/libraries/Timer/examples/pin_high_10_mins/pin_high_10_mins.pde new file mode 100755 index 0000000..3700d48 --- /dev/null +++ b/libraries/Timer/examples/pin_high_10_mins/pin_high_10_mins.pde @@ -0,0 +1,17 @@ +#include "Timer.h" + +Timer t; +int pin = 13; + +void setup() +{ + pinMode(pin, OUTPUT); + t.pulse(pin, 10 * 1000, HIGH); // 10 seconds + // t.pulse(pin, 10 * 60 * 1000, HIGH); // 10 minutes +} + +void loop() +{ + t.update(); +} + diff --git a/libraries/Timer/examples/read_A0_flashLED/read_A0_flashLED.pde b/libraries/Timer/examples/read_A0_flashLED/read_A0_flashLED.pde new file mode 100755 index 0000000..e103e37 --- /dev/null +++ b/libraries/Timer/examples/read_A0_flashLED/read_A0_flashLED.pde @@ -0,0 +1,22 @@ +#include "Timer.h" + +Timer t; +int pin = 13; + +void setup() +{ + Serial.begin(9600); + pinMode(pin, OUTPUT); + t.oscillate(pin, 100, LOW); + t.every(1000, takeReading); +} + +void loop() +{ + t.update(); +} + +void takeReading() +{ + Serial.println(analogRead(0)); +} diff --git a/libraries/Timer/keywords.txt b/libraries/Timer/keywords.txt new file mode 100755 index 0000000..a5107b8 --- /dev/null +++ b/libraries/Timer/keywords.txt @@ -0,0 +1,31 @@ +####################################### +# Syntax Coloring Map For Timer Library +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +Timer KEYWORD1 +Event KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +every KEYWORD2 +after KEYWORD2 +oscillate KEYWORD2 +pulse KEYWORD2 +pulseImmediate KEYWORD2 +stop KEYWORD2 +update KEYWORD2 +findFreeEventIndex KEYWORD2 + +####################################### +# Instances (KEYWORD2) +####################################### + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/software/StruyckenKS69/StruyckenKS69.ino b/software/StruyckenKS69/StruyckenKS69.ino new file mode 100644 index 0000000..a70773c --- /dev/null +++ b/software/StruyckenKS69/StruyckenKS69.ino @@ -0,0 +1,97 @@ +//After Komputerstrukturen 1969/70 by Peter Struycken with MAX7219 + +/* + * dataPin pin on the Arduino where data gets shifted out + * clockPin pin for the clock + * csPin pin for selecting the device + * numDevices maximum number of devices that can be controled +LedControl(int dataPin, int clkPin, int csPin, int numDevices=1); +*/ + +#include "LedControl.h" //Imports the library + +static const int DATA_PIN = 20; +static const int CLK_PIN = 5; +static const int CS_PIN = 21; + +LedControl lc = LedControl(DATA_PIN, CLK_PIN, CS_PIN, 1); + +#define brightness 1 //Values from 1 to 15 to set the brightness +int analogPin = 0; //analogPin for the random seed data + +unsigned char world[8][8]; +unsigned char state[4][4]; +int prev_i; +int prev_j; + +void setWorld() +{ + for (int i = 0; i < 8; i++) + for (int j = 0; j < 8; j++) + world[i][j] = 0; + + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + { + int i2 = i * 2; + int j2 = j * 2; + unsigned char s = state[i][j]; + if (s == 0) + world[i2][j2] = 1; + else if (s == 1) + world[i2][j2+1] = 1; + else if (s == 2) + world[i2+1][j2+1] = 1; + else + world[i2+1][j2] = 1; + } + for (int i = 0; i < 8; i++) + { + int r = 0; + for (int j = 0; j < 8; j++) + r = (r << 1) | world[i][j]; + lc.setColumn(0, 7-i, r); + } +} + +void setup() { + lc.shutdown(0, false); + lc.setIntensity(0, brightness); + lc.clearDisplay(0); + randomSeed(analogRead(analogPin)); + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + state[i][j] = random(4); + setWorld(); + prev_i = 0; + prev_j = 0; +} + +/*******************************************************************************/ + +void loop() +{ + delay(300); + + int i = random(3); + if (i >= prev_i) + i++; + int j = random(3); + if (j >= prev_j) + j++; + int old_s = state[i][j]; + state[i][j] = (old_s + (random(2) ? 1 : 3)) % 4; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + if ( state[i][j] == 2 && state[i][j+1] == 3 + && state[i+1][j+1] == 0 && state[i+1][j] == 1) + { + state[i][j] = old_s; + return; + } + setWorld(); + delay(1000); + prev_i = i; + prev_j = j; + +} diff --git a/software/batterij/batterij.ino b/software/batterij/batterij.ino new file mode 100644 index 0000000..a63b52b --- /dev/null +++ b/software/batterij/batterij.ino @@ -0,0 +1,82 @@ + +#include "LedControl.h" +#include "penlight.h" +#include "lipo.h" + +static const float Vin = 4.5; + +/* using VCC, GND, DIN 20, CS 21, CLK 5 for the MAX7219 */ +static const int DATA_PIN = 20; +static const int CLK_PIN = 5; +static const int CS_PIN = 21; + +LedControl lc=LedControl(DATA_PIN, CLK_PIN, CS_PIN, 1); + +void setup() { + lc.shutdown(0,false); + /* Set the brightness to a medium values */ + lc.setIntensity(0,15); + /* and clear the display */ + lc.clearDisplay(0); +} + +void loop() { + float batteryV; + for (;;) { + batteryV = analogRead(A0) / (51.0 * Vin); + + if (batteryV <= 1) { + render(penlight1,20); + } + else if (batteryV <= 1.1) { + render(penlight2,20); + } + else if (batteryV <= 1.2) { + render(penlight3,20); + } + else if (batteryV <= 1.3) { + render(penlight4,20); + } + else if (batteryV <= 1.4) { + render(penlight5,20); + } + else if (batteryV <= 1.5) { + render(penlight6,20); + } + else if (batteryV <= 2) { + render(penlight7,20); + } + else if (batteryV <= 3.6) { + render(lipo1,20); + } + else if (batteryV <= 3.7) { + render(lipo2,20); + } + else if (batteryV <= 3.8) { + render(lipo3,20); + } + else if (batteryV <= 3.9) { + render(lipo4,20); + } + else if (batteryV <= 4) { + render(lipo5,20); + } + else if (batteryV <= 4.1) { + render(lipo6,20); + } + else { + render(lipo7,20); + } + } +} + +void render(const byte* frame, long delaytime) { + for (int r = 0; r < 8; r++) { + lc.setColumn(0, 7-r, pgm_read_byte(&frame[r])); + } +} + + + + + diff --git a/software/batterij/lipo.h b/software/batterij/lipo.h new file mode 100644 index 0000000..ba0252f --- /dev/null +++ b/software/batterij/lipo.h @@ -0,0 +1,75 @@ +const byte lipo1[8] PROGMEM = { + B00111100, + B01000010, + B01000010, + B01000010, + B01000010, + B01000010, + B01000010, + B01111110 + }; + + const byte lipo2[8] PROGMEM = { + B00111100, + B01000010, + B01000010, + B01000010, + B01000010, + B01111110, + B01111110, + }; + + const byte lipo3[8] PROGMEM = { + B00111100, + B01000010, + B01000010, + B01000010, + B01000010, + B01111110, + B01111110, + B01111110 + }; + + const byte lipo4[8] PROGMEM = { + B00111100, + B01000010, + B01000010, + B01000010, + B01111110, + B01111110, + B01111110, + B01111110 + }; + + const byte lipo5[8] PROGMEM = { + B00111100, + B01000010, + B01000010, + B01111110, + B01111110, + B01111110, + B01111110, + B01111110 + }; + + const byte lipo6[8] PROGMEM = { + B00111100, + B01000010, + B01111110, + B01111110, + B01111110, + B01111110, + B01111110, + B01111110 + }; + + const byte lipo7[8] PROGMEM = { + B00111100, + B01111110, + B01111110, + B01111110, + B01111110, + B01111110, + B01111110, + B01111110 + }; diff --git a/software/batterij/penlight.h b/software/batterij/penlight.h new file mode 100644 index 0000000..3a26915 --- /dev/null +++ b/software/batterij/penlight.h @@ -0,0 +1,78 @@ +const byte penlight1[8] PROGMEM = { + B00011000, + B00100100, + B00100100, + B00100100, + B00100100, + B00100100, + B00100100, + B00111100 + }; + + const byte penlight2[8] PROGMEM = { + B00011000, + B00100100, + B00100100, + B00100100, + B00100100, + B00100100, + B00111100, + B00111100 + }; + + const byte penlight3[8] PROGMEM = { + B00011000, + B00100100, + B00100100, + B00100100, + B00100100, + B00111100, + B00111100, + B00111100 + }; + + const byte penlight4[8] PROGMEM = { + B00011000, + B00100100, + B00100100, + B00100100, + B00111100, + B00111100, + B00111100, + B00111100 + }; + + const byte penlight5[8] PROGMEM = { + B00011000, + B00100100, + B00100100, + B00111100, + B00111100, + B00111100, + B00111100, + B00111100 + }; + + const byte penlight6[8] PROGMEM = { + B00011000, + B00100100, + B00111100, + B00111100, + B00111100, + B00111100, + B00111100, + B00111100 + }; + + const byte penlight7[8] PROGMEM = { + B00011000, + B00111100, + B00111100, + B00111100, + B00111100, + B00111100, + B00111100, + B00111100 + }; + + diff --git a/software/conway/conway.ino b/software/conway/conway.ino new file mode 100644 index 0000000..59a728e --- /dev/null +++ b/software/conway/conway.ino @@ -0,0 +1,123 @@ +//Game of Life with MAX7219 + +/* + + * dataPin pin on the Arduino where data gets shifted out + * clockPin pin for the clock + * csPin pin for selecting the device + * numDevices maximum number of devices that can be controled +LedControl(int dataPin, int clkPin, int csPin, int numDevices=1); +*/ +/*******************************************************************************/ + +#include "LedControl.h" //Imports the library + +static const int DATA_PIN = 20; +static const int CLK_PIN = 5; +static const int CS_PIN = 21; + +LedControl lc = LedControl(DATA_PIN, CLK_PIN, CS_PIN, 1); + +#define SIZEX 8 //Sets the X axis size +#define SIZEY 8 //Sets the Y axis size +#define reseedrate 100 //Sets the rate the world is re-seeded +#define brightness 15 //Values from 1 to 15 to set the brightness +long density = 35; //Sets density % during seeding +unsigned long delaytime = 150; //Sets the time each generation is shown +int generation = 0; //Counter for re-seeding +int analogPin = 0; //analogPin for the random seed data +bool stable = true; + +unsigned char world1[8][8]; +unsigned char world2[8][8]; + + +/*******************************************************************************/ +/* randomize */ + +void seedWorld(unsigned char world1[8][8]) +{ + int i, j; + for (i = 0; i < SIZEX; i++) + { + for (j = 0; j < SIZEY; j++) + { + if (random(100) < density); { + world1[i][j] = random(2); + } + } + } +} + +/*******************************************************************************/ + +void setup() { + lc.shutdown(0, false); + lc.setIntensity(0, brightness); + lc.clearDisplay(0); + randomSeed(analogRead(analogPin)); + seedWorld(world1); +} + +/*******************************************************************************/ + +void loop() +{ + + if (stable || generation++ > reseedrate) + { + delay(1000); + seedWorld(world1); + lc.clearDisplay(0); + delay(300); + generation = 0; + } + + for (int i = 0; i < SIZEX; i++) + { + int above = (i + SIZEX - 1) % SIZEX; + int below = (i + 1) % SIZEX; + + for (int j = 0; j < SIZEY; j++) + { + int left = (j + SIZEY - 1) % SIZEY; + int right = (j + 1) % SIZEY; + int a = 0; + a += world1[above][left]; + a += world1[above][j]; + a += world1[above][right]; + a += world1[i][left]; + a += world1[i][right]; + a += world1[below][left]; + a += world1[below][j]; + a += world1[below][right]; + + if ((world1[i][j] == 0) && (a == 3)) { + world2[i][j] = 1; + } + if ((world1[i][j] == 1) && ((a == 2) || (a == 3))) { + world2[i][j] = 1; + } + if ((world1[i][j] == 1) && ((a == 1) || (a == 0) || (a > 3))) { + world2[i][j] = 0; + } + } + } + stable = true; + for (int i = 0; i < SIZEX; i++) + { + int r = 0; + for (int j = 0; j < SIZEY; j++) + { + if (world1[i][j] != world2[i][j]) + { + stable = false; + world1[i][j] = world2[i][j]; + } + r = (r << 1) | world2[i][j]; + } + lc.setColumn(0, i, r); + } + + delay(delaytime); +} diff --git a/software/cp437/cp437.ino b/software/cp437/cp437.ino new file mode 100644 index 0000000..6df1a9c --- /dev/null +++ b/software/cp437/cp437.ino @@ -0,0 +1,49 @@ +#include "font.h" +#include "LedControl.h" + + +/* using VCC, GND, DIN 20, CS 21, CLK 5 for the MAX7219 */ +static const int DATA_PIN = 20; +static const int CLK_PIN = 5; +static const int CS_PIN = 21; + +LedControl lc=LedControl(DATA_PIN, CLK_PIN, CS_PIN, 1); + +void setup() { + /* + The MAX72XX is in power-saving mode on startup, + we have to do a wakeup call + */ + lc.shutdown(0,false); + /* Set the brightness to a medium values */ + lc.setIntensity(0,15); + /* and clear the display */ + lc.clearDisplay(0); +} + +void letter (const byte c) +{ + for (byte col = 0; col < 8; col++) { + // ijduino is 90 degrees turned compared to 'normal' operation + lc.setRow(0, col, pgm_read_byte (&cp437_font [c] [col])); + } +} // end of letter + + +void showString (const char * s, const unsigned long time) +{ + char c; + while (c = *s++) + { + letter (c); + delay (time); + } +} // end of showString + +void loop () +{ + showString ("IJhack is f*cking cool !%$#@& \\o/ ", 500); +} // + + + diff --git a/software/cp437/font.h b/software/cp437/font.h new file mode 100644 index 0000000..20f56f8 --- /dev/null +++ b/software/cp437/font.h @@ -0,0 +1,778 @@ +#if (ARDUINO >= 100) +#include +#else +#include +#endif + + +const byte cp437_font [256] [8] PROGMEM = { + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + , // 0x00 + { + 0x7E, 0x81, 0x95, 0xB1, 0xB1, 0x95, 0x81, 0x7E } + , // 0x01 + { + 0x7E, 0xFF, 0xEB, 0xCF, 0xCF, 0xEB, 0xFF, 0x7E } + , // 0x02 + { + 0x0E, 0x1F, 0x3F, 0x7E, 0x3F, 0x1F, 0x0E, 0x00 } + , // 0x03 + { + 0x08, 0x1C, 0x3E, 0x7F, 0x3E, 0x1C, 0x08, 0x00 } + , // 0x04 + { + 0x18, 0xBA, 0xFF, 0xFF, 0xFF, 0xBA, 0x18, 0x00 } + , // 0x05 + { + 0x10, 0xB8, 0xFC, 0xFF, 0xFC, 0xB8, 0x10, 0x00 } + , // 0x06 + { + 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00 } + , // 0x07 + { + 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF } + , // 0x08 + { + 0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00 } + , // 0x09 + { + 0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF } + , // 0x0A + { + 0x70, 0xF8, 0x88, 0x88, 0xFD, 0x7F, 0x07, 0x0F } + , // 0x0B + { + 0x00, 0x4E, 0x5F, 0xF1, 0xF1, 0x5F, 0x4E, 0x00 } + , // 0x0C + { + 0xC0, 0xE0, 0xFF, 0x7F, 0x05, 0x05, 0x07, 0x07 } + , // 0x0D + { + 0xC0, 0xFF, 0x7F, 0x05, 0x05, 0x65, 0x7F, 0x3F } + , // 0x0E + { + 0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99 } + , // 0x0F + { + 0x7F, 0x3E, 0x3E, 0x1C, 0x1C, 0x08, 0x08, 0x00 } + , // 0x10 + { + 0x08, 0x08, 0x1C, 0x1C, 0x3E, 0x3E, 0x7F, 0x00 } + , // 0x11 + { + 0x00, 0x24, 0x66, 0xFF, 0xFF, 0x66, 0x24, 0x00 } + , // 0x12 + { + 0x00, 0x5F, 0x5F, 0x00, 0x00, 0x5F, 0x5F, 0x00 } + , // 0x13 + { + 0x06, 0x0F, 0x09, 0x7F, 0x7F, 0x01, 0x7F, 0x7F } + , // 0x14 + { + 0x40, 0xDA, 0xBF, 0xA5, 0xFD, 0x59, 0x03, 0x02 } + , // 0x15 + { + 0x00, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x00 } + , // 0x16 + { + 0x80, 0x94, 0xB6, 0xFF, 0xFF, 0xB6, 0x94, 0x80 } + , // 0x17 + { + 0x00, 0x04, 0x06, 0x7F, 0x7F, 0x06, 0x04, 0x00 } + , // 0x18 + { + 0x00, 0x10, 0x30, 0x7F, 0x7F, 0x30, 0x10, 0x00 } + , // 0x19 + { + 0x08, 0x08, 0x08, 0x2A, 0x3E, 0x1C, 0x08, 0x00 } + , // 0x1A + { + 0x08, 0x1C, 0x3E, 0x2A, 0x08, 0x08, 0x08, 0x00 } + , // 0x1B + { + 0x3C, 0x3C, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00 } + , // 0x1C + { + 0x08, 0x1C, 0x3E, 0x08, 0x08, 0x3E, 0x1C, 0x08 } + , // 0x1D + { + 0x30, 0x38, 0x3C, 0x3E, 0x3E, 0x3C, 0x38, 0x30 } + , // 0x1E + { + 0x06, 0x0E, 0x1E, 0x3E, 0x3E, 0x1E, 0x0E, 0x06 } + , // 0x1F + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + , // ' ' + { + 0x00, 0x06, 0x5F, 0x5F, 0x06, 0x00, 0x00, 0x00 } + , // '!' + { + 0x00, 0x07, 0x07, 0x00, 0x07, 0x07, 0x00, 0x00 } + , // '"' + { + 0x14, 0x7F, 0x7F, 0x14, 0x7F, 0x7F, 0x14, 0x00 } + , // '#' + { + 0x24, 0x2E, 0x6B, 0x6B, 0x3A, 0x12, 0x00, 0x00 } + , // '$' + { + 0x46, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x62, 0x00 } + , // '%' + { + 0x30, 0x7A, 0x4F, 0x5D, 0x37, 0x7A, 0x48, 0x00 } + , // '&' + { + 0x04, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 } + , // ''' + { + 0x00, 0x1C, 0x3E, 0x63, 0x41, 0x00, 0x00, 0x00 } + , // '(' + { + 0x00, 0x41, 0x63, 0x3E, 0x1C, 0x00, 0x00, 0x00 } + , // ')' + { + 0x08, 0x2A, 0x3E, 0x1C, 0x1C, 0x3E, 0x2A, 0x08 } + , // '*' + { + 0x08, 0x08, 0x3E, 0x3E, 0x08, 0x08, 0x00, 0x00 } + , // '+' + { + 0x00, 0x80, 0xE0, 0x60, 0x00, 0x00, 0x00, 0x00 } + , // ',' + { + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00 } + , // '-' + { + 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00 } + , // '.' + { + 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00 } + , // '/' + { + 0x3E, 0x7F, 0x71, 0x59, 0x4D, 0x7F, 0x3E, 0x00 } + , // '0' + { + 0x40, 0x42, 0x7F, 0x7F, 0x40, 0x40, 0x00, 0x00 } + , // '1' + { + 0x62, 0x73, 0x59, 0x49, 0x6F, 0x66, 0x00, 0x00 } + , // '2' + { + 0x22, 0x63, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00 } + , // '3' + { + 0x18, 0x1C, 0x16, 0x53, 0x7F, 0x7F, 0x50, 0x00 } + , // '4' + { + 0x27, 0x67, 0x45, 0x45, 0x7D, 0x39, 0x00, 0x00 } + , // '5' + { + 0x3C, 0x7E, 0x4B, 0x49, 0x79, 0x30, 0x00, 0x00 } + , // '6' + { + 0x03, 0x03, 0x71, 0x79, 0x0F, 0x07, 0x00, 0x00 } + , // '7' + { + 0x36, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00 } + , // '8' + { + 0x06, 0x4F, 0x49, 0x69, 0x3F, 0x1E, 0x00, 0x00 } + , // '9' + { + 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00 } + , // ':' + { + 0x00, 0x80, 0xE6, 0x66, 0x00, 0x00, 0x00, 0x00 } + , // ';' + { + 0x08, 0x1C, 0x36, 0x63, 0x41, 0x00, 0x00, 0x00 } + , // '<' + { + 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00 } + , // '=' + { + 0x00, 0x41, 0x63, 0x36, 0x1C, 0x08, 0x00, 0x00 } + , // '>' + { + 0x02, 0x03, 0x51, 0x59, 0x0F, 0x06, 0x00, 0x00 } + , // '?' + { + 0x3E, 0x7F, 0x41, 0x5D, 0x5D, 0x1F, 0x1E, 0x00 } + , // '@' + { + 0x7C, 0x7E, 0x13, 0x13, 0x7E, 0x7C, 0x00, 0x00 } + , // 'A' + { + 0x41, 0x7F, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00 } + , // 'B' + { + 0x1C, 0x3E, 0x63, 0x41, 0x41, 0x63, 0x22, 0x00 } + , // 'C' + { + 0x41, 0x7F, 0x7F, 0x41, 0x63, 0x3E, 0x1C, 0x00 } + , // 'D' + { + 0x41, 0x7F, 0x7F, 0x49, 0x5D, 0x41, 0x63, 0x00 } + , // 'E' + { + 0x41, 0x7F, 0x7F, 0x49, 0x1D, 0x01, 0x03, 0x00 } + , // 'F' + { + 0x1C, 0x3E, 0x63, 0x41, 0x51, 0x73, 0x72, 0x00 } + , // 'G' + { + 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00 } + , // 'H' + { + 0x00, 0x41, 0x7F, 0x7F, 0x41, 0x00, 0x00, 0x00 } + , // 'I' + { + 0x30, 0x70, 0x40, 0x41, 0x7F, 0x3F, 0x01, 0x00 } + , // 'J' + { + 0x41, 0x7F, 0x7F, 0x08, 0x1C, 0x77, 0x63, 0x00 } + , // 'K' + { + 0x41, 0x7F, 0x7F, 0x41, 0x40, 0x60, 0x70, 0x00 } + , // 'L' + { + 0x7F, 0x7F, 0x0E, 0x1C, 0x0E, 0x7F, 0x7F, 0x00 } + , // 'M' + { + 0x7F, 0x7F, 0x06, 0x0C, 0x18, 0x7F, 0x7F, 0x00 } + , // 'N' + { + 0x1C, 0x3E, 0x63, 0x41, 0x63, 0x3E, 0x1C, 0x00 } + , // 'O' + { + 0x41, 0x7F, 0x7F, 0x49, 0x09, 0x0F, 0x06, 0x00 } + , // 'P' + { + 0x1E, 0x3F, 0x21, 0x71, 0x7F, 0x5E, 0x00, 0x00 } + , // 'Q' + { + 0x41, 0x7F, 0x7F, 0x09, 0x19, 0x7F, 0x66, 0x00 } + , // 'R' + { + 0x26, 0x6F, 0x4D, 0x59, 0x73, 0x32, 0x00, 0x00 } + , // 'S' + { + 0x03, 0x41, 0x7F, 0x7F, 0x41, 0x03, 0x00, 0x00 } + , // 'T' + { + 0x7F, 0x7F, 0x40, 0x40, 0x7F, 0x7F, 0x00, 0x00 } + , // 'U' + { + 0x1F, 0x3F, 0x60, 0x60, 0x3F, 0x1F, 0x00, 0x00 } + , // 'V' + { + 0x7F, 0x7F, 0x30, 0x18, 0x30, 0x7F, 0x7F, 0x00 } + , // 'W' + { + 0x43, 0x67, 0x3C, 0x18, 0x3C, 0x67, 0x43, 0x00 } + , // 'X' + { + 0x07, 0x4F, 0x78, 0x78, 0x4F, 0x07, 0x00, 0x00 } + , // 'Y' + { + 0x47, 0x63, 0x71, 0x59, 0x4D, 0x67, 0x73, 0x00 } + , // 'Z' + { + 0x00, 0x7F, 0x7F, 0x41, 0x41, 0x00, 0x00, 0x00 } + , // '[' + { + 0x01, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00 } + , // backslash + { + 0x00, 0x41, 0x41, 0x7F, 0x7F, 0x00, 0x00, 0x00 } + , // ']' + { + 0x08, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x08, 0x00 } + , // '^' + { + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 } + , // '_' + { + 0x00, 0x00, 0x03, 0x07, 0x04, 0x00, 0x00, 0x00 } + , // '`' + { + 0x20, 0x74, 0x54, 0x54, 0x3C, 0x78, 0x40, 0x00 } + , // 'a' + { + 0x41, 0x7F, 0x3F, 0x48, 0x48, 0x78, 0x30, 0x00 } + , // 'b' + { + 0x38, 0x7C, 0x44, 0x44, 0x6C, 0x28, 0x00, 0x00 } + , // 'c' + { + 0x30, 0x78, 0x48, 0x49, 0x3F, 0x7F, 0x40, 0x00 } + , // 'd' + { + 0x38, 0x7C, 0x54, 0x54, 0x5C, 0x18, 0x00, 0x00 } + , // 'e' + { + 0x48, 0x7E, 0x7F, 0x49, 0x03, 0x02, 0x00, 0x00 } + , // 'f' + { + 0x98, 0xBC, 0xA4, 0xA4, 0xF8, 0x7C, 0x04, 0x00 } + , // 'g' + { + 0x41, 0x7F, 0x7F, 0x08, 0x04, 0x7C, 0x78, 0x00 } + , // 'h' + { + 0x00, 0x44, 0x7D, 0x7D, 0x40, 0x00, 0x00, 0x00 } + , // 'i' + { + 0x60, 0xE0, 0x80, 0x80, 0xFD, 0x7D, 0x00, 0x00 } + , // 'j' + { + 0x41, 0x7F, 0x7F, 0x10, 0x38, 0x6C, 0x44, 0x00 } + , // 'k' + { + 0x00, 0x41, 0x7F, 0x7F, 0x40, 0x00, 0x00, 0x00 } + , // 'l' + { + 0x7C, 0x7C, 0x18, 0x38, 0x1C, 0x7C, 0x78, 0x00 } + , // 'm' + { + 0x7C, 0x7C, 0x04, 0x04, 0x7C, 0x78, 0x00, 0x00 } + , // 'n' + { + 0x38, 0x7C, 0x44, 0x44, 0x7C, 0x38, 0x00, 0x00 } + , // 'o' + { + 0x84, 0xFC, 0xF8, 0xA4, 0x24, 0x3C, 0x18, 0x00 } + , // 'p' + { + 0x18, 0x3C, 0x24, 0xA4, 0xF8, 0xFC, 0x84, 0x00 } + , // 'q' + { + 0x44, 0x7C, 0x78, 0x4C, 0x04, 0x1C, 0x18, 0x00 } + , // 'r' + { + 0x48, 0x5C, 0x54, 0x54, 0x74, 0x24, 0x00, 0x00 } + , // 's' + { + 0x00, 0x04, 0x3E, 0x7F, 0x44, 0x24, 0x00, 0x00 } + , // 't' + { + 0x3C, 0x7C, 0x40, 0x40, 0x3C, 0x7C, 0x40, 0x00 } + , // 'u' + { + 0x1C, 0x3C, 0x60, 0x60, 0x3C, 0x1C, 0x00, 0x00 } + , // 'v' + { + 0x3C, 0x7C, 0x70, 0x38, 0x70, 0x7C, 0x3C, 0x00 } + , // 'w' + { + 0x44, 0x6C, 0x38, 0x10, 0x38, 0x6C, 0x44, 0x00 } + , // 'x' + { + 0x9C, 0xBC, 0xA0, 0xA0, 0xFC, 0x7C, 0x00, 0x00 } + , // 'y' + { + 0x4C, 0x64, 0x74, 0x5C, 0x4C, 0x64, 0x00, 0x00 } + , // 'z' + { + 0x08, 0x08, 0x3E, 0x77, 0x41, 0x41, 0x00, 0x00 } + , // '{' + { + 0x00, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0x00 } + , // '|' + { + 0x41, 0x41, 0x77, 0x3E, 0x08, 0x08, 0x00, 0x00 } + , // '}' + { + 0x02, 0x03, 0x01, 0x03, 0x02, 0x03, 0x01, 0x00 } + , // '~' + { + 0x70, 0x78, 0x4C, 0x46, 0x4C, 0x78, 0x70, 0x00 } + , // 0x7F + { + 0x0E, 0x9F, 0x91, 0xB1, 0xFB, 0x4A, 0x00, 0x00 } + , // 0x80 + { + 0x3A, 0x7A, 0x40, 0x40, 0x7A, 0x7A, 0x40, 0x00 } + , // 0x81 + { + 0x38, 0x7C, 0x54, 0x55, 0x5D, 0x19, 0x00, 0x00 } + , // 0x82 + { + 0x02, 0x23, 0x75, 0x55, 0x55, 0x7D, 0x7B, 0x42 } + , // 0x83 + { + 0x21, 0x75, 0x54, 0x54, 0x7D, 0x79, 0x40, 0x00 } + , // 0x84 + { + 0x21, 0x75, 0x55, 0x54, 0x7C, 0x78, 0x40, 0x00 } + , // 0x85 + { + 0x20, 0x74, 0x57, 0x57, 0x7C, 0x78, 0x40, 0x00 } + , // 0x86 + { + 0x18, 0x3C, 0xA4, 0xA4, 0xE4, 0x40, 0x00, 0x00 } + , // 0x87 + { + 0x02, 0x3B, 0x7D, 0x55, 0x55, 0x5D, 0x1B, 0x02 } + , // 0x88 + { + 0x39, 0x7D, 0x54, 0x54, 0x5D, 0x19, 0x00, 0x00 } + , // 0x89 + { + 0x39, 0x7D, 0x55, 0x54, 0x5C, 0x18, 0x00, 0x00 } + , // 0x8A + { + 0x01, 0x45, 0x7C, 0x7C, 0x41, 0x01, 0x00, 0x00 } + , // 0x8B + { + 0x02, 0x03, 0x45, 0x7D, 0x7D, 0x43, 0x02, 0x00 } + , // 0x8C + { + 0x01, 0x45, 0x7D, 0x7C, 0x40, 0x00, 0x00, 0x00 } + , // 0x8D + { + 0x79, 0x7D, 0x16, 0x12, 0x16, 0x7D, 0x79, 0x00 } + , // 0x8E + { + 0x70, 0x78, 0x2B, 0x2B, 0x78, 0x70, 0x00, 0x00 } + , // 0x8F + { + 0x44, 0x7C, 0x7C, 0x55, 0x55, 0x45, 0x00, 0x00 } + , // 0x90 + { + 0x20, 0x74, 0x54, 0x54, 0x7C, 0x7C, 0x54, 0x54 } + , // 0x91 + { + 0x7C, 0x7E, 0x0B, 0x09, 0x7F, 0x7F, 0x49, 0x00 } + , // 0x92 + { + 0x32, 0x7B, 0x49, 0x49, 0x7B, 0x32, 0x00, 0x00 } + , // 0x93 + { + 0x32, 0x7A, 0x48, 0x48, 0x7A, 0x32, 0x00, 0x00 } + , // 0x94 + { + 0x32, 0x7A, 0x4A, 0x48, 0x78, 0x30, 0x00, 0x00 } + , // 0x95 + { + 0x3A, 0x7B, 0x41, 0x41, 0x7B, 0x7A, 0x40, 0x00 } + , // 0x96 + { + 0x3A, 0x7A, 0x42, 0x40, 0x78, 0x78, 0x40, 0x00 } + , // 0x97 + { + 0x9A, 0xBA, 0xA0, 0xA0, 0xFA, 0x7A, 0x00, 0x00 } + , // 0x98 + { + 0x01, 0x19, 0x3C, 0x66, 0x66, 0x3C, 0x19, 0x01 } + , // 0x99 + { + 0x3D, 0x7D, 0x40, 0x40, 0x7D, 0x3D, 0x00, 0x00 } + , // 0x9A + { + 0x18, 0x3C, 0x24, 0xE7, 0xE7, 0x24, 0x24, 0x00 } + , // 0x9B + { + 0x68, 0x7E, 0x7F, 0x49, 0x43, 0x66, 0x20, 0x00 } + , // 0x9C + { + 0x2B, 0x2F, 0xFC, 0xFC, 0x2F, 0x2B, 0x00, 0x00 } + , // 0x9D + { + 0xFF, 0xFF, 0x09, 0x09, 0x2F, 0xF6, 0xF8, 0xA0 } + , // 0x9E + { + 0x40, 0xC0, 0x88, 0xFE, 0x7F, 0x09, 0x03, 0x02 } + , // 0x9F + { + 0x20, 0x74, 0x54, 0x55, 0x7D, 0x79, 0x40, 0x00 } + , // 0xA0 + { + 0x00, 0x44, 0x7D, 0x7D, 0x41, 0x00, 0x00, 0x00 } + , // 0xA1 + { + 0x30, 0x78, 0x48, 0x4A, 0x7A, 0x32, 0x00, 0x00 } + , // 0xA2 + { + 0x38, 0x78, 0x40, 0x42, 0x7A, 0x7A, 0x40, 0x00 } + , // 0xA3 + { + 0x7A, 0x7A, 0x0A, 0x0A, 0x7A, 0x70, 0x00, 0x00 } + , // 0xA4 + { + 0x7D, 0x7D, 0x19, 0x31, 0x7D, 0x7D, 0x00, 0x00 } + , // 0xA5 + { + 0x00, 0x26, 0x2F, 0x29, 0x2F, 0x2F, 0x28, 0x00 } + , // 0xA6 + { + 0x00, 0x26, 0x2F, 0x29, 0x2F, 0x26, 0x00, 0x00 } + , // 0xA7 + { + 0x30, 0x78, 0x4D, 0x45, 0x60, 0x20, 0x00, 0x00 } + , // 0xA8 + { + 0x38, 0x38, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00 } + , // 0xA9 + { + 0x08, 0x08, 0x08, 0x08, 0x38, 0x38, 0x00, 0x00 } + , // 0xAA + { + 0x4F, 0x6F, 0x30, 0x18, 0xCC, 0xEE, 0xBB, 0x91 } + , // 0xAB + { + 0x4F, 0x6F, 0x30, 0x18, 0x6C, 0x76, 0xFB, 0xF9 } + , // 0xAC + { + 0x00, 0x00, 0x00, 0x7B, 0x7B, 0x00, 0x00, 0x00 } + , // 0xAD + { + 0x08, 0x1C, 0x36, 0x22, 0x08, 0x1C, 0x36, 0x22 } + , // 0xAE + { + 0x22, 0x36, 0x1C, 0x08, 0x22, 0x36, 0x1C, 0x08 } + , // 0xAF + { + 0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00 } + , // 0xB0 + { + 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 } + , // 0xB1 + { + 0xDD, 0xFF, 0xAA, 0x77, 0xDD, 0xAA, 0xFF, 0x77 } + , // 0xB2 + { + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00 } + , // 0xB3 + { + 0x10, 0x10, 0x10, 0xFF, 0xFF, 0x00, 0x00, 0x00 } + , // 0xB4 + { + 0x14, 0x14, 0x14, 0xFF, 0xFF, 0x00, 0x00, 0x00 } + , // 0xB5 + { + 0x10, 0x10, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00 } + , // 0xB6 + { + 0x10, 0x10, 0xF0, 0xF0, 0x10, 0xF0, 0xF0, 0x00 } + , // 0xB7 + { + 0x14, 0x14, 0x14, 0xFC, 0xFC, 0x00, 0x00, 0x00 } + , // 0xB8 + { + 0x14, 0x14, 0xF7, 0xF7, 0x00, 0xFF, 0xFF, 0x00 } + , // 0xB9 + { + 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00 } + , // 0xBA + { + 0x14, 0x14, 0xF4, 0xF4, 0x04, 0xFC, 0xFC, 0x00 } + , // 0xBB + { + 0x14, 0x14, 0x17, 0x17, 0x10, 0x1F, 0x1F, 0x00 } + , // 0xBC + { + 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x1F, 0x1F, 0x00 } + , // 0xBD + { + 0x14, 0x14, 0x14, 0x1F, 0x1F, 0x00, 0x00, 0x00 } + , // 0xBE + { + 0x10, 0x10, 0x10, 0xF0, 0xF0, 0x00, 0x00, 0x00 } + , // 0xBF + { + 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x10, 0x10, 0x10 } + , // 0xC0 + { + 0x10, 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x10 } + , // 0xC1 + { + 0x10, 0x10, 0x10, 0xF0, 0xF0, 0x10, 0x10, 0x10 } + , // 0xC2 + { + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x10, 0x10, 0x10 } + , // 0xC3 + { + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 } + , // 0xC4 + { + 0x10, 0x10, 0x10, 0xFF, 0xFF, 0x10, 0x10, 0x10 } + , // 0xC5 + { + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x14, 0x14, 0x14 } + , // 0xC6 + { + 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x10 } + , // 0xC7 + { + 0x00, 0x00, 0x1F, 0x1F, 0x10, 0x17, 0x17, 0x14 } + , // 0xC8 + { + 0x00, 0x00, 0xFC, 0xFC, 0x04, 0xF4, 0xF4, 0x14 } + , // 0xC9 + { + 0x14, 0x14, 0x17, 0x17, 0x10, 0x17, 0x17, 0x14 } + , // 0xCA + { + 0x14, 0x14, 0xF4, 0xF4, 0x04, 0xF4, 0xF4, 0x14 } + , // 0xCB + { + 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xF7, 0xF7, 0x14 } + , // 0xCC + { + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14 } + , // 0xCD + { + 0x14, 0x14, 0xF7, 0xF7, 0x00, 0xF7, 0xF7, 0x14 } + , // 0xCE + { + 0x14, 0x14, 0x14, 0x17, 0x17, 0x14, 0x14, 0x14 } + , // 0xCF + { + 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x1F, 0x1F, 0x10 } + , // 0xD0 + { + 0x14, 0x14, 0x14, 0xF4, 0xF4, 0x14, 0x14, 0x14 } + , // 0xD1 + { + 0x10, 0x10, 0xF0, 0xF0, 0x10, 0xF0, 0xF0, 0x10 } + , // 0xD2 + { + 0x00, 0x00, 0x1F, 0x1F, 0x10, 0x1F, 0x1F, 0x10 } + , // 0xD3 + { + 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x14, 0x14, 0x14 } + , // 0xD4 + { + 0x00, 0x00, 0x00, 0xFC, 0xFC, 0x14, 0x14, 0x14 } + , // 0xD5 + { + 0x00, 0x00, 0xF0, 0xF0, 0x10, 0xF0, 0xF0, 0x10 } + , // 0xD6 + { + 0x10, 0x10, 0xFF, 0xFF, 0x10, 0xFF, 0xFF, 0x10 } + , // 0xD7 + { + 0x14, 0x14, 0x14, 0xFF, 0xFF, 0x14, 0x14, 0x14 } + , // 0xD8 + { + 0x10, 0x10, 0x10, 0x1F, 0x1F, 0x00, 0x00, 0x00 } + , // 0xD9 + { + 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x10, 0x10, 0x10 } + , // 0xDA + { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } + , // 0xDB + { + 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0 } + , // 0xDC + { + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 } + , // 0xDD + { + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF } + , // 0xDE + { + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F } + , // 0xDF + { + 0x38, 0x7C, 0x44, 0x6C, 0x38, 0x6C, 0x44, 0x00 } + , // 0xE0 + { + 0xFC, 0xFE, 0x2A, 0x2A, 0x3E, 0x14, 0x00, 0x00 } + , // 0xE1 + { + 0x7E, 0x7E, 0x02, 0x02, 0x06, 0x06, 0x00, 0x00 } + , // 0xE2 + { + 0x02, 0x7E, 0x7E, 0x02, 0x7E, 0x7E, 0x02, 0x00 } + , // 0xE3 + { + 0x63, 0x77, 0x5D, 0x49, 0x63, 0x63, 0x00, 0x00 } + , // 0xE4 + { + 0x38, 0x7C, 0x44, 0x7C, 0x3C, 0x04, 0x04, 0x00 } + , // 0xE5 + { + 0x80, 0xFE, 0x7E, 0x20, 0x20, 0x3E, 0x1E, 0x00 } + , // 0xE6 + { + 0x04, 0x06, 0x02, 0x7E, 0x7C, 0x06, 0x02, 0x00 } + , // 0xE7 + { + 0x99, 0xBD, 0xE7, 0xE7, 0xBD, 0x99, 0x00, 0x00 } + , // 0xE8 + { + 0x1C, 0x3E, 0x6B, 0x49, 0x6B, 0x3E, 0x1C, 0x00 } + , // 0xE9 + { + 0x4C, 0x7E, 0x73, 0x01, 0x73, 0x7E, 0x4C, 0x00 } + , // 0xEA + { + 0x30, 0x78, 0x4A, 0x4F, 0x7D, 0x39, 0x00, 0x00 } + , // 0xEB + { + 0x18, 0x3C, 0x24, 0x3C, 0x3C, 0x24, 0x3C, 0x18 } + , // 0xEC + { + 0x98, 0xFC, 0x64, 0x3C, 0x3E, 0x27, 0x3D, 0x18 } + , // 0xED + { + 0x1C, 0x3E, 0x6B, 0x49, 0x49, 0x00, 0x00, 0x00 } + , // 0xEE + { + 0x7E, 0x7F, 0x01, 0x01, 0x7F, 0x7E, 0x00, 0x00 } + , // 0xEF + { + 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x00, 0x00 } + , // 0xF0 + { + 0x44, 0x44, 0x5F, 0x5F, 0x44, 0x44, 0x00, 0x00 } + , // 0xF1 + { + 0x40, 0x51, 0x5B, 0x4E, 0x44, 0x40, 0x00, 0x00 } + , // 0xF2 + { + 0x40, 0x44, 0x4E, 0x5B, 0x51, 0x40, 0x00, 0x00 } + , // 0xF3 + { + 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x01, 0x07, 0x06 } + , // 0xF4 + { + 0x60, 0xE0, 0x80, 0xFF, 0x7F, 0x00, 0x00, 0x00 } + , // 0xF5 + { + 0x08, 0x08, 0x6B, 0x6B, 0x08, 0x08, 0x00, 0x00 } + , // 0xF6 + { + 0x24, 0x36, 0x12, 0x36, 0x24, 0x36, 0x12, 0x00 } + , // 0xF7 + { + 0x00, 0x06, 0x0F, 0x09, 0x0F, 0x06, 0x00, 0x00 } + , // 0xF8 + { + 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00 } + , // 0xF9 + { + 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00 } + , // 0xFA + { + 0x10, 0x30, 0x70, 0xC0, 0xFF, 0xFF, 0x01, 0x01 } + , // 0xFB + { + 0x00, 0x1F, 0x1F, 0x01, 0x1F, 0x1E, 0x00, 0x00 } + , // 0xFC + { + 0x00, 0x19, 0x1D, 0x17, 0x12, 0x00, 0x00, 0x00 } + , // 0xFD + { + 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00 } + , // 0xFE + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + , // 0xFF +}; // end of cp437_font + diff --git a/software/domineering/domineering.ino b/software/domineering/domineering.ino new file mode 100644 index 0000000..41fc5b0 --- /dev/null +++ b/software/domineering/domineering.ino @@ -0,0 +1,138 @@ +/* + * Domineering + * + * Allows you to play the game domineering + * (See https://en.wikipedia.org/wiki/Domineering) + * with the use of a potentiometer. Player take + * turns removing two blinking leds by turning the + * potentiometer. After a user stops turning the + * potentiometer the blinking slows down and removes + * the two blinking leds, giving the turn to the + * other player. + * + * The size of the playing field can be changed by + * modifying BOTTOM and TOP defines (taking into + * account: (0 <= BOTTOM < TOP <= 8) + */ +static const int DATA_PIN = 20; +static const int CLK_PIN = 5; +static const int CS_PIN = 21; + +#include "LedControl.h" +#include "Timer.h" + +#define POTPIN A5 // Potentiometer + +LedControl lc = LedControl(DATA_PIN, CLK_PIN, CS_PIN, 1); + +#define brightness 1 //Values from 1 to 15 to set the brightness +uint8_t matrix[8]; +#define MAT(X,Y) (matrix[X] & (1 << Y)) +#define SETMAT(X,Y) matrix[X] |= (1 << Y) +#define RESETMAT(X,Y) matrix[X] &= ~(1 << Y) +uint8_t x_p[56]; +uint8_t y_p[56]; +#define BOTTOM 2 +#define TOP 7 + +void showmat() +{ + for (uint8_t x = 0; x < 8; x++) + lc.setColumn(0, x, matrix[x]); +} + +void init_field() +{ + for (uint8_t i = 0; i < 8; i++) + matrix[i] = 0; + for (uint8_t y = BOTTOM; y < TOP; y++) + for (uint8_t x = BOTTOM; x < TOP; x++) + SETMAT(x,y); + showmat(); +} + +bool vert_player = false; + +void setup() { + pinMode(POTPIN, INPUT); + + lc.shutdown(0, false); + lc.setIntensity(0, brightness); + lc.clearDisplay(0); + Serial.begin(9600); + Serial.println("Start"); + init_field(); +} + + +void loop() { + uint8_t len = 0; + uint8_t v_x = 0; + uint8_t v_y = 0; + if (vert_player) + { + v_x = 1; + for (uint8_t y = BOTTOM; y < TOP; y++) + for (uint8_t x = BOTTOM; x < TOP-1; x++) + if (MAT(x,y) != 0 && MAT(x+1, y) != 0) + { + x_p[len] = x; + y_p[len] = y; + len++; + } + } + else + { + v_y = 1; + for (uint8_t x = BOTTOM; x < TOP; x++) + for (uint8_t y = BOTTOM; y < TOP-1; y++) + if (MAT(x,y) != 0 && MAT(x, y+1) != 0) + { + x_p[len] = x; + y_p[len] = y; + len++; + } + } + if (len == 0) + { + init_field(); + return; + } + + int prev_pos = -1; + bool moved = len == 1; + int d = 50; + for (;;) + { + int val = analogRead(POTPIN); + int pos = (val - 12)/(1000/len); + if (pos < 0) + pos = 0; + if (pos >= len) + pos = len - 1; + if (prev_pos != -1 && pos != prev_pos) + { + moved = true; + d = 50; + } + else if (moved) + d += 50; + prev_pos = pos; + + RESETMAT(x_p[pos], y_p[pos]); + RESETMAT(x_p[pos]+v_x, y_p[pos]+v_y); + showmat(); + + delay(d); + + if (d > 500) + break; + + SETMAT(x_p[pos], y_p[pos]); + SETMAT(x_p[pos]+v_x, y_p[pos]+v_y); + showmat(); + + delay(d); + } + vert_player = !vert_player; +} diff --git a/software/ijblinktext/ijblinktext.ino b/software/ijblinktext/ijblinktext.ino new file mode 100644 index 0000000..ff41b45 --- /dev/null +++ b/software/ijblinktext/ijblinktext.ino @@ -0,0 +1,61 @@ +//We always have to include the library +#include "LedControlMS.h" + +/* + Now we need a LedControl to work with. + ***** These pin numbers will probably not work with your hardware ***** + pin 20 is connected to the DataIn + pin 5 is connected to the CLK + pin 21 is connected to LOAD +*/ +#define NBR_MTX 4 +LedControl lc=LedControl(20,5,21, NBR_MTX); + + +/* we always wait a bit between updates of the display */ +String scrollString= "IJHACK 4 Screens on One IJduino "; +int stringLength=scrollString.length(); +char ch0, ch1, ch2, ch3; +int nextCharIndex=0; + + +void setup() { + /* + The MAX72XX is in power-saving mode on startup, + we have to do a wakeup call + */ + Serial.begin (9600); + Serial.println("Setup"); + Serial.println(scrollString); + Serial.println(stringLength); + + for (int i=0; i< NBR_MTX; i++){ + lc.shutdown(i,false); + /* Set the brightness to a low value */ + lc.setIntensity(i,1); + /* and clear the display */ + lc.clearDisplay(i); + } + delay(100); + lc.clearAll(); + ch0= scrollString[0]; + ch1= scrollString[1]; + ch2= scrollString[2]; + ch3= scrollString[3]; + nextCharIndex=4; +} + +void loop(){ + lc.displayChar(0, lc.getCharArrayPosition(ch0)); + lc.displayChar(1, lc.getCharArrayPosition(ch1)); + lc.displayChar(2, lc.getCharArrayPosition(ch2)); + lc.displayChar(3, lc.getCharArrayPosition(ch3)); + ch0=ch1; + ch1=ch2; + ch2=ch3; + ch3=scrollString[nextCharIndex++]; + if (nextCharIndex>=stringLength) nextCharIndex=0; + delay(100); + lc.clearAll(); + delay(25); +} diff --git a/software/ijdice/ijdice.ino b/software/ijdice/ijdice.ino new file mode 100644 index 0000000..4afd638 --- /dev/null +++ b/software/ijdice/ijdice.ino @@ -0,0 +1,290 @@ + +#include "LedControl.h" +const int BUTTON_PIN = 9; + + +//#define POTPIN A0 // Potentiometer +long randNumber; +int oldrandNumber; + + +const int BAUD_RATE = 9600; + + +int old_button_state = LOW; +int current_button_state = LOW; + + +byte logo[] = { + B11000011, + B11000011, + B00000000, + B00000011, + B11000011, + B11100111, + B01111110, + B00111100 +}; +byte D[] = { + B11111100, + B11111110, + B11000111, + B11000011, + B11000011, + B11000111, + B11111110, + B11111100 +}; +byte I[] = { + B00111100, + B00111100, + B00011000, + B00011000, + B00011000, + B00011000, + B00111100, + B00111100 +}; +byte C[] = { + B01111110, + B11111111, + B11000011, + B11000000, + B11000000, + B11000011, + B11111111, + B01111110 +}; +byte E[] = { + B11111110, + B11111110, + B11000000, + B11111000, + B11111000, + B11000000, + B11111110, + B11111110 +}; + +byte one[] = { + B00000000, + B00000000, + B00000000, + B00011000, + B00011000, + B00000000, + B00000000, + B00000000 +}; +byte two[] = { + B01100000, + B01100000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000110, + B00000110 +}; +byte three[] = { + B01100000, + B01100000, + B00000000, + B00011000, + B00011000, + B00000000, + B00000110, + B00000110 +}; +byte four[] = { + B01100110, + B01100110, + B00000000, + B00000000, + B00000000, + B00000000, + B01100110, + B01100110 +}; +byte five[] = { + B01100110, + B01100110, + B00000000, + B00011000, + B00011000, + B00000000, + B01100110, + B01100110 +}; +byte six[] = { + B01100110, + B01100110, + B00000000, + B01100110, + B01100110, + B00000000, + B01100110, + B01100110 +}; + + +static const int DATA_PIN = 20; +static const int CLK_PIN = 5; +static const int CS_PIN = 21; + +LedControl lc=LedControl(DATA_PIN, CLK_PIN, CS_PIN, 1); + +void setSprite(byte *sprite) { + for (int r = 0; r < 8; r++) { + lc.setColumn(0, 7 - r, sprite[r]); + } +} + + +void setup() { + // The MAX72XX is in power-saving mode on startup, + // we have to do a wakeup call + // pinMode(POTPIN, INPUT); + randomSeed(analogRead(5)); + Serial.begin(BAUD_RATE); + lc.shutdown(0, false); + // Set the brightness to a medium values + lc.setIntensity(0, 5); + // and clear the display + lc.clearDisplay(0); + randomSeed(analogRead(0)); + //#ifdef DEBUG + Serial.println("GO"); + //#endif + + lc.setIntensity(0, 15); + setSprite(logo); + delay(500); + lc.clearDisplay(0); + lc.setIntensity(0, 13); + setSprite(D); + delay(500); + lc.clearDisplay(0); + lc.setIntensity(0, 11); + setSprite(I); + delay(500); + lc.clearDisplay(0); + lc.setIntensity(0, 9); + setSprite(C); + delay(500); + lc.clearDisplay(0); + lc.setIntensity(0, 7); + setSprite(E); + delay(500); + lc.clearDisplay(0); + lc.setIntensity(0, 5); + delay(2000); +} + + +void loop() { + int current_button_state = digitalRead(BUTTON_PIN); + + if (current_button_state == HIGH && old_button_state != current_button_state) { + randomdice(); + delay(50); + old_button_state = current_button_state; + } + else + rolldice(); +}; + + +void rolldice() { + int current_button_state = digitalRead(BUTTON_PIN); + + if (current_button_state == HIGH && old_button_state != current_button_state) { + randomdice(); + delay(50); + } + // for (int i = 0; i <= 6; i++) { + setSprite(one); + delay(10); + //lc.clearDisplay(0); + setSprite(two); + delay(10); + //lc.clearDisplay(0); + setSprite(three); + delay(10); + //lc.clearDisplay(0); + setSprite(four); + delay(10); + //lc.clearDisplay(0); + setSprite(five); + delay(10); + //lc.clearDisplay(0); + setSprite(six); + delay(10); + //lc.clearDisplay(0); + // } + old_button_state = current_button_state; +} + + + + +void randomdice() { + lc.setIntensity(0, 15); + randNumber = random(1, 6); + Serial.println(randNumber); + if (randNumber == oldrandNumber) + { + Serial.println("dubble roll"); + } + + if (randNumber == 1) + { + Serial.println("11"); + setSprite(one); + // delay(500); + // lc.clearDisplay(0); + } + if (randNumber == 2) + { + Serial.println("22"); + setSprite(two); + // delay(500); + // lc.clearDisplay(0); + } + if (randNumber == 3) + { + Serial.println("33"); + setSprite(three); + // delay(500); + // lc.clearDisplay(0); + } + if (randNumber == 4) + { + Serial.println("44"); + setSprite(four); + // delay(500); + // lc.clearDisplay(0); + } + if (randNumber == 5) + { + Serial.println("55"); + setSprite(five); + // delay(500); + // lc.clearDisplay(0); + } + if (randNumber == 6) + { + Serial.println("66"); + setSprite(six); + // delay(500); + // lc.clearDisplay(0); + + } + delay(2000); + lc.setIntensity(0, 5); + + //else; + oldrandNumber = randNumber; + + +} diff --git a/software/ijhack/ijhack.ino b/software/ijhack/ijhack.ino deleted file mode 100644 index 65b9f26..0000000 --- a/software/ijhack/ijhack.ino +++ /dev/null @@ -1,2276 +0,0 @@ - -/* IJduino 1.0 -Requires: -* 8X8 LED grid MAX7219 -* Mini Breadboard -* Atmega328 -* Button -* 2 Wires -* 4.5 Volt - (c) IJhack 2014 GNU GPL - http://ijhack.org/ -*/ -#include "LedControl.h" - -/* using VCC, GND, DIN 21, CS 21, CLK 5 for the MAX7219 */ -LedControl lc=LedControl(20,5,21,1); - -int lowPin = 11; /* ground pin for the buton ;-) */ -int buttonPin = 9; /* choose the input pin for the pushbutton */ - -int animations = 13; /* the number of animations we have */ - -int lastButtonState = LOW; /* the previous reading from the input pin */ -long lastDebounceTime = 0; /* the last time the output pin was toggled */ -long debounceDelay = 50; /* the debounce time; increase if the output flickers */ -int anicount = 0; -int buttonState = LOW; - -void setup() { - /* - The MAX72XX is in power-saving mode on startup, - we have to do a wakeup call - */ - lc.shutdown(0,false); - /* Set the brightness to a medium values */ - lc.setIntensity(0,15); - /* and clear the display */ - lc.clearDisplay(0); - /* setup pins */ - pinMode(buttonPin, INPUT_PULLUP); - pinMode(lowPin, OUTPUT); - digitalWrite(lowPin, LOW); -} - -void loop() { - switch (anicount) { - case 0: - ijhacklogo(); - break; - case 1: - ghost(); - break; - case 2: - invade(); - break; - case 3: - heart(); - break; - case 4: - invadesquid(); - break; - case 5: - jumper(); - break; - case 6: - ijlogowink(); - break; - case 7: - heartbeat(); - break; - case 8: - eq(); - break; - case 9: - invaderagain(); - break; - case 10: - pong(); - break; - case 11: - snake(); - break; - case 12: - arrows(); - break; - case 13: - directions(); - break; - } -} - -bool render(byte* animation, int delaytime) { - lc.setColumn(0,0,animation[7]); - lc.setColumn(0,1,animation[6]); - lc.setColumn(0,2,animation[5]); - lc.setColumn(0,3,animation[4]); - lc.setColumn(0,4,animation[3]); - lc.setColumn(0,5,animation[2]); - lc.setColumn(0,6,animation[1]); - lc.setColumn(0,7,animation[0]); - - long startTime = millis(); - while ((startTime + delaytime) > millis()){ - - // read the state of the switch into a local variable: - int reading = digitalRead(buttonPin); - - // check to see if you just pressed the button - // (i.e. the input went from HIGH to LOW), and you've waited - // long enough since the last press to ignore any noise: - - // If the switch changed, due to noise or pressing: - if (reading != lastButtonState) { - // reset the debouncing timer - lastDebounceTime = millis(); - } - - if ((millis() - lastDebounceTime) > debounceDelay) { - // whatever the reading is at, it's been there for longer - // than the debounce delay, so take it as the actual current state: - - // if the button state has changed: - if (reading != buttonState) { - buttonState = reading; - - // only toggle the animation if the new button state is HIGH - if (buttonState == LOW) { - anicount++; - if (anicount > animations) { - anicount = 0; - } - return true; - } - } - } - - // save the reading. Next time through the loop, - // it'll be the lastButtonState: - lastButtonState = reading; - } - return false; /* don't skip the rest */ -} - -void invade() { - byte invade[8]={ -B00100100, -B00100100, -B01111110, -B11011011, -B11111111, -B11111111, -B10100101, -B00100100}; - -byte devade[8]={ -B00100100, -B10100101, -B11111111, -B11011011, -B11111111, -B01111110, -B00100100, -B00100100}; - - bool skip = render(invade, 500); - if (skip) { - return; - } - render(devade, 500); -} - -void invadesquid() { - byte invadesquid[8]={ -B00011000, -B00111100, -B01111110, -B11011011, -B11111111, -B01011010, -B10000001, -B01000010}; - - byte devadesquid[8]={ -B00011000, -B00111100, -B01111110, -B11011011, -B11111111, -B00100100, -B01011010, -B10100101}; - - bool skip = render(invadesquid, 500); - if (skip) { - return; - } - render(devadesquid, 500); -} - -void ghost() { - - byte ghost1[8]={ -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000}; - - byte ghost2[8]={ -B00000000, -B00000000, -B10000000, -B10000000, -B10000000, -B10000000, -B10000000, -B10000000}; - - byte ghost3[8]={ -B00000000, -B10000000, -B11000000, -B01000000, -B11000000, -B11000000, -B11000000, -B01000000}; - - byte ghost4[8]={ -B10000000, -B11000000, -B01100000, -B00100000, -B11100000, -B01100000, -B11100000, -B00100000}; - - byte ghost5[8]={ -B11000000, -B11100000, -B10110000, -B10010000, -B11110000, -B00110000, -B11110000, -B01010000}; - - byte ghost6[8]={ -B11100000, -B11110000, -B01011000, -B01001000, -B11111000, -B00011000, -B11111000, -B10101000}; - - byte ghost7[8]={ -B01110000, -B11111000, -B10101100, -B00100100, -B11111100, -B10001100, -B11111100, -B01010100}; - - byte ghost8[8]={ -B00111000, -B01111100, -B11010110, -B10010010, -B11111110, -B11000110, -B11111110, -B10101010}; - -byte ghost9[8]={ -B00011100, -B00111110, -B01101011, -B01001001, -B01111111, -B01100011, -B01111111, -B01010101}; - -byte ghost9a[8]={ -B00011100, -B00111110, -B01101101, -B01001001, -B01111111, -B01100011, -B01111111, -B01010101}; - -byte ghost9b[8]={ -B00011100, -B00111110, -B01011011, -B01001001, -B01111111, -B01100011, -B01111111, -B01010101}; - -byte ghost9c[8]={ -B00011100, -B00111110, -B01001001, -B01011011, -B01111111, -B01100011, -B01111111, -B01010101}; - -byte ghost9d[8]={ -B00011100, -B00111110, -B01001001, -B01101101, -B01111111, -B01100011, -B01111111, -B01010101}; - -byte ghost9e[8]={ -B00011100, -B00111110, -B01101101, -B01001001, -B01111111, -B01100011, -B01111111, -B01010101}; - -byte ghost10[8]={ -B00001110, -B00011111, -B00110101, -B00100100, -B00111111, -B00110001, -B00111111, -B00101010}; - -byte ghost11[8]={ -B00000111, -B00001111, -B00011010, -B00010010, -B00011111, -B00011000, -B00011111, -B00010101}; - -byte ghost12[8]={ -B00000011, -B00000111, -B00001101, -B00001001, -B00001111, -B00001100, -B00001111, -B00001010}; - -byte ghost13[8]={ -B00000001, -B00000011, -B00000110, -B00000100, -B00000111, -B00000110, -B00000111, -B00000101}; - -byte ghost14[8]={ -B00000000, -B00000001, -B00000011, -B00000010, -B00000011, -B00000011, -B00000011, -B00000010}; - -byte ghost15[8]={ -B00000000, -B00000000, -B00000001, -B00000001, -B00000001, -B00000001, -B00000001, -B00000001}; - - -byte ghost16[8]={ -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000}; - - bool skip; - skip = render(ghost1, 200); - if (skip) { - return; - } - skip = render(ghost2, 200); - if (skip) { - return; - } - skip = render(ghost3, 200); - if (skip) { - return; - } - skip = render(ghost4, 200); - if (skip) { - return; - } - skip = render(ghost5, 200); - if (skip) { - return; - } - skip = render(ghost6, 200); - if (skip) { - return; - } - skip = render(ghost7, 200); - if (skip) { - return; - } - skip = render(ghost8, 200); - if (skip) { - return; - } - skip = render(ghost9, 200); - if (skip) { - return; - } - skip = render(ghost9a, 200); - if (skip) { - return; - } - skip = render(ghost9b, 200); - if (skip) { - return; - } - skip = render(ghost9c, 200); - if (skip) { - return; - } - skip = render(ghost9d, 200); - if (skip) { - return; - } - skip = render(ghost9e, 200); - if (skip) { - return; - } - skip = render(ghost9a, 200); - if (skip) { - return; - } - skip = render(ghost9b, 200); - if (skip) { - return; - } - skip = render(ghost9c, 200); - if (skip) { - return; - } - skip = render(ghost9d, 200); - if (skip) { - return; - } - skip = render(ghost9e, 200); - if (skip) { - return; - } - skip = render(ghost9a, 200); - if (skip) { - return; - } - skip = render(ghost9b, 200); - if (skip) { - return; - } - skip = render(ghost9c, 200); - if (skip) { - return; - } - skip = render(ghost9d, 200); - if (skip) { - return; - } - skip = render(ghost9e, 200); - if (skip) { - return; - } - skip = render(ghost9, 200); - if (skip) { - return; - } - skip = render(ghost10, 200); - if (skip) { - return; - } - skip = render(ghost11, 200); - if (skip) { - return; - } - skip = render(ghost12, 200); - if (skip) { - return; - } - skip = render(ghost13, 200); - if (skip) { - return; - } - skip = render(ghost14, 200); - if (skip) { - return; - } - skip = render(ghost15, 200); - if (skip) { - return; - } - render(ghost16, 200); -} - -void ijlogowink() { - byte logowink0[8]={ -B11000011, -B11000011, -B00000000, -B00000011, -B11000011, -B11100111, -B01111110, -B00111100}; - - byte logowink1[8]={ -B00000011, -B00000011, -B00000000, -B00000011, -B11000011, -B11100111, -B01111110, -B00111100}; - - byte logowink2[8]={ -B11000000, -B11000000, -B00000000, -B00000011, -B11000011, -B11100111, -B01111110, -B00111100}; - - byte logowink3[8]={ -B11000011, -B11000011, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000}; - - bool skip; - skip = render(logowink0, 500); - if (skip) { - return; - } - skip = render(logowink1, 500); - if (skip) { - return; - } - skip = render(logowink0, 500); - if (skip) { - return; - } - skip = render(logowink2, 500); - if (skip) { - return; - } - skip = render(logowink0, 500); - if (skip) { - return; - } - skip = render(logowink3, 500); -} -void ijhacklogo() { - /* here is the data for the characters */ - byte ij[8]={ -B11000011, -B11000011, -B00000000, -B00000011, -B11000011, -B11100111, -B01111110, -B00111100}; - - byte h[8]={ -B11000011, -B11000011, -B11000011, -B11111111, -B11111111, -B11000011, -B11000011, -B11000011 }; - - byte a[8]={ -B00011000, -B00111100, -B01100110, -B11000011, -B11111111, -B11111111, -B11000011, -B11000011 }; - - byte c[8]={ -B01111110, -B11111111, -B11000011, -B11000000, -B11000000, -B11000011, -B11111111, -B01111110 }; - - byte k[8]={ -B11000111, -B11011110, -B11111100, -B11110000, -B11110000, -B11111100, -B11011110, -B11000111 - }; - - bool skip; - skip = render(ij, 500); - if (skip) { - return; - } - skip = render(h, 500); - if (skip) { - return; - } - skip = render(a, 500); - if (skip) { - return; - } - skip = render(c, 500); - if (skip) { - return; - } - render(k, 500); -} - -void heart() { - - /* here is the data for the characters */ - byte heart2[8]={B00000000, -B01100110, -B10011001, -B10000001, -B10000001, -B01000010, -B00100100, -B00011000}; - - /* here is the data for the characters */ - byte heart1[8]={ -B00000000, -B01100110, -B11111111, -B11111111, -B11111111, -B01111110, -B00111100, -B00011000}; - - bool skip = render(heart1, 500); - if (skip) { - return; - } - render(heart2, 500); -} - -void jumper() { - byte jumpdown[8]={ -B00111100, -B00111100, -B00011000, -B01111110, -B00011000, -B00011000, -B00100100, -B00100100}; - - byte jumpup[8]={ -B00111100, -B01011010, -B00111100, -B00011000, -B00011000, -B00100100, -B01000010, -B00000000}; - - bool skip = render(jumpdown, 500); - if (skip) { - return; - } - render(jumpup, 500); -} - -void heartbeat() { - byte heart1[8]={ -B00000000, -B00000100, -B00000110, -B00000101, -B11100100, -B00010100, -B00001100, -B00000100}; - - byte heart2[8]={ -B00000000, -B00000010, -B00000011, -B00000010, -B11110010, -B00001010, -B00000110, -B00000010}; - - byte heart3[8]={ -B00000000, -B00000001, -B00000001, -B00000001, -B11111001, -B00000101, -B00000011, -B00000001}; - - byte heart4[8]={ -B00000000, -B00000000, -B00000000, -B00000000, -B11111100, -B00000010, -B00000001, -B00000000}; - - byte heart5[8]={ -B00000000, -B00000000, -B00000000, -B00000000, -B11111110, -B00000001, -B00000000, -B00000000}; - - byte heart6[8]={ -B00000000, -B00000000, -B00000000, -B00000000, -B11111111, -B00000000, -B00000000, -B00000000}; - - byte heart7[8]={ -B00000000, -B00000000, -B00000000, -B10000000, -B01111111, -B00000000, -B00000000, -B00000000}; - - byte heart8[8]={ -B00000000, -B00000000, -B10000000, -B01000000, -B00111111, -B00000000, -B00000000, -B00000000}; - - byte heart9[8]={ -B00000000, -B10000000, -B11000000, -B10100000, -B10011111, -B10000000, -B10000000, -B10000000}; - - byte heart10[8]={ -B00000000, -B01000000, -B01100000, -B01010000, -B01001111, -B01000000, -B11000000, -B01000000}; - - byte heart11[8]={ -B00000000, -B00100000, -B00110000, -B00101000, -B00100111, -B10100000, -B01100000, -B00100000}; - - byte heart12[8]={ -B00000000, -B00010000, -B00011000, -B00010100, -B10010011, -B01010000, -B00110000, -B00010000}; - - byte heart13[8]={ -B00000000, -B00001000, -B00001100, -B00001010, -B11001001, -B00101000, -B00011000, -B00001000}; - - bool skip; - skip = render(heart6, 100); - if (skip) { - return; - } - skip = render(heart6, 100); - if (skip) { - return; - } - skip = render(heart7, 100); - if (skip) { - return; - } - skip = render(heart8, 100); - if (skip) { - return; - } - skip = render(heart9, 100); - if (skip) { - return; - } - skip = render(heart10, 100); - if (skip) { - return; - } - skip = render(heart11, 100); - if (skip) { - return; - } - skip = render(heart12, 100); - if (skip) { - return; - } - skip = render(heart13, 100); - if (skip) { - return; - } - skip = render(heart1, 100); - if (skip) { - return; - } - skip = render(heart2, 100); - if (skip) { - return; - } - skip = render(heart3, 100); - if (skip) { - return; - } - skip = render(heart4, 100); - if (skip) { - return; - } - skip = render(heart5, 100); - if (skip) { - return; - } - render(heart6, 100); -} - -void eq() { - byte eq1[8]={ -B00000000, -B00001100, -B11001100, -B11001100, -B11111100, -B11111100, -B11111111, -B11111111}; - - byte eq2[8]={ -B00000000, -B00001100, -B11001100, -B11001100, -B11111100, -B11111100, -B11111111, -B11111111}; - - byte eq3[8]={ -B00000000, -B00001100, -B11001100, -B11001100, -B11111100, -B11111100, -B11111111, -B11111111}; - - byte eq4[8]={ -B00000000, -B00000000, -B00001100, -B11001100, -B11001100, -B11111111, -B11111111, -B11111111}; - - byte eq5[8]={ -B00000000, -B00000000, -B00000000, -B00001100, -B11001111, -B11001111, -B11111111, -B11111111}; - - byte eq6[8]={ -B00000000, -B00000000, -B00000000, -B00000011, -B00001111, -B11001111, -B11001111, -B11111111}; - - byte eq7[8]={ -B00000000, -B00000000, -B00000011, -B00000011, -B00001111, -B00001111, -B11001111, -B11001111}; - - byte eq8[8]={ -B00000000, -B00000000, -B00000000, -B00000011, -B00000011, -B00001111, -B00001111, -B11111111}; - - byte eq9[8]={ -B00000000, -B00000000, -B00000000, -B00000000, -B00000011, -B00000011, -B00111111, -B11111111}; - - byte eq10[8]={ -B00000000, -B00000000, -B00000000, -B00000000, -B00000011, -B00000011, -B00111111, -B11111111}; - - byte eq11[8]={ -B00000000, -B00000000, -B00000000, -B00000000, -B00000011, -B00001111, -B11001111, -B11111111}; - - byte eq12[8]={ -B00000000, -B00000000, -B00000000, -B00000000, -B00001100, -B11001111, -B11111111, -B11111111}; - - byte eq13[8]={ -B00000000, -B00000000, -B00000000, -B00001100, -B11001100, -B11111111, -B11111111, -B11111111}; - - byte eq14[8]={ -B00000000, -B00000000, -B00001100, -B11001100, -B11001100, -B11111111, -B11111111, -B11111111}; - - byte eq15[8]={ -B00000000, -B00001100, -B11001100, -B11001100, -B11001100, -B11111100, -B11111111, -B11111111}; - - bool skip; - skip = render(eq1, 50); - if (skip) { - return; - } - skip = render(eq2, 50); - if (skip) { - return; - } - skip = render(eq3, 50); - if (skip) { - return; - } - skip = render(eq4, 50); - if (skip) { - return; - } - skip = render(eq5, 50); - if (skip) { - return; - } - skip = render(eq6, 50); - if (skip) { - return; - } - skip = render(eq7, 50); - if (skip) { - return; - } - skip = render(eq8, 50); - if (skip) { - return; - } - skip = render(eq9, 50); - if (skip) { - return; - } - skip = render(eq10, 50); - if (skip) { - return; - } - skip = render(eq11, 50); - if (skip) { - return; - } - skip = render(eq12, 50); - if (skip) { - return; - } - skip = render(eq13, 50); - if (skip) { - return; - } - skip = render(eq14, 50); - if (skip) { - return; - } - render(eq15, 50); -} - - - -void invaderagain() { - byte invader1[8]={ -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000}; - - byte invader2[8]={ -B00000000, -B00000000, -B10000000, -B10000000, -B10000000, -B10000000, -B10000000, -B10000000}; - - byte invader3[8]={ -B00000000, -B10000000, -B11000000, -B11000000, -B01000000, -B01000000, -B01000000, -B11000000}; - - byte invader4[8]={ -B10000000, -B11000000, -B01100000, -B11100000, -B10100000, -B00100000, -B00100000, -B01100000}; - - byte invader5[8]={ -B01000000, -B11100000, -B10110000, -B11110000, -B01010000, -B10010000, -B00010000, -B00110000}; - - byte invader6[8]={ -B00100000, -B11110000, -B11011000, -B11111000, -B00101000, -B11001000, -B00001000, -B00011000}; - - byte invader7[8]={ -B10010000, -B11111000, -B01101100, -B11111100, -B10010100, -B01100100, -B00000100, -B00001100}; - - byte invader8[8]={ -B01001000, -B11111100, -B10110110, -B11111110, -B01001010, -B00110010, -B00000010, -B10000110}; - - byte invader9[8]={ -B00100100, -B01111110, -B11011011, -B11111111, -B10100101, -B10011001, -B10000001, -B11000011}; - - byte invader9a[8]={ -B00100100, -B00011000, -B01111110, -B11011011, -B11111111, -B11011011, -B10011001, -B11000011}; - - byte invader10[8]={ -B00010010, -B00111111, -B01101101, -B01111111, -B01010010, -B01001100, -B01000000, -B01100001}; - - - byte invader11[8]={ -B00001001, -B00011111, -B00110110, -B00111111, -B00101001, -B00100110, -B00100000, -B00110000}; - - - - byte invader12[8]={ -B00000100, -B00001111, -B00011011, -B00011111, -B00010100, -B00010011, -B00010000, -B00011000}; - - byte invader13[8]={ -B00000010, -B00000111, -B00001101, -B00001111, -B00001010, -B00001001, -B00001000, -B00001100}; - - - byte invader14[8]={ -B00000001, -B00000011, -B00000110, -B00000111, -B00000101, -B00000100, -B00000100, -B00000110}; - - byte invader15[8]={ -B00000000, -B00000001, -B00000011, -B00000011, -B00000010, -B00000010, -B00000010, -B00000011}; - - byte invader16[8]={ -B00000000, -B00000000, -B00000001, -B00000001, -B00000001, -B00000001, -B00000001, -B00000001}; - - bool skip; - skip = render(invader1, 200); - if (skip) { - return; - } - skip = render(invader2, 200); - if (skip) { - return; - } - skip = render(invader3, 200); - if (skip) { - return; - } - skip = render(invader4, 200); - if (skip) { - return; - } - skip = render(invader5, 200); - if (skip) { - return; - } - skip = render(invader6, 200); - if (skip) { - return; - } - skip = render(invader7, 200); - if (skip) { - return; - } - skip = render(invader8, 200); - if (skip) { - return; - } - skip = render(invader9, 200); - if (skip) { - return; - } - skip = render(invader9a, 200); - if (skip) { - return; - } - skip = render(invader9, 200); - if (skip) { - return; - } - skip = render(invader9a, 200); - if (skip) { - return; - } - skip = render(invader9, 200); - if (skip) { - return; - } - skip = render(invader9a, 200); - if (skip) { - return; - } - skip = render(invader9, 200); - if (skip) { - return; - } - skip = render(invader10, 200); - if (skip) { - return; - } - skip = render(invader11, 200); - if (skip) { - return; - } - skip = render(invader12, 200); - if (skip) { - return; - } - skip = render(invader13, 200); - if (skip) { - return; - } - skip = render(invader14, 200); - if (skip) { - return; - } - skip = render(invader15, 200); - if (skip) { - return; - } - skip = render(invader16, 200); - if (skip) { - return; - } - render(invader1, 200); -} - - -void pong() { - byte pong1[8]={ -B00111000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00011100}; - - byte pong2[8]={ -B00111000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000001, -B00000000, -B00001110}; - - byte pong3[8]={ -B00111000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000010, -B00000111}; - - - byte pong4[8]={ -B00111000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000100, -B00000000, -B00000111}; - - byte pong5[8]={ -B00111000, -B00000000, -B00000000, -B00000000, -B00001000, -B00000000, -B00000000, -B00000111}; - - byte pong6[8]={ -B00111000, -B00000000, -B00000000, -B00010000, -B00000000, -B00000000, -B00000000, -B00001110}; - - byte pong7[8]={ -B01110000, -B00000000, -B00100000, -B00000000, -B00000000, -B00000000, -B00000000, -B00001110}; - - byte pong8[8]={ -B11100000, -B01000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00011100}; - - byte pong9[8]={ -B11100000, -B00000000, -B00100000, -B00000000, -B00000000, -B00000000, -B00000000, -B00011100}; - - byte pong10[8]={ -B11100000, -B00000000, -B00000000, -B00010000, -B00000000, -B00000000, -B00000000, -B00111000}; - - byte pong11[8]={ -B01110000, -B00000000, -B00000000, -B00000000, -B00001000, -B00000000, -B00000000, -B01110000}; - - byte pong12[8]={ -B01110000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000100, -B00000000, -B00111000}; - - byte pong13[8]={ -B01110000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000010, -B00011100}; - - byte pong14[8]={ -B00111000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00011101}; - - bool skip; - skip = render(pong1, 200); - if (skip) { - return; - } - skip = render(pong2, 200); - if (skip) { - return; - } - skip = render(pong3, 200); - if (skip) { - return; - } - skip = render(pong4, 200); - if (skip) { - return; - } - skip = render(pong5, 200); - if (skip) { - return; - } - skip = render(pong6, 200); - if (skip) { - return; - } - skip = render(pong7, 200); - if (skip) { - return; - } - skip = render(pong8, 200); - if (skip) { - return; - } - skip = render(pong9, 200); - if (skip) { - return; - } - skip = render(pong10, 200); - if (skip) { - return; - } - skip = render(pong11, 200); - if (skip) { - return; - } - skip = render(pong12, 200); - if (skip) { - return; - } - skip = render(pong13, 200); - if (skip) { - return; - } - skip = render(pong14, 200); -} - - -void snake() { - byte snake1[8]={ -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000}; - - byte snake2[8]={ -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000001, -B00000000}; - - byte snake3[8]={ -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000011, -B00000000}; - - byte snake4[8]={ -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000111, -B00000000}; - - byte snake5[8]={ -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00001110, -B00000000}; - - byte snake6[8]={ -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00011100, -B00000000}; - - byte snake7[8]={ -B00000000, -B00000000, -B01000000, -B00000000, -B00000000, -B00000000, -B00111000, -B00000000}; - - byte snake8[8]={ -B00000000, -B00000000, -B01000000, -B00000000, -B00000000, -B00100000, -B00110000, -B00000000}; - - byte snake9[8]={ -B00000000, -B00000000, -B01000000, -B00000000, -B00100000, -B00100000, -B00100000, -B00000000}; - - byte snake10[8]={ -B00000000, -B00000000, -B01000000, -B00100000, -B00100000, -B00100000, -B00000000, -B00000000}; - - byte snake11[8]={ -B00000000, -B00000000, -B01100000, -B00100000, -B00100000, -B00000000, -B00000000, -B00000000}; - - byte snake12[8]={ -B00000000, -B01000000, -B01100000, -B00100000, -B00100000, -B00000000, -B00000000, -B00000000}; - - byte snake13[8]={ -B01000000, -B01000000, -B01100000, -B00100000, -B00000000, -B00000000, -B00000000, -B00000000}; - - byte snake14[8]={ -B01100000, -B01000000, -B01100000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000}; - - byte snake15[8]={ -B01110000, -B01000000, -B01000000, -B00000000, -B00000100, -B00000000, -B00000000, -B00000000}; - - byte snake16[8]={ -B01111000, -B01000000, -B00000000, -B00000000, -B00000100, -B00000000, -B00000000, -B00000000}; - - byte snake17[8]={ -B01111100, -B00000000, -B00000000, -B00000000, -B00000100, -B00000000, -B00000000, -B00000000}; - - byte snake18[8]={ -B00111100, -B00000100, -B00000000, -B00000000, -B00000100, -B00000000, -B00000000, -B00000000}; - - byte snake19[8]={ -B00011100, -B00000100, -B00000100, -B00000000, -B00000100, -B00000000, -B00000000, -B00000000}; - - byte snake20[8]={ -B00001100, -B00000100, -B00000100, -B00000100, -B00000100, -B00000000, -B00000000, -B00000000}; - - byte snake21[8]={ -B00001100, -B00000100, -B00000100, -B00000100, -B00000100, -B00000100, -B00000000, -B00000000}; - - byte snake22[8]={ -B00000100, -B00000100, -B00000100, -B00000100, -B00000100, -B00000100, -B00000100, -B00000000}; - - byte snake23[8]={ -B00000000, -B00000100, -B00000100, -B00100100, -B00000100, -B00000100, -B00001100, -B00000000}; - - byte snake24[8]={ -B00000000, -B00000000, -B00000100, -B00100100, -B00000100, -B00000100, -B00011100, -B00000000}; - - byte snake25[8]={ -B00000000, -B00000000, -B00000000, -B00100100, -B00000100, -B00010100, -B00011100, -B00000000}; - - byte snake26[8]={ -B00000000, -B00000000, -B00000000, -B00100000, -B00010100, -B00010100, -B00011100, -B00000000}; - - byte snake27[8]={ -B00000000, -B00000000, -B00000000, -B00100000, -B00110000, -B00010100, -B00011100, -B00000000}; - - byte snake28[8]={ -B00000000, -B00000000, -B00000000, -B01100000, -B00110000, -B00010100, -B00011100, -B00000000}; - - byte snake29[8]={ -B00000000, -B00000000, -B00000000, -B11100000, -B00110000, -B00010100, -B00011100, -B00000000}; - - - byte snake30[8]={ -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000}; - - bool skip; - skip = render(snake1, 200); - if (skip) { - return; - } - skip = render(snake2, 200); - if (skip) { - return; - } - skip = render(snake3, 200); - if (skip) { - return; - } - skip = render(snake4, 200); - if (skip) { - return; - } - skip = render(snake5, 200); - if (skip) { - return; - } - skip = render(snake6, 200); - if (skip) { - return; - } - skip = render(snake7, 200); - if (skip) { - return; - } - skip = render(snake8, 200); - if (skip) { - return; - } - skip = render(snake9, 200); - if (skip) { - return; - } - skip = render(snake10, 200); - if (skip) { - return; - } - skip = render(snake11, 200); - if (skip) { - return; - } - skip = render(snake12, 200); - if (skip) { - return; - } - skip = render(snake13, 200); - if (skip) { - return; - } - skip = render(snake14, 200); - if (skip) { - return; - } - skip = render(snake15, 200); - if (skip) { - return; - } - skip = render(snake16, 200); - if (skip) { - return; - } - skip = render(snake17, 200); - if (skip) { - return; - } - skip = render(snake18, 200); - if (skip) { - return; - } - skip = render(snake19, 200); - if (skip) { - return; - } - skip = render(snake20, 200); - if (skip) { - return; - } - skip = render(snake21, 200); - if (skip) { - return; - } - skip = render(snake22, 200); - if (skip) { - return; - } - skip = render(snake23, 200); - if (skip) { - return; - } - skip = render(snake24, 200); - if (skip) { - return; - } - skip = render(snake25, 200); - if (skip) { - return; - } - skip = render(snake26, 200); - if (skip) { - return; - } - skip = render(snake27, 200); - if (skip) { - return; - } - skip = render(snake28, 200); - if (skip) { - return; - } - skip = render(snake29, 200); - if (skip) { - return; - } - skip = render(snake30, 200); - if (skip) { - return; - } - skip = render(snake29, 200); - if (skip) { - return; - } - skip = render(snake30, 200); - if (skip) { - return; - } - skip = render(snake29, 200); - if (skip) { - return; - } - skip = render(snake30, 200); -} - - - - - -void arrows() { - byte arrowup[8]={ -B00000000, -B00011000, -B00111100, -B01111110, -B00011000, -B00011000, -B00011000, -B00000000}; - - byte arrowdown[8]={ -B00000000, -B00011000, -B00011000, -B00011000, -B01111110, -B00111100, -B00011000, -B00000000}; - - byte arrowright[8]={ -B00000000, -B00001000, -B00001100, -B01111110, -B01111110, -B00001100, -B00001000, -B00000000}; - - - byte arrowleft[8]={ -B00000000, -B00010000, -B00110000, -B01111110, -B01111110, -B00110000, -B00010000, -B00000000}; - - bool skip; - skip = render(arrowup, 200); - if (skip) { - return; - } - skip = render(arrowright, 200); - if (skip) { - return; - } - skip = render(arrowdown, 200); - if (skip) { - return; - } - skip = render(arrowleft, 200); -} - - -void directions() { - byte directions1[8]={ -B00000000, -B00000000, -B00000000, -B10000000, -B00000000, -B00000000, -B00000000, -B00000000}; - - byte directions2[8]={ -B00000000, -B00000000, -B10000000, -B01000000, -B10000000, -B00000000, -B00000000, -B00000000}; - - byte directions3[8]={ -B00000000, -B10000000, -B01000000, -B00100000, -B01000000, -B10000000, -B00000000, -B00000000}; - - byte directions4[8]={ -B10000000, -B01000000, -B00100000, -B00010000, -B00100000, -B01000000, -B10000000, -B00000000}; - - byte directions5[8]={ -B01000000, -B00100000, -B00010000, -B00001000, -B00010000, -B00100000, -B01000000, -B00000000}; - - byte directions6[8]={ -B00100000, -B00010000, -B00001000, -B00000100, -B00001000, -B00010000, -B00100000, -B00000000}; - - byte directions7[8]={ -B00010000, -B00001000, -B00000100, -B00000010, -B00000100, -B00001000, -B00010000, -B00000000}; - - byte directions8[8]={ -B00001000, -B00000100, -B00000010, -B00000001, -B00000010, -B00000100, -B00001000, -B00000000}; - - byte directions9[8]={ -B00000100, -B00000010, -B00000001, -B00000000, -B00000001, -B00000010, -B00000100, -B00000000}; - - byte directions10[8]={ -B00000010, -B00000001, -B00000000, -B00000000, -B00000000, -B00000001, -B00000010, -B00000000}; - - byte directions11[8]={ -B00000001, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000001, -B00000000}; - - byte directions12[8]={ -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000, -B00000000}; - - bool skip; - skip = render(directions1, 200); - if (skip) { - return; - } - skip = render(directions2, 200); - if (skip) { - return; - } - skip = render(directions3, 200); - if (skip) { - return; - } - skip = render(directions4, 200); - if (skip) { - return; - } - skip = render(directions5, 200); - if (skip) { - return; - } - skip = render(directions6, 200); - if (skip) { - return; - } - skip = render(directions7, 200); - if (skip) { - return; - } - skip = render(directions8, 200); - if (skip) { - return; - } - skip = render(directions9, 200); - if (skip) { - return; - } - skip = render(directions10, 200); - if (skip) { - return; - } - skip = render(directions11, 200); - if (skip) { - return; - } - skip = render(directions12, 200); -} - diff --git a/software/ijkanoid/ijkanoid.ino b/software/ijkanoid/ijkanoid.ino new file mode 100644 index 0000000..8c1db23 --- /dev/null +++ b/software/ijkanoid/ijkanoid.ino @@ -0,0 +1,299 @@ +/** +* IJkanoid on an 8x8 matrix +* +* NOT FINISHED YET !! +* +* 0 1 2 3 4 5 6 7 +* 0 +* 1 +* 2 7 0 1 +* 3 6 X 2 (directions) +* 4 5 4 3 +* 5 +* 6 +* 7 [pad] +* +* +* Based on pong code from +* http://www.itopen.it/2012/03/09/arduino-pong-with-8x8-led-matrix-and-max7219/ +* +*/ + + +#include "LedControl.h" +#include "Timer.h" + + +#define POTPIN A5 // Potentiometer +#define PADSIZE 3 +#define BALL_DELAY 200 +#define GAME_DELAY 10 +#define BOUNCE_VERTICAL 1 +#define BOUNCE_HORIZONTAL -1 +#define NEW_GAME_ANIMATION_SPEED 50 +#define HIT_NONE 0 +#define HIT_CENTER 1 +#define HIT_LEFT 2 +#define HIT_RIGHT 3 + + +//#define DEBUG 1 + +const byte sad[] = { +B00000000, +B01000100, +B00010000, +B00010000, +B00000000, +B00111000, +B01000100, +B00000000 +}; + +const byte smile[] = { +B00000000, +B01000100, +B00010000, +B00010000, +B00010000, +B01000100, +B00111000, +B00000000 +}; + + +Timer timer; + +LedControl lc = LedControl(20,5,21,1); + +byte direction; // Wind rose, 0 is north +int xball; +int yball; +int yball_prev; +byte xpad; +int ball_timer; + +void setSprite(const byte *sprite){ + for(int r = 0; r < 8; r++){ + lc.setColumn(0, 7-r, sprite[r]); + } +} + +void newGame() { + lc.clearDisplay(0); + // initial position + xball = random(1, 7); + yball = 4; + direction = random(3, 6); // Go south + for(int r = 0; r < 8; r++){ + for(int c = 0; c < 8; c++){ + lc.setLed(0, r, c, HIGH); + delay(NEW_GAME_ANIMATION_SPEED); + } + } + setSprite(smile); + delay(1500); + lc.clearDisplay(0); +} + +void setPad() { + xpad = map(analogRead(POTPIN), 0, 1020, 8 - PADSIZE, 0); +} + +void debug(const char* desc){ +#ifdef DEBUG + Serial.print(desc); + Serial.print(" XY: "); + Serial.print(xball); + Serial.print(", "); + Serial.print(yball); + Serial.print(" XPAD: "); + Serial.print(xpad); + Serial.print(" DIR: "); + Serial.println(direction); +#endif +} + +int checkBounce() { + if(!xball || !yball || xball == 7 || yball == 6){ + int bounce = (yball == 0 || yball == 6) ? BOUNCE_HORIZONTAL : BOUNCE_VERTICAL; +#ifdef DEBUG + debug(bounce == BOUNCE_HORIZONTAL ? "HORIZONTAL" : "VERTICAL"); +#endif + return bounce; + } + return 0; +} + +int getHit() { + if(yball != 6 || xball < xpad || xball > xpad + PADSIZE){ + return HIT_NONE; + } + if(xball == xpad + PADSIZE / 2){ + return HIT_CENTER; + } + return xball < xpad + PADSIZE / 2 ? HIT_LEFT : HIT_RIGHT; +} + +bool checkLoose() { + return yball == 6 && getHit() == HIT_NONE; +} + +void moveBall() { + debug("MOVE"); + int bounce = checkBounce(); + if(bounce) { + switch(direction){ + case 0: + direction = 4; + break; + case 1: + direction = (bounce == BOUNCE_VERTICAL) ? 7 : 3; + break; + case 2: + direction = 6; + break; + case 6: + direction = 2; + break; + case 7: + direction = (bounce == BOUNCE_VERTICAL) ? 1 : 5; + break; + case 5: + direction = (bounce == BOUNCE_VERTICAL) ? 3 : 7; + break; + case 3: + direction = (bounce == BOUNCE_VERTICAL) ? 5 : 1; + break; + case 4: + direction = 0; + break; + } + debug("->"); + } + + // Check hit: modify direction is left or right + switch(getHit()){ + case HIT_LEFT: + if(direction == 0){ + direction = 7; + } else if (direction == 1){ + direction = 0; + } + break; + case HIT_RIGHT: + if(direction == 0){ + direction = 1; + } else if(direction == 7){ + direction = 0; + } + break; + } + + // Check orthogonal directions and borders ... + if((direction == 0 && xball == 0) || (direction == 4 && xball == 7)){ + direction++; + } + if(direction == 0 && xball == 7){ + direction = 7; + } + if(direction == 4 && xball == 0){ + direction = 3; + } + if(direction == 2 && yball == 0){ + direction = 3; + } + if(direction == 2 && yball == 6){ + direction = 1; + } + if(direction == 6 && yball == 0){ + direction = 5; + } + if(direction == 6 && yball == 6){ + direction = 7; + } + + // "Corner" case + if(xball == 0 && yball == 0){ + direction = 3; + } + if(xball == 0 && yball == 6){ + direction = 1; + } + if(xball == 7 && yball == 6){ + direction = 7; + } + if(xball == 7 && yball == 0){ + direction = 5; + } + + yball_prev = yball; + if(2 < direction && direction < 6) { + yball++; + } else if(direction != 6 && direction != 2) { + yball--; + } + if(0 < direction && direction < 4) { + xball++; + } else if(direction != 0 && direction != 4) { + xball--; + } + xball = max(0, min(7, xball)); + yball = max(0, min(6, yball)); + debug("AFTER MOVE"); +} + +void gameOver() { + setSprite(sad); + delay(1500); + lc.clearDisplay(0); +} + +void drawGame() { + if(yball_prev != yball){ + lc.setColumn(0, 7-yball_prev, 0); + } + lc.setColumn(0, 7-yball, byte(1 << (xball))); + byte padmap = byte(0xFF >> (8 - PADSIZE) << xpad) ; +#ifdef DEBUG + //Serial.println(padmap, BIN); +#endif + lc.setColumn(0, 0, padmap); +} + +void setup() { + // The MAX72XX is in power-saving mode on startup, + // we have to do a wakeup call + pinMode(POTPIN, INPUT); + + lc.shutdown(0,false); + // Set the brightness to a medium values + lc.setIntensity(0, 8); + // and clear the display + lc.clearDisplay(0); + randomSeed(analogRead(0)); +#ifdef DEBUG + Serial.begin(9600); + Serial.println("Pong"); +#endif + newGame(); + ball_timer = timer.every(BALL_DELAY, moveBall); +} + + +void loop() { + timer.update(); + // Move pad + setPad(); +#ifdef DEBUG + Serial.println(xpad); +#endif + // Update screen + drawGame(); + if(checkLoose()) { + debug("LOOSE"); + gameOver(); + newGame(); + } + delay(GAME_DELAY); +} diff --git a/software/ijnimations/aliens.ino b/software/ijnimations/aliens.ino new file mode 100644 index 0000000..38b3c74 --- /dev/null +++ b/software/ijnimations/aliens.ino @@ -0,0 +1,338 @@ +/* + IJnimation Aliens by Einstein + */ +const byte alien1[8] PROGMEM = { + + // Animation bitmaps. Each frame of animation MUST contain + // 8 lines of graphics data (there is no error checking for + // length). Each line should be prefixed with the letter 'B', + // followed by exactly 8 binary digits (0 or 1), no more, + // no less (again, no error checking). '0' represents an + // 'off' pixel, '1' an 'on' pixel. End line with a comma. + B00011000, // This is the first frame for alien #1 + B00111100, // If you squint you can kind of see the + B01111110, // image in the 0's and 1's. + B11011011, + B11111111, + B00100100, + B01011010, + B10100101 + // The 9th line (required) is the time to display this frame, + // in 1/100ths of a second (e.g. 100 = 1 sec, 25 = 1/4 sec, + // etc.). Range is 0 (no delay) to 255 (2.55 seconds). If + // longer delays are needed, make duplicate frames. + //25, // 0.25 seconds +}; + +const byte alien2[8] PROGMEM = { + B00011000, // This is the second frame for alien #1 + B00111100, + B01111110, + B11011011, + B11111111, + B00100100, + B01011010, + B01000010 + //25, // 0.25 second delay +}; + +const byte alien3[8] PROGMEM = { + // Frames 3 & 4 for alien #1 are duplicates of frames 1 & 2. + // Rather than list them 'the tall way' again, the lines are merged here... + B00011000, + B00111100, + B01111110, + B11011011, + B11111111, + B00100100, + B01011010, + B10100101 +}; + +const byte alien4[8] PROGMEM = { + B00011000, + B00111100, + B01111110, + B11011011, + B11111111, + B00100100, + B01011010, + B01000010 +}; + +const byte alien5[8] PROGMEM = { + + B00000000, // First frame for alien #2 + B00111100, + B01111110, + B11011011, + B11011011, + B01111110, + B00100100, + B11000011 + //25, // 0.25 second delay +}; + +const byte alien6[8] PROGMEM = { + B00111100, // Second frame for alien #2 + B01111110, + B11011011, + B11011011, + B01111110, + B00100100, + B00100100, + B00100100 + //25, +}; + +const byte alien7[8] PROGMEM = { + // Frames 3 & 4 for alien #2 are duplicates of frames 1 & 2 + B00000000, + B00111100, + B01111110, + B11011011, + B11011011, + B01111110, + B00100100, + B11000011 +}; + +const byte alien8[8] PROGMEM = { + B00111100, + B01111110, + B11011011, + B11011011, + B01111110, + B00100100, + B00100100, + B00100100 +}; + +const byte alien9[8] PROGMEM = { + + B00100100, // First frame for alien #3 + B00100100, + B01111110, + B11011011, + B11111111, + B11111111, + B10100101, + B00100100 + //25, +}; + +const byte alien10[8] PROGMEM = { + B00100100, // Second frame for alien #3 + B10100101, + B11111111, + B11011011, + B11111111, + B01111110, + B00100100, + B01000010 + //25, +}; + +const byte alien11[8] PROGMEM = { + // Frames are duplicated as with prior aliens + B00100100, + B00100100, + B01111110, + B11011011, + B11111111, + B11111111, + B10100101, + B00100100 +}; + +const byte alien12[8] PROGMEM = { + B00100100, + B10100101, + B11111111, + B11011011, + B11111111, + B01111110, + B00100100, + B01000010 +}; + +const byte alien13[8] PROGMEM = { + B00111100, // First frame for alien #4 + B01111110, + B10110011, + B01111110, + B00111100, + B00000000, + B00001000, + B00000000 + //12, // ~1/8 second delay +}; + +const byte alien14[8] PROGMEM = { + B00111100, // Second frame for alien #4 + B01111110, + B10011001, + B01111110, + B00111100, + B00000000, + B00001000, + B00001000 + //12, +}; + +const byte alien15[8] PROGMEM = { + B00111100, // Third frame for alien #4 (NOT a repeat of frame 1) + B01111110, + B11001101, + B01111110, + B00111100, + B00000000, + B00000000, + B00001000 + //12, +}; + +const byte alien16[8] PROGMEM = { + B00111100, // Fourth frame for alien #4 (NOT a repeat of frame 2) + B01111110, + B11100111, + B01111110, + B00111100, + B00000000, + B00000000, + B00000000 + //12, +}; + +const byte alien17[8] PROGMEM = { + // Frames 5-8 are duplicates of 1-4, lines merged for brevity + B00111100, + B01111110, + B10110011, + B01111110, + B00111100, + B00000000, + B00001000, + B00000000 +}; + +const byte alien18[8] PROGMEM = { + B00111100, + B01111110, + B10011001, + B01111110, + B00111100, + B00000000, + B00001000, + B00001000 +}; + +const byte alien19[8] PROGMEM = { + B00111100, + B01111110, + B11001101, + B01111110, + B00111100, + B00000000, + B00000000, + B00001000 +}; + +const byte alien20[8] PROGMEM = { + B00111100, + B01111110, + B11100111, + B01111110, + B00111100, + B00000000, + B00000000, + B00000000 +}; + +int aliens() { + + + bool skip; + skip = render(alien1, 200); + if (skip) { + return true; + } + skip = render(alien2, 200); + if (skip) { + return true; + } + skip = render(alien3, 200); + if (skip) { + return true; + } + skip = render(alien4, 200); + if (skip) { + return true; + } + skip = render(alien5, 200); + if (skip) { + return true; + } + skip = render(alien6, 200); + if (skip) { + return true; + } + skip = render(alien7, 200); + if (skip) { + return true; + } + skip = render(alien8, 200); + if (skip) { + return true; + } + skip = render(alien9, 200); + if (skip) { + return true; + } + skip = render(alien10, 200); + if (skip) { + return true; + } + skip = render(alien11, 200); + if (skip) { + return true; + } + skip = render(alien12, 200); + if (skip) { + return true; + } + skip = render(alien13, 200); + if (skip) { + return true; + } + skip = render(alien14, 200); + if (skip) { + return true; + } + skip = render(alien15, 200); + if (skip) { + return true; + } + skip = render(alien16, 200); + if (skip) { + return true; + } + skip = render(alien17, 200); + if (skip) { + return true; + } + skip = render(alien18, 200); + if (skip) { + return true; + } + skip = render(alien19, 200); + if (skip) { + return true; + } + skip = render(alien20, 200); + if (skip) { + return true; + } + return false; +} + diff --git a/software/ijnimations/arrows.ino b/software/ijnimations/arrows.ino new file mode 100644 index 0000000..e7ad35e --- /dev/null +++ b/software/ijnimations/arrows.ino @@ -0,0 +1,65 @@ +/* + IJnimation Arrows by Realitygaps +*/ + const byte arrowup[8] PROGMEM = { + B00000000, + B00011000, + B00111100, + B01111110, + B00011000, + B00011000, + B00011000, + B00000000}; + + const byte arrowdown[8] PROGMEM = { + B00000000, + B00011000, + B00011000, + B00011000, + B01111110, + B00111100, + B00011000, + B00000000}; + + const byte arrowright[8] PROGMEM = { + B00000000, + B00001000, + B00001100, + B01111110, + B01111110, + B00001100, + B00001000, + B00000000}; + + + const byte arrowleft[8] PROGMEM = { + B00000000, + B00010000, + B00110000, + B01111110, + B01111110, + B00110000, + B00010000, + B00000000}; + +int arrows() { + bool skip; + skip = render(arrowup, 200); + if (skip) { + return true; + } + skip = render(arrowright, 200); + if (skip) { + return true; + } + skip = render(arrowdown, 200); + if (skip) { + return true; + } + skip = render(arrowleft, 200); + if (skip) { + return true; + } + return false; +} + diff --git a/software/ijnimations/battery.ino b/software/ijnimations/battery.ino new file mode 100644 index 0000000..2508d56 --- /dev/null +++ b/software/ijnimations/battery.ino @@ -0,0 +1,64 @@ +/* + battery animation by Einstein + */ + +const byte animation1[8] PROGMEM = { + B00111100, B01000010, B01000010, B01000010, B01000010, B01000010, B01000010, B01111110 +}; + +const byte animation2[8] PROGMEM = { + B00111100, B01000010, B01000010, B01000010, B01000010, B01000010, B01111110, B01111110 +}; + +const byte animation3[8] PROGMEM = { + B00111100, B01000010, B01000010, B01000010, B01000010, B01111110, B01111110, B01111110 +}; + +const byte animation4[8] PROGMEM = { + B00111100, B01000010, B01000010, B01000010, B01111110, B01111110, B01111110, B01111110 +}; + +const byte animation5[8] PROGMEM = { + B00111100, B01000010, B01000010, B01111110, B01111110, B01111110, B01111110, B01111110 +}; + +const byte animation6[8] PROGMEM = { + B00111100, B01000010, B01111110, B01111110, B01111110, B01111110, B01111110, B01111110 +}; + +const byte animation7[8] PROGMEM = { + B00111100, B01111110, B01111110, B01111110, B01111110, B01111110, B01111110, B01111110 +}; + +int battery() { + bool skip = render(animation1, 500); + if (skip) { + return true; + } + skip = render(animation2, 500); + if (skip) { + return true; + } + skip = render(animation3, 500); + if (skip) { + return true; + } + skip = render(animation4, 500); + if (skip) { + return true; + } + skip = render(animation5, 500); + if (skip) { + return true; + } + skip = render(animation6, 500); + if (skip) { + return true; + } + skip = render(animation7, 500); + if (skip) { + return true; + } + return false; +} + diff --git a/software/ijnimations/blockanim.ino b/software/ijnimations/blockanim.ino new file mode 100644 index 0000000..3e15fa5 --- /dev/null +++ b/software/ijnimations/blockanim.ino @@ -0,0 +1,161 @@ +/* + IJnimation blockanim by Einstein + */ +const byte ba1[8] PROGMEM = { + B11111111, + B11111111, + B11111111, + B11111111, + B11111111, + B11111111, + B11111111, + B11111111 +}; + +const byte ba2[8] PROGMEM = { + B00000000, + B01111110, + B01111110, + B01111110, + B01111110, + B01111110, + B01111110, + B00000000 +}; + +const byte ba3[8] PROGMEM = { + B00000000, + B00000000, + B00111100, + B00111100, + B00111100, + B00111100, + B00000000, + B00000000 +}; + +const byte ba4[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00011000, + B00011000, + B00000000, + B00000000, + B00000000 +}; + +const byte ba5[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000 +}; + +const byte ba6[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00011000, + B00011000, + B00000000, + B00000000, + B00000000 +}; + +const byte ba7[8] PROGMEM = { + B00000000, + B00000000, + B00111100, + B00111100, + B00111100, + B00111100, + B00000000, + B00000000 +}; + +const byte ba8[8] PROGMEM = { + + B00000000, + B01111110, + B01111110, + B01111110, + B01111110, + B01111110, + B01111110, + B00000000 +}; + +const byte ba9[8] PROGMEM = { + + B11111111, + B11111111, + B11111111, + B11111111, + B11111111, + B11111111, + B11111111, + B11111111 +}; + +const byte ba10[8] PROGMEM = { + + B11111111, + B11111111, + B11111111, + B11111111, + B11111111, + B11111111, + B11111111, + B11111111 + +}; +int blockanim() { + bool skip; + skip = render(ba1, 200); + if (skip) { + return true; + } + skip = render(ba2, 200); + if (skip) { + return true; + } + skip = render(ba3, 200); + if (skip) { + return true; + } + skip = render(ba4, 200); + if (skip) { + return true; + } + skip = render(ba5, 200); + if (skip) { + return true; + } + skip = render(ba6, 200); + if (skip) { + return true; + } + skip = render(ba7, 200); + if (skip) { + return true; + } + skip = render(ba8, 200); + if (skip) { + return true; + } + skip = render(ba9, 200); + if (skip) { + return true; + } + skip = render(ba10, 200); + if (skip) { + return true; + } + return false; +} + diff --git a/software/ijnimations/diagonals.ino b/software/ijnimations/diagonals.ino new file mode 100644 index 0000000..bb6caa1 --- /dev/null +++ b/software/ijnimations/diagonals.ino @@ -0,0 +1,37 @@ +/* + IJnimation 'diagonals' by Yvette Cendes + */ +const byte diagonal1[8] PROGMEM = { + B01010101, + B10101010, + B01010101, + B10101010, + B01010101, + B10101010, + B01010101, + B10101010 +}; + +const byte diagonal2[8] PROGMEM = { + B10101010, + B01010101, + B10101010, + B01010101, + B10101010, + B01010101, + B10101010, + B01010101 +}; + +int diagonals() { + bool skip = render(diagonal1, 500); + if (skip) { + return true; + } + skip = render(diagonal2, 500); + if (skip) { + return true; + } + return false; +} + diff --git a/software/ijnimations/directions.ino b/software/ijnimations/directions.ino new file mode 100644 index 0000000..c7b7297 --- /dev/null +++ b/software/ijnimations/directions.ino @@ -0,0 +1,176 @@ +/* + IJnimation directions by realitygaps + */ +const byte directions1[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B10000000, + B00000000, + B00000000, + B00000000, + B00000000}; + +const byte directions2[8] PROGMEM = { + B00000000, + B00000000, + B10000000, + B01000000, + B10000000, + B00000000, + B00000000, + B00000000}; + +const byte directions3[8] PROGMEM = { + B00000000, + B10000000, + B01000000, + B00100000, + B01000000, + B10000000, + B00000000, + B00000000}; + +const byte directions4[8] PROGMEM = { + B10000000, + B01000000, + B00100000, + B00010000, + B00100000, + B01000000, + B10000000, + B00000000}; + +const byte directions5[8] PROGMEM = { + B01000000, + B00100000, + B00010000, + B00001000, + B00010000, + B00100000, + B01000000, + B00000000}; + +const byte directions6[8] PROGMEM = { + B00100000, + B00010000, + B00001000, + B00000100, + B00001000, + B00010000, + B00100000, + B00000000}; + +const byte directions7[8] PROGMEM = { + B00010000, + B00001000, + B00000100, + B00000010, + B00000100, + B00001000, + B00010000, + B00000000}; + +const byte directions8[8] PROGMEM = { + B00001000, + B00000100, + B00000010, + B00000001, + B00000010, + B00000100, + B00001000, + B00000000}; + +const byte directions9[8] PROGMEM = { + B00000100, + B00000010, + B00000001, + B00000000, + B00000001, + B00000010, + B00000100, + B00000000}; + +const byte directions10[8] PROGMEM = { + B00000010, + B00000001, + B00000000, + B00000000, + B00000000, + B00000001, + B00000010, + B00000000}; + +const byte directions11[8] PROGMEM = { + B00000001, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000001, + B00000000}; + +const byte directions12[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000}; + +int directions() { + bool skip; + skip = render(directions1, 200); + if (skip) { + return true; + } + skip = render(directions2, 200); + if (skip) { + return true; + } + skip = render(directions3, 200); + if (skip) { + return true; + } + skip = render(directions4, 200); + if (skip) { + return true; + } + skip = render(directions5, 200); + if (skip) { + return true; + } + skip = render(directions6, 200); + if (skip) { + return true; + } + skip = render(directions7, 200); + if (skip) { + return true; + } + skip = render(directions8, 200); + if (skip) { + return true; + } + skip = render(directions9, 200); + if (skip) { + return true; + } + skip = render(directions10, 200); + if (skip) { + return true; + } + skip = render(directions11, 200); + if (skip) { + return true; + } + skip = render(directions12, 200); + if (skip) { + return true; + } + return false; +} + diff --git a/software/ijnimations/eq.ino b/software/ijnimations/eq.ino new file mode 100644 index 0000000..18933ef --- /dev/null +++ b/software/ijnimations/eq.ino @@ -0,0 +1,219 @@ +/* + IJnimation EQ by realitygaps + */ +const byte eq1[8] PROGMEM = { + B00000000, + B00001100, + B11001100, + B11001100, + B11111100, + B11111100, + B11111111, + B11111111}; + +const byte eq2[8] PROGMEM = { + B00000000, + B00001100, + B11001100, + B11001100, + B11111100, + B11111100, + B11111111, + B11111111}; + +const byte eq3[8] PROGMEM = { + B00000000, + B00001100, + B11001100, + B11001100, + B11111100, + B11111100, + B11111111, + B11111111}; + +const byte eq4[8] PROGMEM = { + B00000000, + B00000000, + B00001100, + B11001100, + B11001100, + B11111111, + B11111111, + B11111111}; + +const byte eq5[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00001100, + B11001111, + B11001111, + B11111111, + B11111111}; + +const byte eq6[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000011, + B00001111, + B11001111, + B11001111, + B11111111}; + +const byte eq7[8] PROGMEM = { + B00000000, + B00000000, + B00000011, + B00000011, + B00001111, + B00001111, + B11001111, + B11001111}; + +const byte eq8[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000011, + B00000011, + B00001111, + B00001111, + B11111111}; + +const byte eq9[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000000, + B00000011, + B00000011, + B00111111, + B11111111}; + +const byte eq10[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000000, + B00000011, + B00000011, + B00111111, + B11111111}; + +const byte eq11[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000000, + B00000011, + B00001111, + B11001111, + B11111111}; + +const byte eq12[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000000, + B00001100, + B11001111, + B11111111, + B11111111}; + +const byte eq13[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00001100, + B11001100, + B11111111, + B11111111, + B11111111}; + +const byte eq14[8] PROGMEM = { + B00000000, + B00000000, + B00001100, + B11001100, + B11001100, + B11111111, + B11111111, + B11111111}; + +const byte eq15[8] PROGMEM = { + B00000000, + B00001100, + B11001100, + B11001100, + B11001100, + B11111100, + B11111111, + B11111111}; + +int eq() { + bool skip; + skip = render(eq1, 50); + if (skip) { + return true; + } + skip = render(eq2, 50); + if (skip) { + return true; + } + skip = render(eq3, 50); + if (skip) { + return true; + } + skip = render(eq4, 50); + if (skip) { + return true; + } + skip = render(eq5, 50); + if (skip) { + return true; + } + skip = render(eq6, 50); + if (skip) { + return true; + } + skip = render(eq7, 50); + if (skip) { + return true; + } + skip = render(eq8, 50); + if (skip) { + return true; + } + skip = render(eq9, 50); + if (skip) { + return true; + } + skip = render(eq10, 50); + if (skip) { + return true; + } + skip = render(eq11, 50); + if (skip) { + return true; + } + skip = render(eq12, 50); + if (skip) { + return true; + } + skip = render(eq13, 50); + if (skip) { + return true; + } + skip = render(eq14, 50); + if (skip) { + return true; + } + skip = render(eq15, 50); + if (skip) { + return true; + } + return false; +} + + diff --git a/software/ijnimations/ghost.ino b/software/ijnimations/ghost.ino new file mode 100644 index 0000000..bd5706d --- /dev/null +++ b/software/ijnimations/ghost.ino @@ -0,0 +1,347 @@ +/* + IJnimation ghost by realitygaps + */ +const byte ghost1[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000}; + +const byte ghost2[8] PROGMEM = { + B00000000, + B00000000, + B10000000, + B10000000, + B10000000, + B10000000, + B10000000, + B10000000}; + +const byte ghost3[8] PROGMEM = { + B00000000, + B10000000, + B11000000, + B01000000, + B11000000, + B11000000, + B11000000, + B01000000}; + +const byte ghost4[8] PROGMEM = { + B10000000, + B11000000, + B01100000, + B00100000, + B11100000, + B01100000, + B11100000, + B00100000}; + +const byte ghost5[8] PROGMEM = { + B11000000, + B11100000, + B10110000, + B10010000, + B11110000, + B00110000, + B11110000, + B01010000}; + +const byte ghost6[8] PROGMEM = { + B11100000, + B11110000, + B01011000, + B01001000, + B11111000, + B00011000, + B11111000, + B10101000}; + +const byte ghost7[8] PROGMEM = { + B01110000, + B11111000, + B10101100, + B00100100, + B11111100, + B10001100, + B11111100, + B01010100}; + +const byte ghost8[8] PROGMEM = { + B00111000, + B01111100, + B11010110, + B10010010, + B11111110, + B11000110, + B11111110, + B10101010}; + +const byte ghost9[8] PROGMEM = { + B00011100, + B00111110, + B01101011, + B01001001, + B01111111, + B01100011, + B01111111, + B01010101}; + +const byte ghost9a[8] PROGMEM = { + B00011100, + B00111110, + B01101101, + B01001001, + B01111111, + B01100011, + B01111111, + B01010101}; + +const byte ghost9b[8] PROGMEM = { + B00011100, + B00111110, + B01011011, + B01001001, + B01111111, + B01100011, + B01111111, + B01010101}; + +const byte ghost9c[8] PROGMEM = { + B00011100, + B00111110, + B01001001, + B01011011, + B01111111, + B01100011, + B01111111, + B01010101}; + +const byte ghost9d[8] PROGMEM = { + B00011100, + B00111110, + B01001001, + B01101101, + B01111111, + B01100011, + B01111111, + B01010101}; + +const byte ghost9e[8] PROGMEM = { + B00011100, + B00111110, + B01101101, + B01001001, + B01111111, + B01100011, + B01111111, + B01010101}; + +const byte ghost10[8] PROGMEM = { + B00001110, + B00011111, + B00110101, + B00100100, + B00111111, + B00110001, + B00111111, + B00101010}; + +const byte ghost11[8] PROGMEM = { + B00000111, + B00001111, + B00011010, + B00010010, + B00011111, + B00011000, + B00011111, + B00010101}; + +const byte ghost12[8] PROGMEM = { + B00000011, + B00000111, + B00001101, + B00001001, + B00001111, + B00001100, + B00001111, + B00001010}; + +const byte ghost13[8] PROGMEM = { + B00000001, + B00000011, + B00000110, + B00000100, + B00000111, + B00000110, + B00000111, + B00000101}; + +const byte ghost14[8] PROGMEM = { + B00000000, + B00000001, + B00000011, + B00000010, + B00000011, + B00000011, + B00000011, + B00000010}; + +const byte ghost15[8] PROGMEM = { + B00000000, + B00000000, + B00000001, + B00000001, + B00000001, + B00000001, + B00000001, + B00000001}; + + +const byte ghost16[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000}; + +int ghost() { + bool skip; + skip = render(ghost1, 200); + if (skip) { + return true; + } + skip = render(ghost2, 200); + if (skip) { + return true; + } + skip = render(ghost3, 200); + if (skip) { + return true; + } + skip = render(ghost4, 200); + if (skip) { + return true; + } + skip = render(ghost5, 200); + if (skip) { + return true; + } + skip = render(ghost6, 200); + if (skip) { + return true; + } + skip = render(ghost7, 200); + if (skip) { + return true; + } + skip = render(ghost8, 200); + if (skip) { + return true; + } + skip = render(ghost9, 200); + if (skip) { + return true; + } + skip = render(ghost9a, 200); + if (skip) { + return true; + } + skip = render(ghost9b, 200); + if (skip) { + return true; + } + skip = render(ghost9c, 200); + if (skip) { + return true; + } + skip = render(ghost9d, 200); + if (skip) { + return true; + } + skip = render(ghost9e, 200); + if (skip) { + return true; + } + skip = render(ghost9a, 200); + if (skip) { + return true; + } + skip = render(ghost9b, 200); + if (skip) { + return true; + } + skip = render(ghost9c, 200); + if (skip) { + return true; + } + skip = render(ghost9d, 200); + if (skip) { + return true; + } + skip = render(ghost9e, 200); + if (skip) { + return true; + } + skip = render(ghost9a, 200); + if (skip) { + return true; + } + skip = render(ghost9b, 200); + if (skip) { + return true; + } + skip = render(ghost9c, 200); + if (skip) { + return true; + } + skip = render(ghost9d, 200); + if (skip) { + return true; + } + skip = render(ghost9e, 200); + if (skip) { + return true; + } + skip = render(ghost9, 200); + if (skip) { + return true; + } + skip = render(ghost10, 200); + if (skip) { + return true; + } + skip = render(ghost11, 200); + if (skip) { + return true; + } + skip = render(ghost12, 200); + if (skip) { + return true; + } + skip = render(ghost13, 200); + if (skip) { + return true; + } + skip = render(ghost14, 200); + if (skip) { + return true; + } + skip = render(ghost15, 200); + if (skip) { + return true; + } + skip = render(ghost16, 200); + if (skip) { + return true; + } + return false; +} + diff --git a/software/ijnimations/heart.ino b/software/ijnimations/heart.ino new file mode 100644 index 0000000..c94ddad --- /dev/null +++ b/software/ijnimations/heart.ino @@ -0,0 +1,38 @@ +/* + IJnimation heart by damnlie + */ +/* here is the data for the characters */ +const byte heart2[8] PROGMEM = { + B00000000, + B01100110, + B10011001, + B10000001, + B10000001, + B01000010, + B00100100, + B00011000}; + +/* here is the data for the characters */ +const byte heart1[8] PROGMEM = { + B00000000, + B01100110, + B11111111, + B11111111, + B11111111, + B01111110, + B00111100, + B00011000}; + +int heart() { + bool skip = render(heart1, 500); + if (skip) { + return true; + } + skip = render(heart2, 500); + if (skip) { + return true; + } + return false; +} + + diff --git a/software/ijnimations/heartbeat.ino b/software/ijnimations/heartbeat.ino new file mode 100644 index 0000000..dabe534 --- /dev/null +++ b/software/ijnimations/heartbeat.ino @@ -0,0 +1,199 @@ +/* + IJnimation heartbeatbeat by realitygaps + */ +const byte heartbeat1[8] PROGMEM = { + B00000000, + B00000100, + B00000110, + B00000101, + B11100100, + B00010100, + B00001100, + B00000100}; + +const byte heartbeat2[8] PROGMEM = { + B00000000, + B00000010, + B00000011, + B00000010, + B11110010, + B00001010, + B00000110, + B00000010}; + +const byte heartbeat3[8] PROGMEM = { + B00000000, + B00000001, + B00000001, + B00000001, + B11111001, + B00000101, + B00000011, + B00000001}; + +const byte heartbeat4[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000000, + B11111100, + B00000010, + B00000001, + B00000000}; + +const byte heartbeat5[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000000, + B11111110, + B00000001, + B00000000, + B00000000}; + +const byte heartbeat6[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000000, + B11111111, + B00000000, + B00000000, + B00000000}; + +const byte heartbeat7[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B10000000, + B01111111, + B00000000, + B00000000, + B00000000}; + +const byte heartbeat8[8] PROGMEM = { + B00000000, + B00000000, + B10000000, + B01000000, + B00111111, + B00000000, + B00000000, + B00000000}; + +const byte heartbeat9[8] PROGMEM = { + B00000000, + B10000000, + B11000000, + B10100000, + B10011111, + B10000000, + B10000000, + B10000000}; + +const byte heartbeat10[8] PROGMEM = { + B00000000, + B01000000, + B01100000, + B01010000, + B01001111, + B01000000, + B11000000, + B01000000}; + +const byte heartbeat11[8] PROGMEM = { + B00000000, + B00100000, + B00110000, + B00101000, + B00100111, + B10100000, + B01100000, + B00100000}; + +const byte heartbeat12[8] PROGMEM = { + B00000000, + B00010000, + B00011000, + B00010100, + B10010011, + B01010000, + B00110000, + B00010000}; + +const byte heartbeat13[8] PROGMEM = { + B00000000, + B00001000, + B00001100, + B00001010, + B11001001, + B00101000, + B00011000, + B00001000}; + +int heartbeat() { + bool skip; + skip = render(heartbeat6, 100); + if (skip) { + return true; + } + skip = render(heartbeat6, 100); + if (skip) { + return true; + } + skip = render(heartbeat7, 100); + if (skip) { + return true; + } + skip = render(heartbeat8, 100); + if (skip) { + return true; + } + skip = render(heartbeat9, 100); + if (skip) { + return true; + } + skip = render(heartbeat10, 100); + if (skip) { + return true; + } + skip = render(heartbeat11, 100); + if (skip) { + return true; + } + skip = render(heartbeat12, 100); + if (skip) { + return true; + } + skip = render(heartbeat13, 100); + if (skip) { + return true; + } + skip = render(heartbeat1, 100); + if (skip) { + return true; + } + skip = render(heartbeat2, 100); + if (skip) { + return true; + } + skip = render(heartbeat3, 100); + if (skip) { + return true; + } + skip = render(heartbeat4, 100); + if (skip) { + return true; + } + skip = render(heartbeat5, 100); + if (skip) { + return true; + } + skip = render(heartbeat6, 100); + if (skip) { + return true; + } + return false; +} + + diff --git a/software/ijnimations/ijhacklogo.ino b/software/ijnimations/ijhacklogo.ino new file mode 100644 index 0000000..a093390 --- /dev/null +++ b/software/ijnimations/ijhacklogo.ino @@ -0,0 +1,83 @@ +/* + IJnimation IJHACK by Einstein, damnlie, the_JinX + */ + +/* here is the data for the characters */ +const byte ij[8] PROGMEM = { + B11000011, + B11000011, + B00000000, + B00000011, + B11000011, + B11100111, + B01111110, + B00111100}; + +const byte h[8] PROGMEM = { + B11000011, + B11000011, + B11000011, + B11111111, + B11111111, + B11000011, + B11000011, + B11000011 }; + +const byte a[8] PROGMEM = { + B00011000, + B00111100, + B01100110, + B11000011, + B11111111, + B11111111, + B11000011, + B11000011 }; + +const byte c[8] PROGMEM = { + B01111110, + B11111111, + B11000011, + B11000000, + B11000000, + B11000011, + B11111111, + B01111110 }; + +const byte k[8] PROGMEM = { + B11000111, + B11011110, + B11111100, + B11110000, + B11110000, + B11111100, + B11011110, + B11000111 +}; + + +int ijhacklogo() { + + bool skip; + skip = render(ij, 500); + if (skip) { + return true; + } + skip = render(h, 500); + if (skip) { + return true; + } + skip = render(a, 500); + if (skip) { + return true; + } + skip = render(c, 500); + if (skip) { + return true; + } + skip = render(k, 500); + if (skip) { + return true; + } + return false; +} + diff --git a/software/ijnimations/ijlogowink.ino b/software/ijnimations/ijlogowink.ino new file mode 100644 index 0000000..d1aa04d --- /dev/null +++ b/software/ijnimations/ijlogowink.ino @@ -0,0 +1,72 @@ +/* + IJnimation IJwink by realitygaps, Einstein, the_JinX, damnlie + */ +const byte logowink0[8] PROGMEM = { + B11000011, + B11000011, + B00000000, + B00000011, + B11000011, + B11100111, + B01111110, + B00111100}; + +const byte logowink1[8] PROGMEM = { + B00000011, + B00000011, + B00000000, + B00000011, + B11000011, + B11100111, + B01111110, + B00111100}; + +const byte logowink2[8] PROGMEM = { + B11000000, + B11000000, + B00000000, + B00000011, + B11000011, + B11100111, + B01111110, + B00111100}; + +const byte logowink3[8] PROGMEM = { + B11000011, + B11000011, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000}; + +int ijlogowink() { + bool skip; + skip = render(logowink0, 500); + if (skip) { + return true; + } + skip = render(logowink1, 500); + if (skip) { + return true; + } + skip = render(logowink0, 500); + if (skip) { + return true; + } + skip = render(logowink2, 500); + if (skip) { + return true; + } + skip = render(logowink0, 500); + if (skip) { + return true; + } + skip = render(logowink3, 500); + if (skip) { + return true; + } + return false; +} + diff --git a/software/ijnimations/ijnimations.ino b/software/ijnimations/ijnimations.ino new file mode 100644 index 0000000..ca8828b --- /dev/null +++ b/software/ijnimations/ijnimations.ino @@ -0,0 +1,119 @@ +/* IJduino 1.5 +Requires: + * 8X8 LED grid MAX7219 + * Mini Breadboard + * Atmega328 + * Button + * 2 Wires + * 4.5 Volt + (c) IJhack 2014 GNU GPL +http://ijhack.org/ + */ +#include "LedControl.h" + +/* using VCC, GND, DIN 20, CS 21, CLK 5 for the MAX7219 */ +static const int DATA_PIN = 20; +static const int CLK_PIN = 5; +static const int CS_PIN = 21; + +LedControl lc=LedControl(DATA_PIN, CLK_PIN, CS_PIN, 1); + +static const int lowPin = 11; /* ground pin for the buton ;-) */ +static const int buttonPin = 9; /* choose the input pin for the pushbutton */ + +static const int INTENSITY = 5; + +static const int animations = 24; +int (*ijnimations[animations])() = { + ijhacklogo, ghost, invader, heart, invadesquid, jumper, ijlogowink, + heartbeat, eq, invaderagain, pong, snake, arrows, directions, + packman, diagonals, waterdrip, aliens, blockanim, pulse, tewdoodles, + battery, xmastree, sproet +}; + +int lastButtonState = LOW; /* the previous reading from the input pin */ +unsigned long lastDebounceTime = 0; /* the last time the output pin was toggled */ +unsigned long debounceDelay = 50; /* the debounce time; increase if the output flickers */ +int animation = 0; +int buttonState = LOW; + +void setup() { + /* + The MAX72XX is in power-saving mode on startup, + we have to do a wakeup call + */ + lc.shutdown(0,false); + /* Set the brightness to a medium values */ + lc.setIntensity(0,INTENSITY); + /* and clear the display */ + lc.clearDisplay(0); + /* setup pins */ + pinMode(buttonPin, INPUT_PULLUP); + pinMode(lowPin, OUTPUT); + digitalWrite(lowPin, LOW); +} + +void loop() { + bool skip; + if (animation == 0) { + for (int all = 0; all < animations; all++) { + for (int looper = 0; looper < 3; looper++) { + skip = (bool)(ijnimations)[all](); + if (skip) { + return; + } + } + } + } else { + (ijnimations)[animation](); + } +} + +int render(const byte* frame, long delaytime) { + // render to screen + for (int r = 0; r < 8; r++) { + lc.setColumn(0, 7-r, pgm_read_byte(&frame[r])); + } + + unsigned long startTime = millis(); + while ((startTime + delaytime) > millis()){ + + // read the state of the switch into a local variable: + int reading = digitalRead(buttonPin); + + // check to see if you just pressed the button + // (i.e. the input went from HIGH to LOW), and you've waited + // long enough since the last press to ignore any noise: + + // If the switch changed, due to noise or pressing: + if (reading != lastButtonState) { + // reset the debouncing timer + lastDebounceTime = millis(); + } + + if ((millis() - lastDebounceTime) > debounceDelay) { + // whatever the reading is at, it's been there for longer + // than the debounce delay, so take it as the actual current state: + + // if the button state has changed: + if (reading != buttonState) { + buttonState = reading; + + // only toggle the animation if the new button state is HIGH + if (buttonState == LOW) { + animation++; + if (animation > animations) { + animation = 0; + } + return true; + } + } + } + + // save the reading. Next time through the loop, + // it'll be the lastButtonState: + lastButtonState = reading; + } + return false; /* don't skip the rest */ +} + diff --git a/software/ijnimations/invader.ino b/software/ijnimations/invader.ino new file mode 100644 index 0000000..fbc11b1 --- /dev/null +++ b/software/ijnimations/invader.ino @@ -0,0 +1,35 @@ +/* + First IJnimation "invader" by realitygaps + */ +const byte invade[8] PROGMEM = { + B00100100, + B00100100, + B01111110, + B11011011, + B11111111, + B11111111, + B10100101, + B00100100}; + +const byte devade[8] PROGMEM = { + B00100100, + B10100101, + B11111111, + B11011011, + B11111111, + B01111110, + B00100100, + B00100100}; + +int invader() { + bool skip = render(invade, 500); + if (skip) { + return true; + } + skip = render(devade, 500); + if (skip) { + return true; + } + return false; +} + diff --git a/software/ijnimations/invaderagain.ino b/software/ijnimations/invaderagain.ino new file mode 100644 index 0000000..c04fb3b --- /dev/null +++ b/software/ijnimations/invaderagain.ino @@ -0,0 +1,276 @@ +/* + IJnimation invader again by realitygaps + */ +const byte invader1[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000}; + +const byte invader2[8] PROGMEM = { + B00000000, + B00000000, + B10000000, + B10000000, + B10000000, + B10000000, + B10000000, + B10000000}; + +const byte invader3[8] PROGMEM = { + B00000000, + B10000000, + B11000000, + B11000000, + B01000000, + B01000000, + B01000000, + B11000000}; + +const byte invader4[8] PROGMEM = { + B10000000, + B11000000, + B01100000, + B11100000, + B10100000, + B00100000, + B00100000, + B01100000}; + +const byte invader5[8] PROGMEM = { + B01000000, + B11100000, + B10110000, + B11110000, + B01010000, + B10010000, + B00010000, + B00110000}; + +const byte invader6[8] PROGMEM = { + B00100000, + B11110000, + B11011000, + B11111000, + B00101000, + B11001000, + B00001000, + B00011000}; + +const byte invader7[8] PROGMEM = { + B10010000, + B11111000, + B01101100, + B11111100, + B10010100, + B01100100, + B00000100, + B00001100}; + +const byte invader8[8] PROGMEM = { + B01001000, + B11111100, + B10110110, + B11111110, + B01001010, + B00110010, + B00000010, + B10000110}; + +const byte invader9[8] PROGMEM = { + B00100100, + B01111110, + B11011011, + B11111111, + B10100101, + B10011001, + B10000001, + B11000011}; + +const byte invader9a[8] PROGMEM = { + B00100100, + B00011000, + B01111110, + B11011011, + B11111111, + B11011011, + B10011001, + B11000011}; + +const byte invader10[8] PROGMEM = { + B00010010, + B00111111, + B01101101, + B01111111, + B01010010, + B01001100, + B01000000, + B01100001}; + + +const byte invader11[8] PROGMEM = { + B00001001, + B00011111, + B00110110, + B00111111, + B00101001, + B00100110, + B00100000, + B00110000}; + + + +const byte invader12[8] PROGMEM = { + B00000100, + B00001111, + B00011011, + B00011111, + B00010100, + B00010011, + B00010000, + B00011000}; + +const byte invader13[8] PROGMEM = { + B00000010, + B00000111, + B00001101, + B00001111, + B00001010, + B00001001, + B00001000, + B00001100}; + + +const byte invader14[8] PROGMEM = { + B00000001, + B00000011, + B00000110, + B00000111, + B00000101, + B00000100, + B00000100, + B00000110}; + +const byte invader15[8] PROGMEM = { + B00000000, + B00000001, + B00000011, + B00000011, + B00000010, + B00000010, + B00000010, + B00000011}; + +const byte invader16[8] PROGMEM = { + B00000000, + B00000000, + B00000001, + B00000001, + B00000001, + B00000001, + B00000001, + B00000001}; + + +int invaderagain() { + bool skip; + skip = render(invader1, 200); + if (skip) { + return true; + } + skip = render(invader2, 200); + if (skip) { + return true; + } + skip = render(invader3, 200); + if (skip) { + return true; + } + skip = render(invader4, 200); + if (skip) { + return true; + } + skip = render(invader5, 200); + if (skip) { + return true; + } + skip = render(invader6, 200); + if (skip) { + return true; + } + skip = render(invader7, 200); + if (skip) { + return true; + } + skip = render(invader8, 200); + if (skip) { + return true; + } + skip = render(invader9, 200); + if (skip) { + return true; + } + skip = render(invader9a, 200); + if (skip) { + return true; + } + skip = render(invader9, 200); + if (skip) { + return true; + } + skip = render(invader9a, 200); + if (skip) { + return true; + } + skip = render(invader9, 200); + if (skip) { + return true; + } + skip = render(invader9a, 200); + if (skip) { + return true; + } + skip = render(invader9, 200); + if (skip) { + return true; + } + skip = render(invader10, 200); + if (skip) { + return true; + } + skip = render(invader11, 200); + if (skip) { + return true; + } + skip = render(invader12, 200); + if (skip) { + return true; + } + skip = render(invader13, 200); + if (skip) { + return true; + } + skip = render(invader14, 200); + if (skip) { + return true; + } + skip = render(invader15, 200); + if (skip) { + return true; + } + skip = render(invader16, 200); + if (skip) { + return true; + } + skip = render(invader1, 200); + if (skip) { + return true; + } + return false; +} + + diff --git a/software/ijnimations/invadesquid.ino b/software/ijnimations/invadesquid.ino new file mode 100644 index 0000000..037da2d --- /dev/null +++ b/software/ijnimations/invadesquid.ino @@ -0,0 +1,36 @@ +/* + IJnimation invadesuid by realitygaps + */ +const byte invadesquid1[8] PROGMEM = { + B00011000, + B00111100, + B01111110, + B11011011, + B11111111, + B01011010, + B10000001, + B01000010}; + +const byte devadesquid1[8] PROGMEM = { + B00011000, + B00111100, + B01111110, + B11011011, + B11111111, + B00100100, + B01011010, + B10100101}; + +int invadesquid() { + bool skip = render(invadesquid1, 500); + if (skip) { + return true; + } + skip = render(devadesquid1, 500); + if (skip) { + return true; + } + return false; +} + + diff --git a/software/ijnimations/jumper.ino b/software/ijnimations/jumper.ino new file mode 100644 index 0000000..4db7327 --- /dev/null +++ b/software/ijnimations/jumper.ino @@ -0,0 +1,36 @@ +/* + IJnimation jumper byrealitygaps + */ +const byte jumpdown[8] PROGMEM = { + B00111100, + B00111100, + B00011000, + B01111110, + B00011000, + B00011000, + B00100100, + B00100100}; + +const byte jumpup[8] PROGMEM = { + B00111100, + B01011010, + B00111100, + B00011000, + B00011000, + B00100100, + B01000010, + B00000000}; + + +int jumper() { + bool skip = render(jumpdown, 500); + if (skip) { + return true; + } + skip = render(jumpup, 500); + if (skip) { + return true; + } + return false; +} + diff --git a/software/ijnimations/packman.ino b/software/ijnimations/packman.ino new file mode 100644 index 0000000..ec30a4c --- /dev/null +++ b/software/ijnimations/packman.ino @@ -0,0 +1,250 @@ +/* + IJnimation "packman" by damnlie + */ + +const byte packman1[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000}; + + +const byte packman2[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B10000000, + B00000000, + B00000000, + B10000000, + B00000000}; + + +const byte packman3[8] PROGMEM = { + B00000000, + B00000000, + B10000000, + B11000000, + B00000000, + B00000000, + B11000000, + B10000000}; + + + +const byte packman4[8] PROGMEM = { + B00000000, + B10000000, + B11000000, + B11100000, + B00000000, + B00000000, + B11100000, + B11000000}; + + + +const byte packman5[8] PROGMEM = { + B00000000, + B11000000, + B01100000, + B11110000, + B10000000, + B10000000, + B11110000, + B11100000}; + +const byte packman6[8] PROGMEM = { + B00000000, + B11100000, + B11110000, + B01111000, + B11000000, + B11000000, + B11111000, + B11110000}; + + +const byte packman7[8] PROGMEM = { + B00000000, + B01110000, + B11111000, + B10111100, + B11100000, + B11100000, + B11111100, + B01111000}; + + +const byte packman8[8] PROGMEM = { + B00000000, + B00111000, + B01111100, + B11011110, + B11110000, + B11110000, + B01111110, + B00111100}; + +const byte packman9[8] PROGMEM = { + B00000000, + B00011100, + B00111110, + B01101111, + B01111000, + B01111000, + B00111111, + B00011110}; + + +const byte packman10[8] PROGMEM = { + B00000000, + B00001110, + B00011111, + B00110111, + B00111100, + B00111100, + B00011111, + B00001111}; + + +const byte packman11[8] PROGMEM = { + B00000000, + B00000111, + B00001111, + B00011011, + B00011110, + B00011110, + B00001111, + B00000111}; + + +const byte packman12[8] PROGMEM = { + B00000000, + B00000011, + B00000111, + B00001101, + B00001111, + B00001111, + B00000111, + B00000011}; + + + +const byte packman13[8] PROGMEM = { + B00000000, + B00000001, + B00000011, + B00000110, + B00000111, + B00000111, + B00000011, + B00000001}; + + +const byte packman14[8] PROGMEM = { + B00000000, + B00000000, + B00000001, + B00000011, + B00000011, + B00000011, + B00000001, + B00000000}; + + + +const byte packman15[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000001, + B00000001, + B00000001, + B00000000, + B00000000}; + + +const byte packman16[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000}; + +int packman() { + bool skip; + skip = render(packman1, 200); + if (skip) { + return true; + } + skip = render(packman2, 200); + if (skip) { + return true; + } + skip = render(packman3, 200); + if (skip) { + return true; + } + skip = render(packman4, 200); + if (skip) { + return true; + } + skip = render(packman5, 200); + if (skip) { + return true; + } + skip = render(packman6, 200); + if (skip) { + return true; + } + skip = render(packman7, 200); + if (skip) { + return true; + } + skip = render(packman8, 200); + if (skip) { + return true; + } + skip = render(packman9, 200); + if (skip) { + return true; + } + skip = render(packman10, 200); + if (skip) { + return true; + } + skip = render(packman11, 200); + if (skip) { + return true; + } + skip = render(packman12, 200); + if (skip) { + return true; + } + skip = render(packman13, 200); + if (skip) { + return true; + } + skip = render(packman14, 200); + if (skip) { + return true; + } + skip = render(packman15, 200); + if (skip) { + return true; + } + skip = render(packman16, 200); + if (skip) { + return true; + } + return false; +} + diff --git a/software/ijnimations/pong.ino b/software/ijnimations/pong.ino new file mode 100644 index 0000000..210c672 --- /dev/null +++ b/software/ijnimations/pong.ino @@ -0,0 +1,207 @@ +/* + IJnimation pong byrealitygaps + */ +const byte pong1[8] PROGMEM = { + B00111000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00011100}; + +const byte pong2[8] PROGMEM = { + B00111000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000001, + B00000000, + B00001110}; + +const byte pong3[8] PROGMEM = { + B00111000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000010, + B00000111}; + + +const byte pong4[8] PROGMEM = { + B00111000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000100, + B00000000, + B00000111}; + +const byte pong5[8] PROGMEM = { + B00111000, + B00000000, + B00000000, + B00000000, + B00001000, + B00000000, + B00000000, + B00000111}; + +const byte pong6[8] PROGMEM = { + B00111000, + B00000000, + B00000000, + B00010000, + B00000000, + B00000000, + B00000000, + B00001110}; + +const byte pong7[8] PROGMEM = { + B01110000, + B00000000, + B00100000, + B00000000, + B00000000, + B00000000, + B00000000, + B00001110}; + +const byte pong8[8] PROGMEM = { + B11100000, + B01000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00011100}; + +const byte pong9[8] PROGMEM = { + B11100000, + B00000000, + B00100000, + B00000000, + B00000000, + B00000000, + B00000000, + B00011100}; + +const byte pong10[8] PROGMEM = { + B11100000, + B00000000, + B00000000, + B00010000, + B00000000, + B00000000, + B00000000, + B00111000}; + +const byte pong11[8] PROGMEM = { + B01110000, + B00000000, + B00000000, + B00000000, + B00001000, + B00000000, + B00000000, + B01110000}; + +const byte pong12[8] PROGMEM = { + B01110000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000100, + B00000000, + B00111000}; + +const byte pong13[8] PROGMEM = { + B01110000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000010, + B00011100}; + +const byte pong14[8] PROGMEM = { + B00111000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00011101}; + + +int pong() { + bool skip; + skip = render(pong1, 200); + if (skip) { + return true; + } + skip = render(pong2, 200); + if (skip) { + return true; + } + skip = render(pong3, 200); + if (skip) { + return true; + } + skip = render(pong4, 200); + if (skip) { + return true; + } + skip = render(pong5, 200); + if (skip) { + return true; + } + skip = render(pong6, 200); + if (skip) { + return true; + } + skip = render(pong7, 200); + if (skip) { + return true; + } + skip = render(pong8, 200); + if (skip) { + return true; + } + skip = render(pong9, 200); + if (skip) { + return true; + } + skip = render(pong10, 200); + if (skip) { + return true; + } + skip = render(pong11, 200); + if (skip) { + return true; + } + skip = render(pong12, 200); + if (skip) { + return true; + } + skip = render(pong13, 200); + if (skip) { + return true; + } + skip = render(pong14, 200); + if (skip) { + return true; + } + return false; +} + + diff --git a/software/ijnimations/pulse.ino b/software/ijnimations/pulse.ino new file mode 100644 index 0000000..9baf605 --- /dev/null +++ b/software/ijnimations/pulse.ino @@ -0,0 +1,35 @@ +/* + IJnimation pulse by Einstein + */ +const byte bigHeart[] PROGMEM = { + B01100110, + B11111111, + B11111111, + B11111111, + B01111110, + B00111100, + B00011000, + B00000000}; + +const byte smallHeart[] PROGMEM = { + B00000000, + B00000000, + B00010100, + B00111110, + B00111110, + B00011100, + B00001000, + B00000000}; + +int pulse() { + bool skip = render(bigHeart, 500); + if (skip) { + return true; + } + skip = render(smallHeart, 500); + if (skip) { + return true; + } + return false; +} + diff --git a/software/ijnimations/snake.ino b/software/ijnimations/snake.ino new file mode 100644 index 0000000..dff85ff --- /dev/null +++ b/software/ijnimations/snake.ino @@ -0,0 +1,448 @@ +/* + IJnimation snake by realitygaps + */ +const byte snake1[8] PROGMEM ={ + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000}; + +const byte snake2[8] PROGMEM ={ + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000001, + B00000000}; + +const byte snake3[8] PROGMEM ={ + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000011, + B00000000}; + +const byte snake4[8] PROGMEM ={ + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000111, + B00000000}; + +const byte snake5[8] PROGMEM ={ + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00001110, + B00000000}; + +const byte snake6[8] PROGMEM ={ + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00011100, + B00000000}; + +const byte snake7[8] PROGMEM ={ + B00000000, + B00000000, + B01000000, + B00000000, + B00000000, + B00000000, + B00111000, + B00000000}; + +const byte snake8[8] PROGMEM ={ + B00000000, + B00000000, + B01000000, + B00000000, + B00000000, + B00100000, + B00110000, + B00000000}; + +const byte snake9[8] PROGMEM ={ + B00000000, + B00000000, + B01000000, + B00000000, + B00100000, + B00100000, + B00100000, + B00000000}; + +const byte snake10[8] PROGMEM ={ + B00000000, + B00000000, + B01000000, + B00100000, + B00100000, + B00100000, + B00000000, + B00000000}; + +const byte snake11[8] PROGMEM ={ + B00000000, + B00000000, + B01100000, + B00100000, + B00100000, + B00000000, + B00000000, + B00000000}; + +const byte snake12[8] PROGMEM ={ + B00000000, + B01000000, + B01100000, + B00100000, + B00100000, + B00000000, + B00000000, + B00000000}; + +const byte snake13[8] PROGMEM ={ + B01000000, + B01000000, + B01100000, + B00100000, + B00000000, + B00000000, + B00000000, + B00000000}; + +const byte snake14[8] PROGMEM ={ + B01100000, + B01000000, + B01100000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000}; + +const byte snake15[8] PROGMEM ={ + B01110000, + B01000000, + B01000000, + B00000000, + B00000100, + B00000000, + B00000000, + B00000000}; + +const byte snake16[8] PROGMEM ={ + B01111000, + B01000000, + B00000000, + B00000000, + B00000100, + B00000000, + B00000000, + B00000000}; + +const byte snake17[8] PROGMEM ={ + B01111100, + B00000000, + B00000000, + B00000000, + B00000100, + B00000000, + B00000000, + B00000000}; + +const byte snake18[8] PROGMEM ={ + B00111100, + B00000100, + B00000000, + B00000000, + B00000100, + B00000000, + B00000000, + B00000000}; + +const byte snake19[8] PROGMEM ={ + B00011100, + B00000100, + B00000100, + B00000000, + B00000100, + B00000000, + B00000000, + B00000000}; + +const byte snake20[8] PROGMEM ={ + B00001100, + B00000100, + B00000100, + B00000100, + B00000100, + B00000000, + B00000000, + B00000000}; + +const byte snake21[8] PROGMEM ={ + B00001100, + B00000100, + B00000100, + B00000100, + B00000100, + B00000100, + B00000000, + B00000000}; + +const byte snake22[8] PROGMEM ={ + B00000100, + B00000100, + B00000100, + B00000100, + B00000100, + B00000100, + B00000100, + B00000000}; + +const byte snake23[8] PROGMEM ={ + B00000000, + B00000100, + B00000100, + B00100100, + B00000100, + B00000100, + B00001100, + B00000000}; + +const byte snake24[8] PROGMEM ={ + B00000000, + B00000000, + B00000100, + B00100100, + B00000100, + B00000100, + B00011100, + B00000000}; + +const byte snake25[8] PROGMEM ={ + B00000000, + B00000000, + B00000000, + B00100100, + B00000100, + B00010100, + B00011100, + B00000000}; + +const byte snake26[8] PROGMEM ={ + B00000000, + B00000000, + B00000000, + B00100000, + B00010100, + B00010100, + B00011100, + B00000000}; + +const byte snake27[8] PROGMEM ={ + B00000000, + B00000000, + B00000000, + B00100000, + B00110000, + B00010100, + B00011100, + B00000000}; + +const byte snake28[8] PROGMEM ={ + B00000000, + B00000000, + B00000000, + B01100000, + B00110000, + B00010100, + B00011100, + B00000000}; + +const byte snake29[8] PROGMEM ={ + B00000000, + B00000000, + B00000000, + B11100000, + B00110000, + B00010100, + B00011100, + B00000000}; + + +const byte snake30[8] PROGMEM ={ + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000}; + +int snake() { + + bool skip; + skip = render(snake1, 200); + if (skip) { + return true; + } + skip = render(snake2, 200); + if (skip) { + return true; + } + skip = render(snake3, 200); + if (skip) { + return true; + } + skip = render(snake4, 200); + if (skip) { + return true; + } + skip = render(snake5, 200); + if (skip) { + return true; + } + skip = render(snake6, 200); + if (skip) { + return true; + } + skip = render(snake7, 200); + if (skip) { + return true; + } + skip = render(snake8, 200); + if (skip) { + return true; + } + skip = render(snake9, 200); + if (skip) { + return true; + } + skip = render(snake10, 200); + if (skip) { + return true; + } + skip = render(snake11, 200); + if (skip) { + return true; + } + skip = render(snake12, 200); + if (skip) { + return true; + } + skip = render(snake13, 200); + if (skip) { + return true; + } + skip = render(snake14, 200); + if (skip) { + return true; + } + skip = render(snake15, 200); + if (skip) { + return true; + } + skip = render(snake16, 200); + if (skip) { + return true; + } + skip = render(snake17, 200); + if (skip) { + return true; + } + skip = render(snake18, 200); + if (skip) { + return true; + } + skip = render(snake19, 200); + if (skip) { + return true; + } + skip = render(snake20, 200); + if (skip) { + return true; + } + skip = render(snake21, 200); + if (skip) { + return true; + } + skip = render(snake22, 200); + if (skip) { + return true; + } + skip = render(snake23, 200); + if (skip) { + return true; + } + skip = render(snake24, 200); + if (skip) { + return true; + } + skip = render(snake25, 200); + if (skip) { + return true; + } + skip = render(snake26, 200); + if (skip) { + return true; + } + skip = render(snake27, 200); + if (skip) { + return true; + } + skip = render(snake28, 200); + if (skip) { + return true; + } + skip = render(snake29, 200); + if (skip) { + return true; + } + skip = render(snake30, 200); + if (skip) { + return true; + } + skip = render(snake29, 200); + if (skip) { + return true; + } + skip = render(snake30, 200); + if (skip) { + return true; + } + skip = render(snake29, 200); + if (skip) { + return true; + } + skip = render(snake30, 200); + if (skip) { + return true; + } + return false; +} + + + diff --git a/software/ijnimations/sproet.ino b/software/ijnimations/sproet.ino new file mode 100644 index 0000000..864869b --- /dev/null +++ b/software/ijnimations/sproet.ino @@ -0,0 +1,413 @@ +/* + IJnimation bij Sproet + */ +const byte sproet1[8] PROGMEM = {B10010010, +B01101101, +B10010010, +B01101101, +B10010010, +B01101101, +B10010010, +B01101101}; + +const byte sproet2[8] PROGMEM = {B01001001, +B10110110, +B01001001, +B10110110, +B01001001, +B10110110, +B01001001, +B10100110}; + +const byte sproet3[8] PROGMEM = {B01101101, +B10010010, +B01101101, +B10010010, +B01101101, +B10010010, +B01101101, +B10010010}; + +const byte sproet4[8] PROGMEM = {B00101001, +B10010010, +B01100101, +B10010010, +B01001001, +B10010010, +B00101101, +B10010010}; + +const byte sproet5[8] PROGMEM = {B00101000, +B10010010, +B00100101, +B10010000, +B01001000, +B00010010, +B00100001, +B10010010}; + +const byte sproet6[8] PROGMEM = {B00101000, +B10000000, +B00100101, +B00000000, +B01001000, +B00000010, +B00000000, +B10010010}; + +const byte sproet7[8] PROGMEM = {B00000000, +B00000000, +B00101000, +B00010100, +B01001000, +B00010010, +B00000000, +B00010000}; + +const byte sproet8[8] PROGMEM = {B00000000, +B00000000, +B00101000, +B00010100, +B01001000, +B00010010, +B00000000, +B00010000}; + +const byte sproet9[8] PROGMEM = {B00000000, +B00000000, +B00100000, +B00000100, +B00000000, +B00010000, +B00000000, +B00000000}; + +const byte sproet10[8] PROGMEM = {B00000000, +B00000000, +B00000000, +B00010000, +B00001000, +B00000000, +B00000000, +B00000000}; + +const byte sproet11[8] PROGMEM = {B10000100, +B00000010, +B00000000, +B00000000, +B00000000, +B10000000, +B00000000, +B00010001}; + +const byte sproet12[8] PROGMEM = {B10000100, +B01001010, +B00110000, +B00010000, +B01001000, +B10010100, +B00010010, +B00010001}; + +const byte sproet13[8] PROGMEM = {B10000100, +B01001010, +B00111000, +B00111110, +B01111000, +B10111100, +B00010010, +B00010001}; + +const byte sproet14[8] PROGMEM = {B10000100, +B01001010, +B00110000, +B00101110, +B01010000, +B10111100, +B00010010, +B00010001}; + +const byte sproet15[8] PROGMEM = {B00101010, +B10001001, +B00110000, +B10101111, +B01010000, +B10111101, +B00010010, +B10010101}; + +const byte sproet16[8] PROGMEM = {B00101010, +B11001001, +B00110100, +B10100111, +B01010100, +B10100101, +B01011010, +B10110101}; + +const byte sproet17[8] PROGMEM = {B00101010, +B11111111, +B00110100, +B10100111, +B01110100, +B10100101, +B11111111, +B10110101}; + +const byte sproet18[8] PROGMEM = {B00101010, +B11111111, +B00100100, +B10110111, +B10101100, +B00100101, +B11111111, +B00110100}; + +const byte sproet19[8] PROGMEM = {B00100100, +B11111111, +B00100100, +B00100100, +B00100100, +B00100100, +B11111111, +B00100100}; + +const byte sproet20[8] PROGMEM = {B01000010, +B11111111, +B01000010, +B01000010, +B01000010, +B01000010, +B11111111, +B01000010}; + +const byte sproet21[8] PROGMEM = {B11111111, +B01000010, +B01000010, +B01000010, +B01000010, +B01000010, +B01000010, +B11111111}; + +const byte sproet22[8] PROGMEM = {B11111111, +B10000001, +B10000001, +B10000001, +B10000001, +B10000001, +B10000001, +B11111111}; + +const byte sproet23[8] PROGMEM = {B11111111, +B00000000, +B00000000, +B00000000, +B00000000, +B00000000, +B00000000, +B11111111}; + +const byte sproet24[8] PROGMEM = {B10101010, +B00000000, +B00000000, +B00000000, +B00000000, +B00000000, +B00000000, +B10101010}; + +const byte sproet25[8] PROGMEM = {B00000000, +B00000000, +B00000000, +B00000000, +B00000000, +B00000000, +B00000000, +B00000000}; + +const byte sproet26[8] PROGMEM = {B00000000, +B00000000, +B00000000, +B00001000, +B00010000, +B00000000, +B00000000, +B00000000}; + +const byte sproet27[8] PROGMEM = {B00000000, +B00000000, +B00100000, +B00001000, +B00010000, +B00000100, +B00000000, +B00000000}; + +const byte sproet28[8] PROGMEM = {B10000000, +B01000000, +B00100000, +B00001000, +B00010000, +B00000100, +B00000010, +B00000001}; + +const byte sproet29[8] PROGMEM = {B10000011, +B01000100, +B00100100, +B00001000, +B00010000, +B00100100, +B00100010, +B11000001}; + +const byte sproet30[8] PROGMEM = {B01000000, +B00100010, +B00010101, +B00001000, +B00010000, +B10101000, +B01000100, +B00000010}; + +const byte sproet31[8] PROGMEM = {B00100000, +B00010000, +B00001100, +B10001010, +B01010001, +B00110000, +B00001000, +B00000100}; + + + + +int sproet() { + bool skip = render(sproet1, 500); + if (skip) { + return true; + } + skip = render(sproet2, 500); + if (skip) { + return true; + } + skip = render(sproet3, 500); + if (skip) { + return true; + } + skip = render(sproet4, 500); + if (skip) { + return true; + } + skip = render(sproet5, 500); + if (skip) { + return true; + } + skip = render(sproet6, 500); + if (skip) { + return true; + } + skip = render(sproet7, 500); + if (skip) { + return true; + } + skip = render(sproet8, 500); + if (skip) { + return true; + } + skip = render(sproet9, 500); + if (skip) { + return true; + } + skip = render(sproet10, 500); + if (skip) { + return true; + } + skip = render(sproet11, 500); + if (skip) { + return true; + } + skip = render(sproet12, 500); + if (skip) { + return true; + } + skip = render(sproet13, 500); + if (skip) { + return true; + } + skip = render(sproet14, 500); + if (skip) { + return true; + } + skip = render(sproet15, 500); + if (skip) { + return true; + } + skip = render(sproet16, 500); + if (skip) { + return true; + } + skip = render(sproet17, 500); + if (skip) { + return true; + } + skip = render(sproet18, 500); + if (skip) { + return true; + } + skip = render(sproet19, 500); + if (skip) { + return true; + } + skip = render(sproet20, 500); + if (skip) { + return true; + } + skip = render(sproet21, 500); + if (skip) { + return true; + } + skip = render(sproet22, 500); + if (skip) { + return true; + } + skip = render(sproet23, 500); + if (skip) { + return true; + } + skip = render(sproet24, 500); + if (skip) { + return true; + } + skip = render(sproet25, 500); + if (skip) { + return true; + } + skip = render(sproet26, 500); + if (skip) { + return true; + } + skip = render(sproet27, 500); + if (skip) { + return true; + } + skip = render(sproet28, 500); + if (skip) { + return true; + } + skip = render(sproet29, 500); + if (skip) { + return true; + } + skip = render(sproet30, 500); + if (skip) { + return true; + } + skip = render(sproet31, 500); + if (skip) { + return true; + } + return false; +} + diff --git a/software/ijnimations/tewdoodles.ino b/software/ijnimations/tewdoodles.ino new file mode 100644 index 0000000..104abf9 --- /dev/null +++ b/software/ijnimations/tewdoodles.ino @@ -0,0 +1,142 @@ +/* + Impressive 9 frame animation that will simply blow your mind! + + http://i.imgur.com/O55vc.gif + + By tew + */ +const byte tewdoodle1[8] PROGMEM = +{ + B11111111, + B10000001, + B10000001, + B10000001, + B10000001, + B10000001, + B10000001, + B11111111 +}; + +const byte tewdoodle2[8] PROGMEM ={ + B10000001, + B01111110, + B01000010, + B01000010, + B01000010, + B01000010, + B01111110, + B10000001 }; + +const byte tewdoodle3[8] PROGMEM ={ + B10000001, + B01000010, + B00111100, + B00100100, + B00100100, + B00111100, + B01000010, + B10000001 }; + +const byte tewdoodle4[8] PROGMEM ={ + B10000001, + B01000010, + B00100100, + B00011000, + B00011000, + B00100100, + B01000010, + B10000001 }; + +const byte tewdoodle5[8] PROGMEM ={ + B00000000, + B01000010, + B00100100, + B00011000, + B00011000, + B00100100, + B01000010, + B00000000 }; + +const byte tewdoodle6[8] PROGMEM ={ + B00000000, + B00000000, + B00100100, + B00011000, + B00011000, + B00100100, + B00000000, + B00000000 }; + +const byte tewdoodle7[8] PROGMEM ={ + B00000000, + B00000000, + B00000000, + B00011000, + B00011000, + B00000000, + B00000000, + B00000000 }; + +const byte tewdoodle8[8] PROGMEM ={ + B00000000, + B00000000, + B00000000, + B00010000, + B00001000, + B00000000, + B00000000, + B00000000 }; + +const byte tewdoodle9[8] PROGMEM ={ + B00000000, + B00000000, + B00000000, + B00001000, + B00010000, + B00000000, + B00000000, + B00000000 }; + +int tewdoodles() { + + bool skip; + skip = render(tewdoodle1, 100); + if (skip) { + return true; + } + skip = render(tewdoodle2, 100); + if (skip) { + return true; + } + skip = render(tewdoodle3, 100); + if (skip) { + return true; + } + skip = render(tewdoodle4, 100); + if (skip) { + return true; + } + skip = render(tewdoodle5, 100); + if (skip) { + return true; + } + skip = render(tewdoodle6, 100); + if (skip) { + return true; + } + skip = render(tewdoodle7, 100); + if (skip) { + return true; + } + skip = render(tewdoodle8, 100); + if (skip) { + return true; + } + skip = render(tewdoodle9, 100); + if (skip) { + return true; + } + return false; + +} + diff --git a/software/ijnimations/waterdrip.ino b/software/ijnimations/waterdrip.ino new file mode 100644 index 0000000..3395115 --- /dev/null +++ b/software/ijnimations/waterdrip.ino @@ -0,0 +1,174 @@ +/* + IJnimation waterdrip by Einstein + */ +const byte drip1[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B11111111, + B11111111 +}; + + +const byte drip2[8] PROGMEM = { + B00011000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B11111111, + B11111111 +}; + +const byte drip3[8] PROGMEM = { + B00011000, + B00011000, + B00000000, + B00000000, + B00000000, + B00000000, + B11111111, + B11111111 +}; + +const byte drip4[8] PROGMEM = { + B00000000, + B00011000, + B00011000, + B00000000, + B00000000, + B00000000, + B11111111, + B11111111 +}; + +const byte drip5[8] PROGMEM = { + B00000000, + B00000000, + B00011000, + B00011000, + B00000000, + B00000000, + B11111111, + B11111111 +}; + +const byte drip6[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00011000, + B00011000, + B00000000, + B11111111, + B11111111 +}; +const byte drip7[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00011000, + B11111111, + B11111111 +}; + +const byte drip8[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B11100111, + B11111111 +}; + +const byte drip9[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00100100, + B11011011, + B11111111 +}; + +const byte drip10[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B01011010, + B10100001, + B11111111 +}; + +const byte drip11[8] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B01111110, + B11111111 + +}; + +int waterdrip() { + bool skip; + skip = render(drip1, 100); + if (skip) { + return true; + } + skip = render(drip2, 100); + if (skip) { + return true; + } + skip = render(drip3, 100); + if (skip) { + return true; + } + skip = render(drip4, 100); + if (skip) { + return true; + } + skip = render(drip5, 100); + if (skip) { + return true; + } + skip = render(drip6, 100); + if (skip) { + return true; + } + skip = render(drip7, 100); + if (skip) { + return true; + } + skip = render(drip8, 100); + if (skip) { + return true; + } + skip = render(drip9, 100); + if (skip) { + return true; + } + skip = render(drip10, 100); + if (skip) { + return true; + } + skip = render(drip11, 100); + if (skip) { + return true; + } + return false; +} + diff --git a/software/ijnimations/xmastree.ino b/software/ijnimations/xmastree.ino new file mode 100644 index 0000000..3da394d --- /dev/null +++ b/software/ijnimations/xmastree.ino @@ -0,0 +1,40 @@ +/* + xmastree by Einstein + */ +const byte xmastree1[8] PROGMEM = { + B10011000,B00111100,B01111110,B11111111,B00111100,B01111110,B11111111,B00011000 +}; + +const byte xmastree2[8] PROGMEM = { + B00011001,B00111100,B01111110,B11111111,B00111100,B01111110,B11111111,B00011000 +}; + +const byte xmastree3[8] PROGMEM = { + B01011000,B00111100,B01111110,B11111111,B00111100,B01111110,B11111111,B00011000 +}; + + +const byte xmastree4[8] PROGMEM = { + B00011010,B00111100,B01111110,B11111111,B00111100,B01111110,B11111111,B00011000 +}; + +int xmastree() { + bool skip = render(xmastree1, 500); + if (skip) { + return true; + } + skip = render(xmastree2, 500); + if (skip) { + return true; + } + skip = render(xmastree3, 500); + if (skip) { + return true; + } + skip = render(xmastree4, 500); + if (skip) { + return true; + } + return false; +} + diff --git a/software/ijpong_oneplayer/ijpong_oneplayer.ino b/software/ijpong_oneplayer/ijpong_oneplayer.ino new file mode 100644 index 0000000..bd0320a --- /dev/null +++ b/software/ijpong_oneplayer/ijpong_oneplayer.ino @@ -0,0 +1,368 @@ +/** +* Play pong on an 8x8 matrix +* +* 0 1 2 3 4 5 6 7 +* 0 +* 1 +* 2 7 0 1 +* 3 6 X 2 (directions) +* 4 5 4 3 +* 5 +* 6 +* 7 [pad] +* +* +* Based on code from http://www.itopen.it/2012/03/09/arduino-pong-with-8x8-led-matrix-and-max7219/ +* +*/ + +static const int DATA_PIN = 20; +static const int CLK_PIN = 5; +static const int CS_PIN = 21; + +#include "LedControl.h" +#include "Timer.h" + + +#define POTPIN A5 // Potentiometer +#define PADSIZE 2 +#define BALL_DELAY 200 +#define GAME_DELAY 10 +#define BOUNCE_VERTICAL 1 +#define BOUNCE_HORIZONTAL -1 +#define NEW_GAME_ANIMATION_SPEED 50 +#define HIT_NONE 0 +#define HIT_CENTER 1 +#define HIT_LEFT 2 +#define HIT_RIGHT 3 + + +//#define DEBUG 1 + + +byte sad[] = { + B11000011, + B11000011, + B00000000, + B00000000, + B00111100, + B01111110, + B11100111, + B11000011 +}; + +byte smile[] = { + B11000011, + B11000011, + B00000000, + B00000011, + B11000011, + B11100111, + B01111110, + B00111100 +}; + +byte P[] = { + B01111110, + B11111111, + B11000011, + B11000011, + B11111111, + B11111110, + B11000000, + B11000000 +}; +byte O[] = { + B01111110, + B11111111, + B11000011, + B11000011, + B11000011, + B11000011, + B11111111, + B01111110 +}; +byte N[] = { + B11000011, + B11100011, + B11110011, + B11111011, + B11011111, + B11001111, + B11000111, + B11000011 +}; +byte G[] = { + B01111110, + B11111111, + B11000011, + B11000000, + B11001111, + B11000011, + B11111111, + B01111110 +}; +Timer timer; + +LedControl lc=LedControl(DATA_PIN, CLK_PIN, CS_PIN, 1); + +byte direction; // Wind rose, 0 is north +int xball; +int yball; +int yball_prev; +byte xpad; +int ball_timer; + +void setSprite(byte *sprite) { + for (int r = 0; r < 8; r++) { + lc.setColumn(0, 7 - r, sprite[r]); + } +} + + +void newGame() { + + setSprite(smile); + delay(500); + lc.clearDisplay(0); + setSprite(P); + delay(500); + lc.clearDisplay(0); + setSprite(O); + delay(500); + lc.clearDisplay(0); + setSprite(N); + delay(500); + lc.clearDisplay(0); + setSprite(G); + delay(500); + + lc.clearDisplay(0); +// initial position +xball = random(1, 7); +yball = 1; +direction = random(3, 6); // Go south +for (int r = 0; r < 8; r++) { +for (int c = 0; c < 8; c++) { +lc.setLed(0, c, r, HIGH); +delay(NEW_GAME_ANIMATION_SPEED); +} +} +//setSprite(smile); +// +//delay(1500); +// +lc.clearDisplay(0); +} + + + +void setPad() { + xpad = map(analogRead(POTPIN), 0, 1020, 8 - PADSIZE, 0); +} + +void debug(const char* desc) { +#ifdef DEBUG + Serial.print(desc); + Serial.print(" XY: "); + Serial.print(xball); + Serial.print(", "); + Serial.print(yball); + Serial.print(" XPAD: "); + Serial.print(xpad); + Serial.print(" DIR: "); + Serial.println(direction); +#endif +} + +int checkBounce() { + if (!xball || !yball || xball == 7 || yball == 6) { + int bounce = (yball == 0 || yball == 6) ? BOUNCE_HORIZONTAL : BOUNCE_VERTICAL; +#ifdef DEBUG + debug(bounce == BOUNCE_HORIZONTAL ? "HORIZONTAL" : "VERTICAL"); +#endif + return bounce; + } + return 0; +} + +int getHit() { + if (yball != 6 || xball < xpad || xball > xpad + PADSIZE) { + return HIT_NONE; + } + if (xball == xpad + PADSIZE / 2) { + return HIT_CENTER; + } + return xball < xpad + PADSIZE / 2 ? HIT_LEFT : HIT_RIGHT; +} + +bool checkLoose() { + return yball == 6 && getHit() == HIT_NONE; +} + +void moveBall() { + debug("MOVE"); + int bounce = checkBounce(); + if (bounce) { + switch (direction) { + case 0: + direction = 4; + break; + case 1: + direction = (bounce == BOUNCE_VERTICAL) ? 7 : 3; + break; + case 2: + direction = 6; + break; + case 6: + direction = 2; + break; + case 7: + direction = (bounce == BOUNCE_VERTICAL) ? 1 : 5; + break; + case 5: + direction = (bounce == BOUNCE_VERTICAL) ? 3 : 7; + break; + case 3: + direction = (bounce == BOUNCE_VERTICAL) ? 5 : 1; + break; + case 4: + direction = 0; + break; + } + debug("->"); + } + + // Check hit: modify direction is left or right + switch (getHit()) { + case HIT_LEFT: + if (direction == 0) { + direction = 7; + } else if (direction == 1) { + direction = 0; + } + break; + case HIT_RIGHT: + if (direction == 0) { + direction = 1; + } else if (direction == 7) { + direction = 0; + } + break; + } + + // Check orthogonal directions and borders ... + if ((direction == 0 && xball == 0) || (direction == 4 && xball == 7)) { + direction++; + } + if (direction == 0 && xball == 7) { + direction = 7; + } + if (direction == 4 && xball == 0) { + direction = 3; + } + if (direction == 2 && yball == 0) { + direction = 3; + } + if (direction == 2 && yball == 6) { + direction = 1; + } + if (direction == 6 && yball == 0) { + direction = 5; + } + if (direction == 6 && yball == 6) { + direction = 7; + } + + // "Corner" case + if (xball == 0 && yball == 0) { + direction = 3; + } + if (xball == 0 && yball == 6) { + direction = 1; + } + if (xball == 7 && yball == 6) { + direction = 7; + } + if (xball == 7 && yball == 0) { + direction = 5; + } + + yball_prev = yball; + if (2 < direction && direction < 6) { + yball++; + } else if (direction != 6 && direction != 2) { + yball--; + } + if (0 < direction && direction < 4) { + xball++; + } else if (direction != 0 && direction != 4) { + xball--; + } + xball = max(0, min(7, xball)); + yball = max(0, min(6, yball)); + debug("AFTER MOVE"); +} + +void gameOver() { + setSprite(sad); + delay(500); + lc.clearDisplay(0); + delay(500); + setSprite(sad); + delay(500); + lc.clearDisplay(0); + delay(500); + setSprite(sad); + delay(1500); + lc.clearDisplay(0); +} + +void drawGame() { + if (yball_prev != yball) { + lc.setColumn(0, 7 - yball_prev, 0); + } + lc.setColumn(0, 7 - yball, byte(1 << (xball))); + byte padmap = byte(0xFF >> (8 - PADSIZE) << xpad) ; +#ifdef DEBUG + //Serial.println(padmap, BIN); +#endif + lc.setColumn(0, 0, padmap); +} + +void setup() { + // The MAX72XX is in power-saving mode on startup, + // we have to do a wakeup call + pinMode(POTPIN, INPUT); + + lc.shutdown(0, false); + // Set the brightness to a medium values + lc.setIntensity(0, 8); + // and clear the display + lc.clearDisplay(0); + randomSeed(analogRead(0)); +#ifdef DEBUG + Serial.begin(9600); + Serial.println("Pong"); +#endif + newGame(); + ball_timer = timer.every(BALL_DELAY, moveBall); +} + + +void loop() { + timer.update(); + // Move pad + setPad(); +#ifdef DEBUG + Serial.println(xpad); +#endif + // Update screen + drawGame(); + if (checkLoose()) { + debug("LOOSE"); + gameOver(); + newGame(); + } + delay(GAME_DELAY); +} diff --git a/software/imperialmarch/imperialmarch.ino b/software/imperialmarch/imperialmarch.ino new file mode 100644 index 0000000..1dc9528 --- /dev/null +++ b/software/imperialmarch/imperialmarch.ino @@ -0,0 +1,273 @@ +// From http://www.instructables.com/id/How-to-easily-play-music-with-buzzer-on-arduino-Th/ + +// NB: ALL NOTES DEFINED WITH STANDARD ENGLISH NAMES, EXCEPT FROM "A" +//THAT IS CALLED WITH THE ITALIAN NAME "LA" BECAUSE A0,A1...ARE THE ANALOG PINS ON ARDUINO. +// (Ab IS CALLED Ab AND NOT LAb) +#define C0 16.35 +#define Db0 17.32 +#define D0 18.35 +#define Eb0 19.45 +#define E0 20.60 +#define F0 21.83 +#define Gb0 23.12 +#define G0 24.50 +#define Ab0 25.96 +#define LA0 27.50 +#define Bb0 29.14 +#define B0 30.87 +#define C1 32.70 +#define Db1 34.65 +#define D1 36.71 +#define Eb1 38.89 +#define E1 41.20 +#define F1 43.65 +#define Gb1 46.25 +#define G1 49.00 +#define Ab1 51.91 +#define LA1 55.00 +#define Bb1 58.27 +#define B1 61.74 +#define C2 65.41 +#define Db2 69.30 +#define D2 73.42 +#define Eb2 77.78 +#define E2 82.41 +#define F2 87.31 +#define Gb2 92.50 +#define G2 98.00 +#define Ab2 103.83 +#define LA2 110.00 +#define Bb2 116.54 +#define B2 123.47 +#define C3 130.81 +#define Db3 138.59 +#define D3 146.83 +#define Eb3 155.56 +#define E3 164.81 +#define F3 174.61 +#define Gb3 185.00 +#define G3 196.00 +#define Ab3 207.65 +#define LA3 220.00 +#define Bb3 233.08 +#define B3 246.94 +#define C4 261.63 +#define Db4 277.18 +#define D4 293.66 +#define Eb4 311.13 +#define E4 329.63 +#define F4 349.23 +#define Gb4 369.99 +#define G4 392.00 +#define Ab4 415.30 +#define LA4 440.00 +#define Bb4 466.16 +#define B4 493.88 +#define C5 523.25 +#define Db5 554.37 +#define D5 587.33 +#define Eb5 622.25 +#define E5 659.26 +#define F5 698.46 +#define Gb5 739.99 +#define G5 783.99 +#define Ab5 830.61 +#define LA5 880.00 +#define Bb5 932.33 +#define B5 987.77 +#define C6 1046.50 +#define Db6 1108.73 +#define D6 1174.66 +#define Eb6 1244.51 +#define E6 1318.51 +#define F6 1396.91 +#define Gb6 1479.98 +#define G6 1567.98 +#define Ab6 1661.22 +#define LA6 1760.00 +#define Bb6 1864.66 +#define B6 1975.53 +#define C7 2093.00 +#define Db7 2217.46 +#define D7 2349.32 +#define Eb7 2489.02 +#define E7 2637.02 +#define F7 2793.83 +#define Gb7 2959.96 +#define G7 3135.96 +#define Ab7 3322.44 +#define LA7 3520.01 +#define Bb7 3729.31 +#define B7 3951.07 +#define C8 4186.01 +#define Db8 4434.92 +#define D8 4698.64 +#define Eb8 4978.03 +// DURATION OF THE NOTES +#define BPM 120 // you can change this value changing all the others +#define H 2*Q //half 2/4 +#define Q 60000/BPM //quarter 1/4 +#define E Q/2 //eighth 1/8 +#define S Q/4 // sixteenth 1/16 +#define W 4*Q // whole 4/4 + +int outpin = 8; + +void setup() { +pinMode(outpin, OUTPUT); +} + +// the loop routine runs over and over again forever: +void loop() { + //tone(pin, note, duration) + tone(outpin,LA3,Q); + delay(1+Q); //delay duration should always be 1 ms more than the note in order to separate them. + tone(outpin,LA3,Q); + delay(1+Q); + tone(outpin,LA3,Q); + delay(1+Q); + tone(outpin,F3,E+S); + delay(1+E+S); + tone(outpin,C4,S); + delay(1+S); + + tone(outpin,LA3,Q); + delay(1+Q); + tone(outpin,F3,E+S); + delay(1+E+S); + tone(outpin,C4,S); + delay(1+S); + tone(outpin,LA3,H); + delay(1+H); + + tone(outpin,E4,Q); + delay(1+Q); + tone(outpin,E4,Q); + delay(1+Q); + tone(outpin,E4,Q); + delay(1+Q); + tone(outpin,F4,E+S); + delay(1+E+S); + tone(outpin,C4,S); + delay(1+S); + + tone(outpin,Ab3,Q); + delay(1+Q); + tone(outpin,F3,E+S); + delay(1+E+S); + tone(outpin,C4,S); + delay(1+S); + tone(outpin,LA3,H); + delay(1+H); + + tone(outpin,LA4,Q); + delay(1+Q); + tone(outpin,LA3,E+S); + delay(1+E+S); + tone(outpin,LA3,S); + delay(1+S); + tone(outpin,LA4,Q); + delay(1+Q); + tone(outpin,Ab4,E+S); + delay(1+E+S); + tone(outpin,G4,S); + delay(1+S); + + tone(outpin,Gb4,S); + delay(1+S); + tone(outpin,E4,S); + delay(1+S); + tone(outpin,F4,E); + delay(1+E); + delay(1+E);//PAUSE + tone(outpin,Bb3,E); + delay(1+E); + tone(outpin,Eb4,Q); + delay(1+Q); + tone(outpin,D4,E+S); + delay(1+E+S); + tone(outpin,Db4,S); + delay(1+S); + + tone(outpin,C4,S); + delay(1+S); + tone(outpin,B3,S); + delay(1+S); + tone(outpin,C4,E); + delay(1+E); + delay(1+E);//PAUSE QUASI FINE RIGA + tone(outpin,F3,E); + delay(1+E); + tone(outpin,Ab3,Q); + delay(1+Q); + tone(outpin,F3,E+S); + delay(1+E+S); + tone(outpin,LA3,S); + delay(1+S); + + tone(outpin,C4,Q); + delay(1+Q); + tone(outpin,LA3,E+S); + delay(1+E+S); + tone(outpin,C4,S); + delay(1+S); + tone(outpin,E4,H); + delay(1+H); + + tone(outpin,LA4,Q); + delay(1+Q); + tone(outpin,LA3,E+S); + delay(1+E+S); + tone(outpin,LA3,S); + delay(1+S); + tone(outpin,LA4,Q); + delay(1+Q); + tone(outpin,Ab4,E+S); + delay(1+E+S); + tone(outpin,G4,S); + delay(1+S); + + tone(outpin,Gb4,S); + delay(1+S); + tone(outpin,E4,S); + delay(1+S); + tone(outpin,F4,E); + delay(1+E); + delay(1+E);//PAUSE + tone(outpin,Bb3,E); + delay(1+E); + tone(outpin,Eb4,Q); + delay(1+Q); + tone(outpin,D4,E+S); + delay(1+E+S); + tone(outpin,Db4,S); + delay(1+S); + + tone(outpin,C4,S); + delay(1+S); + tone(outpin,B3,S); + delay(1+S); + tone(outpin,C4,E); + delay(1+E); + delay(1+E);//PAUSE QUASI FINE RIGA + tone(outpin,F3,E); + delay(1+E); + tone(outpin,Ab3,Q); + delay(1+Q); + tone(outpin,F3,E+S); + delay(1+E+S); + tone(outpin,C4,S); + delay(1+S); + + tone(outpin,LA3,Q); + delay(1+Q); + tone(outpin,F3,E+S); + delay(1+E+S); + tone(outpin,C4,S); + delay(1+S); + tone(outpin,LA3,H); + delay(1+H); + + delay(2*H); + +} diff --git a/software/newsticker/font.h b/software/newsticker/font.h new file mode 100644 index 0000000..20f56f8 --- /dev/null +++ b/software/newsticker/font.h @@ -0,0 +1,778 @@ +#if (ARDUINO >= 100) +#include +#else +#include +#endif + + +const byte cp437_font [256] [8] PROGMEM = { + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + , // 0x00 + { + 0x7E, 0x81, 0x95, 0xB1, 0xB1, 0x95, 0x81, 0x7E } + , // 0x01 + { + 0x7E, 0xFF, 0xEB, 0xCF, 0xCF, 0xEB, 0xFF, 0x7E } + , // 0x02 + { + 0x0E, 0x1F, 0x3F, 0x7E, 0x3F, 0x1F, 0x0E, 0x00 } + , // 0x03 + { + 0x08, 0x1C, 0x3E, 0x7F, 0x3E, 0x1C, 0x08, 0x00 } + , // 0x04 + { + 0x18, 0xBA, 0xFF, 0xFF, 0xFF, 0xBA, 0x18, 0x00 } + , // 0x05 + { + 0x10, 0xB8, 0xFC, 0xFF, 0xFC, 0xB8, 0x10, 0x00 } + , // 0x06 + { + 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00 } + , // 0x07 + { + 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF } + , // 0x08 + { + 0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00 } + , // 0x09 + { + 0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF } + , // 0x0A + { + 0x70, 0xF8, 0x88, 0x88, 0xFD, 0x7F, 0x07, 0x0F } + , // 0x0B + { + 0x00, 0x4E, 0x5F, 0xF1, 0xF1, 0x5F, 0x4E, 0x00 } + , // 0x0C + { + 0xC0, 0xE0, 0xFF, 0x7F, 0x05, 0x05, 0x07, 0x07 } + , // 0x0D + { + 0xC0, 0xFF, 0x7F, 0x05, 0x05, 0x65, 0x7F, 0x3F } + , // 0x0E + { + 0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99 } + , // 0x0F + { + 0x7F, 0x3E, 0x3E, 0x1C, 0x1C, 0x08, 0x08, 0x00 } + , // 0x10 + { + 0x08, 0x08, 0x1C, 0x1C, 0x3E, 0x3E, 0x7F, 0x00 } + , // 0x11 + { + 0x00, 0x24, 0x66, 0xFF, 0xFF, 0x66, 0x24, 0x00 } + , // 0x12 + { + 0x00, 0x5F, 0x5F, 0x00, 0x00, 0x5F, 0x5F, 0x00 } + , // 0x13 + { + 0x06, 0x0F, 0x09, 0x7F, 0x7F, 0x01, 0x7F, 0x7F } + , // 0x14 + { + 0x40, 0xDA, 0xBF, 0xA5, 0xFD, 0x59, 0x03, 0x02 } + , // 0x15 + { + 0x00, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x00 } + , // 0x16 + { + 0x80, 0x94, 0xB6, 0xFF, 0xFF, 0xB6, 0x94, 0x80 } + , // 0x17 + { + 0x00, 0x04, 0x06, 0x7F, 0x7F, 0x06, 0x04, 0x00 } + , // 0x18 + { + 0x00, 0x10, 0x30, 0x7F, 0x7F, 0x30, 0x10, 0x00 } + , // 0x19 + { + 0x08, 0x08, 0x08, 0x2A, 0x3E, 0x1C, 0x08, 0x00 } + , // 0x1A + { + 0x08, 0x1C, 0x3E, 0x2A, 0x08, 0x08, 0x08, 0x00 } + , // 0x1B + { + 0x3C, 0x3C, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00 } + , // 0x1C + { + 0x08, 0x1C, 0x3E, 0x08, 0x08, 0x3E, 0x1C, 0x08 } + , // 0x1D + { + 0x30, 0x38, 0x3C, 0x3E, 0x3E, 0x3C, 0x38, 0x30 } + , // 0x1E + { + 0x06, 0x0E, 0x1E, 0x3E, 0x3E, 0x1E, 0x0E, 0x06 } + , // 0x1F + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + , // ' ' + { + 0x00, 0x06, 0x5F, 0x5F, 0x06, 0x00, 0x00, 0x00 } + , // '!' + { + 0x00, 0x07, 0x07, 0x00, 0x07, 0x07, 0x00, 0x00 } + , // '"' + { + 0x14, 0x7F, 0x7F, 0x14, 0x7F, 0x7F, 0x14, 0x00 } + , // '#' + { + 0x24, 0x2E, 0x6B, 0x6B, 0x3A, 0x12, 0x00, 0x00 } + , // '$' + { + 0x46, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x62, 0x00 } + , // '%' + { + 0x30, 0x7A, 0x4F, 0x5D, 0x37, 0x7A, 0x48, 0x00 } + , // '&' + { + 0x04, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 } + , // ''' + { + 0x00, 0x1C, 0x3E, 0x63, 0x41, 0x00, 0x00, 0x00 } + , // '(' + { + 0x00, 0x41, 0x63, 0x3E, 0x1C, 0x00, 0x00, 0x00 } + , // ')' + { + 0x08, 0x2A, 0x3E, 0x1C, 0x1C, 0x3E, 0x2A, 0x08 } + , // '*' + { + 0x08, 0x08, 0x3E, 0x3E, 0x08, 0x08, 0x00, 0x00 } + , // '+' + { + 0x00, 0x80, 0xE0, 0x60, 0x00, 0x00, 0x00, 0x00 } + , // ',' + { + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00 } + , // '-' + { + 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00 } + , // '.' + { + 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00 } + , // '/' + { + 0x3E, 0x7F, 0x71, 0x59, 0x4D, 0x7F, 0x3E, 0x00 } + , // '0' + { + 0x40, 0x42, 0x7F, 0x7F, 0x40, 0x40, 0x00, 0x00 } + , // '1' + { + 0x62, 0x73, 0x59, 0x49, 0x6F, 0x66, 0x00, 0x00 } + , // '2' + { + 0x22, 0x63, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00 } + , // '3' + { + 0x18, 0x1C, 0x16, 0x53, 0x7F, 0x7F, 0x50, 0x00 } + , // '4' + { + 0x27, 0x67, 0x45, 0x45, 0x7D, 0x39, 0x00, 0x00 } + , // '5' + { + 0x3C, 0x7E, 0x4B, 0x49, 0x79, 0x30, 0x00, 0x00 } + , // '6' + { + 0x03, 0x03, 0x71, 0x79, 0x0F, 0x07, 0x00, 0x00 } + , // '7' + { + 0x36, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00 } + , // '8' + { + 0x06, 0x4F, 0x49, 0x69, 0x3F, 0x1E, 0x00, 0x00 } + , // '9' + { + 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00 } + , // ':' + { + 0x00, 0x80, 0xE6, 0x66, 0x00, 0x00, 0x00, 0x00 } + , // ';' + { + 0x08, 0x1C, 0x36, 0x63, 0x41, 0x00, 0x00, 0x00 } + , // '<' + { + 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00 } + , // '=' + { + 0x00, 0x41, 0x63, 0x36, 0x1C, 0x08, 0x00, 0x00 } + , // '>' + { + 0x02, 0x03, 0x51, 0x59, 0x0F, 0x06, 0x00, 0x00 } + , // '?' + { + 0x3E, 0x7F, 0x41, 0x5D, 0x5D, 0x1F, 0x1E, 0x00 } + , // '@' + { + 0x7C, 0x7E, 0x13, 0x13, 0x7E, 0x7C, 0x00, 0x00 } + , // 'A' + { + 0x41, 0x7F, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00 } + , // 'B' + { + 0x1C, 0x3E, 0x63, 0x41, 0x41, 0x63, 0x22, 0x00 } + , // 'C' + { + 0x41, 0x7F, 0x7F, 0x41, 0x63, 0x3E, 0x1C, 0x00 } + , // 'D' + { + 0x41, 0x7F, 0x7F, 0x49, 0x5D, 0x41, 0x63, 0x00 } + , // 'E' + { + 0x41, 0x7F, 0x7F, 0x49, 0x1D, 0x01, 0x03, 0x00 } + , // 'F' + { + 0x1C, 0x3E, 0x63, 0x41, 0x51, 0x73, 0x72, 0x00 } + , // 'G' + { + 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00 } + , // 'H' + { + 0x00, 0x41, 0x7F, 0x7F, 0x41, 0x00, 0x00, 0x00 } + , // 'I' + { + 0x30, 0x70, 0x40, 0x41, 0x7F, 0x3F, 0x01, 0x00 } + , // 'J' + { + 0x41, 0x7F, 0x7F, 0x08, 0x1C, 0x77, 0x63, 0x00 } + , // 'K' + { + 0x41, 0x7F, 0x7F, 0x41, 0x40, 0x60, 0x70, 0x00 } + , // 'L' + { + 0x7F, 0x7F, 0x0E, 0x1C, 0x0E, 0x7F, 0x7F, 0x00 } + , // 'M' + { + 0x7F, 0x7F, 0x06, 0x0C, 0x18, 0x7F, 0x7F, 0x00 } + , // 'N' + { + 0x1C, 0x3E, 0x63, 0x41, 0x63, 0x3E, 0x1C, 0x00 } + , // 'O' + { + 0x41, 0x7F, 0x7F, 0x49, 0x09, 0x0F, 0x06, 0x00 } + , // 'P' + { + 0x1E, 0x3F, 0x21, 0x71, 0x7F, 0x5E, 0x00, 0x00 } + , // 'Q' + { + 0x41, 0x7F, 0x7F, 0x09, 0x19, 0x7F, 0x66, 0x00 } + , // 'R' + { + 0x26, 0x6F, 0x4D, 0x59, 0x73, 0x32, 0x00, 0x00 } + , // 'S' + { + 0x03, 0x41, 0x7F, 0x7F, 0x41, 0x03, 0x00, 0x00 } + , // 'T' + { + 0x7F, 0x7F, 0x40, 0x40, 0x7F, 0x7F, 0x00, 0x00 } + , // 'U' + { + 0x1F, 0x3F, 0x60, 0x60, 0x3F, 0x1F, 0x00, 0x00 } + , // 'V' + { + 0x7F, 0x7F, 0x30, 0x18, 0x30, 0x7F, 0x7F, 0x00 } + , // 'W' + { + 0x43, 0x67, 0x3C, 0x18, 0x3C, 0x67, 0x43, 0x00 } + , // 'X' + { + 0x07, 0x4F, 0x78, 0x78, 0x4F, 0x07, 0x00, 0x00 } + , // 'Y' + { + 0x47, 0x63, 0x71, 0x59, 0x4D, 0x67, 0x73, 0x00 } + , // 'Z' + { + 0x00, 0x7F, 0x7F, 0x41, 0x41, 0x00, 0x00, 0x00 } + , // '[' + { + 0x01, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00 } + , // backslash + { + 0x00, 0x41, 0x41, 0x7F, 0x7F, 0x00, 0x00, 0x00 } + , // ']' + { + 0x08, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x08, 0x00 } + , // '^' + { + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 } + , // '_' + { + 0x00, 0x00, 0x03, 0x07, 0x04, 0x00, 0x00, 0x00 } + , // '`' + { + 0x20, 0x74, 0x54, 0x54, 0x3C, 0x78, 0x40, 0x00 } + , // 'a' + { + 0x41, 0x7F, 0x3F, 0x48, 0x48, 0x78, 0x30, 0x00 } + , // 'b' + { + 0x38, 0x7C, 0x44, 0x44, 0x6C, 0x28, 0x00, 0x00 } + , // 'c' + { + 0x30, 0x78, 0x48, 0x49, 0x3F, 0x7F, 0x40, 0x00 } + , // 'd' + { + 0x38, 0x7C, 0x54, 0x54, 0x5C, 0x18, 0x00, 0x00 } + , // 'e' + { + 0x48, 0x7E, 0x7F, 0x49, 0x03, 0x02, 0x00, 0x00 } + , // 'f' + { + 0x98, 0xBC, 0xA4, 0xA4, 0xF8, 0x7C, 0x04, 0x00 } + , // 'g' + { + 0x41, 0x7F, 0x7F, 0x08, 0x04, 0x7C, 0x78, 0x00 } + , // 'h' + { + 0x00, 0x44, 0x7D, 0x7D, 0x40, 0x00, 0x00, 0x00 } + , // 'i' + { + 0x60, 0xE0, 0x80, 0x80, 0xFD, 0x7D, 0x00, 0x00 } + , // 'j' + { + 0x41, 0x7F, 0x7F, 0x10, 0x38, 0x6C, 0x44, 0x00 } + , // 'k' + { + 0x00, 0x41, 0x7F, 0x7F, 0x40, 0x00, 0x00, 0x00 } + , // 'l' + { + 0x7C, 0x7C, 0x18, 0x38, 0x1C, 0x7C, 0x78, 0x00 } + , // 'm' + { + 0x7C, 0x7C, 0x04, 0x04, 0x7C, 0x78, 0x00, 0x00 } + , // 'n' + { + 0x38, 0x7C, 0x44, 0x44, 0x7C, 0x38, 0x00, 0x00 } + , // 'o' + { + 0x84, 0xFC, 0xF8, 0xA4, 0x24, 0x3C, 0x18, 0x00 } + , // 'p' + { + 0x18, 0x3C, 0x24, 0xA4, 0xF8, 0xFC, 0x84, 0x00 } + , // 'q' + { + 0x44, 0x7C, 0x78, 0x4C, 0x04, 0x1C, 0x18, 0x00 } + , // 'r' + { + 0x48, 0x5C, 0x54, 0x54, 0x74, 0x24, 0x00, 0x00 } + , // 's' + { + 0x00, 0x04, 0x3E, 0x7F, 0x44, 0x24, 0x00, 0x00 } + , // 't' + { + 0x3C, 0x7C, 0x40, 0x40, 0x3C, 0x7C, 0x40, 0x00 } + , // 'u' + { + 0x1C, 0x3C, 0x60, 0x60, 0x3C, 0x1C, 0x00, 0x00 } + , // 'v' + { + 0x3C, 0x7C, 0x70, 0x38, 0x70, 0x7C, 0x3C, 0x00 } + , // 'w' + { + 0x44, 0x6C, 0x38, 0x10, 0x38, 0x6C, 0x44, 0x00 } + , // 'x' + { + 0x9C, 0xBC, 0xA0, 0xA0, 0xFC, 0x7C, 0x00, 0x00 } + , // 'y' + { + 0x4C, 0x64, 0x74, 0x5C, 0x4C, 0x64, 0x00, 0x00 } + , // 'z' + { + 0x08, 0x08, 0x3E, 0x77, 0x41, 0x41, 0x00, 0x00 } + , // '{' + { + 0x00, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0x00 } + , // '|' + { + 0x41, 0x41, 0x77, 0x3E, 0x08, 0x08, 0x00, 0x00 } + , // '}' + { + 0x02, 0x03, 0x01, 0x03, 0x02, 0x03, 0x01, 0x00 } + , // '~' + { + 0x70, 0x78, 0x4C, 0x46, 0x4C, 0x78, 0x70, 0x00 } + , // 0x7F + { + 0x0E, 0x9F, 0x91, 0xB1, 0xFB, 0x4A, 0x00, 0x00 } + , // 0x80 + { + 0x3A, 0x7A, 0x40, 0x40, 0x7A, 0x7A, 0x40, 0x00 } + , // 0x81 + { + 0x38, 0x7C, 0x54, 0x55, 0x5D, 0x19, 0x00, 0x00 } + , // 0x82 + { + 0x02, 0x23, 0x75, 0x55, 0x55, 0x7D, 0x7B, 0x42 } + , // 0x83 + { + 0x21, 0x75, 0x54, 0x54, 0x7D, 0x79, 0x40, 0x00 } + , // 0x84 + { + 0x21, 0x75, 0x55, 0x54, 0x7C, 0x78, 0x40, 0x00 } + , // 0x85 + { + 0x20, 0x74, 0x57, 0x57, 0x7C, 0x78, 0x40, 0x00 } + , // 0x86 + { + 0x18, 0x3C, 0xA4, 0xA4, 0xE4, 0x40, 0x00, 0x00 } + , // 0x87 + { + 0x02, 0x3B, 0x7D, 0x55, 0x55, 0x5D, 0x1B, 0x02 } + , // 0x88 + { + 0x39, 0x7D, 0x54, 0x54, 0x5D, 0x19, 0x00, 0x00 } + , // 0x89 + { + 0x39, 0x7D, 0x55, 0x54, 0x5C, 0x18, 0x00, 0x00 } + , // 0x8A + { + 0x01, 0x45, 0x7C, 0x7C, 0x41, 0x01, 0x00, 0x00 } + , // 0x8B + { + 0x02, 0x03, 0x45, 0x7D, 0x7D, 0x43, 0x02, 0x00 } + , // 0x8C + { + 0x01, 0x45, 0x7D, 0x7C, 0x40, 0x00, 0x00, 0x00 } + , // 0x8D + { + 0x79, 0x7D, 0x16, 0x12, 0x16, 0x7D, 0x79, 0x00 } + , // 0x8E + { + 0x70, 0x78, 0x2B, 0x2B, 0x78, 0x70, 0x00, 0x00 } + , // 0x8F + { + 0x44, 0x7C, 0x7C, 0x55, 0x55, 0x45, 0x00, 0x00 } + , // 0x90 + { + 0x20, 0x74, 0x54, 0x54, 0x7C, 0x7C, 0x54, 0x54 } + , // 0x91 + { + 0x7C, 0x7E, 0x0B, 0x09, 0x7F, 0x7F, 0x49, 0x00 } + , // 0x92 + { + 0x32, 0x7B, 0x49, 0x49, 0x7B, 0x32, 0x00, 0x00 } + , // 0x93 + { + 0x32, 0x7A, 0x48, 0x48, 0x7A, 0x32, 0x00, 0x00 } + , // 0x94 + { + 0x32, 0x7A, 0x4A, 0x48, 0x78, 0x30, 0x00, 0x00 } + , // 0x95 + { + 0x3A, 0x7B, 0x41, 0x41, 0x7B, 0x7A, 0x40, 0x00 } + , // 0x96 + { + 0x3A, 0x7A, 0x42, 0x40, 0x78, 0x78, 0x40, 0x00 } + , // 0x97 + { + 0x9A, 0xBA, 0xA0, 0xA0, 0xFA, 0x7A, 0x00, 0x00 } + , // 0x98 + { + 0x01, 0x19, 0x3C, 0x66, 0x66, 0x3C, 0x19, 0x01 } + , // 0x99 + { + 0x3D, 0x7D, 0x40, 0x40, 0x7D, 0x3D, 0x00, 0x00 } + , // 0x9A + { + 0x18, 0x3C, 0x24, 0xE7, 0xE7, 0x24, 0x24, 0x00 } + , // 0x9B + { + 0x68, 0x7E, 0x7F, 0x49, 0x43, 0x66, 0x20, 0x00 } + , // 0x9C + { + 0x2B, 0x2F, 0xFC, 0xFC, 0x2F, 0x2B, 0x00, 0x00 } + , // 0x9D + { + 0xFF, 0xFF, 0x09, 0x09, 0x2F, 0xF6, 0xF8, 0xA0 } + , // 0x9E + { + 0x40, 0xC0, 0x88, 0xFE, 0x7F, 0x09, 0x03, 0x02 } + , // 0x9F + { + 0x20, 0x74, 0x54, 0x55, 0x7D, 0x79, 0x40, 0x00 } + , // 0xA0 + { + 0x00, 0x44, 0x7D, 0x7D, 0x41, 0x00, 0x00, 0x00 } + , // 0xA1 + { + 0x30, 0x78, 0x48, 0x4A, 0x7A, 0x32, 0x00, 0x00 } + , // 0xA2 + { + 0x38, 0x78, 0x40, 0x42, 0x7A, 0x7A, 0x40, 0x00 } + , // 0xA3 + { + 0x7A, 0x7A, 0x0A, 0x0A, 0x7A, 0x70, 0x00, 0x00 } + , // 0xA4 + { + 0x7D, 0x7D, 0x19, 0x31, 0x7D, 0x7D, 0x00, 0x00 } + , // 0xA5 + { + 0x00, 0x26, 0x2F, 0x29, 0x2F, 0x2F, 0x28, 0x00 } + , // 0xA6 + { + 0x00, 0x26, 0x2F, 0x29, 0x2F, 0x26, 0x00, 0x00 } + , // 0xA7 + { + 0x30, 0x78, 0x4D, 0x45, 0x60, 0x20, 0x00, 0x00 } + , // 0xA8 + { + 0x38, 0x38, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00 } + , // 0xA9 + { + 0x08, 0x08, 0x08, 0x08, 0x38, 0x38, 0x00, 0x00 } + , // 0xAA + { + 0x4F, 0x6F, 0x30, 0x18, 0xCC, 0xEE, 0xBB, 0x91 } + , // 0xAB + { + 0x4F, 0x6F, 0x30, 0x18, 0x6C, 0x76, 0xFB, 0xF9 } + , // 0xAC + { + 0x00, 0x00, 0x00, 0x7B, 0x7B, 0x00, 0x00, 0x00 } + , // 0xAD + { + 0x08, 0x1C, 0x36, 0x22, 0x08, 0x1C, 0x36, 0x22 } + , // 0xAE + { + 0x22, 0x36, 0x1C, 0x08, 0x22, 0x36, 0x1C, 0x08 } + , // 0xAF + { + 0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00 } + , // 0xB0 + { + 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 } + , // 0xB1 + { + 0xDD, 0xFF, 0xAA, 0x77, 0xDD, 0xAA, 0xFF, 0x77 } + , // 0xB2 + { + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00 } + , // 0xB3 + { + 0x10, 0x10, 0x10, 0xFF, 0xFF, 0x00, 0x00, 0x00 } + , // 0xB4 + { + 0x14, 0x14, 0x14, 0xFF, 0xFF, 0x00, 0x00, 0x00 } + , // 0xB5 + { + 0x10, 0x10, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00 } + , // 0xB6 + { + 0x10, 0x10, 0xF0, 0xF0, 0x10, 0xF0, 0xF0, 0x00 } + , // 0xB7 + { + 0x14, 0x14, 0x14, 0xFC, 0xFC, 0x00, 0x00, 0x00 } + , // 0xB8 + { + 0x14, 0x14, 0xF7, 0xF7, 0x00, 0xFF, 0xFF, 0x00 } + , // 0xB9 + { + 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00 } + , // 0xBA + { + 0x14, 0x14, 0xF4, 0xF4, 0x04, 0xFC, 0xFC, 0x00 } + , // 0xBB + { + 0x14, 0x14, 0x17, 0x17, 0x10, 0x1F, 0x1F, 0x00 } + , // 0xBC + { + 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x1F, 0x1F, 0x00 } + , // 0xBD + { + 0x14, 0x14, 0x14, 0x1F, 0x1F, 0x00, 0x00, 0x00 } + , // 0xBE + { + 0x10, 0x10, 0x10, 0xF0, 0xF0, 0x00, 0x00, 0x00 } + , // 0xBF + { + 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x10, 0x10, 0x10 } + , // 0xC0 + { + 0x10, 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x10 } + , // 0xC1 + { + 0x10, 0x10, 0x10, 0xF0, 0xF0, 0x10, 0x10, 0x10 } + , // 0xC2 + { + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x10, 0x10, 0x10 } + , // 0xC3 + { + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 } + , // 0xC4 + { + 0x10, 0x10, 0x10, 0xFF, 0xFF, 0x10, 0x10, 0x10 } + , // 0xC5 + { + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x14, 0x14, 0x14 } + , // 0xC6 + { + 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x10 } + , // 0xC7 + { + 0x00, 0x00, 0x1F, 0x1F, 0x10, 0x17, 0x17, 0x14 } + , // 0xC8 + { + 0x00, 0x00, 0xFC, 0xFC, 0x04, 0xF4, 0xF4, 0x14 } + , // 0xC9 + { + 0x14, 0x14, 0x17, 0x17, 0x10, 0x17, 0x17, 0x14 } + , // 0xCA + { + 0x14, 0x14, 0xF4, 0xF4, 0x04, 0xF4, 0xF4, 0x14 } + , // 0xCB + { + 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xF7, 0xF7, 0x14 } + , // 0xCC + { + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14 } + , // 0xCD + { + 0x14, 0x14, 0xF7, 0xF7, 0x00, 0xF7, 0xF7, 0x14 } + , // 0xCE + { + 0x14, 0x14, 0x14, 0x17, 0x17, 0x14, 0x14, 0x14 } + , // 0xCF + { + 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x1F, 0x1F, 0x10 } + , // 0xD0 + { + 0x14, 0x14, 0x14, 0xF4, 0xF4, 0x14, 0x14, 0x14 } + , // 0xD1 + { + 0x10, 0x10, 0xF0, 0xF0, 0x10, 0xF0, 0xF0, 0x10 } + , // 0xD2 + { + 0x00, 0x00, 0x1F, 0x1F, 0x10, 0x1F, 0x1F, 0x10 } + , // 0xD3 + { + 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x14, 0x14, 0x14 } + , // 0xD4 + { + 0x00, 0x00, 0x00, 0xFC, 0xFC, 0x14, 0x14, 0x14 } + , // 0xD5 + { + 0x00, 0x00, 0xF0, 0xF0, 0x10, 0xF0, 0xF0, 0x10 } + , // 0xD6 + { + 0x10, 0x10, 0xFF, 0xFF, 0x10, 0xFF, 0xFF, 0x10 } + , // 0xD7 + { + 0x14, 0x14, 0x14, 0xFF, 0xFF, 0x14, 0x14, 0x14 } + , // 0xD8 + { + 0x10, 0x10, 0x10, 0x1F, 0x1F, 0x00, 0x00, 0x00 } + , // 0xD9 + { + 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x10, 0x10, 0x10 } + , // 0xDA + { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } + , // 0xDB + { + 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0 } + , // 0xDC + { + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 } + , // 0xDD + { + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF } + , // 0xDE + { + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F } + , // 0xDF + { + 0x38, 0x7C, 0x44, 0x6C, 0x38, 0x6C, 0x44, 0x00 } + , // 0xE0 + { + 0xFC, 0xFE, 0x2A, 0x2A, 0x3E, 0x14, 0x00, 0x00 } + , // 0xE1 + { + 0x7E, 0x7E, 0x02, 0x02, 0x06, 0x06, 0x00, 0x00 } + , // 0xE2 + { + 0x02, 0x7E, 0x7E, 0x02, 0x7E, 0x7E, 0x02, 0x00 } + , // 0xE3 + { + 0x63, 0x77, 0x5D, 0x49, 0x63, 0x63, 0x00, 0x00 } + , // 0xE4 + { + 0x38, 0x7C, 0x44, 0x7C, 0x3C, 0x04, 0x04, 0x00 } + , // 0xE5 + { + 0x80, 0xFE, 0x7E, 0x20, 0x20, 0x3E, 0x1E, 0x00 } + , // 0xE6 + { + 0x04, 0x06, 0x02, 0x7E, 0x7C, 0x06, 0x02, 0x00 } + , // 0xE7 + { + 0x99, 0xBD, 0xE7, 0xE7, 0xBD, 0x99, 0x00, 0x00 } + , // 0xE8 + { + 0x1C, 0x3E, 0x6B, 0x49, 0x6B, 0x3E, 0x1C, 0x00 } + , // 0xE9 + { + 0x4C, 0x7E, 0x73, 0x01, 0x73, 0x7E, 0x4C, 0x00 } + , // 0xEA + { + 0x30, 0x78, 0x4A, 0x4F, 0x7D, 0x39, 0x00, 0x00 } + , // 0xEB + { + 0x18, 0x3C, 0x24, 0x3C, 0x3C, 0x24, 0x3C, 0x18 } + , // 0xEC + { + 0x98, 0xFC, 0x64, 0x3C, 0x3E, 0x27, 0x3D, 0x18 } + , // 0xED + { + 0x1C, 0x3E, 0x6B, 0x49, 0x49, 0x00, 0x00, 0x00 } + , // 0xEE + { + 0x7E, 0x7F, 0x01, 0x01, 0x7F, 0x7E, 0x00, 0x00 } + , // 0xEF + { + 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x00, 0x00 } + , // 0xF0 + { + 0x44, 0x44, 0x5F, 0x5F, 0x44, 0x44, 0x00, 0x00 } + , // 0xF1 + { + 0x40, 0x51, 0x5B, 0x4E, 0x44, 0x40, 0x00, 0x00 } + , // 0xF2 + { + 0x40, 0x44, 0x4E, 0x5B, 0x51, 0x40, 0x00, 0x00 } + , // 0xF3 + { + 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x01, 0x07, 0x06 } + , // 0xF4 + { + 0x60, 0xE0, 0x80, 0xFF, 0x7F, 0x00, 0x00, 0x00 } + , // 0xF5 + { + 0x08, 0x08, 0x6B, 0x6B, 0x08, 0x08, 0x00, 0x00 } + , // 0xF6 + { + 0x24, 0x36, 0x12, 0x36, 0x24, 0x36, 0x12, 0x00 } + , // 0xF7 + { + 0x00, 0x06, 0x0F, 0x09, 0x0F, 0x06, 0x00, 0x00 } + , // 0xF8 + { + 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00 } + , // 0xF9 + { + 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00 } + , // 0xFA + { + 0x10, 0x30, 0x70, 0xC0, 0xFF, 0xFF, 0x01, 0x01 } + , // 0xFB + { + 0x00, 0x1F, 0x1F, 0x01, 0x1F, 0x1E, 0x00, 0x00 } + , // 0xFC + { + 0x00, 0x19, 0x1D, 0x17, 0x12, 0x00, 0x00, 0x00 } + , // 0xFD + { + 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00 } + , // 0xFE + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + , // 0xFF +}; // end of cp437_font + diff --git a/software/newsticker/newsticker.ino b/software/newsticker/newsticker.ino new file mode 100644 index 0000000..7641bdf --- /dev/null +++ b/software/newsticker/newsticker.ino @@ -0,0 +1,82 @@ +/* + * new sticker + * + * Displays rotating text send to RX pin. The text + * should be terminated with newline character. + * Received text is echoed to TX pin. + * See http://www.iwriteiam.nl/D1607.html#19b for + * how to connect HC-06 bluetooth module with + * two resistors of 1Kohm and 1.8kohm to IJduino, + * such that bluetooth app can be used to update + * text. + */ +#include "font.h" +#include "LedControl.h" + + +/* using VCC, GND, DIN 20, CS 21, CLK 5 for the MAX7219 */ +static const int DATA_PIN = 20; +static const int CLK_PIN = 5; +static const int CS_PIN = 21; + +LedControl lc=LedControl(DATA_PIN, CLK_PIN, CS_PIN, 1); + +byte matrix[8]; +byte textbuffer[65] = "TkkrLab is cool \\o/ "; +byte *cur_char; + +void setup() { + lc.shutdown(0,false); + lc.setIntensity(0,1); + lc.clearDisplay(0); + for (uint8_t i = 0; i < 8; i++) + matrix[i] = 0; + cur_char = textbuffer; +} + +void display_shift() +{ + for (uint8_t i = 0; i < 8; i++) + lc.setRow(0, i, matrix[i]); + for (uint8_t i = 0; i < 7; i++) + matrix[i] = matrix[i+1]; + matrix[7] = 0; + delay(50); + Serial.begin(9600); +} + +void letter (const byte c) +{ + display_shift(); + + for (byte col = 0; col < 8; col++) { + matrix[7] = pgm_read_byte (&cp437_font [c] [col]); + display_shift(); + } +} + +void loop () +{ + byte len = 0; + if (Serial.available()) + len = Serial.readBytesUntil(10, textbuffer, 64); + + if (len > 0) + { + textbuffer[len] = '\0'; + Serial.print("I received: "); + Serial.println((char*)textbuffer); + cur_char = textbuffer; + } + else + { + if (*(++cur_char) == '\0') + cur_char = textbuffer; + } + //Serial.print("Display: "); + //Serial.println(*cur_char, DEC); + letter(*cur_char); +} + + + diff --git a/software/pong/pong.ino b/software/pong/pong.ino new file mode 100644 index 0000000..8cb55a6 --- /dev/null +++ b/software/pong/pong.ino @@ -0,0 +1,149 @@ +#include "Pong.h" + +// LedControl library: +// +// http://playground.arduino.cc/Main/LedControl +// http://www.wayoda.org/arduino/ledcontrol/index.html + +#include "LedControl.h" + +static const int DATA_PIN = 20; +static const int CLK_PIN = 5; +static const int CS_PIN = 21; + +static const int PADDLE0_PIN = 5; +static const int PADDLE1_PIN = 4; + +static char pongchars[][8] = { + { 0b00000000, 0b01111100, 0b01000010, 0b01000010, + 0b01111100, 0b01000000, 0b01000000, 0b00000000, }, // P + { 0b00000000, 0b00111100, 0b01000010, 0b01000010, + 0b01000010, 0b01000010, 0b00111100, 0b00000000, }, // O + { 0b00000000, 0b01000010, 0b01100010, 0b01010010, + 0b01001010, 0b01000110, 0b01000010, 0b00000000, }, // N + { 0b00000000, 0b00111100, 0b01000000, 0b01000000, + 0b01111100, 0b01000010, 0b00111100, 0b00000000, }, // G +}; + +static char digit[][5] = { + { 0b111, 0b101, 0b101, 0b101, 0b111 }, + { 0b001, 0b001, 0b001, 0b001, 0b001 }, + { 0b111, 0b001, 0b111, 0b100, 0b111 }, + { 0b111, 0b001, 0b111, 0b001, 0b111 }, + { 0b101, 0b101, 0b111, 0b001, 0b001 }, + { 0b111, 0b100, 0b111, 0b001, 0b111 }, + { 0b111, 0b100, 0b111, 0b101, 0b111 }, + { 0b111, 0b001, 0b001, 0b001, 0b001 }, + { 0b111, 0b101, 0b111, 0b101, 0b111 }, + { 0b111, 0b101, 0b111, 0b001, 0b111 }, +}; + +class LedMatrixPong : public Pong +{ +public: + LedMatrixPong(LedControl& ledControl, int paddle0_pin, int paddle1_pin) : + ledControl_(ledControl), + Pong(ROWS, COLS, paddle0_pin, paddle1_pin) {} + + void showPaddle(Paddle& p) { setPaddle(p, true); } + void hidePaddle(Paddle& p) { setPaddle(p, false); } + + void showBall(Ball& b) { ledControl_.setLed(0, b.col(), b.row(), true); } + void hideBall(Ball& b) { ledControl_.setLed(0, b.col(), b.row(), false); } + + void startGame(); + void showScore(); + +private: + static const int ROWS = 8; + static const int COLS = 8; + + void sayPong(int delay_ms); + void setPaddle(const Paddle& p, bool state); + + LedControl& ledControl_; +}; + +void LedMatrixPong::startGame() +{ + ledControl_.clearDisplay(0); + sayPong(500); + + for (int row = MAX_ROW; row >= 0; row--) { + ledControl_.setColumn(0, row, 0xff); + delay(100); + ledControl_.setColumn(0, row, 0); + } + + start(); +} + +void LedMatrixPong::sayPong(int delay_ms) +{ + for (int c = 0; c < 4; c++) { + for (int r = 0; r <= MAX_ROW; r++) { + ledControl_.setColumn(0, 7-r, pongchars[c][r]); + } + delay(delay_ms); + } +} + +void LedMatrixPong::showScore() +{ + for (int step = 0; step < 10; step++) { + ledControl_.clearDisplay(0); + ledControl_.setLed(0, 3, 4, true); + ledControl_.setLed(0, 4, 4, true); + + int i = (step < 8) ? step : 14 - step; + int j = 4; + while (i >= 0 && j >= 0) { + for (int k = 0; k < 3; k++) { + ledControl_.setLed(0, 2-k, 7-i, digit[score_[0]][j] & (1<= 100) +#include +#else +#include +#endif + +byte Font8x5[104*8] PROGMEM = + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x00, + 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x0A, 0x00, + 0x0E, 0x15, 0x05, 0x0E, 0x14, 0x15, 0x0E, 0x00, + 0x13, 0x13, 0x08, 0x04, 0x02, 0x19, 0x19, 0x00, + 0x06, 0x09, 0x05, 0x02, 0x15, 0x09, 0x16, 0x00, + 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x02, 0x01, 0x01, 0x01, 0x02, 0x04, 0x00, + 0x01, 0x02, 0x04, 0x04, 0x04, 0x02, 0x01, 0x00, + 0x00, 0x0A, 0x15, 0x0E, 0x15, 0x0A, 0x00, 0x00, + 0x00, 0x04, 0x04, 0x1F, 0x04, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x01, + 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x10, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01, 0x00, + 0x0E, 0x11, 0x19, 0x15, 0x13, 0x11, 0x0E, 0x00, + 0x04, 0x06, 0x04, 0x04, 0x04, 0x04, 0x0E, 0x00, + 0x0E, 0x11, 0x10, 0x0C, 0x02, 0x01, 0x1F, 0x00, + 0x0E, 0x11, 0x10, 0x0C, 0x10, 0x11, 0x0E, 0x00, + 0x08, 0x0C, 0x0A, 0x09, 0x1F, 0x08, 0x08, 0x00, + 0x1F, 0x01, 0x01, 0x0E, 0x10, 0x11, 0x0E, 0x00, + 0x0C, 0x02, 0x01, 0x0F, 0x11, 0x11, 0x0E, 0x00, + 0x1F, 0x10, 0x08, 0x04, 0x02, 0x02, 0x02, 0x00, + 0x0E, 0x11, 0x11, 0x0E, 0x11, 0x11, 0x0E, 0x00, + 0x0E, 0x11, 0x11, 0x1E, 0x10, 0x08, 0x06, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x02, 0x01, + 0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x00, + 0x00, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x00, + 0x01, 0x02, 0x04, 0x08, 0x04, 0x02, 0x01, 0x00, + 0x0E, 0x11, 0x10, 0x08, 0x04, 0x00, 0x04, 0x00, + 0x0E, 0x11, 0x1D, 0x15, 0x0D, 0x01, 0x1E, 0x00, + 0x04, 0x0A, 0x11, 0x11, 0x1F, 0x11, 0x11, 0x00, + 0x0F, 0x11, 0x11, 0x0F, 0x11, 0x11, 0x0F, 0x00, + 0x0E, 0x11, 0x01, 0x01, 0x01, 0x11, 0x0E, 0x00, + 0x07, 0x09, 0x11, 0x11, 0x11, 0x09, 0x07, 0x00, + 0x1F, 0x01, 0x01, 0x0F, 0x01, 0x01, 0x1F, 0x00, + 0x1F, 0x01, 0x01, 0x0F, 0x01, 0x01, 0x01, 0x00, + 0x0E, 0x11, 0x01, 0x0D, 0x11, 0x19, 0x16, 0x00, + 0x11, 0x11, 0x11, 0x1F, 0x11, 0x11, 0x11, 0x00, + 0x07, 0x02, 0x02, 0x02, 0x02, 0x02, 0x07, 0x00, + 0x1C, 0x08, 0x08, 0x08, 0x08, 0x09, 0x06, 0x00, + 0x11, 0x09, 0x05, 0x03, 0x05, 0x09, 0x11, 0x00, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0F, 0x00, + 0x11, 0x1B, 0x15, 0x15, 0x11, 0x11, 0x11, 0x00, + 0x11, 0x13, 0x13, 0x15, 0x19, 0x19, 0x11, 0x00, + 0x0E, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0E, 0x00, + 0x0F, 0x11, 0x11, 0x0F, 0x01, 0x01, 0x01, 0x00, + 0x0E, 0x11, 0x11, 0x11, 0x15, 0x09, 0x16, 0x00, + 0x0F, 0x11, 0x11, 0x0F, 0x05, 0x09, 0x11, 0x00, + 0x0E, 0x11, 0x01, 0x0E, 0x10, 0x11, 0x0E, 0x00, + 0x1F, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0E, 0x00, + 0x11, 0x11, 0x11, 0x11, 0x0A, 0x0A, 0x04, 0x00, + 0x41, 0x41, 0x41, 0x49, 0x2A, 0x2A, 0x14, 0x00, + 0x11, 0x11, 0x0A, 0x04, 0x0A, 0x11, 0x11, 0x00, + 0x11, 0x11, 0x11, 0x0A, 0x04, 0x04, 0x04, 0x00, + 0x1F, 0x10, 0x08, 0x04, 0x02, 0x01, 0x1F, 0x00, + 0x07, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x00, + 0x01, 0x01, 0x02, 0x04, 0x08, 0x10, 0x10, 0x00, + 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x00, + 0x00, 0x04, 0x0A, 0x11, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, + 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x08, 0x0E, 0x09, 0x0E, 0x00, + 0x01, 0x01, 0x0D, 0x13, 0x11, 0x13, 0x0D, 0x00, + 0x00, 0x00, 0x06, 0x09, 0x01, 0x09, 0x06, 0x00, + 0x10, 0x10, 0x16, 0x19, 0x11, 0x19, 0x16, 0x00, + 0x00, 0x00, 0x06, 0x09, 0x07, 0x01, 0x0E, 0x00, + 0x04, 0x0A, 0x02, 0x07, 0x02, 0x02, 0x02, 0x00, + 0x00, 0x00, 0x06, 0x09, 0x09, 0x06, 0x08, 0x07, + 0x01, 0x01, 0x0D, 0x13, 0x11, 0x11, 0x11, 0x00, + 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, + 0x04, 0x00, 0x06, 0x04, 0x04, 0x04, 0x04, 0x03, + 0x01, 0x01, 0x09, 0x05, 0x03, 0x05, 0x09, 0x00, + 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, + 0x00, 0x00, 0x15, 0x2B, 0x29, 0x29, 0x29, 0x00, + 0x00, 0x00, 0x0D, 0x13, 0x11, 0x11, 0x11, 0x00, + 0x00, 0x00, 0x06, 0x09, 0x09, 0x09, 0x06, 0x00, + 0x00, 0x00, 0x0D, 0x13, 0x13, 0x0D, 0x01, 0x01, + 0x00, 0x00, 0x16, 0x19, 0x19, 0x16, 0x10, 0x10, + 0x00, 0x00, 0x0D, 0x13, 0x01, 0x01, 0x01, 0x00, + 0x00, 0x00, 0x0E, 0x01, 0x06, 0x08, 0x07, 0x00, + 0x00, 0x02, 0x07, 0x02, 0x02, 0x02, 0x04, 0x00, + 0x00, 0x00, 0x11, 0x11, 0x11, 0x19, 0x16, 0x00, + 0x00, 0x00, 0x11, 0x11, 0x11, 0x0A, 0x04, 0x00, + 0x00, 0x00, 0x11, 0x11, 0x15, 0x15, 0x0A, 0x00, + 0x00, 0x00, 0x11, 0x0A, 0x04, 0x0A, 0x11, 0x00, + 0x00, 0x00, 0x09, 0x09, 0x09, 0x0E, 0x08, 0x06, + 0x00, 0x00, 0x0F, 0x08, 0x06, 0x01, 0x0F, 0x00, + 0x04, 0x02, 0x02, 0x01, 0x02, 0x02, 0x04, 0x00, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, + 0x01, 0x02, 0x02, 0x04, 0x02, 0x02, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1C, 0x2A, 0x49, 0x49, 0x41, 0x22, 0x1C, 0x00, + 0x1C, 0x22, 0x51, 0x49, 0x41, 0x22, 0x1C, 0x00, + 0x1C, 0x22, 0x41, 0x79, 0x41, 0x22, 0x1C, 0x00, + 0x1C, 0x22, 0x41, 0x49, 0x51, 0x22, 0x1C, 0x00, + 0x1C, 0x22, 0x41, 0x49, 0x49, 0x2A, 0x1C, 0x00, + 0x1C, 0x22, 0x41, 0x49, 0x45, 0x22, 0x1C, 0x00, + 0x1C, 0x22, 0x41, 0x4F, 0x41, 0x22, 0x1C, 0x00, + 0x1C, 0x22, 0x45, 0x49, 0x41, 0x22, 0x1C, 0x00}; + + +byte lentbl_S[104] PROGMEM = +{ + 2, 2, 3, 5, 5, 5, 5, 2, + 3, 3, 5, 5, 2, 5, 1, 5, + 5, 4, 5, 5, 5, 5, 5, 5, + 5, 5, 1, 2, 4, 4, 4, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 3, 5, 5, 4, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 7, + 5, 5, 5, 3, 5, 3, 5, 5, + 2, 4, 5, 4, 5, 4, 4, 4, + 5, 2, 3, 4, 2, 6, 5, 4, + 5, 5, 5, 4, 3, 5, 5, 5, + 5, 4, 4, 3, 2, 3, 0, 0, + 7, 7, 7, 7, 7, 7, 7, 7 +}; + diff --git a/software/proportional/proportional.ino b/software/proportional/proportional.ino new file mode 100644 index 0000000..f4a4f0a --- /dev/null +++ b/software/proportional/proportional.ino @@ -0,0 +1,180 @@ +#include "LedControl.h" // need the library +#include +#include "PropFont.h" +// Data wire is plugged into port 10 on the Arduino +#define ONE_WIRE_BUS 10 + +static const int DATA_PIN = 20; +static const int CLK_PIN = 5; +static const int CS_PIN = 21; +static const int DISPLAYS = 1; + +static const int DELAY = 50; + +//LedControl lc=LedControl(12,11,10,6); // 6 matrices, 6 MAX7219s. +LedControl lc=LedControl(DATA_PIN, CLK_PIN, CS_PIN, DISPLAYS); + +// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) +OneWire ds(ONE_WIRE_BUS); + +int count = 0; +char msg[80] = " IJhack temp test :-)"; + +int msgsize = strlen(msg); +int curcharix = 0; +int curcharbit = 0; +int curcharixsave = 0; +int curcharbitsave = 0; +int curcharixsave2 = 0; +int curcharbitsave2 = 0; +char curchar; + +void setup() + +{ + for (int i = 0; i < DISPLAYS; i++) { + lc.shutdown(i,false);// turn off power saving, enables display + lc.setIntensity(i,15);// sets brightness (0~15 possible values) + lc.clearDisplay(i);// clear screen + } + checkTemp(); +} + +void checkTemp() +{ + byte i; + byte present = 0; + byte type_s; + byte data[12]; + byte addr[8]; + + if ( !ds.search(addr)) { + if (count == 0) { + strncpy(msg, " No thermometer found.", 80); + msgsize = strlen(msg); + return; + } + ds.reset_search(); + delay(250); + count = 0; + return; + } + + ds.reset(); + ds.select(addr); + ds.write(0x44, 1); // start conversion, with parasite power on at the end + + delay(1000); // maybe 750ms is enough, maybe not + // we might do a ds.depower() here, but the reset will take care of it. + + present = ds.reset(); + ds.select(addr); + ds.write(0xBE); // Read Scratchpad + + for ( i = 0; i < 9; i++) { // we need 9 bytes + data[i] = ds.read(); + } + + // Convert the data to actual temperature + // because the result is a 16 bit signed integer, it should + // be stored to an "int16_t" type, which is always 16 bits + // even when compiled on a 32 bit processor. + int16_t raw = (data[1] << 8) | data[0]; + if (type_s) { + raw = raw << 3; // 9 bit resolution default + if (data[7] == 0x10) { + // "count remain" gives full 12 bit resolution + raw = (raw & 0xFFF0) + 12 - data[6]; + } + } + else { + byte cfg = (data[4] & 0x60); + // at lower res, the low bits are undefined, so let's zero them + if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms + else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms + else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms + //// default is 12 bit resolution, 750 ms conversion time + } + + float temp = (float)raw / 16.0; + int itemp = int(temp); + + count ++; + sprintf(msg, " Zone %d: %d.%d'C", count, itemp, int((temp-itemp)*100)); + + msgsize = strlen(msg); +} + + + +void loop() +{ + int i,j,k; + for (;;) + { + curcharixsave2 = curcharix; + curcharbitsave2 = curcharbit; + + for (i=DISPLAYS;i>=0;i--) // Loop through our 1 display + { + for (j=0;j<8;j++) // Set up rows on current display + { + byte outputbyte = 0; + curchar = msg[curcharix]; + curcharixsave = curcharix; + curcharbitsave = curcharbit; + for (k=7;k>=0;k--) // Copy over data for 8 columns to current row and send it to current display + { + // This byte is the bitmap of the current character for the current row + byte currentcharbits = pgm_read_byte(&Font8x5[((curchar-32)*8)+j]); + if (currentcharbits & (1< pgm_read_byte(&lentbl_S[curchar-32])) // we are past the end of this character, so advance. + { + curcharbit = 0; + curcharix += 1; + if (curcharix+1 > msgsize) curcharix=0; + curchar = msg[curcharix]; + } + } + + lc.setColumn(i, 7-j, outputbyte); + + if (j != 7) // if this is not the last row, roll back advancement, if it is, leave the counters advanced. + { + curcharix = curcharixsave; + curcharbit = curcharbitsave; + } + + } + + } + + curcharix = curcharixsave2; + curcharbit = curcharbitsave2; + + curchar = msg[curcharix]; + + // advance the current character bit of current character + curcharbit ++; + + if (curcharbit > pgm_read_byte(&lentbl_S[curchar-32])) // we are past the end of this character, so advance. + { + curcharbit = 0; + curcharix += 1; + if (curcharix+1 > msgsize) { + checkTemp(); + curcharix=0; + } + curchar = msg[curcharix]; + + } + + delay(DELAY); + } +} + diff --git a/software/snake/snake.ino b/software/snake/snake.ino new file mode 100644 index 0000000..ec53928 --- /dev/null +++ b/software/snake/snake.ino @@ -0,0 +1,215 @@ +/* + * Domineering + * + * Allows you to play the game domineering + * (See https://en.wikipedia.org/wiki/Domineering) + * with the use of a potentiometer. Player take + * turns removing two blinking leds by turning the + * potentiometer. After a user stops turning the + * potentiometer the blinking slows down and removes + * the two blinking leds, giving the turn to the + * other player. + * + * The size of the playing field can be changed by + * modifying BOTTOM and TOP defines (taking into + * account: (0 <= BOTTOM < TOP <= 8) + */ +static const int DATA_PIN = 20; +static const int CLK_PIN = 5; +static const int CS_PIN = 21; + +#include "LedControl.h" +#include "Timer.h" + +#define POTPIN A5 // Potentiometer + +LedControl lc = LedControl(DATA_PIN, CLK_PIN, CS_PIN, 1); + +#define brightness 1 //Values from 1 to 15 to set the brightness +uint8_t matrix[8]; +#define MAT(X,Y) (matrix[X] & (1 << Y)) +#define SETMAT(X,Y) matrix[X] |= (1 << Y) +#define RESETMAT(X,Y) matrix[X] &= ~(1 << Y) + +uint8_t apple_x; +uint8_t apple_y; + +uint8_t snake_x[70]; +uint8_t snake_y[70]; +uint8_t snake_len; +uint8_t snake_dir; +uint8_t make_longer = 0; + +void show_field(bool apple_on) +{ + for (uint8_t i = 0; i < 8; i++) + matrix[i] = 0; + for (uint8_t i = 0; i < snake_len; i++) + SETMAT(snake_x[i], snake_y[i]); + if (apple_on) + SETMAT(apple_x, apple_y); + for (uint8_t x = 0; x < 8; x++) + lc.setColumn(0, x, matrix[x]); +} + +void place_random_apple() +{ + bool ok = false; + while (!ok) + { + apple_x = random(8); + apple_y = random(8); + ok = true; + for (uint8_t i = 0; i < snake_len; i++) + if (snake_x[i] == apple_x && snake_y[i] == apple_y) + { + ok = false; + break; + } + } +} + +void setup() { + pinMode(POTPIN, INPUT); + + lc.shutdown(0, false); + lc.setIntensity(0, brightness); + lc.clearDisplay(0); + Serial.begin(9600); + Serial.println("Start"); + snake_len = 3; + snake_x[0] = 4; + snake_y[0] = 6; + snake_x[1] = 5; + snake_y[1] = 6; + snake_x[2] = 6; + snake_y[2] = 6; + snake_dir = 0; + place_random_apple(); +} + + +void loop() { + int startp = analogRead(POTPIN); + for (uint8_t i = 0; i < 5; i++) + { + show_field(true); + delay(100); + show_field(false); + delay(100); + } + if (make_longer > 0) + { + snake_len++; + make_longer--; + } + + for (uint8_t i = snake_len-1; i > 0; i--) + { + snake_x[i] = snake_x[i-1]; + snake_y[i] = snake_y[i-1]; + } + int endp = analogRead(POTPIN); + if (endp > startp + 50) + snake_dir = (snake_dir + 1)%4; + else if (endp < startp - 50) + snake_dir = (snake_dir + 3)%4; + if (snake_dir == 0) + snake_x[0]--; + else if (snake_dir == 2) + snake_x[0]++; + else if (snake_dir == 1) + snake_y[0]--; + else if (snake_dir == 3) + snake_y[0]++; + + if ( snake_x[0] < 0 || snake_x[0] > 7 + || snake_y[0] < 0 || snake_y[0] > 7) + { + delay(2000); + setup(); + } + for (uint8_t i = 1; i < snake_len; i++) + if (snake_x[0] == snake_x[i] && snake_y[0] == snake_y[i]) + { + delay(2000); + setup(); + } + if (snake_x[0] == apple_x && snake_y[0] == apple_y) + { + make_longer = 2; + place_random_apple(); + } +} +/* + uint8_t len = 0; + uint8_t v_x = 0; + uint8_t v_y = 0; + if (vert_player) + { + v_x = 1; + for (uint8_t y = BOTTOM; y < TOP; y++) + for (uint8_t x = BOTTOM; x < TOP-1; x++) + if (MAT(x,y) != 0 && MAT(x+1, y) != 0) + { + x_p[len] = x; + y_p[len] = y; + len++; + } + } + else + { + v_y = 1; + for (uint8_t x = BOTTOM; x < TOP; x++) + for (uint8_t y = BOTTOM; y < TOP-1; y++) + if (MAT(x,y) != 0 && MAT(x, y+1) != 0) + { + x_p[len] = x; + y_p[len] = y; + len++; + } + } + if (len == 0) + { + init_field(); + return; + } + + int prev_pos = -1; + bool moved = len == 1; + int d = 50; + for (;;) + { + int val = ; + int pos = (val - 12)/(1000/len); + if (pos < 0) + pos = 0; + if (pos >= len) + pos = len - 1; + if (prev_pos != -1 && pos != prev_pos) + { + moved = true; + d = 50; + } + else if (moved) + d += 50; + prev_pos = pos; + + RESETMAT(x_p[pos], y_p[pos]); + RESETMAT(x_p[pos]+v_x, y_p[pos]+v_y); + showmat(); + + delay(d); + + if (d > 500) + break; + + SETMAT(x_p[pos], y_p[pos]); + SETMAT(x_p[pos]+v_x, y_p[pos]+v_y); + showmat(); + + delay(d); + } + vert_player = !vert_player; +} +*/ diff --git a/software/tetrijs/tetrijs.ino b/software/tetrijs/tetrijs.ino new file mode 100644 index 0000000..f1e2065 --- /dev/null +++ b/software/tetrijs/tetrijs.ino @@ -0,0 +1,398 @@ +/* TETRIJS + * Not finished !! + * Based on code from + * http://open-source-project.com/projects/arduino-led-tetris/tetris-source-code/ + */ + +#include + +LedControl lc = LedControl(20, 5, 21, 1); + +const unsigned short brick_count = 7; +const unsigned int bricks[ brick_count ][4] = { + { //1×4 + 0b0100010001000100, + 0b0000000011110000, + 0b0100010001000100, + 0b0000000011110000 + }, + { // T + 0b0100111000000000, + 0b0100011001000000, + 0b1110010000000000, + 0b0100110001000000 + }, + { //2×2 + 0b0000011001100000, + 0b0000011001100000, + 0b0000011001100000, + 0b0000011001100000 + }, + { // L + 0b0000000011100010, + 0b0000010001001100, + 0b0000100011100000, + 0b0000011001000100 + }, + { //Reverse L + 0b0000000011101000, + 0b0000110001000100, + 0b0000001011100000, + 0b0000010001000110 + }, + { // Z + 0b0000100011000100, + 0b0000011011000000, + 0b0000100011000100, + 0b0000011011000000 + }, + { // S + 0b0000010011001000, + 0b0000110001100000, + 0b0000010011001000, + 0b0000110001100000 + } +}; + +int rightButton = 40; +int leftButton = 42; +int upButton = 44; +int downButton = 46; + +boolean lastrButton = digitalRead(rightButton); +boolean lastlButton = digitalRead(leftButton); +boolean lastdButton = digitalRead(downButton); +boolean lastuButton = digitalRead(upButton); + +int timer = 0; +int timeOut = 100; + +boolean ground = false; +boolean wall[8][8]; +boolean current_brick[4][4]; +boolean sides = false; +boolean drop = false; +boolean leftBrick = false; +boolean rightBrick = false; +boolean rotate = false; + +int current_brick_type = 0;//0; +int next_brick_type = 0; +int rotation = 0;//0; +int pos_x = 2; +int pos_y = 0; +int lastKey = 0; + +void setup() { + + pinMode(rightButton, INPUT); + pinMode(leftButton, INPUT); + pinMode(upButton, INPUT); + pinMode(downButton, INPUT); + + lc.shutdown(0, false); + lc.setIntensity(0, 8); + lc.clearDisplay(0); + + Serial.begin(9600); + + clearWall(); + updateBrickArray(); +} + +void loop() { + + lastKey = input(); + + if ( lastKey == 1) { // Shift left + leftBrick == checkLeftBrick(); + if ( leftBrick == false ) { + pos_x--; + checkSides(); + lastlButton = HIGH; + } + } + + if ( lastKey == 2 ) { // Shift right + rightBrick = checkRightBrick(); + if ( rightBrick == false ) { + pos_x++; + checkSides(); + lastrButton = HIGH; + } + } + + if ( lastKey == 3 ) { // Rotation + if ( checkRotate() == false ) { + rotation++; + if ( rotation >= 4 ) { + rotation = 0; + } + } + updateBrickArray(); + lastuButton = HIGH; + } + + if ( lastKey == 4 ) { // Drop block + timer = timeOut; + delay(50); + } + checkSides(); + disp(); + tick(); + delay(10); +} + +int input() { + + if ( digitalRead( leftButton ) == HIGH && lastlButton == LOW ) { //check left key + return 1; + } + else { + lastlButton = digitalRead( leftButton ); + } + + if ( digitalRead( rightButton ) == HIGH && lastrButton == LOW ) { //check right key + return 2; + } + else { + lastrButton = digitalRead( rightButton ); + } + + if ( digitalRead( upButton ) == HIGH && lastuButton == LOW ) { + return 3; + } + else { + lastuButton = digitalRead( upButton ); + } + + if ( digitalRead( downButton ) == HIGH && lastdButton == LOW ) { + return 4; + } + else { + lastdButton = digitalRead( downButton ); + } + return 0; +} +void updateBrickArray() +{ + int data = bricks[current_brick_type][rotation]; + for ( int i = 0; i < 4; i++ ) + { + for ( int k = 0; k < 4; k++ ) + { + current_brick[k][i] = bitRead(data, 4 * i + 3 - k); + } + } +} +void disp() { + + lc.clearDisplay(0); + for (int x = 0; x < 4; x++) { + for (int y = 0; y < 4; y++) { + if (current_brick[x][y] == true) { + lc.setLed(0, x + pos_x , y + pos_y , true); + } + } + } + + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + + if (wall[x][y] == true) { + lc.setLed(0, x, y, true); + } + } + } +} +void checkSides() { + + for ( int i = 0; i < 4; i++ ) { + for ( int k = 0; k < 4; k++ ) { + if ( current_brick[i][k] == true ) { + + int x = pos_x + i; + int y = pos_y + k; + + if ( x >= 8 || wall[x][y] >= 8 ) { // check if brick is in the right wall + pos_x--; // shift left if true + } + if ( x <= -1 || wall[x][y] <= -1 ) { // check if brick is in the left wall + pos_x++; // shift right if true + } + } + } + } +} +boolean checkLeftBrick() { + + leftBrick = false; + + for ( int i = 0; i < 4; i++ ) { + for ( int k = 0; k < 4; k++ ) { + if ( current_brick[i][k] == true ) { + + int x = pos_x + i; + int y = pos_y + k; + + if ( wall[x - 1][y] == true ) { + leftBrick = true; + Serial.println("Left Brick!"); + } + } + } + } + return leftBrick; +} + +boolean checkRightBrick() { + + rightBrick = false; + + for ( int i = 0; i < 4; i++ ) { + for ( int k = 0; k < 4; k++ ) { + if ( current_brick[i][k] == true ) { + + int x = pos_x + i; + int y = pos_y + k; + + if ( wall[x + 1][y] == true ) { + rightBrick = true; + Serial.println("Right Brick!"); + } + } + } + } + return rightBrick; +} +boolean checkDrop() { + + for ( int i = 0; i < 4; i++ ) { + for ( int k = 0; k < 4; k++ ) { + if ( current_brick[i][k] == true ) { + + int x = pos_x + i; + int y = pos_y + k + 1; + + if ( y >= 8 ) { + return true; + } + + if ( wall[x][y] == true ) { + return true; + } + } + } + } + return false; +} + +void tick() { + + drop = checkDrop(); + if ( timer == timeOut ) { + if ( drop == true ) { + addToWall(); + current_brick_type++; + if ( current_brick_type >= 7 ) { + current_brick_type = 0; + } + checkLine(); + updateBrickArray(); + pos_y = 0; + pos_x = 2; + timer = 0; + } + else if ( drop == false ) { + pos_y++; + timer = 0; + } + } + timer++; +} + +void addToWall() { + + for ( int i = 0; i < 4; i++ ) { + for ( int k = 0; k < 4; k++ ) { + if ( current_brick[i][k] == true ) { + + int x = pos_x + i; + int y = pos_y + k; + + wall[x][y] = true; + } + } + } +} + +void clearWall() { + for ( int i = 0; i < 8; i++ ) { + for ( int k = 0; k < 8; k++ ) { + wall[i][k] = false; + } + } +} + +boolean checkRotate() { + + rotation++; + updateBrickArray(); + for ( int i = 0; i < 4; i++ ) { + for ( int k = 0; k < 4; k++ ) { + if ( current_brick[i][k] == true ) { + + int x = pos_x + i; + int y = pos_y + k; + + if ( wall[x][y] == true ) { + Serial.println("Rotation blockage!"); + rotation--; + return true; + } + } + } + } + rotation--; + return false; +} +void moveRowDown(int row) +{ + //move "row" down one + for (int c = 0; c < 8; c++) + { + wall[c][row + 1] = wall[c][row]; + wall[c][row] = false; + } +} +void rowCleared(int row) +{ + int rowAbove = row - 1; + + for (int r = rowAbove; r >= 0; r--) + { + moveRowDown(r); + } +} +void checkLine() { + + int line = 0; + for ( int i = 0; i <= 7; i++ ) { + line = 0; + for ( int k = 0; k <= 7; k++ ) { + if ( wall[k][i] == true ) { + line++; + } + if ( line == 8 ) { + + for ( int k = 0; k < 8; k++ ) { + wall[k][i] = false; + Serial.println("Line!"); + } + rowCleared(i); + } + } + } + +} + diff --git a/software/tetristune/tetristune.ino b/software/tetristune/tetristune.ino new file mode 100644 index 0000000..d039752 --- /dev/null +++ b/software/tetristune/tetristune.ino @@ -0,0 +1,197 @@ +// From http://www.instructables.com/id/How-to-easily-play-music-with-buzzer-on-arduino-Th/ + +// NB: ALL NOTES DEFINED WITH STANDARD ENGLISH NAMES, EXCEPT FROM "A" +//THAT IS CALLED WITH THE ITALIAN NAME "LA" BECAUSE A0,A1...ARE THE ANALOG PINS ON ARDUINO. +// (Ab IS CALLED Ab AND NOT LAb) +#define C0 16.35 +#define Db0 17.32 +#define D0 18.35 +#define Eb0 19.45 +#define E0 20.60 +#define F0 21.83 +#define Gb0 23.12 +#define G0 24.50 +#define Ab0 25.96 +#define LA0 27.50 +#define Bb0 29.14 +#define B0 30.87 +#define C1 32.70 +#define Db1 34.65 +#define D1 36.71 +#define Eb1 38.89 +#define E1 41.20 +#define F1 43.65 +#define Gb1 46.25 +#define G1 49.00 +#define Ab1 51.91 +#define LA1 55.00 +#define Bb1 58.27 +#define B1 61.74 +#define C2 65.41 +#define Db2 69.30 +#define D2 73.42 +#define Eb2 77.78 +#define E2 82.41 +#define F2 87.31 +#define Gb2 92.50 +#define G2 98.00 +#define Ab2 103.83 +#define LA2 110.00 +#define Bb2 116.54 +#define B2 123.47 +#define C3 130.81 +#define Db3 138.59 +#define D3 146.83 +#define Eb3 155.56 +#define E3 164.81 +#define F3 174.61 +#define Gb3 185.00 +#define G3 196.00 +#define Ab3 207.65 +#define LA3 220.00 +#define Bb3 233.08 +#define B3 246.94 +#define C4 261.63 +#define Db4 277.18 +#define D4 293.66 +#define Eb4 311.13 +#define E4 329.63 +#define F4 349.23 +#define Gb4 369.99 +#define G4 392.00 +#define Ab4 415.30 +#define LA4 440.00 +#define Bb4 466.16 +#define B4 493.88 +#define C5 523.25 +#define Db5 554.37 +#define D5 587.33 +#define Eb5 622.25 +#define E5 659.26 +#define F5 698.46 +#define Gb5 739.99 +#define G5 783.99 +#define Ab5 830.61 +#define LA5 880.00 +#define Bb5 932.33 +#define B5 987.77 +#define C6 1046.50 +#define Db6 1108.73 +#define D6 1174.66 +#define Eb6 1244.51 +#define E6 1318.51 +#define F6 1396.91 +#define Gb6 1479.98 +#define G6 1567.98 +#define Ab6 1661.22 +#define LA6 1760.00 +#define Bb6 1864.66 +#define B6 1975.53 +#define C7 2093.00 +#define Db7 2217.46 +#define D7 2349.32 +#define Eb7 2489.02 +#define E7 2637.02 +#define F7 2793.83 +#define Gb7 2959.96 +#define G7 3135.96 +#define Ab7 3322.44 +#define LA7 3520.01 +#define Bb7 3729.31 +#define B7 3951.07 +#define C8 4186.01 +#define Db8 4434.92 +#define D8 4698.64 +#define Eb8 4978.03 +// DURATION OF THE NOTES +#define BPM 120 // you can change this value changing all the others +#define H 2*Q //half 2/4 +#define Q 60000/BPM //quarter 1/4 +#define E Q/2 //eighth 1/8 +#define S Q/4 // sixteenth 1/16 +#define W 4*Q // whole 4/4 + +int outpin = 8; + +void setup() { +pinMode(outpin, OUTPUT); +} + +// the loop routine runs over and over again forever: +void loop() { + tone(outpin, E4, Q); + delay(1+Q); + tone(outpin, B3, E); + delay(1+E); + tone(outpin, C4, E); + delay(1+E); + tone(outpin, D4, Q); + delay(1+Q); + tone(outpin, C4, E); + delay(1+E); + tone(outpin, B3, E); + delay(1+E); + tone(outpin, LA3, Q); + delay(1+Q); + tone(outpin, LA3, E); + delay(1+E); + tone(outpin, C4, E); + delay(1+E); + tone(outpin, E4, Q); + delay(1+Q); + tone(outpin, D4, E); + delay(1+E); + tone(outpin, C4, E); + delay(1+E); + tone(outpin, B3, Q+E); + delay(1+Q+E); + tone(outpin, C4, E); + delay(1+E); + tone(outpin, D4, Q); + delay(1+Q); + tone(outpin, E4, Q); + delay(1+Q); + tone(outpin, C4, Q); + delay(1+Q); + tone(outpin, LA3, Q); + delay(1+Q); + tone(outpin, LA3, H); + delay(1+H); + delay(1+E); + tone(outpin, D4, Q); + delay(1+Q); + tone(outpin, F4, E); + delay(1+E); + tone(outpin, LA4, Q); + delay(1+Q); + tone(outpin, G4, E); + delay(1+E); + tone(outpin, F4, E); + delay(1+E); + tone(outpin, E4, Q+E); + delay(1+Q+E); + tone(outpin, C4, E); + delay(1+E); + tone(outpin, E4, Q); + delay(1+Q); + tone(outpin, D4, E); + delay(1+E); + tone(outpin, C4, E); + delay(1+E); + tone(outpin, B3, Q); + delay(1+Q); + tone(outpin, B3, E); + delay(1+E); + tone(outpin, C4, E); + delay(1+E); + tone(outpin, D4, Q); + delay(1+Q); + tone(outpin, E4, Q); + delay(1+Q); + tone(outpin, C4, Q); + delay(1+Q); + tone(outpin, LA3, Q); + delay(1+Q); + tone(outpin, LA3, H); + delay(1+H); + } diff --git a/software/thermgraph/thermgraph.ino b/software/thermgraph/thermgraph.ino new file mode 100644 index 0000000..1cc2c9a --- /dev/null +++ b/software/thermgraph/thermgraph.ino @@ -0,0 +1,232 @@ +// Graphic thermometer: shows to indicate if temperature +// goes up of down. It uses DHT22, but probably also +// works with DHT11. + +#include "LedControl.h" //Imports the library + +static const int DATA_PIN = 20; +static const int CLK_PIN = 5; +static const int CS_PIN = 21; + +LedControl lc = LedControl(DATA_PIN, CLK_PIN, CS_PIN, 1); + +#define brightness 1 //Values from 1 to 15 to set the brightness + +#define DHTPIN A3 // A3 is pin 26 (PC3/ADC3/PCINT11) of atmega328 +#define TIMEOUT 10000 + +#define SHIFT_EVERY_MIN 5 +#define SHIFT_AT_STEPS (24*SHIFT_EVERY_MIN) + +uint16_t shiftstep; +uint8_t last_temp; +uint16_t base_temp; + +void setup() { + lc.shutdown(0, false); + lc.setIntensity(0, brightness); + lc.clearDisplay(0); + Serial.begin(9600); + Serial.println("Start"); + shiftstep = 0; + base_temp = 0; +} + +uint8_t matrix[8]; + +void loop() { + uint8_t data[5] = { 0, 0, 0, 0, 0 }; + + uint8_t mask = 128; + uint8_t idx = 0; + + uint8_t bit = digitalPinToBitMask(DHTPIN); + uint8_t port = digitalPinToPort(DHTPIN); + volatile uint8_t *PIR = portInputRegister(port); + + // REQUEST SAMPLE + pinMode(DHTPIN, OUTPUT); + digitalWrite(DHTPIN, HIGH); // T-be + delay(250); + // switch last value on + if (base_temp != 0) + { + matrix[last_temp] |= 1; + lc.setColumn(0, last_temp, matrix[last_temp]); + } + pinMode(DHTPIN, OUTPUT); + digitalWrite(DHTPIN, LOW); // T-go + delay(20); + digitalWrite(DHTPIN, HIGH); + delayMicroseconds(40); + pinMode(DHTPIN, INPUT_PULLUP); + delayMicroseconds(10); + + uint32_t t_mid = micros(); + + // GET ACKNOWLEDGE or TIMEOUT + uint16_t loopCntLOW = TIMEOUT; + while ((*PIR & bit) == LOW ) // T-rel + { + if (--loopCntLOW == 0) + { + //Serial.println("Low init err"); + return; + } + } + + t_mid = 50; //(10 + micros() - t_mid)*50/80; + + uint16_t loopCntHIGH = TIMEOUT; + while ((*PIR & bit) != LOW ) // T-reh + { + if (--loopCntHIGH == 0) + { + //Serial.println("Error 2"); + return; + } + } + + for (uint8_t i = 0; i < 40; i++) + { + loopCntLOW = TIMEOUT; + while ((*PIR & bit) == LOW ) + { + if (--loopCntLOW == 0) + { + //Serial.print("Error 3, cycle "); Serial.print(i); + return; + } + } + + uint32_t t = micros(); + + loopCntHIGH = TIMEOUT; + while ((*PIR & bit) != LOW ) + { + if (--loopCntLOW == 0) + { + //Serial.print("Error 4, cycle "); Serial.print(i); + return; + } + } + + data[i/8] <<= 1; + if (micros() - t > t_mid) + data[i/8] |= 1; + } + pinMode(DHTPIN, OUTPUT); + digitalWrite(DHTPIN, HIGH); + +/* + for (uint8_t i = 0; i < 40; i++) + { + if (i % 8 == 0) + Serial.println(); + Serial.print(cycles[i]); + + if (data[i/8] & (1 << (7-i%8))) + Serial.print("_ "); + else + Serial.print("X "); + } + */ + for (uint8_t i = 0; i < 5; i++) + { + Serial.print(data[i]); + Serial.print(" "); + } + Serial.println(); + if (data[4] != ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) { + Serial.println("Checksum err"); + return; + } + uint16_t temp = ((uint16_t)data[2])*256 + data[3]; + Serial.print("Temp = "); + Serial.print(temp); + Serial.println(); + + temp /= 2; + + if (base_temp == 0) + { + base_temp = temp - 3; + } + bool did_move = false; + + // move up or down depending on new measurement + while (temp < base_temp) + { + for (uint8_t i = 7; i > 0; i--) + matrix[i] = matrix[i-1]; + matrix[0] = 0; + base_temp--; + did_move = true; + } + while (temp > base_temp + 7) + { + for (uint8_t i = 0; i < 7; i++) + matrix[i] = matrix[i+1]; + matrix[7] = 0; + base_temp++; + did_move = true; + } + last_temp = temp - base_temp; + + // move left after number of steps, only if did not move up or down + if (++shiftstep >= SHIFT_AT_STEPS && !did_move) + { + for (uint8_t i = 0; i < 8; i++) + matrix[i] <<= 1; + shiftstep -= SHIFT_AT_STEPS; + did_move = true; + } + + matrix[last_temp] |= 1; + + // if did not move, move up or down to center graph + if (!did_move) + { + uint8_t top = 0; // empty lines on the top + for (; top < 7; top++) + if (matrix[7-top] != 0) + break; + uint8_t bottom = 0; // empty lines on the bottom + for (; bottom < 7; bottom++) + if (matrix[bottom] != 0) + break; + if (bottom >= top + 2) + { + for (uint8_t i = 0; i < 7; i++) + matrix[i] = matrix[i+1]; + matrix[7] = 0; + base_temp++; + last_temp--; + } + if (top >= bottom + 2) + { + for (uint8_t i = 7; i > 0; i--) + matrix[i] = matrix[i-1]; + matrix[0] = 0; + base_temp--; + last_temp++; + } + } + + // update display + for (uint8_t i = 0; i < 8; i++) + lc.setColumn(0, i, matrix[i]); + + // blink last temperature for 2 seconds + for (uint8_t s = 0;;) + { + delay(200); + matrix[last_temp] &= 254; + lc.setColumn(0, last_temp, matrix[last_temp]); + if (s++ == 5) + break; + delay(200); + matrix[last_temp] |= 1; + lc.setColumn(0, last_temp, matrix[last_temp]); + } +} diff --git a/software/thermometer/font.h b/software/thermometer/font.h new file mode 100644 index 0000000..1b16b55 --- /dev/null +++ b/software/thermometer/font.h @@ -0,0 +1,266 @@ +#if (ARDUINO >= 100) +#include +#else +#include +#endif + +// bit patterns for the CP437 font + +byte cp437_font[256][8] PROGMEM = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x00 + { 0x7E, 0x81, 0x95, 0xB1, 0xB1, 0x95, 0x81, 0x7E }, // 0x01 + { 0x7E, 0xFF, 0xEB, 0xCF, 0xCF, 0xEB, 0xFF, 0x7E }, // 0x02 + { 0x0E, 0x1F, 0x3F, 0x7E, 0x3F, 0x1F, 0x0E, 0x00 }, // 0x03 + { 0x08, 0x1C, 0x3E, 0x7F, 0x3E, 0x1C, 0x08, 0x00 }, // 0x04 + { 0x18, 0xBA, 0xFF, 0xFF, 0xFF, 0xBA, 0x18, 0x00 }, // 0x05 + { 0x10, 0xB8, 0xFC, 0xFF, 0xFC, 0xB8, 0x10, 0x00 }, // 0x06 + { 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00 }, // 0x07 + { 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF }, // 0x08 + { 0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00 }, // 0x09 + { 0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF }, // 0x0A + { 0x70, 0xF8, 0x88, 0x88, 0xFD, 0x7F, 0x07, 0x0F }, // 0x0B + { 0x00, 0x4E, 0x5F, 0xF1, 0xF1, 0x5F, 0x4E, 0x00 }, // 0x0C + { 0xC0, 0xE0, 0xFF, 0x7F, 0x05, 0x05, 0x07, 0x07 }, // 0x0D + { 0xC0, 0xFF, 0x7F, 0x05, 0x05, 0x65, 0x7F, 0x3F }, // 0x0E + { 0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99 }, // 0x0F + { 0x7F, 0x3E, 0x3E, 0x1C, 0x1C, 0x08, 0x08, 0x00 }, // 0x10 + { 0x08, 0x08, 0x1C, 0x1C, 0x3E, 0x3E, 0x7F, 0x00 }, // 0x11 + { 0x00, 0x24, 0x66, 0xFF, 0xFF, 0x66, 0x24, 0x00 }, // 0x12 + { 0x00, 0x5F, 0x5F, 0x00, 0x00, 0x5F, 0x5F, 0x00 }, // 0x13 + { 0x06, 0x0F, 0x09, 0x7F, 0x7F, 0x01, 0x7F, 0x7F }, // 0x14 + { 0x40, 0xDA, 0xBF, 0xA5, 0xFD, 0x59, 0x03, 0x02 }, // 0x15 + { 0x00, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x00 }, // 0x16 + { 0x80, 0x94, 0xB6, 0xFF, 0xFF, 0xB6, 0x94, 0x80 }, // 0x17 + { 0x00, 0x04, 0x06, 0x7F, 0x7F, 0x06, 0x04, 0x00 }, // 0x18 + { 0x00, 0x10, 0x30, 0x7F, 0x7F, 0x30, 0x10, 0x00 }, // 0x19 + { 0x08, 0x08, 0x08, 0x2A, 0x3E, 0x1C, 0x08, 0x00 }, // 0x1A + { 0x08, 0x1C, 0x3E, 0x2A, 0x08, 0x08, 0x08, 0x00 }, // 0x1B + { 0x3C, 0x3C, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00 }, // 0x1C + { 0x08, 0x1C, 0x3E, 0x08, 0x08, 0x3E, 0x1C, 0x08 }, // 0x1D + { 0x30, 0x38, 0x3C, 0x3E, 0x3E, 0x3C, 0x38, 0x30 }, // 0x1E + { 0x06, 0x0E, 0x1E, 0x3E, 0x3E, 0x1E, 0x0E, 0x06 }, // 0x1F + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // ' ' + { 0x00, 0x06, 0x5F, 0x5F, 0x06, 0x00, 0x00, 0x00 }, // '!' + { 0x00, 0x07, 0x07, 0x00, 0x07, 0x07, 0x00, 0x00 }, // '"' + { 0x14, 0x7F, 0x7F, 0x14, 0x7F, 0x7F, 0x14, 0x00 }, // '#' + { 0x24, 0x2E, 0x6B, 0x6B, 0x3A, 0x12, 0x00, 0x00 }, // '$' + { 0x46, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x62, 0x00 }, // '%' + { 0x30, 0x7A, 0x4F, 0x5D, 0x37, 0x7A, 0x48, 0x00 }, // '&' + { 0x04, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 }, // ''' + { 0x00, 0x1C, 0x3E, 0x63, 0x41, 0x00, 0x00, 0x00 }, // '(' + { 0x00, 0x41, 0x63, 0x3E, 0x1C, 0x00, 0x00, 0x00 }, // ')' + { 0x08, 0x2A, 0x3E, 0x1C, 0x1C, 0x3E, 0x2A, 0x08 }, // '*' + { 0x08, 0x08, 0x3E, 0x3E, 0x08, 0x08, 0x00, 0x00 }, // '+' + { 0x00, 0x80, 0xE0, 0x60, 0x00, 0x00, 0x00, 0x00 }, // ',' + { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00 }, // '-' + { 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00 }, // '.' + { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00 }, // '/' + { 0x3E, 0x7F, 0x71, 0x59, 0x4D, 0x7F, 0x3E, 0x00 }, // '0' + { 0x40, 0x42, 0x7F, 0x7F, 0x40, 0x40, 0x00, 0x00 }, // '1' + { 0x62, 0x73, 0x59, 0x49, 0x6F, 0x66, 0x00, 0x00 }, // '2' + { 0x22, 0x63, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00 }, // '3' + { 0x18, 0x1C, 0x16, 0x53, 0x7F, 0x7F, 0x50, 0x00 }, // '4' + { 0x27, 0x67, 0x45, 0x45, 0x7D, 0x39, 0x00, 0x00 }, // '5' + { 0x3C, 0x7E, 0x4B, 0x49, 0x79, 0x30, 0x00, 0x00 }, // '6' + { 0x03, 0x03, 0x71, 0x79, 0x0F, 0x07, 0x00, 0x00 }, // '7' + { 0x36, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00 }, // '8' + { 0x06, 0x4F, 0x49, 0x69, 0x3F, 0x1E, 0x00, 0x00 }, // '9' + { 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00 }, // ':' + { 0x00, 0x80, 0xE6, 0x66, 0x00, 0x00, 0x00, 0x00 }, // ';' + { 0x08, 0x1C, 0x36, 0x63, 0x41, 0x00, 0x00, 0x00 }, // '<' + { 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00 }, // '=' + { 0x00, 0x41, 0x63, 0x36, 0x1C, 0x08, 0x00, 0x00 }, // '>' + { 0x02, 0x03, 0x51, 0x59, 0x0F, 0x06, 0x00, 0x00 }, // '?' + { 0x3E, 0x7F, 0x41, 0x5D, 0x5D, 0x1F, 0x1E, 0x00 }, // '@' + { 0x7C, 0x7E, 0x13, 0x13, 0x7E, 0x7C, 0x00, 0x00 }, // 'A' + { 0x41, 0x7F, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00 }, // 'B' + { 0x1C, 0x3E, 0x63, 0x41, 0x41, 0x63, 0x22, 0x00 }, // 'C' + { 0x41, 0x7F, 0x7F, 0x41, 0x63, 0x3E, 0x1C, 0x00 }, // 'D' + { 0x41, 0x7F, 0x7F, 0x49, 0x5D, 0x41, 0x63, 0x00 }, // 'E' + { 0x41, 0x7F, 0x7F, 0x49, 0x1D, 0x01, 0x03, 0x00 }, // 'F' + { 0x1C, 0x3E, 0x63, 0x41, 0x51, 0x73, 0x72, 0x00 }, // 'G' + { 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00 }, // 'H' + { 0x00, 0x41, 0x7F, 0x7F, 0x41, 0x00, 0x00, 0x00 }, // 'I' + { 0x30, 0x70, 0x40, 0x41, 0x7F, 0x3F, 0x01, 0x00 }, // 'J' + { 0x41, 0x7F, 0x7F, 0x08, 0x1C, 0x77, 0x63, 0x00 }, // 'K' + { 0x41, 0x7F, 0x7F, 0x41, 0x40, 0x60, 0x70, 0x00 }, // 'L' + { 0x7F, 0x7F, 0x0E, 0x1C, 0x0E, 0x7F, 0x7F, 0x00 }, // 'M' + { 0x7F, 0x7F, 0x06, 0x0C, 0x18, 0x7F, 0x7F, 0x00 }, // 'N' + { 0x1C, 0x3E, 0x63, 0x41, 0x63, 0x3E, 0x1C, 0x00 }, // 'O' + { 0x41, 0x7F, 0x7F, 0x49, 0x09, 0x0F, 0x06, 0x00 }, // 'P' + { 0x1E, 0x3F, 0x21, 0x71, 0x7F, 0x5E, 0x00, 0x00 }, // 'Q' + { 0x41, 0x7F, 0x7F, 0x09, 0x19, 0x7F, 0x66, 0x00 }, // 'R' + { 0x26, 0x6F, 0x4D, 0x59, 0x73, 0x32, 0x00, 0x00 }, // 'S' + { 0x03, 0x41, 0x7F, 0x7F, 0x41, 0x03, 0x00, 0x00 }, // 'T' + { 0x7F, 0x7F, 0x40, 0x40, 0x7F, 0x7F, 0x00, 0x00 }, // 'U' + { 0x1F, 0x3F, 0x60, 0x60, 0x3F, 0x1F, 0x00, 0x00 }, // 'V' + { 0x7F, 0x7F, 0x30, 0x18, 0x30, 0x7F, 0x7F, 0x00 }, // 'W' + { 0x43, 0x67, 0x3C, 0x18, 0x3C, 0x67, 0x43, 0x00 }, // 'X' + { 0x07, 0x4F, 0x78, 0x78, 0x4F, 0x07, 0x00, 0x00 }, // 'Y' + { 0x47, 0x63, 0x71, 0x59, 0x4D, 0x67, 0x73, 0x00 }, // 'Z' + { 0x00, 0x7F, 0x7F, 0x41, 0x41, 0x00, 0x00, 0x00 }, // '[' + { 0x01, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00 }, // backslash + { 0x00, 0x41, 0x41, 0x7F, 0x7F, 0x00, 0x00, 0x00 }, // ']' + { 0x08, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x08, 0x00 }, // '^' + { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, // '_' + { 0x00, 0x00, 0x03, 0x07, 0x04, 0x00, 0x00, 0x00 }, // '`' + { 0x20, 0x74, 0x54, 0x54, 0x3C, 0x78, 0x40, 0x00 }, // 'a' + { 0x41, 0x7F, 0x3F, 0x48, 0x48, 0x78, 0x30, 0x00 }, // 'b' + { 0x38, 0x7C, 0x44, 0x44, 0x6C, 0x28, 0x00, 0x00 }, // 'c' + { 0x30, 0x78, 0x48, 0x49, 0x3F, 0x7F, 0x40, 0x00 }, // 'd' + { 0x38, 0x7C, 0x54, 0x54, 0x5C, 0x18, 0x00, 0x00 }, // 'e' + { 0x48, 0x7E, 0x7F, 0x49, 0x03, 0x02, 0x00, 0x00 }, // 'f' + { 0x98, 0xBC, 0xA4, 0xA4, 0xF8, 0x7C, 0x04, 0x00 }, // 'g' + { 0x41, 0x7F, 0x7F, 0x08, 0x04, 0x7C, 0x78, 0x00 }, // 'h' + { 0x00, 0x44, 0x7D, 0x7D, 0x40, 0x00, 0x00, 0x00 }, // 'i' + { 0x60, 0xE0, 0x80, 0x80, 0xFD, 0x7D, 0x00, 0x00 }, // 'j' + { 0x41, 0x7F, 0x7F, 0x10, 0x38, 0x6C, 0x44, 0x00 }, // 'k' + { 0x00, 0x41, 0x7F, 0x7F, 0x40, 0x00, 0x00, 0x00 }, // 'l' + { 0x7C, 0x7C, 0x18, 0x38, 0x1C, 0x7C, 0x78, 0x00 }, // 'm' + { 0x7C, 0x7C, 0x04, 0x04, 0x7C, 0x78, 0x00, 0x00 }, // 'n' + { 0x38, 0x7C, 0x44, 0x44, 0x7C, 0x38, 0x00, 0x00 }, // 'o' + { 0x84, 0xFC, 0xF8, 0xA4, 0x24, 0x3C, 0x18, 0x00 }, // 'p' + { 0x18, 0x3C, 0x24, 0xA4, 0xF8, 0xFC, 0x84, 0x00 }, // 'q' + { 0x44, 0x7C, 0x78, 0x4C, 0x04, 0x1C, 0x18, 0x00 }, // 'r' + { 0x48, 0x5C, 0x54, 0x54, 0x74, 0x24, 0x00, 0x00 }, // 's' + { 0x00, 0x04, 0x3E, 0x7F, 0x44, 0x24, 0x00, 0x00 }, // 't' + { 0x3C, 0x7C, 0x40, 0x40, 0x3C, 0x7C, 0x40, 0x00 }, // 'u' + { 0x1C, 0x3C, 0x60, 0x60, 0x3C, 0x1C, 0x00, 0x00 }, // 'v' + { 0x3C, 0x7C, 0x70, 0x38, 0x70, 0x7C, 0x3C, 0x00 }, // 'w' + { 0x44, 0x6C, 0x38, 0x10, 0x38, 0x6C, 0x44, 0x00 }, // 'x' + { 0x9C, 0xBC, 0xA0, 0xA0, 0xFC, 0x7C, 0x00, 0x00 }, // 'y' + { 0x4C, 0x64, 0x74, 0x5C, 0x4C, 0x64, 0x00, 0x00 }, // 'z' + { 0x08, 0x08, 0x3E, 0x77, 0x41, 0x41, 0x00, 0x00 }, // '{' + { 0x00, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0x00 }, // '|' + { 0x41, 0x41, 0x77, 0x3E, 0x08, 0x08, 0x00, 0x00 }, // '}' + { 0x02, 0x03, 0x01, 0x03, 0x02, 0x03, 0x01, 0x00 }, // '~' + { 0x70, 0x78, 0x4C, 0x46, 0x4C, 0x78, 0x70, 0x00 }, // 0x7F + { 0x0E, 0x9F, 0x91, 0xB1, 0xFB, 0x4A, 0x00, 0x00 }, // 0x80 + { 0x3A, 0x7A, 0x40, 0x40, 0x7A, 0x7A, 0x40, 0x00 }, // 0x81 + { 0x38, 0x7C, 0x54, 0x55, 0x5D, 0x19, 0x00, 0x00 }, // 0x82 + { 0x02, 0x23, 0x75, 0x55, 0x55, 0x7D, 0x7B, 0x42 }, // 0x83 + { 0x21, 0x75, 0x54, 0x54, 0x7D, 0x79, 0x40, 0x00 }, // 0x84 + { 0x21, 0x75, 0x55, 0x54, 0x7C, 0x78, 0x40, 0x00 }, // 0x85 + { 0x20, 0x74, 0x57, 0x57, 0x7C, 0x78, 0x40, 0x00 }, // 0x86 + { 0x18, 0x3C, 0xA4, 0xA4, 0xE4, 0x40, 0x00, 0x00 }, // 0x87 + { 0x02, 0x3B, 0x7D, 0x55, 0x55, 0x5D, 0x1B, 0x02 }, // 0x88 + { 0x39, 0x7D, 0x54, 0x54, 0x5D, 0x19, 0x00, 0x00 }, // 0x89 + { 0x39, 0x7D, 0x55, 0x54, 0x5C, 0x18, 0x00, 0x00 }, // 0x8A + { 0x01, 0x45, 0x7C, 0x7C, 0x41, 0x01, 0x00, 0x00 }, // 0x8B + { 0x02, 0x03, 0x45, 0x7D, 0x7D, 0x43, 0x02, 0x00 }, // 0x8C + { 0x01, 0x45, 0x7D, 0x7C, 0x40, 0x00, 0x00, 0x00 }, // 0x8D + { 0x79, 0x7D, 0x16, 0x12, 0x16, 0x7D, 0x79, 0x00 }, // 0x8E + { 0x70, 0x78, 0x2B, 0x2B, 0x78, 0x70, 0x00, 0x00 }, // 0x8F + { 0x44, 0x7C, 0x7C, 0x55, 0x55, 0x45, 0x00, 0x00 }, // 0x90 + { 0x20, 0x74, 0x54, 0x54, 0x7C, 0x7C, 0x54, 0x54 }, // 0x91 + { 0x7C, 0x7E, 0x0B, 0x09, 0x7F, 0x7F, 0x49, 0x00 }, // 0x92 + { 0x32, 0x7B, 0x49, 0x49, 0x7B, 0x32, 0x00, 0x00 }, // 0x93 + { 0x32, 0x7A, 0x48, 0x48, 0x7A, 0x32, 0x00, 0x00 }, // 0x94 + { 0x32, 0x7A, 0x4A, 0x48, 0x78, 0x30, 0x00, 0x00 }, // 0x95 + { 0x3A, 0x7B, 0x41, 0x41, 0x7B, 0x7A, 0x40, 0x00 }, // 0x96 + { 0x3A, 0x7A, 0x42, 0x40, 0x78, 0x78, 0x40, 0x00 }, // 0x97 + { 0x9A, 0xBA, 0xA0, 0xA0, 0xFA, 0x7A, 0x00, 0x00 }, // 0x98 + { 0x01, 0x19, 0x3C, 0x66, 0x66, 0x3C, 0x19, 0x01 }, // 0x99 + { 0x3D, 0x7D, 0x40, 0x40, 0x7D, 0x3D, 0x00, 0x00 }, // 0x9A + { 0x18, 0x3C, 0x24, 0xE7, 0xE7, 0x24, 0x24, 0x00 }, // 0x9B + { 0x68, 0x7E, 0x7F, 0x49, 0x43, 0x66, 0x20, 0x00 }, // 0x9C + { 0x2B, 0x2F, 0xFC, 0xFC, 0x2F, 0x2B, 0x00, 0x00 }, // 0x9D + { 0xFF, 0xFF, 0x09, 0x09, 0x2F, 0xF6, 0xF8, 0xA0 }, // 0x9E + { 0x40, 0xC0, 0x88, 0xFE, 0x7F, 0x09, 0x03, 0x02 }, // 0x9F + { 0x20, 0x74, 0x54, 0x55, 0x7D, 0x79, 0x40, 0x00 }, // 0xA0 + { 0x00, 0x44, 0x7D, 0x7D, 0x41, 0x00, 0x00, 0x00 }, // 0xA1 + { 0x30, 0x78, 0x48, 0x4A, 0x7A, 0x32, 0x00, 0x00 }, // 0xA2 + { 0x38, 0x78, 0x40, 0x42, 0x7A, 0x7A, 0x40, 0x00 }, // 0xA3 + { 0x7A, 0x7A, 0x0A, 0x0A, 0x7A, 0x70, 0x00, 0x00 }, // 0xA4 + { 0x7D, 0x7D, 0x19, 0x31, 0x7D, 0x7D, 0x00, 0x00 }, // 0xA5 + { 0x00, 0x26, 0x2F, 0x29, 0x2F, 0x2F, 0x28, 0x00 }, // 0xA6 + { 0x00, 0x26, 0x2F, 0x29, 0x2F, 0x26, 0x00, 0x00 }, // 0xA7 + { 0x30, 0x78, 0x4D, 0x45, 0x60, 0x20, 0x00, 0x00 }, // 0xA8 + { 0x38, 0x38, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00 }, // 0xA9 + { 0x08, 0x08, 0x08, 0x08, 0x38, 0x38, 0x00, 0x00 }, // 0xAA + { 0x4F, 0x6F, 0x30, 0x18, 0xCC, 0xEE, 0xBB, 0x91 }, // 0xAB + { 0x4F, 0x6F, 0x30, 0x18, 0x6C, 0x76, 0xFB, 0xF9 }, // 0xAC + { 0x00, 0x00, 0x00, 0x7B, 0x7B, 0x00, 0x00, 0x00 }, // 0xAD + { 0x08, 0x1C, 0x36, 0x22, 0x08, 0x1C, 0x36, 0x22 }, // 0xAE + { 0x22, 0x36, 0x1C, 0x08, 0x22, 0x36, 0x1C, 0x08 }, // 0xAF + { 0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00 }, // 0xB0 + { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 }, // 0xB1 + { 0xDD, 0xFF, 0xAA, 0x77, 0xDD, 0xAA, 0xFF, 0x77 }, // 0xB2 + { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00 }, // 0xB3 + { 0x10, 0x10, 0x10, 0xFF, 0xFF, 0x00, 0x00, 0x00 }, // 0xB4 + { 0x14, 0x14, 0x14, 0xFF, 0xFF, 0x00, 0x00, 0x00 }, // 0xB5 + { 0x10, 0x10, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00 }, // 0xB6 + { 0x10, 0x10, 0xF0, 0xF0, 0x10, 0xF0, 0xF0, 0x00 }, // 0xB7 + { 0x14, 0x14, 0x14, 0xFC, 0xFC, 0x00, 0x00, 0x00 }, // 0xB8 + { 0x14, 0x14, 0xF7, 0xF7, 0x00, 0xFF, 0xFF, 0x00 }, // 0xB9 + { 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00 }, // 0xBA + { 0x14, 0x14, 0xF4, 0xF4, 0x04, 0xFC, 0xFC, 0x00 }, // 0xBB + { 0x14, 0x14, 0x17, 0x17, 0x10, 0x1F, 0x1F, 0x00 }, // 0xBC + { 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x1F, 0x1F, 0x00 }, // 0xBD + { 0x14, 0x14, 0x14, 0x1F, 0x1F, 0x00, 0x00, 0x00 }, // 0xBE + { 0x10, 0x10, 0x10, 0xF0, 0xF0, 0x00, 0x00, 0x00 }, // 0xBF + { 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x10, 0x10, 0x10 }, // 0xC0 + { 0x10, 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x10 }, // 0xC1 + { 0x10, 0x10, 0x10, 0xF0, 0xF0, 0x10, 0x10, 0x10 }, // 0xC2 + { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x10, 0x10, 0x10 }, // 0xC3 + { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 }, // 0xC4 + { 0x10, 0x10, 0x10, 0xFF, 0xFF, 0x10, 0x10, 0x10 }, // 0xC5 + { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x14, 0x14, 0x14 }, // 0xC6 + { 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x10 }, // 0xC7 + { 0x00, 0x00, 0x1F, 0x1F, 0x10, 0x17, 0x17, 0x14 }, // 0xC8 + { 0x00, 0x00, 0xFC, 0xFC, 0x04, 0xF4, 0xF4, 0x14 }, // 0xC9 + { 0x14, 0x14, 0x17, 0x17, 0x10, 0x17, 0x17, 0x14 }, // 0xCA + { 0x14, 0x14, 0xF4, 0xF4, 0x04, 0xF4, 0xF4, 0x14 }, // 0xCB + { 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xF7, 0xF7, 0x14 }, // 0xCC + { 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14 }, // 0xCD + { 0x14, 0x14, 0xF7, 0xF7, 0x00, 0xF7, 0xF7, 0x14 }, // 0xCE + { 0x14, 0x14, 0x14, 0x17, 0x17, 0x14, 0x14, 0x14 }, // 0xCF + { 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x1F, 0x1F, 0x10 }, // 0xD0 + { 0x14, 0x14, 0x14, 0xF4, 0xF4, 0x14, 0x14, 0x14 }, // 0xD1 + { 0x10, 0x10, 0xF0, 0xF0, 0x10, 0xF0, 0xF0, 0x10 }, // 0xD2 + { 0x00, 0x00, 0x1F, 0x1F, 0x10, 0x1F, 0x1F, 0x10 }, // 0xD3 + { 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x14, 0x14, 0x14 }, // 0xD4 + { 0x00, 0x00, 0x00, 0xFC, 0xFC, 0x14, 0x14, 0x14 }, // 0xD5 + { 0x00, 0x00, 0xF0, 0xF0, 0x10, 0xF0, 0xF0, 0x10 }, // 0xD6 + { 0x10, 0x10, 0xFF, 0xFF, 0x10, 0xFF, 0xFF, 0x10 }, // 0xD7 + { 0x14, 0x14, 0x14, 0xFF, 0xFF, 0x14, 0x14, 0x14 }, // 0xD8 + { 0x10, 0x10, 0x10, 0x1F, 0x1F, 0x00, 0x00, 0x00 }, // 0xD9 + { 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x10, 0x10, 0x10 }, // 0xDA + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, // 0xDB + { 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0 }, // 0xDC + { 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 }, // 0xDD + { 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF }, // 0xDE + { 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F }, // 0xDF + { 0x38, 0x7C, 0x44, 0x6C, 0x38, 0x6C, 0x44, 0x00 }, // 0xE0 + { 0xFC, 0xFE, 0x2A, 0x2A, 0x3E, 0x14, 0x00, 0x00 }, // 0xE1 + { 0x7E, 0x7E, 0x02, 0x02, 0x06, 0x06, 0x00, 0x00 }, // 0xE2 + { 0x02, 0x7E, 0x7E, 0x02, 0x7E, 0x7E, 0x02, 0x00 }, // 0xE3 + { 0x63, 0x77, 0x5D, 0x49, 0x63, 0x63, 0x00, 0x00 }, // 0xE4 + { 0x38, 0x7C, 0x44, 0x7C, 0x3C, 0x04, 0x04, 0x00 }, // 0xE5 + { 0x80, 0xFE, 0x7E, 0x20, 0x20, 0x3E, 0x1E, 0x00 }, // 0xE6 + { 0x04, 0x06, 0x02, 0x7E, 0x7C, 0x06, 0x02, 0x00 }, // 0xE7 + { 0x99, 0xBD, 0xE7, 0xE7, 0xBD, 0x99, 0x00, 0x00 }, // 0xE8 + { 0x1C, 0x3E, 0x6B, 0x49, 0x6B, 0x3E, 0x1C, 0x00 }, // 0xE9 + { 0x4C, 0x7E, 0x73, 0x01, 0x73, 0x7E, 0x4C, 0x00 }, // 0xEA + { 0x30, 0x78, 0x4A, 0x4F, 0x7D, 0x39, 0x00, 0x00 }, // 0xEB + { 0x18, 0x3C, 0x24, 0x3C, 0x3C, 0x24, 0x3C, 0x18 }, // 0xEC + { 0x98, 0xFC, 0x64, 0x3C, 0x3E, 0x27, 0x3D, 0x18 }, // 0xED + { 0x1C, 0x3E, 0x6B, 0x49, 0x49, 0x00, 0x00, 0x00 }, // 0xEE + { 0x7E, 0x7F, 0x01, 0x01, 0x7F, 0x7E, 0x00, 0x00 }, // 0xEF + { 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x00, 0x00 }, // 0xF0 + { 0x44, 0x44, 0x5F, 0x5F, 0x44, 0x44, 0x00, 0x00 }, // 0xF1 + { 0x40, 0x51, 0x5B, 0x4E, 0x44, 0x40, 0x00, 0x00 }, // 0xF2 + { 0x40, 0x44, 0x4E, 0x5B, 0x51, 0x40, 0x00, 0x00 }, // 0xF3 + { 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x01, 0x07, 0x06 }, // 0xF4 + { 0x60, 0xE0, 0x80, 0xFF, 0x7F, 0x00, 0x00, 0x00 }, // 0xF5 + { 0x08, 0x08, 0x6B, 0x6B, 0x08, 0x08, 0x00, 0x00 }, // 0xF6 + { 0x24, 0x36, 0x12, 0x36, 0x24, 0x36, 0x12, 0x00 }, // 0xF7 + { 0x00, 0x06, 0x0F, 0x09, 0x0F, 0x06, 0x00, 0x00 }, // 0xF8 + { 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00 }, // 0xF9 + { 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00 }, // 0xFA + { 0x10, 0x30, 0x70, 0xC0, 0xFF, 0xFF, 0x01, 0x01 }, // 0xFB + { 0x00, 0x1F, 0x1F, 0x01, 0x1F, 0x1E, 0x00, 0x00 }, // 0xFC + { 0x00, 0x19, 0x1D, 0x17, 0x12, 0x00, 0x00, 0x00 }, // 0xFD + { 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00 }, // 0xFE + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0xFF +}; // end of cp437_font diff --git a/software/thermometer/thermometer.ino b/software/thermometer/thermometer.ino new file mode 100644 index 0000000..95e8499 --- /dev/null +++ b/software/thermometer/thermometer.ino @@ -0,0 +1,110 @@ +#include +#include "font.h" +// Data wire is plugged into port 2 on the Arduino +#define ONE_WIRE_BUS 2 + +// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) +OneWire ds(ONE_WIRE_BUS); + +#include "LedControl.h" + +/* using VCC, GND, DIN 20, CS 21, CLK 5 for the MAX7219 */ +static const int DATA_PIN = 20; +static const int CLK_PIN = 5; +static const int CS_PIN = 21; + +LedControl lc=LedControl(DATA_PIN, CLK_PIN, CS_PIN, 1); + +void setup() { + /* + The MAX72XX is in power-saving mode on startup, + we have to do a wakeup call + */ + lc.shutdown(0,false); + /* Set the brightness to a medium values */ + lc.setIntensity(0,15); + /* and clear the display */ + lc.clearDisplay(0); +} + +void letter (const byte c) +{ + for (byte col = 0; col < 8; col++) { + // ijduino is 90 degrees turned compared to 'normal' operation + lc.setRow(0, col, pgm_read_byte (&cp437_font [c] [col])); + } +} // end of letter + +void showString (const char * s, const unsigned long time) +{ + char c; + while (c = *s++) + { + letter (c); + delay (time); + } +} // end of showString + +int count = 0; +void loop(void) { + byte i; + byte present = 0; + byte type_s; + byte data[12]; + byte addr[8]; + + if ( !ds.search(addr)) { + if (count == 0) { + showString("No thermometer found. ", 200); + } + ds.reset_search(); + delay(250); + count = 0; + return; + } + + ds.reset(); + ds.select(addr); + ds.write(0x44, 1); // start conversion, with parasite power on at the end + + delay(1000); // maybe 750ms is enough, maybe not + // we might do a ds.depower() here, but the reset will take care of it. + + present = ds.reset(); + ds.select(addr); + ds.write(0xBE); // Read Scratchpad + + for ( i = 0; i < 9; i++) { // we need 9 bytes + data[i] = ds.read(); + } + + // Convert the data to actual temperature + // because the result is a 16 bit signed integer, it should + // be stored to an "int16_t" type, which is always 16 bits + // even when compiled on a 32 bit processor. + int16_t raw = (data[1] << 8) | data[0]; + if (type_s) { + raw = raw << 3; // 9 bit resolution default + if (data[7] == 0x10) { + // "count remain" gives full 12 bit resolution + raw = (raw & 0xFFF0) + 12 - data[6]; + } + } + else { + byte cfg = (data[4] & 0x60); + // at lower res, the low bits are undefined, so let's zero them + if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms + else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms + else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms + //// default is 12 bit resolution, 750 ms conversion time + } + + float temp = (float)raw / 16.0; + int itemp = int(temp); + + char meuk[75]; + count ++; + sprintf(meuk, "Zone %d %d.%d\xF8""C ", count, itemp, int((temp-itemp)*100)); + showString(meuk, 500); +} + diff --git a/software/workshop2/menuitems.h b/software/workshop2/menuitems.h new file mode 100644 index 0000000..8b6f3ab --- /dev/null +++ b/software/workshop2/menuitems.h @@ -0,0 +1,49 @@ + +byte menuitems[5][8] PROGMEM = { + { + B11000011, + B11000011, + B00000000, + B00000011, + B11000011, + B11100111, + B01111110, + B00111100 + }, { + B11000011, + B11000011, + B11000011, + B11111111, + B11111111, + B11000011, + B11000011, + B11000011 + }, { + B00011000, + B00111100, + B01100110, + B11000011, + B11111111, + B11111111, + B11000011, + B11000011 + }, { + B01111110, + B11111111, + B11000011, + B11000000, + B11000000, + B11000011, + B11111111, + B01111110 + }, { + B11000111, + B11011110, + B11111100, + B11110000, + B11110000, + B11111100, + B11011110, + B11000111 + } +} diff --git a/software/workshop2/readinput.ino b/software/workshop2/readinput.ino new file mode 100644 index 0000000..e93a626 --- /dev/null +++ b/software/workshop2/readinput.ino @@ -0,0 +1,41 @@ +int readinput(long delaytime) { + unsigned long startTime = millis(); + while ((startTime + delaytime) > millis()){ + // read the state of the switch into a local variable: + int reading = digitalRead(buttonPin); + + // check to see if you just pressed the button + // (i.e. the input went from HIGH to LOW), and you've waited + // long enough since the last press to ignore any noise: + + // If the switch changed, due to noise or pressing: + if (reading != lastButtonState) { + // reset the debouncing timer + lastDebounceTime = millis(); + } + + if ((millis() - lastDebounceTime) > debounceDelay) { + // whatever the reading is at, it's been there for longer + // than the debounce delay, so take it as the actual current state: + + // if the button state has changed: + if (reading != buttonState) { + buttonState = reading; + + // only toggle the animation if the new button state is HIGH + if (buttonState == LOW) { + animation++; + if (animation > animations) { + animation = 0; + } + return true; + } + } + } + + // save the reading. Next time through the loop, + // it'll be the lastButtonState: + lastButtonState = reading; + } + return false; /* don't skip the rest */ +} diff --git a/software/workshop2/render.ino b/software/workshop2/render.ino new file mode 100644 index 0000000..568d167 --- /dev/null +++ b/software/workshop2/render.ino @@ -0,0 +1,5 @@ +void render(const byte* frame, int screen) { + for (int i = 0; i < 8; i++) { + lc.setColumn(screen, i, frame[7-i]); + } +} diff --git a/software/workshop2/workshop2.ino b/software/workshop2/workshop2.ino new file mode 100644 index 0000000..4cd0c1e --- /dev/null +++ b/software/workshop2/workshop2.ino @@ -0,0 +1,91 @@ +/* IJduino 1.4 +Requires: + * 8X8 LED grid MAX7219 + * Mini Breadboard + * Atmega328 + * Button + * 2 Wires + * 4.5 Volt + (c) IJhack 2014 GNU GPL +http://ijhack.org/ + */ +#include "LedControl.h" + +// animations +#include "menuitems.h" + +/* using VCC, GND, DIN 20, CS 21, CLK 5 for the MAX7219 */ +static const int DATA_PIN = 20; +static const int CLK_PIN = 5; +static const int CS_PIN = 21; + +static const int INTENSITY = 5; +static const int DISPLAYS = 1; + +/* choose the input pin for the pushbutton */ +static const int buttonPin = 9; + + + +LedControl lc=LedControl(DATA_PIN, CLK_PIN, CS_PIN, DISPLAYS); + +// byte screen[DISPLAYS][8]; +byte screen[8]; + +const byte* menuscreen[5][8] = {ij, h, a, c, k}; + +// basic startup +int lastButtonState = LOW; /* the previous reading from the input pin */ +unsigned long lastDebounceTime = 0; /* the last time the output pin was toggled */ +unsigned long debounceDelay = 50; /* the debounce time; increase if the output flickers */ +int animation = 0; +int animations = 0; +int buttonState = LOW; +int shift = 0; + +void setup() { + /* + The MAX72XX is in power-saving mode on startup, + we have to do a wakeup call + */ + lc.shutdown(0,false); + /* Set the brightness value */ + lc.setIntensity(0,INTENSITY); + /* and clear the display */ + lc.clearDisplay(0); + /* setup pins */ + pinMode(buttonPin, INPUT_PULLUP); +} + +void loop() { + bool skip; + + + load(ij); + + render(screen, 0); + + readinput(1000); + + load(a); + + render(screen, 0); + + readinput(1000); + +} + +void moveleft() { + shift++; + if (shift > 7) { + shift = 0; + } +} + +void load(const byte* frame) { + + for (int r = 0; r < 8; r++) { + screen[r] = pgm_read_byte(&frame[r]); + } + +} diff --git a/software/zolapong/zolapong.ino b/software/zolapong/zolapong.ino new file mode 100644 index 0000000..92108ea --- /dev/null +++ b/software/zolapong/zolapong.ino @@ -0,0 +1,476 @@ +// Developed by Eduardo Zola (Zola Labs) + +#include "LedControl.h" + +byte MSG[8*20]; + +byte SPACE[8] = { + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000, + B00000000 +}; + + +byte Z[8] = { + B00000000, + B01111110, + B00000100, + B00001000, + B00010000, + B00100000, + B01111110, + B00000000 +}; + + +byte O[8] = { + B00000000, + B00111100, + B01000010, + B01000010, + B01000010, + B01000010, + B00111100, + B00000000 +}; + +byte L[8] = { + B00000000, + B01000000, + B01000000, + B01000000, + B01000000, + B01000000, + B01111110, + B00000000 +}; + +byte A[8] = { + B00000000, + B00011000, + B00100100, + B01000010, + B01111110, + B01000010, + B01000010, + B00000000 +}; + + +byte P[8] = { + B00000000, + B01111100, + B01000010, + B01000010, + B01111100, + B01000000, + B01000000, + B00000000 +}; + +byte E[8] = { + B00000000, + B01111110, + B01000000, + B01111100, + B01000000, + B01000000, + B01111110, + B00000000 +}; + +byte R[8] = { + B00000000, + B01111100, + B01000010, + B01111100, + B01001000, + B01000100, + B01000010, + B00000000 +}; + + +byte B[8] = { + B00000000, + B01111100, + B01000010, + B01111100, + B01000010, + B01000010, + B01111100, + B00000000 +}; + + +byte W[8] = { + B00000000, + B01000010, + B01000010, + B01000010, + B01000010, + B01011010, + B01100110, + B00000000 +}; + +byte N[8] = { + B00000000, + B01000010, + B01100010, + B01010010, + B01001010, + B01000110, + B01000010, + B00000000 +}; + + +byte I[8] = { + B00000000, + B00111100, + B00011000, + B00011000, + B00011000, + B00011000, + B00111100, + B00000000 +}; + + +int ledPin = 13; +int speakerPin = 8; + +#define N_c 261 +#define N_d 294 +#define N_e 329 +#define N_f 349 +#define N_g 391 +#define N_gS 415 +#define N_a 440 +#define N_aS 455 +#define N_b 466 +#define N_cH 523 +#define N_cSH 554 +#define N_dH 587 +#define N_dSH 622 +#define N_eH 659 +#define N_fH 698 +#define N_fSH 740 +#define N_gH 784 +#define N_gSH 830 +#define N_aH 880 + +int step_col; +int step_row; +int subidas; +boolean showBars_enabled = false; +int row_bar = 0; + +LedControl LC=LedControl(20,5,21,2); // 2 = dois modulos de matrizes de led +//LedControl LC2=LedControl(speakerPin,6,5,1); + +int X = 4,OLD_X,sensor; + +int row,col; +int sc,sr; + +int cnt = 0; +int desarma = 0; + +boolean INTRO_SHOWED = false; + +int dly; + +void setup() { + + Serial.begin(9600); + + pinMode(A5,INPUT); + pinMode(speakerPin, OUTPUT); + + + LC.shutdown(0,false); + LC.setIntensity(0,8); + LC.clearDisplay(0); + + LC.shutdown(1,false); + LC.setIntensity(1,8); + LC.clearDisplay(1); + + randomSeed(analogRead(1)*millis()); + + if(INTRO_SHOWED == false) + { + copyLetter(SPACE,0); + copyLetter(SPACE,1); + + copyLetter(Z,2); + copyLetter(O,3); + copyLetter(L,4); + copyLetter(A,5); + + copyLetter(SPACE,6); + + copyLetter(L,7); + copyLetter(A,8); + copyLetter(B,9); + copyLetter(SPACE,10); + copyLetter(SPACE,11); + + showMSG(11,50); + + INTRO_SHOWED = true; + } + + loose(); + + dly = 500; + + setLED(15,X,true);setLED(15,X+1,true);setLED(15,X+2,true); + OLD_X = -1; + subidas = 0; + + step_col = 1; + step_row = 1; + + sc = step_col; + sr = step_row; + +// row = -step_row; + row = -1+random(3); + col = random(8); + + showBars(false); +} + + + + +void loop() +{ + + + sensor = analogRead(A5); + +//Serial.println(sensor); + X = map(sensor,0,980,1,6); + +// X = int(sensor / 127); +// if(X < 1) X = 1; +// if(X > 6) X = 6; + + if(X != OLD_X) + { + OLD_X = X; + setROW(15,0x00); + setLED(15,X-1,true);setLED(15,X,true);setLED(15,X+1,true); + } + + + if(cnt == 0) + { + setLED(row,col,false); + + + if((subidas==1 || random(2)==1) && showBars_enabled == false && row == 0) {showBars(true);subidas=0;desarma=2+random(5);}; + if(subidas==desarma && showBars_enabled == true) {showBars(false);subidas=0;}; + + if(col == 7) {sc = -step_col;tone(speakerPin,1000,20);}; + if(col == 0) {sc = step_col;tone(speakerPin,1000,20);}; + + if(row == 0) {sr = step_row;subidas++;dly-=5;tone(speakerPin,1000,20);}; + if(dly <= 190) winner(); + + if(showBars_enabled == true && sr > 0 && row < row_bar) + { + if(row == row_bar - 1) {sr=-step_row;tone(speakerPin,1000,20);}; + } + + if(row == 14) + { + if(col >= X-1 && col <= X+1) {sr = -step_row;tone(speakerPin,1500,20);} + else if(col == X-2 && sc > 0) {sr = -step_row; sc = -step_col;tone(speakerPin,1500,20);} + else if(col == X+2 && sc < 0) {sr = -step_row; sc = step_col;tone(speakerPin,1500,20);}; + } + + row += sr; + col += sc; + + if(col == 8) col = 7; + if(col == -1) col = 0; + + setLED(row,col,true); + + if(row == 15) setup(); + + + } + + cnt++; + if(cnt == dly) cnt = 0; +} + + +void setLED(int l,int c, boolean state) +{ + int disp=0; + if(l > 7) {l = l-8;disp=1;}; + LC.setLed(disp,l,c,state); +} + +void setROW(int r,char ch) +{ + int disp = 0; + if(r > 7) {r = r - 8; disp=1;}; + LC.setRow(disp,r,ch); +} + +void loose() +{ + delay(80); + for(row = 0;row<16;row++) + { + setROW(row,0xFF); + tone(speakerPin,row*500,10); + delay(20); + } + + delay(130); + + for(row = 15;row>=0;row--) + { + setROW(row,0x00); + tone(speakerPin,row*500,10); + delay(20); + } + +} + + + +void showBars(boolean show) +{ + showBars_enabled = show; + + if(show) row_bar = 2+random(5); + setROW(row_bar,(show == true ? 0xFF : 0x00) ); +} + +void showLetter(int r,byte *ch) +{ + int i; + for(i = 0;i < 8;i++) setROW(r+i,*(ch+i)); +} + +void copyLetter(byte *ch,int pos) +{ + int i; + for(i = 0;i<8;i++) *(MSG+i+(pos*8)) = *(ch+i); +} + +void showMSG(int qtde,int tempo) +{ + LC.clearDisplay(0); + LC.clearDisplay(1); + + int idx; + for(idx = 0; idx < 8*qtde;idx ++) + { + for(row = 0;row<16;row++) setROW(row,*(MSG+row+idx)); + delay(tempo); + } + + LC.clearDisplay(0); + LC.clearDisplay(1); + +} + + + +void winner() +{ + copyLetter(SPACE,0); + copyLetter(SPACE,1); + + copyLetter(W,2); + copyLetter(I,3); + copyLetter(N,4); + copyLetter(N,5); + copyLetter(E,6); + copyLetter(R,7); + + copyLetter(SPACE,8); + copyLetter(SPACE,9); + + showMSG(9,80); + + march(); + setup(); +} + + +void beep (unsigned char speakerPin, int frequencyInHertz, long timeInMilliseconds) +{ + digitalWrite(ledPin, HIGH); + //use led to visualize the notes being played + + int x; + long delayAmount = (long)(1000000/frequencyInHertz); + long loopTime = (long)((timeInMilliseconds*1000)/(delayAmount*2)); + + for(row = 0;row<16;row++) setROW(row,0xFF); + + for (x=0;x