aboutsummaryrefslogtreecommitdiffstats
path: root/avr-test2/src
diff options
context:
space:
mode:
authorvg <vgm+dev@devys.org>2020-07-07 16:24:01 +0200
committervg <vgm+dev@devys.org>2020-07-07 16:24:01 +0200
commit66dcf910bd4744d8ced56cb9586aa937a1a2d4c5 (patch)
treedf4dca1ae4af1e5df0be0d1f4f2cd0d54751f8e8 /avr-test2/src
downloadhic-66dcf910bd4744d8ced56cb9586aa937a1a2d4c5.tar.gz
hic-66dcf910bd4744d8ced56cb9586aa937a1a2d4c5.tar.bz2
hic-66dcf910bd4744d8ced56cb9586aa937a1a2d4c5.zip
first commitHEADmaster
Diffstat (limited to 'avr-test2/src')
-rw-r--r--avr-test2/src/cube.h32
-rw-r--r--avr-test2/src/draw.cpp559
-rw-r--r--avr-test2/src/draw.h71
-rw-r--r--avr-test2/src/effect.cpp1331
-rw-r--r--avr-test2/src/effect.h54
-rw-r--r--avr-test2/src/font.cpp104
-rw-r--r--avr-test2/src/font.h13
-rw-r--r--avr-test2/src/fuses.txt6
-rw-r--r--avr-test2/src/gameoflife.cpp135
-rw-r--r--avr-test2/src/gameoflife.h9
-rw-r--r--avr-test2/src/launch_effect.cpp182
-rw-r--r--avr-test2/src/launch_effect.h15
-rw-r--r--avr-test2/src/lisence.txt5
-rw-r--r--avr-test2/src/main.cpp450
-rw-r--r--avr-test2/src/main.cpp.bakup447
-rw-r--r--avr-test2/src/main.h50
16 files changed, 3463 insertions, 0 deletions
diff --git a/avr-test2/src/cube.h b/avr-test2/src/cube.h
new file mode 100644
index 0000000..01f19da
--- /dev/null
+++ b/avr-test2/src/cube.h
@@ -0,0 +1,32 @@
+#ifndef CUBE_H
+#define CUBE_H
+
+// Some of the functions are created to be portable
+// These functions will work on cubes of different sizes by
+// changing this constant
+#define CUBE_SIZE 8
+#define CUBE_BYTES 64
+
+// If you change this to anything greather than 8, you also have
+// change how the cube buffer works and probably all the functions
+// in draw.c
+
+// Cube buffer
+// Data from this array is loaded onto the cube for each duty cycle
+extern volatile unsigned char cube[CUBE_SIZE][CUBE_SIZE];
+
+// Framebuffer
+// Animations that take a lot of time to compute are temporarily
+// stored to this array, then loaded into cube[8][8] when the image
+// is ready to be displayed
+extern volatile unsigned char fb[CUBE_SIZE][CUBE_SIZE];
+
+// Some effects can render on different axis
+// for example send pixels along an axis
+// for better readability, we use the following predefined constants
+#define AXIS_X 0x78
+#define AXIS_Y 0x79
+#define AXIS_Z 0x7a
+
+#endif
+
diff --git a/avr-test2/src/draw.cpp b/avr-test2/src/draw.cpp
new file mode 100644
index 0000000..faaa346
--- /dev/null
+++ b/avr-test2/src/draw.cpp
@@ -0,0 +1,559 @@
+#include "draw.h"
+#include "string.h"
+
+// Set a single voxel to ON
+void setvoxel(int x, int y, int z)
+{
+ if (inrange(x,y,z))
+ cube[z][y] |= (1 << x);
+}
+
+// Set a single voxel in the temporary cube buffer to ON
+void tmpsetvoxel(int x, int y, int z)
+{
+ if (inrange(x,y,z))
+ fb[z][y] |= (1 << x);
+}
+
+// Set a single voxel to OFF
+void clrvoxel(int x, int y, int z)
+{
+ if (inrange(x,y,z))
+ cube[z][y] &= ~(1 << x);
+}
+
+// Set a single voxel to OFF
+void tmpclrvoxel(int x, int y, int z)
+{
+ if (inrange(x,y,z))
+ fb[z][y] &= ~(1 << x);
+}
+
+// This function validates that we are drawing inside the cube.
+unsigned char inrange(int x, int y, int z)
+{
+ if (x >= 0 && x < CUBE_SIZE && y >= 0 && y < CUBE_SIZE && z >= 0 && z < CUBE_SIZE)
+ {
+ return 1;
+ } else
+ {
+ // One of the coordinates was outside the cube.
+ return 0;
+ }
+}
+
+// Get the current status of a voxel
+unsigned char getvoxel(int x, int y, int z)
+{
+ if (inrange(x,y,z))
+ {
+ if (cube[z][y] & (1 << x))
+ {
+ return 1;
+ } else
+ {
+ return 0;
+ }
+ } else
+ {
+ return 0;
+ }
+}
+
+// In some effect we want to just take bool and write it to a voxel
+// this function calls the apropriate voxel manipulation function.
+void altervoxel(int x, int y, int z, int state)
+{
+ if (state == 1)
+ {
+ setvoxel(x,y,z);
+ } else
+ {
+ clrvoxel(x,y,z);
+ }
+}
+
+// Flip the state of a voxel.
+// If the voxel is 1, its turned into a 0, and vice versa.
+void flpvoxel(int x, int y, int z)
+{
+ if (inrange(x, y, z))
+ cube[z][y] ^= (1 << x);
+}
+
+// Makes sure x1 is alwas smaller than x2
+// This is usefull for functions that uses for loops,
+// to avoid infinite loops
+void argorder(int ix1, int ix2, int *ox1, int *ox2)
+{
+ if (ix1>ix2)
+ {
+ int tmp;
+ tmp = ix1;
+ ix1= ix2;
+ ix2 = tmp;
+ }
+ *ox1 = ix1;
+ *ox2 = ix2;
+}
+
+// Sets all voxels along a X/Y plane at a given point
+// on axis Z
+void setplane_z (int z)
+{
+ int i;
+ if (z>=0 && z<CUBE_SIZE)
+ {
+ for (i=0;i<CUBE_SIZE;i++)
+ cube[z][i] = 0xff;
+ }
+}
+
+// Clears voxels in the same manner as above
+void clrplane_z (int z)
+{
+ int i;
+ if (z>=0 && z<CUBE_SIZE)
+ {
+ for (i=0;i<CUBE_SIZE;i++)
+ cube[z][i] = 0x00;
+ }
+}
+
+void setplane_x (int x)
+{
+ int z;
+ int y;
+ if (x>=0 && x<CUBE_SIZE)
+ {
+ for (z=0;z<CUBE_SIZE;z++)
+ {
+ for (y=0;y<CUBE_SIZE;y++)
+ {
+ cube[z][y] |= (1 << x);
+ }
+ }
+ }
+}
+
+void clrplane_x (int x)
+{
+ int z;
+ int y;
+ if (x>=0 && x<CUBE_SIZE)
+ {
+ for (z=0;z<CUBE_SIZE;z++)
+ {
+ for (y=0;y<CUBE_SIZE;y++)
+ {
+ cube[z][y] &= ~(1 << x);
+ }
+ }
+ }
+}
+
+void setplane_y (int y)
+{
+ int z;
+ if (y>=0 && y<CUBE_SIZE)
+ {
+ for (z=0;z<CUBE_SIZE;z++)
+ cube[z][y] = 0xff;
+ }
+}
+
+void clrplane_y (int y)
+{
+ int z;
+ if (y>=0 && y<CUBE_SIZE)
+ {
+ for (z=0;z<CUBE_SIZE;z++)
+ cube[z][y] = 0x00;
+ }
+}
+
+void setplane (char axis, unsigned char i)
+{
+ switch (axis)
+ {
+ case AXIS_X:
+ setplane_x(i);
+ break;
+
+ case AXIS_Y:
+ setplane_y(i);
+ break;
+
+ case AXIS_Z:
+ setplane_z(i);
+ break;
+ }
+}
+
+void clrplane (char axis, unsigned char i)
+{
+ switch (axis)
+ {
+ case AXIS_X:
+ clrplane_x(i);
+ break;
+
+ case AXIS_Y:
+ clrplane_y(i);
+ break;
+
+ case AXIS_Z:
+ clrplane_z(i);
+ break;
+ }
+}
+
+// Fill a value into all 64 byts of the cube buffer
+// Mostly used for clearing. fill(0x00)
+// or setting all on. fill(0xff)
+void fill (unsigned char pattern)
+{
+ int z;
+ int y;
+ for (z=0;z<CUBE_SIZE;z++)
+ {
+ for (y=0;y<CUBE_SIZE;y++)
+ {
+ cube[z][y] = pattern;
+ }
+ }
+}
+
+void tmpfill (unsigned char pattern)
+{
+ int z;
+ int y;
+ for (z=0;z<CUBE_SIZE;z++)
+ {
+ for (y=0;y<CUBE_SIZE;y++)
+ {
+ fb[z][y] = pattern;
+ }
+ }
+}
+
+// Draw a box with all walls drawn and all voxels inside set
+void box_filled(int x1, int y1, int z1, int x2, int y2, int z2)
+{
+ int iy;
+ int iz;
+
+ argorder(x1, x2, &x1, &x2);
+ argorder(y1, y2, &y1, &y2);
+ argorder(z1, z2, &z1, &z2);
+
+ for (iz=z1;iz<=z2;iz++)
+ {
+ for (iy=y1;iy<=y2;iy++)
+ {
+ cube[iz][iy] |= byteline(x1,x2);
+ }
+ }
+
+}
+
+// Darw a hollow box with side walls.
+void box_walls(int x1, int y1, int z1, int x2, int y2, int z2)
+{
+ int iy;
+ int iz;
+
+ argorder(x1, x2, &x1, &x2);
+ argorder(y1, y2, &y1, &y2);
+ argorder(z1, z2, &z1, &z2);
+
+ for (iz=z1;iz<=z2;iz++)
+ {
+ for (iy=y1;iy<=y2;iy++)
+ {
+ if (iy == y1 || iy == y2 || iz == z1 || iz == z2)
+ {
+ cube[iz][iy] = byteline(x1,x2);
+ } else
+ {
+ cube[iz][iy] |= ((0x01 << x1) | (0x01 << x2));
+ }
+ }
+ }
+
+}
+
+// Draw a wireframe box. This only draws the corners and edges,
+// no walls.
+void box_wireframe(int x1, int y1, int z1, int x2, int y2, int z2)
+{
+ int iy;
+ int iz;
+
+ argorder(x1, x2, &x1, &x2);
+ argorder(y1, y2, &y1, &y2);
+ argorder(z1, z2, &z1, &z2);
+
+ // Lines along X axis
+ cube[z1][y1] = byteline(x1,x2);
+ cube[z1][y2] = byteline(x1,x2);
+ cube[z2][y1] = byteline(x1,x2);
+ cube[z2][y2] = byteline(x1,x2);
+
+ // Lines along Y axis
+ for (iy=y1;iy<=y2;iy++)
+ {
+ setvoxel(x1,iy,z1);
+ setvoxel(x1,iy,z2);
+ setvoxel(x2,iy,z1);
+ setvoxel(x2,iy,z2);
+ }
+
+ // Lines along Z axis
+ for (iz=z1;iz<=z2;iz++)
+ {
+ setvoxel(x1,y1,iz);
+ setvoxel(x1,y2,iz);
+ setvoxel(x2,y1,iz);
+ setvoxel(x2,y2,iz);
+ }
+
+}
+
+// Returns a byte with a row of 1's drawn in it.
+// byteline(2,5) gives 0b00111100
+char byteline (int start, int end)
+{
+ return ((0xff<<start) & ~(0xff<<(end+1)));
+}
+
+// Flips a byte 180 degrees.
+// MSB becomes LSB, LSB becomes MSB.
+char flipbyte (char byte)
+{
+ char flop = 0x00;
+
+ flop = (flop & 0b11111110) | (0b00000001 & (byte >> 7));
+ flop = (flop & 0b11111101) | (0b00000010 & (byte >> 5));
+ flop = (flop & 0b11111011) | (0b00000100 & (byte >> 3));
+ flop = (flop & 0b11110111) | (0b00001000 & (byte >> 1));
+ flop = (flop & 0b11101111) | (0b00010000 & (byte << 1));
+ flop = (flop & 0b11011111) | (0b00100000 & (byte << 3));
+ flop = (flop & 0b10111111) | (0b01000000 & (byte << 5));
+ flop = (flop & 0b01111111) | (0b10000000 & (byte << 7));
+ return flop;
+}
+
+// Draw a line between any coordinates in 3d space.
+// Uses integer values for input, so dont expect smooth animations.
+void line(int x1, int y1, int z1, int x2, int y2, int z2)
+{
+ float xy; // how many voxels do we move on the y axis for each step on the x axis
+ float xz; // how many voxels do we move on the y axis for each step on the x axis
+ unsigned char x,y,z;
+ unsigned char lasty,lastz;
+
+ // We always want to draw the line from x=0 to x=7.
+ // If x1 is bigget than x2, we need to flip all the values.
+ if (x1>x2)
+ {
+ int tmp;
+ tmp = x2; x2 = x1; x1 = tmp;
+ tmp = y2; y2 = y1; y1 = tmp;
+ tmp = z2; z2 = z1; z1 = tmp;
+ }
+
+
+ if (y1>y2)
+ {
+ xy = (float)(y1-y2)/(float)(x2-x1);
+ lasty = y2;
+ } else
+ {
+ xy = (float)(y2-y1)/(float)(x2-x1);
+ lasty = y1;
+ }
+
+ if (z1>z2)
+ {
+ xz = (float)(z1-z2)/(float)(x2-x1);
+ lastz = z2;
+ } else
+ {
+ xz = (float)(z2-z1)/(float)(x2-x1);
+ lastz = z1;
+ }
+
+
+
+ // For each step of x, y increments by:
+ for (x = x1; x<=x2;x++)
+ {
+ y = (xy*(x-x1))+y1;
+ z = (xz*(x-x1))+z1;
+ setvoxel(x,y,z);
+ }
+
+}
+
+// Delay loop.
+// This is not calibrated to milliseconds,
+// but we had allready made to many effects using this
+// calibration when we figured it might be a good idea
+// to calibrate it.
+void delay_ms(uint16_t x)
+{
+ uint8_t y, z;
+ for ( ; x > 0 ; x--){
+ for ( y = 0 ; y < 90 ; y++){
+ for ( z = 0 ; z < 6 ; z++){
+ asm volatile ("nop");
+ }
+ }
+ }
+}
+
+// Copies the contents of fb (temp cube buffer) into the rendering buffer
+void tmp2cube (void)
+{
+ memcpy((void*)cube, (const void*)fb, 64); // copy the current cube into a buffer.
+}
+
+// Shift the entire contents of the cube along an axis
+// This is great for effects where you want to draw something
+// on one side of the cube and have it flow towards the other
+// side. Like rain flowing down the Z axiz.
+void shift (char axis, int direction)
+{
+ int i, x ,y;
+ int ii, iii;
+ int state;
+
+ for (i = 0; i < CUBE_SIZE; i++)
+ {
+ if (direction == -1)
+ {
+ ii = i;
+ } else
+ {
+ ii = (7-i);
+ }
+
+
+ for (x = 0; x < CUBE_SIZE; x++)
+ {
+ for (y = 0; y < CUBE_SIZE; y++)
+ {
+ if (direction == -1)
+ {
+ iii = ii+1;
+ } else
+ {
+ iii = ii-1;
+ }
+
+ if (axis == AXIS_Z)
+ {
+ state = getvoxel(x,y,iii);
+ altervoxel(x,y,ii,state);
+ }
+
+ if (axis == AXIS_Y)
+ {
+ state = getvoxel(x,iii,y);
+ altervoxel(x,ii,y,state);
+ }
+
+ if (axis == AXIS_X)
+ {
+ state = getvoxel(iii,y,x);
+ altervoxel(ii,y,x,state);
+ }
+ }
+ }
+ }
+
+ if (direction == -1)
+ {
+ i = 7;
+ } else
+ {
+ i = 0;
+ }
+
+ for (x = 0; x < CUBE_SIZE; x++)
+ {
+ for (y = 0; y < CUBE_SIZE; y++)
+ {
+ if (axis == AXIS_Z)
+ clrvoxel(x,y,i);
+
+ if (axis == AXIS_Y)
+ clrvoxel(x,i,y);
+
+ if (axis == AXIS_X)
+ clrvoxel(i,y,x);
+ }
+ }
+}
+
+// Flip the cube 180 degrees along the y axis.
+void mirror_y (void)
+{
+ unsigned char buffer[CUBE_SIZE][CUBE_SIZE];
+ unsigned char x,y,z;
+
+ memcpy(buffer, (const void*)cube, CUBE_BYTES); // copy the current cube into a buffer.
+
+ fill(0x00);
+ for (z=0; z<CUBE_SIZE; z++)
+ {
+ for (y=0; y<CUBE_SIZE; y++)
+ {
+ for (x=0; x<CUBE_SIZE; x++)
+ {
+ if (buffer[z][y] & (0x01 << x))
+ setvoxel(x,CUBE_SIZE-1-y,z);
+ }
+ }
+ }
+
+}
+
+// Flip the cube 180 degrees along the x axis
+void mirror_x (void)
+{
+ unsigned char buffer[CUBE_SIZE][CUBE_SIZE];
+ unsigned char y,z;
+
+ memcpy(buffer, (const void*)cube, CUBE_BYTES); // copy the current cube into a buffer.
+
+ fill(0x00);
+
+ for (z=0; z<CUBE_SIZE; z++)
+ {
+ for (y=0; y<CUBE_SIZE; y++)
+ {
+ // This will break with different buffer sizes..
+ cube[z][y] = flipbyte(buffer[z][y]);
+ }
+ }
+}
+
+// flip the cube 180 degrees along the z axis
+void mirror_z (void)
+{
+ unsigned char buffer[CUBE_SIZE][CUBE_SIZE];
+ unsigned char z, y;
+
+ memcpy(buffer, (const void*)cube, CUBE_BYTES); // copy the current cube into a buffer.
+
+ for (y=0; y<CUBE_SIZE; y++)
+ {
+ for (z=0; z<CUBE_SIZE; z++)
+ {
+ cube[CUBE_SIZE-1-z][y] = buffer[z][y];
+ }
+ }
+}
+
diff --git a/avr-test2/src/draw.h b/avr-test2/src/draw.h
new file mode 100644
index 0000000..abe93d2
--- /dev/null
+++ b/avr-test2/src/draw.h
@@ -0,0 +1,71 @@
+#ifndef DRAW_H
+#define DRAW_H
+
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+
+#include "cube.h"
+
+extern const unsigned char font[480];
+
+// Red led on D2
+#define LED_RED 0x04
+// Green led D3
+#define LED_GREEN 0x08
+// Program led on D4
+#define LED_PGM 0x10;
+// Leds connected to port D
+#define LED_PORT PORTD
+// Programming button on D5
+#define PGM_BTN 0x20
+
+void delay_ms (uint16_t x);
+
+
+void setvoxel(int x, int y, int z);
+void clrvoxel(int x, int y, int z);
+void tmpsetvoxel(int x, int y, int z);
+void tmpclrvoxel(int x, int y, int z);
+
+unsigned char inrange(int x, int y, int z);
+unsigned char getvoxel(int x, int y, int z);
+void flpvoxel(int x, int y, int z);
+
+void altervoxel(int x, int y, int z, int state);
+void setplane_z(int z);
+void clrplane_z(int z);
+void setplane_x(int x);
+void clrplane_x(int x);
+void setplane_y(int y);
+void clrplane_y(int y);
+
+void setplane (char axis, unsigned char i);
+void clrplane (char axis, unsigned char i);
+
+void setline_z(int x, int y, int z1, int z2);
+void setline_x(int z, int y, int x1, int x2);
+void setline_y(int z, int x, int y1, int y2);
+void clrline_z(int x, int y, int z1, int z2);
+void clrline_x(int z, int y, int x1, int x2);
+void clrline_y(int z, int x, int y1, int y2);
+void fill(unsigned char pattern);
+void tmpfill(unsigned char pattern);
+void line(int x1, int y1, int z1, int x2, int y2, int z2);
+void drawchar(char chr, int offset, int layer);
+char flipbyte(char byte);
+void charfly (char chr, int direction, char axis, int mode, uint16_t delay);
+void strfly (char * str, int direction, char axis, int mode, uint16_t delay, uint16_t pause);
+void box_filled(int x1, int y1, int z1, int x2, int y2, int z2);
+void box_walls(int x1, int y1, int z1, int x2, int y2, int z2);
+void box_wireframe(int x1, int y1, int z1, int x2, int y2, int z2);
+char byteline (int start, int end);
+
+void tmp2cube (void);
+void shift (char axis, int direction);
+
+void mirror_x(void);
+void mirror_y(void);
+void mirror_z(void);
+
+#endif
+
diff --git a/avr-test2/src/effect.cpp b/avr-test2/src/effect.cpp
new file mode 100644
index 0000000..d44da4d
--- /dev/null
+++ b/avr-test2/src/effect.cpp
@@ -0,0 +1,1331 @@
+#include "effect.h"
+#include "draw.h"
+#include "font.h"
+#include <math.h>
+#include <avr/interrupt.h>
+
+void effect_test (void)
+{
+
+ int x,y,i;
+
+ for (i=0;i<1000;i++)
+ {
+ x = sin(i/8)*2+3.5;
+ y = cos(i/8)*2+3.5;
+
+ setvoxel(x,y,1);
+ setvoxel(x,y,1);
+ delay_ms(1000);
+ fill(0x00);
+ }
+
+}
+
+
+void effect_stringfly2(const char * str)
+{
+ int x,y,i;
+ unsigned char chr[5];
+
+ while (*str)
+ {
+ font_getchar(*str++, chr);
+
+ // Put a character on the back of the cube
+ for (x = 0; x < 5; x++)
+ {
+ for (y = 0; y < 8; y++)
+ {
+ if ((chr[x] & (0x80>>y)))
+ {
+ setvoxel(7,x+2,y);
+ }
+ }
+ }
+
+ // Shift the entire contents of the cube forward by 6 steps
+ // before placing the next character
+ for (i = 0; i<6; i++)
+ {
+ delay_ms(1000);
+ shift(AXIS_X,-1);
+ }
+ }
+ // Shift the last character out of the cube.
+ for (i = 0; i<8; i++)
+ {
+ delay_ms(1000);
+ shift(AXIS_X,-1);
+ }
+
+}
+
+// Draw a plane on one axis and send it back and forth once.
+void effect_planboing (int plane, int speed)
+{
+ int i;
+ for (i=0;i<8;i++)
+ {
+ fill(0x00);
+ setplane(plane, i);
+ delay_ms(speed);
+ }
+
+ for (i=7;i>=0;i--)
+ {
+ fill(0x00);
+ setplane(plane,i);
+ delay_ms(speed);
+ }
+}
+
+void effect_blinky2()
+{
+ int i,r;
+ fill(0x00);
+
+ for (r=0;r<2;r++)
+ {
+ i = 750;
+ while (i>0)
+ {
+ fill(0x00);
+ delay_ms(i);
+
+ fill(0xff);
+ delay_ms(100);
+
+ i = i - (15+(1000/(i/10)));
+ }
+
+ delay_ms(1000);
+
+ i = 750;
+ while (i>0)
+ {
+ fill(0x00);
+ delay_ms(751-i);
+
+ fill(0xff);
+ delay_ms(100);
+
+ i = i - (15+(1000/(i/10)));
+ }
+ }
+
+}
+
+void effect_box_shrink_grow (int iterations, int rot, int flip, uint16_t delay)
+{
+ int x, i, xyz;
+ for (x=0;x<iterations;x++)
+ {
+ for (i=0;i<16;i++)
+ {
+ xyz = 7-i; // This reverses counter i between 0 and 7.
+ if (i > 7)
+ xyz = i-8; // at i > 7, i 8-15 becomes xyz 0-7.
+
+ fill(0x00); delay_ms(1);
+ cli(); // disable interrupts while the cube is being rotated
+ box_wireframe(0,0,0,xyz,xyz,xyz);
+
+ if (flip > 0) // upside-down
+ mirror_z();
+
+ if (rot == 1 || rot == 3)
+ mirror_y();
+
+ if (rot == 2 || rot == 3)
+ mirror_x();
+
+ sei(); // enable interrupts
+ delay_ms(delay);
+ fill(0x00);
+ }
+ }
+}
+
+// Creates a wireframe box that shrinks or grows out from the center of the cube.
+void effect_box_woopwoop (int delay, int grow)
+{
+ int i,ii;
+
+ fill(0x00);
+ for (i=0;i<4;i++)
+ {
+ ii = i;
+ if (grow > 0)
+ ii = 3-i;
+
+ box_wireframe(4+ii,4+ii,4+ii,3-ii,3-ii,3-ii);
+ delay_ms(delay);
+ fill(0x00);
+ }
+}
+
+
+// Send a voxel flying from one side of the cube to the other
+// If its at the bottom, send it to the top..
+void sendvoxel_z (unsigned char x, unsigned char y, unsigned char z, int delay)
+{
+ int i, ii;
+ for (i=0; i<8; i++)
+ {
+ if (z == 7)
+ {
+ ii = 7-i;
+ clrvoxel(x,y,ii+1);
+ } else
+ {
+ ii = i;
+ clrvoxel(x,y,ii-1);
+ }
+ setvoxel(x,y,ii);
+ delay_ms(delay);
+ }
+}
+
+// Send all the voxels from one side of the cube to the other
+// Start at z and send to the opposite side.
+// Sends in random order.
+void sendplane_rand_z (unsigned char z, int delay, int wait)
+{
+ unsigned char loop = 16;
+ unsigned char x, y;
+
+ fill(0x00);
+
+ setplane_z(z);
+
+ // Send voxels at random untill all 16 have crossed the cube.
+ while(loop)
+ {
+ x = rand()%4;
+ y = rand()%4;
+ if (getvoxel(x,y,z))
+ {
+ // Send the voxel flying
+ sendvoxel_z(x,y,z,delay);
+ delay_ms(wait);
+ loop--; // one down, loop-- to go. when this hits 0, the loop exits.
+ }
+ }
+}
+
+// For each coordinate along X and Y, a voxel is set either at level 0 or at level 7
+// for n iterations, a random voxel is sent to the opposite side of where it was.
+void sendvoxels_rand_z (int iterations, int delay, int wait)
+{
+ unsigned char x, y, last_x = 0, last_y = 0, i;
+
+ fill(0x00);
+
+ // Loop through all the X and Y coordinates
+ for (x=0;x<8;x++)
+ {
+ for (y=0;y<8;y++)
+ {
+ // Then set a voxel either at the top or at the bottom
+ // rand()%2 returns either 0 or 1. multiplying by 7 gives either 0 or 7.
+ setvoxel(x,y,((rand()%2)*7));
+ }
+ }
+
+ for (i=0;i<iterations;i++)
+ {
+ // Pick a random x,y position
+ x = rand()%8;
+ y = rand()%8;
+ // but not the sameone twice in a row
+ if (y != last_y && x != last_x)
+ {
+ // If the voxel at this x,y is at the bottom
+ if (getvoxel(x,y,0))
+ {
+ // send it to the top
+ sendvoxel_z(x,y,0,delay);
+ } else
+ {
+ // if its at the top, send it to the bottom
+ sendvoxel_z(x,y,7,delay);
+ }
+ delay_ms(wait);
+
+ // Remember the last move
+ last_y = y;
+ last_x = x;
+ }
+ }
+
+}
+
+
+// Big ugly function :p but it looks pretty
+void boingboing(uint16_t iterations, int delay, unsigned char mode, unsigned char drawmode)
+{
+ fill(0x00); // Blank the cube
+
+ int x, y, z; // Current coordinates for the point
+ int dx, dy, dz; // Direction of movement
+ int lol, i; // lol?
+ unsigned char crash_x, crash_y, crash_z;
+
+ y = rand()%8;
+ x = rand()%8;
+ z = rand()%8;
+
+ // Coordinate array for the snake.
+ int snake[8][3];
+ for (i=0;i<8;i++)
+ {
+ snake[i][0] = x;
+ snake[i][1] = y;
+ snake[i][2] = z;
+ }
+
+
+ dx = 1;
+ dy = 1;
+ dz = 1;
+
+ while(iterations)
+ {
+ crash_x = 0;
+ crash_y = 0;
+ crash_z = 0;
+
+
+ // Let's mix things up a little:
+ if (rand()%3 == 0)
+ {
+ // Pick a random axis, and set the speed to a random number.
+ lol = rand()%3;
+ if (lol == 0)
+ dx = rand()%3 - 1;
+
+ if (lol == 1)
+ dy = rand()%3 - 1;
+
+ if (lol == 2)
+ dz = rand()%3 - 1;
+ }
+
+ // The point has reached 0 on the x-axis and is trying to go to -1
+ // aka a crash
+ if (dx == -1 && x == 0)
+ {
+ crash_x = 0x01;
+ if (rand()%3 == 1)
+ {
+ dx = 1;
+ } else
+ {
+ dx = 0;
+ }
+ }
+
+ // y axis 0 crash
+ if (dy == -1 && y == 0)
+ {
+ crash_y = 0x01;
+ if (rand()%3 == 1)
+ {
+ dy = 1;
+ } else
+ {
+ dy = 0;
+ }
+ }
+
+ // z axis 0 crash
+ if (dz == -1 && z == 0)
+ {
+ crash_z = 0x01;
+ if (rand()%3 == 1)
+ {
+ dz = 1;
+ } else
+ {
+ dz = 0;
+ }
+ }
+
+ // x axis 7 crash
+ if (dx == 1 && x == 7)
+ {
+ crash_x = 0x01;
+ if (rand()%3 == 1)
+ {
+ dx = -1;
+ } else
+ {
+ dx = 0;
+ }
+ }
+
+ // y axis 7 crash
+ if (dy == 1 && y == 7)
+ {
+ crash_y = 0x01;
+ if (rand()%3 == 1)
+ {
+ dy = -1;
+ } else
+ {
+ dy = 0;
+ }
+ }
+
+ // z azis 7 crash
+ if (dz == 1 && z == 7)
+ {
+ crash_z = 0x01;
+ if (rand()%3 == 1)
+ {
+ dz = -1;
+ } else
+ {
+ dz = 0;
+ }
+ }
+
+ // mode bit 0 sets crash action enable
+ if (mode | 0x01)
+ {
+ if (crash_x)
+ {
+ if (dy == 0)
+ {
+ if (y == 7)
+ {
+ dy = -1;
+ } else if (y == 0)
+ {
+ dy = +1;
+ } else
+ {
+ if (rand()%2 == 0)
+ {
+ dy = -1;
+ } else
+ {
+ dy = 1;
+ }
+ }
+ }
+ if (dz == 0)
+ {
+ if (z == 7)
+ {
+ dz = -1;
+ } else if (z == 0)
+ {
+ dz = 1;
+ } else
+ {
+ if (rand()%2 == 0)
+ {
+ dz = -1;
+ } else
+ {
+ dz = 1;
+ }
+ }
+ }
+ }
+
+ if (crash_y)
+ {
+ if (dx == 0)
+ {
+ if (x == 7)
+ {
+ dx = -1;
+ } else if (x == 0)
+ {
+ dx = 1;
+ } else
+ {
+ if (rand()%2 == 0)
+ {
+ dx = -1;
+ } else
+ {
+ dx = 1;
+ }
+ }
+ }
+ if (dz == 0)
+ {
+ if (z == 3)
+ {
+ dz = -1;
+ } else if (z == 0)
+ {
+ dz = 1;
+ } else
+ {
+ if (rand()%2 == 0)
+ {
+ dz = -1;
+ } else
+ {
+ dz = 1;
+ }
+ }
+ }
+ }
+
+ if (crash_z)
+ {
+ if (dy == 0)
+ {
+ if (y == 7)
+ {
+ dy = -1;
+ } else if (y == 0)
+ {
+ dy = 1;
+ } else
+ {
+ if (rand()%2 == 0)
+ {
+ dy = -1;
+ } else
+ {
+ dy = 1;
+ }
+ }
+ }
+ if (dx == 0)
+ {
+ if (x == 7)
+ {
+ dx = -1;
+ } else if (x == 0)
+ {
+ dx = 1;
+ } else
+ {
+ if (rand()%2 == 0)
+ {
+ dx = -1;
+ } else
+ {
+ dx = 1;
+ }
+ }
+ }
+ }
+ }
+
+ // mode bit 1 sets corner avoid enable
+ if (mode | 0x02)
+ {
+ if ( // We are in one of 8 corner positions
+ (x == 0 && y == 0 && z == 0) ||
+ (x == 0 && y == 0 && z == 7) ||
+ (x == 0 && y == 7 && z == 0) ||
+ (x == 0 && y == 7 && z == 7) ||
+ (x == 7 && y == 0 && z == 0) ||
+ (x == 7 && y == 0 && z == 7) ||
+ (x == 7 && y == 7 && z == 0) ||
+ (x == 7 && y == 7 && z == 7)
+ )
+ {
+ // At this point, the voxel would bounce
+ // back and forth between this corner,
+ // and the exact opposite corner
+ // We don't want that!
+
+ // So we alter the trajectory a bit,
+ // to avoid corner stickyness
+ lol = rand()%3;
+ if (lol == 0)
+ dx = 0;
+
+ if (lol == 1)
+ dy = 0;
+
+ if (lol == 2)
+ dz = 0;
+ }
+ }
+
+ // one last sanity check
+ if (x == 0 && dx == -1)
+ dx = 1;
+
+ if (y == 0 && dy == -1)
+ dy = 1;
+
+ if (z == 0 && dz == -1)
+ dz = 1;
+
+ if (x == 7 && dx == 1)
+ dx = -1;
+
+ if (y == 7 && dy == 1)
+ dy = -1;
+
+ if (z == 7 && dz == 1)
+ dz = -1;
+
+
+ // Finally, move the voxel.
+ x = x + dx;
+ y = y + dy;
+ z = z + dz;
+
+ if (drawmode == 0x01) // show one voxel at time
+ {
+ setvoxel(x,y,z);
+ delay_ms(delay);
+ clrvoxel(x,y,z);
+ } else if (drawmode == 0x02) // flip the voxel in question
+ {
+ flpvoxel(x,y,z);
+ delay_ms(delay);
+ } if (drawmode == 0x03) // draw a snake
+ {
+ for (i=7;i>=0;i--)
+ {
+ snake[i][0] = snake[i-1][0];
+ snake[i][1] = snake[i-1][1];
+ snake[i][2] = snake[i-1][2];
+ }
+ snake[0][0] = x;
+ snake[0][1] = y;
+ snake[0][2] = z;
+
+ for (i=0;i<8;i++)
+ {
+ setvoxel(snake[i][0],snake[i][1],snake[i][2]);
+ }
+ delay_ms(delay);
+ for (i=0;i<8;i++)
+ {
+ clrvoxel(snake[i][0],snake[i][1],snake[i][2]);
+ }
+ }
+
+
+ iterations--;
+ }
+}
+
+// Set or clear exactly 512 voxels in a random order.
+void effect_random_filler (int delay, int state)
+{
+ int x,y,z;
+ int loop = 0;
+
+
+ if (state == 1)
+ {
+ fill(0x00);
+ } else
+ {
+ fill(0xff);
+ }
+
+ while (loop<511)
+ {
+ x = rand()%8;
+ y = rand()%8;
+ z = rand()%8;
+
+ if ((state == 0 && getvoxel(x,y,z) == 0x01) || (state == 1 && getvoxel(x,y,z) == 0x00))
+ {
+ altervoxel(x,y,z,state);
+ delay_ms(delay);
+ loop++;
+ }
+ }
+}
+
+
+void effect_rain (int iterations)
+{
+ int i, ii;
+ int rnd_x;
+ int rnd_y;
+ int rnd_num;
+
+ for (ii=0;ii<iterations;ii++)
+ {
+ rnd_num = rand()%4;
+
+ for (i=0; i < rnd_num;i++)
+ {
+ rnd_x = rand()%8;
+ rnd_y = rand()%8;
+ setvoxel(rnd_x,rnd_y,7);
+ }
+
+ delay_ms(1000);
+ shift(AXIS_Z,-1);
+ }
+}
+
+void effect_z_updown (int iterations, int delay)
+{
+ unsigned char positions[64];
+ unsigned char destinations[64];
+
+ int i,y,move;
+
+ for (i=0; i<64; i++)
+ {
+ positions[i] = 4;
+ destinations[i] = rand()%8;
+ }
+
+ for (i=0; i<8; i++)
+ {
+ effect_z_updown_move(positions, destinations, AXIS_Z);
+ delay_ms(delay);
+ }
+
+ for (i=0;i<iterations;i++)
+ {
+ for (move=0;move<8;move++)
+ {
+ effect_z_updown_move(positions, destinations, AXIS_Z);
+ delay_ms(delay);
+ }
+
+ delay_ms(delay*4);
+
+
+ for (y=0;y<32;y++)
+ {
+ destinations[rand()%64] = rand()%8;
+ }
+
+ }
+
+}
+
+void effect_z_updown_move (unsigned char positions[64], unsigned char destinations[64], char axis)
+{
+ int px;
+ for (px=0; px<64; px++)
+ {
+ if (positions[px]<destinations[px])
+ {
+ positions[px]++;
+ }
+ if (positions[px]>destinations[px])
+ {
+ positions[px]--;
+ }
+ }
+
+ draw_positions_axis (AXIS_Z, positions,0);
+}
+
+void effect_axis_updown_randsuspend (char axis, int delay, int sleep, int invert)
+{
+ unsigned char positions[64];
+ unsigned char destinations[64];
+
+ int i,px;
+
+ // Set 64 random positions
+ for (i=0; i<64; i++)
+ {
+ positions[i] = 0; // Set all starting positions to 0
+ destinations[i] = rand()%8;
+ }
+
+ // Loop 8 times to allow destination 7 to reach all the way
+ for (i=0; i<8; i++)
+ {
+ // For every iteration, move all position one step closer to their destination
+ for (px=0; px<64; px++)
+ {
+ if (positions[px]<destinations[px])
+ {
+ positions[px]++;
+ }
+ }
+ // Draw the positions and take a nap
+ draw_positions_axis (axis, positions,invert);
+ delay_ms(delay);
+ }
+
+ // Set all destinations to 7 (opposite from the side they started out)
+ for (i=0; i<64; i++)
+ {
+ destinations[i] = 7;
+ }
+
+ // Suspend the positions in mid-air for a while
+ delay_ms(sleep);
+
+ // Then do the same thing one more time
+ for (i=0; i<8; i++)
+ {
+ for (px=0; px<64; px++)
+ {
+ if (positions[px]<destinations[px])
+ {
+ positions[px]++;
+ }
+ if (positions[px]>destinations[px])
+ {
+ positions[px]--;
+ }
+ }
+ draw_positions_axis (axis, positions,invert);
+ delay_ms(delay);
+ }
+}
+
+void draw_positions_axis (char axis, unsigned char positions[64], int invert)
+{
+ int x, y, p;
+
+ fill(0x00);
+
+ for (x=0; x<8; x++)
+ {
+ for (y=0; y<8; y++)
+ {
+ if (invert)
+ {
+ p = (7-positions[(x*8)+y]);
+ } else
+ {
+ p = positions[(x*8)+y];
+ }
+
+ if (axis == AXIS_Z)
+ setvoxel(x,y,p);
+
+ if (axis == AXIS_Y)
+ setvoxel(x,p,y);
+
+ if (axis == AXIS_X)
+ setvoxel(p,y,x);
+ }
+ }
+
+}
+
+
+void effect_boxside_randsend_parallel (char axis, int origin, int delay, int mode)
+{
+ int i;
+ int done;
+ unsigned char cubepos[64];
+ unsigned char pos[64];
+ int notdone = 1;
+ int notdone2 = 1;
+ int sent = 0;
+
+ for (i=0;i<64;i++)
+ {
+ pos[i] = 0;
+ }
+
+ while (notdone)
+ {
+ if (mode == 1)
+ {
+ notdone2 = 1;
+ while (notdone2 && sent<64)
+ {
+ i = rand()%64;
+ if (pos[i] == 0)
+ {
+ sent++;
+ pos[i] += 1;
+ notdone2 = 0;
+ }
+ }
+ } else if (mode == 2)
+ {
+ if (sent<64)
+ {
+ pos[sent] += 1;
+ sent++;
+ }
+ }
+
+ done = 0;
+ for (i=0;i<64;i++)
+ {
+ if (pos[i] > 0 && pos[i] <7)
+ {
+ pos[i] += 1;
+ }
+
+ if (pos[i] == 7)
+ done++;
+ }
+
+ if (done == 64)
+ notdone = 0;
+
+ for (i=0;i<64;i++)
+ {
+ if (origin == 0)
+ {
+ cubepos[i] = pos[i];
+ } else
+ {
+ cubepos[i] = (7-pos[i]);
+ }
+ }
+
+
+ delay_ms(delay);
+ draw_positions_axis(axis,cubepos,0);
+ LED_PORT ^= LED_RED;
+ }
+
+}
+
+
+
+
+// Light all leds layer by layer,
+// then unset layer by layer
+void effect_loadbar(int delay)
+{
+ fill(0x00);
+
+ int z,y;
+
+ for (z=0;z<8;z++)
+ {
+ for (y=0;y<8;y++)
+ cube[z][y] = 0xff;
+
+ delay_ms(delay);
+ }
+
+ delay_ms(delay*3);
+
+ for (z=0;z<8;z++)
+ {
+ for (y=0;y<8;y++)
+ cube[z][y] = 0x00;
+
+ delay_ms(delay);
+ }
+}
+
+
+// Set n number of voxels at random positions
+void effect_random_sparkle_flash (int iterations, int voxels, int delay)
+{
+ int i;
+ int v;
+ for (i = 0; i < iterations; i++)
+ {
+ for (v=0;v<=voxels;v++)
+ setvoxel(rand()%8,rand()%8,rand()%8);
+
+ delay_ms(delay);
+ fill(0x00);
+ }
+}
+
+// blink 1 random voxel, blink 2 random voxels..... blink 20 random voxels
+// and back to 1 again.
+void effect_random_sparkle (void)
+{
+ int i;
+
+ for (i=1;i<20;i++)
+ {
+ effect_random_sparkle_flash(5,i,200);
+ }
+
+ for (i=20;i>=1;i--)
+ {
+ effect_random_sparkle_flash(5,i,200);
+ }
+
+}
+
+int effect_telcstairs_do(int x, int val, int delay)
+{
+ int y,z;
+
+ for(y = 0, z = x; y <= z; y++, x--)
+ {
+ if(x < CUBE_SIZE && y < CUBE_SIZE)
+ {
+ cube[x][y] = val;
+ }
+ }
+ delay_ms(delay);
+ return z;
+}
+
+void effect_telcstairs (int invert, int delay, int val)
+{
+ int x;
+
+ if(invert)
+ {
+ for(x = CUBE_SIZE*2; x >= 0; x--)
+ {
+ x = effect_telcstairs_do(x,val,delay);
+ }
+ }
+ else
+ {
+ for(x = 0; x < CUBE_SIZE*2; x++)
+ {
+ x = effect_telcstairs_do(x,val,delay);
+ }
+ }
+}
+
+void effect_wormsqueeze (int size, int axis, int direction, int iterations, int delay)
+{
+ int x, y, i,j,k, dx, dy;
+ int cube_size;
+ int origin = 0;
+
+ if (direction == -1)
+ origin = 7;
+
+ cube_size = 8-(size-1);
+
+ x = rand()%cube_size;
+ y = rand()%cube_size;
+
+ for (i=0; i<iterations; i++)
+ {
+ dx = ((rand()%3)-1);
+ dy = ((rand()%3)-1);
+
+ if ((x+dx) > 0 && (x+dx) < cube_size)
+ x += dx;
+
+ if ((y+dy) > 0 && (y+dy) < cube_size)
+ y += dy;
+
+ shift(axis, direction);
+
+
+ for (j=0; j<size;j++)
+ {
+ for (k=0; k<size;k++)
+ {
+ if (axis == AXIS_Z)
+ setvoxel(x+j,y+k,origin);
+
+ if (axis == AXIS_Y)
+ setvoxel(x+j,origin,y+k);
+
+ if (axis == AXIS_X)
+ setvoxel(origin,y+j,x+k);
+ }
+ }
+
+ delay_ms(delay);
+ }
+}
+
+void effect_smileyspin (int count, int delay, char bitmap)
+{
+ unsigned char dybde[] = {0,1,2,3,4,5,6,7,1,1,2,3,4,5,6,6,2,2,3,3,4,4,5,5,3,3,3,3,4,4,4,4};
+ int d = 0;
+ int flip = 0;
+ int x, y, off;
+ for(int i = 0; i<count; i++)
+ {
+ flip = 0;
+ d = 0;
+ off = 0;
+ // front:
+ for (int s=0;s<7;s++){
+ if(!flip){
+ off++;
+ if (off == 4){
+ flip = 1;
+ off = 0;
+ }
+ } else {
+ off++;
+ }
+ for (x=0; x<8; x++)
+ {
+ d = 0;
+ for (y=0; y<8; y++)
+ {
+ if (font_getbitmappixel ( bitmap, 7-x, y)){
+ if (!flip)
+ setvoxel(y,dybde[8 * off + d++],x);
+ else
+ setvoxel(y,dybde[31 - 8 * off - d++],x);
+ } else {
+ d++;
+ }
+ }
+ }
+ delay_ms(delay);
+ fill(0x00);
+ }
+
+ // side:
+ off = 0;
+ flip = 0;
+ d = 0;
+ for (int s=0;s<7;s++){
+ if(!flip){
+ off++;
+ if (off == 4){
+ flip = 1;
+ off = 0;
+ }
+ } else {
+ off++;
+ }
+ for (x=0; x<8; x++)
+ {
+ d = 0;
+ for (y=0; y<8; y++)
+ {
+ if (font_getbitmappixel ( bitmap, 7-x, y)){
+ if (!flip)
+ setvoxel(dybde[8 * off + d++], 7 - y,x);
+ else
+ setvoxel(dybde[31 - 8 * off - d++],7 - y,x);
+ } else {
+ d++;
+ }
+ }
+ }
+ delay_ms(delay);
+ fill(0x00);
+ }
+
+
+ flip = 0;
+ d = 0;
+ off = 0;
+ // back:
+ for (int s=0;s<7;s++){
+ if(!flip){
+ off++;
+ if (off == 4){
+ flip = 1;
+ off = 0;
+ }
+ } else {
+ off++;
+ }
+ for (x=0; x<8; x++)
+ {
+ d = 0;
+ for (y=0; y<8; y++)
+ {
+ if (font_getbitmappixel ( bitmap, 7-x, 7-y)){
+ if (!flip)
+ setvoxel(y,dybde[8 * off + d++],x);
+ else
+ setvoxel(y,dybde[31 - 8 * off - d++],x);
+ } else {
+ d++;
+ }
+ }
+ }
+ delay_ms(delay);
+ fill(0x00);
+ }
+
+ // other side:
+ off = 0;
+ flip = 0;
+ d = 0;
+ for (int s=0;s<7;s++){
+ if(!flip){
+ off++;
+ if (off == 4){
+ flip = 1;
+ off = 0;
+ }
+ } else {
+ off++;
+ }
+ for (x=0; x<8; x++)
+ {
+ d = 0;
+ for (y=0; y<8; y++)
+ {
+ if (font_getbitmappixel ( bitmap, 7-x, 7-y)){
+ if (!flip)
+ setvoxel(dybde[8 * off + d++], 7 - y,x);
+ else
+ setvoxel(dybde[31 - 8 * off - d++],7 - y,x);
+ } else {
+ d++;
+ }
+ }
+ }
+ delay_ms(delay);
+ fill(0x00);
+ }
+
+ }
+}
+
+
+void effect_pathmove (unsigned char *path, int length)
+{
+ int i,z;
+ unsigned char state;
+
+ for (i=(length-1);i>=1;i--)
+ {
+ for (z=0;z<8;z++)
+ {
+
+ state = getvoxel(((path[(i-1)]>>4) & 0x0f), (path[(i-1)] & 0x0f), z);
+ altervoxel(((path[i]>>4) & 0x0f), (path[i] & 0x0f), z, state);
+ }
+ }
+ for (i=0;i<8;i++)
+ clrvoxel(((path[0]>>4) & 0x0f), (path[0] & 0x0f),i);
+}
+
+void effect_rand_patharound (int iterations, int delay)
+{
+ int z, dz, i;
+ z = 4;
+ unsigned char path[28];
+
+ font_getpath(0,path,28);
+
+ for (i = 0; i < iterations; i++)
+ {
+ dz = ((rand()%3)-1);
+ z += dz;
+
+ if (z>7)
+ z = 7;
+
+ if (z<0)
+ z = 0;
+
+ effect_pathmove(path, 28);
+ setvoxel(0,7,z);
+ delay_ms(delay);
+ }
+}
+
+void effect_pathspiral (int iterations, int delay)
+{
+ int z, i;
+ z = 4;
+ unsigned char path[16];
+
+ font_getpath(1,path,16);
+
+ for (i = 0; i < iterations; i++)
+ {
+ setvoxel(4,0,i%8);
+ delay_ms(delay);
+ effect_pathmove(path, 28);
+
+ }
+}
+
+void effect_path_text (int delay, char *str)
+{
+ int z, i,ii;
+ z = 4;
+ unsigned char path[28];
+ font_getpath(0,path,28);
+
+ unsigned char chr[5];
+ unsigned char stripe;
+
+ while (*str)
+ {
+ //charfly(*str++, direction, axis, mode, delay);
+
+
+ font_getchar(*str++, chr);
+
+ for (ii=0;ii<5;ii++)
+ {
+ //stripe = pgm_read_byte(&font[(chr*5)+ii]);
+ stripe = chr[ii];
+
+ for (z=0;z<8;z++)
+ {
+ if ((stripe>>(7-z)) & 0x01)
+ {
+ setvoxel(0,7,z);
+ } else
+ {
+ clrvoxel(0,7,z);
+ }
+
+ }
+ effect_pathmove(path, 28);
+ delay_ms(delay);
+ }
+
+ effect_pathmove(path, 28);
+ delay_ms(delay);
+ }
+ for (i=0;i<28;i++)
+ {
+ effect_pathmove(path, 28);
+ delay_ms(delay);
+ }
+}
+
+void effect_path_bitmap (int delay, char bitmap, int iterations)
+{
+ int z, i, ii;
+ z = 4;
+ unsigned char path[28];
+ font_getpath(0,path,28);
+
+ for (i=0; i < iterations; i++)
+ {
+ for (ii=0;ii<8;ii++)
+ {
+ for (z=0;z<8;z++)
+ {
+ if (font_getbitmappixel(bitmap,(7-z),ii))
+ {
+ setvoxel(0,7,z);
+ } else
+ {
+ clrvoxel(0,7,z);
+ }
+
+ }
+ delay_ms(delay);
+ effect_pathmove(path, 28);
+ }
+
+ for (ii=0;ii<20;ii++)
+ {
+ delay_ms(delay);
+ effect_pathmove(path, 28);
+ }
+ }
+ for (ii=0;ii<10;ii++)
+ {
+ delay_ms(delay);
+ effect_pathmove(path, 28);
+ }
+}
+
+
+
diff --git a/avr-test2/src/effect.h b/avr-test2/src/effect.h
new file mode 100644
index 0000000..2622acc
--- /dev/null
+++ b/avr-test2/src/effect.h
@@ -0,0 +1,54 @@
+#ifndef EFFECT_H
+#define EFFECT_H
+
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+#include <stdlib.h>
+
+#include "cube.h"
+
+void effect_box_shrink_grow (int iterations, int rot, int flip, uint16_t delay);
+
+void effect_hollow_1 (int iterations, uint16_t delay);
+void effect_hollow_2 (int iterations, int corner, uint16_t delay);
+
+void sendvoxel_z (unsigned char x, unsigned char y, unsigned char z, int delay);
+void sendplane_rand_z (unsigned char z, int delay, int wait);
+void sendvoxels_rand_z (int iterations, int delay, int wait);
+void boingboing(uint16_t iterations, int delay, unsigned char mode, unsigned char drawmode);
+
+void effect_planboing (int plane, int speed);
+
+void effect_random_filler (int delay, int state);
+
+void effect_z_updown (int iterations, int delay);
+void effect_rain(int iterations);
+void effect_stringfly2(const char * str);
+void effect_blinky2(void);
+void draw_positions_axis (char axis, unsigned char positions[64], int invert);
+void effect_axis_updown_randsuspend (char axis, int delay, int sleep, int invert);
+
+void effect_random_sparkle_flash (int iterations, int voxels, int delay);
+void effect_random_sparkle (void);
+
+void effect_box_woopwoop (int delay, int grow);
+void effect_telcstairs (int invert, int delay, int val);
+void effect_loadbar(int delay);
+
+void effect_boxside_randsend_parallel (char axis, int origin, int delay, int mode);
+void effect_smileyspin (int count, int delay, char bitmap);
+void effect_pathmove (unsigned char *path, int length);
+void effect_rand_patharound (int iterations, int delay);
+void effect_pathspiral (int iterations, int delay);
+void effect_path_text (int delay, char *str);
+void effect_path_bitmap (int delay, char bitmap, int iterations);
+void effect_wormsqueeze (int size, int axis, int direction, int iterations, int delay);
+
+void effect_z_updown (int iterations, int delay);
+void effect_z_updown_move (unsigned char positions[64], unsigned char destinations[64], char axis);
+
+
+
+
+#endif
+
diff --git a/avr-test2/src/font.cpp b/avr-test2/src/font.cpp
new file mode 100644
index 0000000..ffb5185
--- /dev/null
+++ b/avr-test2/src/font.cpp
@@ -0,0 +1,104 @@
+#include "font.h"
+#include <avr/eeprom.h>
+
+volatile const unsigned char font[455] EEMEM = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x5f,0x5f,0x00,0x00, // !
+ 0x00,0x03,0x00,0x03,0x00,0x14,0x7f,0x14,0x7f,0x14, // "#
+ 0x24,0x2a,0x7f,0x2a,0x12,0x23,0x13,0x08,0x64,0x62, // $%
+ 0x36,0x49,0x55,0x22,0x50,0x00,0x05,0x03,0x00,0x00, // &'
+ 0x00,0x1c,0x22,0x41,0x00,0x00,0x41,0x22,0x1c,0x00, // ()
+ 0x14,0x08,0x3e,0x08,0x14,0x08,0x08,0x3e,0x08,0x08, // *+
+ 0x00,0x50,0x30,0x00,0x00,0x08,0x08,0x08,0x08,0x08, // ,-
+ 0x00,0x60,0x60,0x00,0x00,0x20,0x10,0x08,0x04,0x02, // ./
+ 0x3e,0x51,0x49,0x45,0x3e,0x00,0x42,0x7f,0x40,0x00, // 01
+ 0x42,0x61,0x51,0x49,0x46,0x21,0x41,0x45,0x4b,0x31, // 23
+ 0x18,0x14,0x12,0x7f,0x10,0x27,0x45,0x45,0x45,0x39, // 45
+ 0x3c,0x4a,0x49,0x49,0x30,0x01,0x71,0x09,0x05,0x03, // 67
+ 0x36,0x49,0x49,0x49,0x36,0x06,0x49,0x49,0x29,0x1e, // 89
+ 0x00,0x36,0x36,0x00,0x00,0x00,0x56,0x36,0x00,0x00, // :;
+ 0x08,0x14,0x22,0x41,0x00,0x14,0x14,0x14,0x14,0x14, // <=
+ 0x00,0x41,0x22,0x14,0x08,0x02,0x01,0x51,0x09,0x06, // >?
+ 0x32,0x49,0x79,0x41,0x3e,0x7e,0x11,0x11,0x11,0x7e, // @A
+ 0x7f,0x49,0x49,0x49,0x36,0x3e,0x41,0x41,0x41,0x22, // BC
+ 0x7f,0x41,0x41,0x22,0x1c,0x7f,0x49,0x49,0x49,0x41, // DE
+ 0x7f,0x09,0x09,0x09,0x01,0x3e,0x41,0x49,0x49,0x7a, // FG
+ 0x7f,0x08,0x08,0x08,0x7f,0x00,0x41,0x7f,0x41,0x00, // HI
+ 0x20,0x40,0x41,0x3f,0x01,0x7f,0x08,0x14,0x22,0x41, // JK
+ 0x7f,0x40,0x40,0x40,0x40,0x7f,0x02,0x0c,0x02,0x7f, // LM
+ 0x7f,0x04,0x08,0x10,0x7f,0x3e,0x41,0x41,0x41,0x3e, // NO
+ 0x7f,0x09,0x09,0x09,0x06,0x3e,0x41,0x51,0x21,0x5e, // PQ
+ 0x7f,0x09,0x19,0x29,0x46,0x46,0x49,0x49,0x49,0x31, // RS
+ 0x01,0x01,0x7f,0x01,0x01,0x3f,0x40,0x40,0x40,0x3f, // TU
+ 0x1f,0x20,0x40,0x20,0x1f,0x3f,0x40,0x38,0x40,0x3f, // VW
+ 0x63,0x14,0x08,0x14,0x63,0x07,0x08,0x70,0x08,0x07, // XY
+ 0x61,0x51,0x49,0x45,0x43,0x00,0x7f,0x41,0x41,0x00, // Z[
+ 0x02,0x04,0x08,0x10,0x20,0x00,0x41,0x41,0x7f,0x00, // \]
+ 0x04,0x02,0x01,0x02,0x04,0x40,0x40,0x40,0x40,0x40, // ^_
+ 0x00,0x01,0x02,0x04,0x00,0x20,0x54,0x54,0x54,0x78, // `a
+ 0x7f,0x48,0x44,0x44,0x38,0x38,0x44,0x44,0x44,0x20, // bc
+ 0x38,0x44,0x44,0x48,0x7f,0x38,0x54,0x54,0x54,0x18, // de
+ 0x08,0x7e,0x09,0x01,0x02,0x0c,0x52,0x52,0x52,0x3e, // fg
+ 0x7f,0x08,0x04,0x04,0x78,0x00,0x44,0x7d,0x40,0x00, // hi
+ 0x20,0x40,0x44,0x3d,0x00,0x7f,0x10,0x28,0x44,0x00, // jk
+ 0x00,0x41,0x7f,0x40,0x00,0x7c,0x04,0x18,0x04,0x78, // lm
+ 0x7c,0x08,0x04,0x04,0x78,0x38,0x44,0x44,0x44,0x38, // no
+ 0x7c,0x14,0x14,0x14,0x08,0x08,0x14,0x14,0x18,0x7c, // pq
+ 0x7c,0x08,0x04,0x04,0x08,0x48,0x54,0x54,0x54,0x20, // rs
+ 0x04,0x3f,0x44,0x40,0x20,0x3c,0x40,0x40,0x20,0x7c, // tu
+ 0x1c,0x20,0x40,0x20,0x1c,0x3c,0x40,0x30,0x40,0x3c, // vw
+ 0x44,0x28,0x10,0x28,0x44,0x0c,0x50,0x50,0x50,0x3c, // xy
+ 0x44,0x64,0x54,0x4c,0x44 // z
+};
+
+
+volatile const unsigned char bitmaps[6][8] EEMEM = {
+ {0xc3,0xc3,0x00,0x18,0x18,0x81,0xff,0x7e}, // smiley 3 small
+ {0x3c,0x42,0x81,0x81,0xc3,0x24,0xa5,0xe7}, // Omega
+ {0x00,0x04,0x06,0xff,0xff,0x06,0x04,0x00}, // Arrow
+ {0x81,0x42,0x24,0x18,0x18,0x24,0x42,0x81}, // X
+ {0xBD,0xA1,0xA1,0xB9,0xA1,0xA1,0xA1,0x00}, // ifi
+ {0xEF,0x48,0x4B,0x49,0x4F,0x00,0x00,0x00} // TG
+};
+
+const unsigned char paths[44] /* PROGMEM */ = {0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x67,0x57,0x47,0x37,0x27,0x17,
+0x04,0x03,0x12,0x21,0x30,0x40,0x51,0x62,0x73,0x74,0x65,0x56,0x47,0x37,0x26,0x15}; // circle, len 16, offset 28
+
+void font_getpath (unsigned char path, unsigned char *destination, int length)
+{
+ int i;
+ int offset = 0;
+
+ if (path == 1)
+ offset=28;
+
+ for (i = 0; i < length; i++)
+ destination[i] = pgm_read_byte(&paths[i+offset]);
+}
+
+void font_getchar (char chr, unsigned char dst[5])
+{
+ uint8_t i;
+ chr -= 32; // our bitmap font starts at ascii char 32.
+
+ for (i = 0; i < 5; i++)
+ dst[i] = (unsigned char)eeprom_read_byte((uint8_t*)&font[(chr*5)+i]);
+}
+
+void font_getbitmap (char bitmap, unsigned char dst[8])
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ dst[i] = (unsigned char)eeprom_read_byte((uint8_t*)&bitmaps[(uint8_t)bitmap][(uint8_t)i]);
+
+}
+
+unsigned char font_getbitmappixel ( char bitmap, char x, char y)
+{
+ uint8_t tmp = eeprom_read_byte((uint8_t*)&bitmaps[(uint8_t)bitmap][(uint8_t)x]);
+ return (tmp >> y) & 0x01;
+}
+
+
+
+
diff --git a/avr-test2/src/font.h b/avr-test2/src/font.h
new file mode 100644
index 0000000..006414b
--- /dev/null
+++ b/avr-test2/src/font.h
@@ -0,0 +1,13 @@
+#ifndef FONT_H
+#define FONT_H
+
+#include <avr/pgmspace.h>
+
+void font_getchar (char chr, unsigned char dst[5]);
+void font_getpath (unsigned char path, unsigned char *destination, int length);
+void font_getbitmap (char bitmap, unsigned char dst[8]);
+unsigned char font_getbitmappixel ( char bitmap, char x, char y);
+
+
+
+#endif
diff --git a/avr-test2/src/fuses.txt b/avr-test2/src/fuses.txt
new file mode 100644
index 0000000..f24e5f5
--- /dev/null
+++ b/avr-test2/src/fuses.txt
@@ -0,0 +1,6 @@
+
+lfuse: 0b11101111
+hfuse: 0b11001001
+
+
+
diff --git a/avr-test2/src/gameoflife.cpp b/avr-test2/src/gameoflife.cpp
new file mode 100644
index 0000000..0a3683a
--- /dev/null
+++ b/avr-test2/src/gameoflife.cpp
@@ -0,0 +1,135 @@
+#include <avr/io.h>
+#include "gameoflife.h"
+#include "cube.h"
+#include "draw.h"
+
+// Game of Life for the 4x4x4 and 8x8x8 led cube
+
+#define GOL_CREATE_MIN 3
+#define GOL_CREATE_MAX 3
+
+#define GOL_TERMINATE_LONELY 1
+#define GOL_TERMINATE_CROWDED 4
+
+#define GOL_X 8
+#define GOL_Y 8
+#define GOL_Z 8
+
+#define GOL_WRAP 0x01
+
+
+
+void gol_play (int iterations, uint16_t delay)
+{
+ int i;
+
+ for (i = 0; i < iterations; i++)
+ {
+ LED_PORT ^= LED_GREEN;
+
+ gol_nextgen();
+
+ if (gol_count_changes() == 0)
+ return;
+
+ tmp2cube();
+
+ delay_ms(delay);
+
+ //led_red(1);
+ }
+}
+
+void gol_nextgen (void)
+{
+ int x,y,z;
+ unsigned char neigh;
+
+ tmpfill(0x00);
+
+ for (x = 0; x < GOL_X; x++)
+ {
+ for (y = 0; y < GOL_Y; y++)
+ {
+ for (z = 0; z < GOL_Z; z++)
+ {
+ neigh = gol_count_neighbors(x, y, z);
+
+ // Current voxel is alive.
+ if (getvoxel(x,y,z) == 0x01)
+ {
+ if (neigh <= GOL_TERMINATE_LONELY)
+ {
+ tmpclrvoxel(x,y,z);
+ } else if(neigh >= GOL_TERMINATE_CROWDED)
+ {
+ tmpclrvoxel(x,y,z);
+ } else
+ {
+ tmpsetvoxel(x,y,z);
+ }
+ // Current voxel is dead.
+ } else
+ {
+ if (neigh >= GOL_CREATE_MIN && neigh <= GOL_CREATE_MAX)
+ tmpsetvoxel(x,y,z);
+ }
+ }
+ }
+ }
+}
+
+unsigned char gol_count_neighbors (int x, int y, int z)
+{
+ int ix, iy, iz; // offset 1 in each direction in each dimension
+ int nx, ny, nz; // neighbours address.
+
+ unsigned char neigh = 0; // number of alive neighbours.
+
+ for (ix = -1; ix < 2; ix++)
+ {
+ for (iy = -1; iy < 2; iy++)
+ {
+ for (iz = -1; iz < 2; iz++)
+ {
+ // Your not your own neighbour, exclude 0,0,0, offset.
+ if ( !(ix == 0 && iy == 0 && iz == 0) )
+ {
+ if (GOL_WRAP == 0x01)
+ {
+ nx = (x+ix)%GOL_X;
+ ny = (y+iy)%GOL_Y;
+ nz = (z+iz)%GOL_Z;
+ } else
+ {
+ nx = x+ix;
+ ny = y+iy;
+ nz = z+iz;
+ }
+
+ if ( getvoxel(nx, ny, nz) )
+ neigh++;
+ }
+ }
+ }
+ }
+ return neigh;
+}
+
+int gol_count_changes (void)
+{
+ int x,y;
+ int i = 0;
+
+ for (x = 0; x < GOL_X; x++)
+ {
+ for (y = 0; y < GOL_Y; y++)
+ {
+ if (fb[x][y] != cube[x][y])
+ i++;
+ }
+ }
+
+ return i;
+}
+
diff --git a/avr-test2/src/gameoflife.h b/avr-test2/src/gameoflife.h
new file mode 100644
index 0000000..e53b900
--- /dev/null
+++ b/avr-test2/src/gameoflife.h
@@ -0,0 +1,9 @@
+#ifndef GOL_H
+#define GOL_H
+
+void gol_play (int iterations, uint16_t delay);
+unsigned char gol_count_neighbors (int x, int y, int z);
+void gol_nextgen (void);
+int gol_count_changes (void);
+
+#endif
diff --git a/avr-test2/src/launch_effect.cpp b/avr-test2/src/launch_effect.cpp
new file mode 100644
index 0000000..19b8d86
--- /dev/null
+++ b/avr-test2/src/launch_effect.cpp
@@ -0,0 +1,182 @@
+#include "launch_effect.h"
+#include "effect.h"
+#include "draw.h"
+#include "gameoflife.h"
+
+void launch_effect (int effect)
+{
+ int i;
+ unsigned char ii;
+
+ fill(0x00);
+
+ switch (effect)
+ {
+ case 0x00:
+ //effect_rain(100);
+ break;
+
+
+ case 1:
+ //sendvoxels_rand_z(20,220,2000);
+ break;
+
+ case 2:
+ //effect_random_filler(5,1);
+ //effect_random_filler(5,0);
+ //effect_random_filler(5,1);
+ //effect_random_filler(5,0);
+ break;
+
+ case 3:
+ //effect_z_updown(20,1000);
+ break;
+
+ case 4:
+ effect_wormsqueeze (2, AXIS_Z, -1, 100, 1000);
+ break;
+
+ case 5:
+ //effect_blinky2();
+ break;
+
+ case 6:
+ for (ii=0;ii<8;ii++)
+ {
+ effect_box_shrink_grow (1, ii%4, ii & 0x04, 450);
+ }
+
+ effect_box_woopwoop(800,0);
+ effect_box_woopwoop(800,1);
+ effect_box_woopwoop(800,0);
+ effect_box_woopwoop(800,1);
+ break;
+
+ case 7:
+ //effect_planboing (AXIS_Z, 400);
+ //effect_planboing (AXIS_X, 400);
+ //effect_planboing (AXIS_Y, 400);
+ //effect_planboing (AXIS_Z, 400);
+ //effect_planboing (AXIS_X, 400);
+ //effect_planboing (AXIS_Y, 400);
+ //fill(0x00);
+ break;
+
+ case 8:
+ fill(0x00);
+ effect_telcstairs(0,800,0xff);
+ effect_telcstairs(0,800,0x00);
+ effect_telcstairs(1,800,0xff);
+ effect_telcstairs(1,800,0xff);
+ break;
+
+ case 9:
+ //effect_axis_updown_randsuspend(AXIS_Z, 550,5000,0);
+ //effect_axis_updown_randsuspend(AXIS_Z, 550,5000,1);
+ //effect_axis_updown_randsuspend(AXIS_Z, 550,5000,0);
+ //effect_axis_updown_randsuspend(AXIS_Z, 550,5000,1);
+ //effect_axis_updown_randsuspend(AXIS_X, 550,5000,0);
+ //effect_axis_updown_randsuspend(AXIS_X, 550,5000,1);
+ //effect_axis_updown_randsuspend(AXIS_Y, 550,5000,0);
+ //effect_axis_updown_randsuspend(AXIS_Y, 550,5000,1);
+ break;
+
+ case 10:
+ //effect_loadbar(700);
+ break;
+
+ case 11:
+ //effect_wormsqueeze (1, AXIS_Z, 1, 100, 1000);
+ break;
+
+
+ case 12:
+ effect_stringfly2("INSTRUCTABLES");
+ break;
+
+ case 13:
+ //fill(0x00);
+ //// Create a random starting point for the Game of Life effect.
+ //for (i = 0; i < 20;i++)
+ //{
+ // setvoxel(rand()%4,rand()%4,rand()%4);
+ //}
+
+ //gol_play(20, 400);
+ break;
+
+ case 14:
+ //effect_boxside_randsend_parallel (AXIS_Z, 0 , 200,1);
+ //delay_ms(1500);
+ //effect_boxside_randsend_parallel (AXIS_Z, 1 , 200,1);
+ //delay_ms(1500);
+
+ //effect_boxside_randsend_parallel (AXIS_Z, 0 , 200,2);
+ //delay_ms(1500);
+ //effect_boxside_randsend_parallel (AXIS_Z, 1 , 200,2);
+ //delay_ms(1500);
+
+ //effect_boxside_randsend_parallel (AXIS_Y, 0 , 200,1);
+ //delay_ms(1500);
+ //effect_boxside_randsend_parallel (AXIS_Y, 1 , 200,1);
+ //delay_ms(1500);
+ break;
+
+ case 15:
+ boingboing(250, 600, 0x01, 0x02);
+ break;
+
+ case 16:
+ //effect_smileyspin(2,1000,0);
+ break;
+
+ case 17:
+ //effect_pathspiral(100,500);
+ break;
+
+ case 18:
+ //effect_path_bitmap(700,2,3);
+ break;
+
+ case 19:
+ //effect_smileyspin(2,1000,1);
+ break;
+
+ case 20:
+ effect_path_text(1000,"TG");
+ break;
+
+ case 21:
+ effect_rand_patharound(200,500);
+ break;
+
+ case 22:
+ effect_wormsqueeze (1, AXIS_Z, -1, 100, 1000);
+ break;
+
+ case 23:
+ effect_smileyspin(2,1000,2);
+ break;
+
+ case 24:
+ effect_random_sparkle();
+ break;
+
+ case 25:
+ effect_wormsqueeze (1, AXIS_Z, -1, 100, 1000);
+ break;
+
+ case 26:
+ boingboing(250, 600, 0x01, 0x03);
+ break;
+
+ // In case the effect number is out of range:
+ default:
+ effect_stringfly2("FAIL");
+ break;
+
+
+
+ }
+}
+
diff --git a/avr-test2/src/launch_effect.h b/avr-test2/src/launch_effect.h
new file mode 100644
index 0000000..072822a
--- /dev/null
+++ b/avr-test2/src/launch_effect.h
@@ -0,0 +1,15 @@
+#ifndef LAUNCH_H
+#define LAUNCH_H
+
+#include "cube.h"
+
+// Total number of effects
+// Used in the main loop to loop through all the effects one by bone.
+// Set this number one higher than the highest number inside switch()
+// in launch_effect() in launch_effect.c
+#define EFFECTS_TOTAL 27
+
+void launch_effect (int effect);
+
+#endif
+
diff --git a/avr-test2/src/lisence.txt b/avr-test2/src/lisence.txt
new file mode 100644
index 0000000..812dab5
--- /dev/null
+++ b/avr-test2/src/lisence.txt
@@ -0,0 +1,5 @@
+Created by Christian Moen (christian@lynet.no) and Ståle Kristoffersen (staalekb@ifi.uio.no) 2011.
+
+Lisence: http://creativecommons.org/licenses/by-nc-sa/3.0/
+
+Happy hacking!! :D
diff --git a/avr-test2/src/main.cpp b/avr-test2/src/main.cpp
new file mode 100644
index 0000000..dfebb37
--- /dev/null
+++ b/avr-test2/src/main.cpp
@@ -0,0 +1,450 @@
+/* (c) copyright N.C. 2011
+ * vim: ts=2 sw=2 et ai
+ */
+
+// ATMEL ATMEGA8
+//
+// +-\/-+
+// (RESET) PC6 1| |28 PC5 (ADC5/SCL)
+// (RXD) PD0 2| |27 PC4 (ADC4/SDA)
+// (TXD) PD1 3| |26 PC3 (ADC3)
+// (INT0) PD2 4| |25 PC2 (ADC2)
+// (INT1) PD3 5| |24 PC1 (ADC1)
+// (XCK/T0) PD4 6| |23 PC0 (ADC0)
+// VCC 7| |22 GND
+// GND 8| |21 AREF
+// (XTAL1/TOSC1) PB6 9| |20 AVCC
+// (XTAL2/TOSC2) PB7 10| |19 PB5 (SCK)
+// (T1) PD5 11| |18 PB4 (MISO)
+// (AIN0) PD6 12| |17 PB3 (MOSI/OC2)
+// (AIN1) PD7 13| |16 PB2 (SS/OC1B)
+// (ICP1) PB0 14| |15 PB1 (OC1A)
+// +----+
+
+extern "C" {
+#include <avr/io.h>
+#include <avr/interrupt.h>
+
+#include <stdlib.h> // rand
+
+
+#include "main.h"
+#include "effect.h"
+#include "launch_effect.h"
+//#include "draw.h"
+
+}
+
+//int myrand() { return rand(); }
+
+#define CUBE_SIZE 8
+
+//#define AXIS_X 1
+//#define AXIS_Y 2
+//#define AXIS_Z 3
+
+volatile unsigned char cube[8][8];
+//volatile unsigned char current_layer = 0;
+extern volatile unsigned char current_layer;
+volatile bool in_wait = false;
+
+volatile unsigned char fb[CUBE_SIZE][CUBE_SIZE];
+/*****************************************************************************
+ * TIME MANAGEMENT
+ *****************************************************************************/
+
+#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
+#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
+#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
+
+// 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 uint32_t timer0_overflow_count = 0;
+volatile uint32_t timer0_millis = 0;
+//static uint8_t timer0_fract = 0;
+
+
+ISR(TIMER0_OVF_vect)
+{
+ // copy these to local variables so they can be stored in registers
+ // (volatile variables must be read from memory on every access)
+ uint32_t m = timer0_millis;
+ //uint8_t f = timer0_fract;
+ static uint8_t timer0_fract = 0;
+
+ m += MILLIS_INC;
+ //f += FRACT_INC;
+ timer0_fract += FRACT_INC;
+ //if (f >= FRACT_MAX) {
+ if (timer0_fract >= FRACT_MAX) {
+ //f -= FRACT_MAX;
+ timer0_fract -= FRACT_MAX;
+ ++m;
+ }
+
+ //timer0_fract = f;
+ timer0_millis = m;
+ //timer0_overflow_count++;
+
+//static uint32_t last_time = 0;
+ //if (timer0_overflow_count & 0x1)
+ //if (m - last_time >= 5) {
+ //debounce_keys(); // called nearly each 2ms (0,002048s)
+ //last_time = m;
+ //}
+}
+
+/*
+inline uint32_t millis()
+{
+ uint32_t 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;
+}
+*/
+
+inline uint32_t millis()
+{
+ return timer0_millis;
+}
+
+void delay(uint32_t ms)
+{
+ in_wait = true;
+ uint32_t time1 = millis();
+ while ((millis()) - time1 < ms);
+ in_wait = false;
+}
+//void delay_ms(uint16_t x)
+//{
+// in_wait = true;
+// uint8_t y, z;
+// for ( ; x > 0 ; x--){
+// for ( y = 0 ; y < 90 ; y++){
+// for ( z = 0 ; z < 6 ; z++){
+// asm volatile ("nop");
+// }
+// }
+// }
+// in_wait = false;
+//}
+
+
+/*****************************************************************************
+ * ACCESSORS
+ *****************************************************************************/
+
+unsigned char inrange(int x, int y, int z);
+void set_led(unsigned char x, unsigned char y, unsigned char z, bool on)
+{
+
+ if (!inrange(x, y, z)) {
+ return;
+ }
+
+ /*
+ assert(x >= 0 && x <= 7);
+ assert(y >= 0 && y <= 7);
+ assert(z >= 0 && z <= 7);
+ */
+
+ if (on) {
+ cube[y][z] |= ((unsigned char)1) << x;
+ }
+ else {
+ cube[y][z] &= ~(((unsigned char)1) << x);
+ }
+}
+
+void clear_led()
+{
+ for (unsigned char z = 0; z < 8; ++z) {
+ for (unsigned char y = 0; y < 8; ++y) {
+ cube[y][z] = 0;
+ }
+ }
+}
+
+/*****************************************************************************
+ * RENDER
+ *****************************************************************************/
+
+ISR(TIMER2_COMP_vect)
+{
+ PORTD &= ~0x08; // layer down, should be done before latch
+ PORTD &= ~0x20; // latch low
+ unsigned char current_layer_ = current_layer;
+ for (unsigned char j = 0; j < 8; ++j) {
+ unsigned char val = cube[j][current_layer_];
+ PORTD &= ~0x10;
+ PORTC = val;
+ PORTD = (PORTD & ~0xC0) | (val & 0xC0);
+ PORTD |= 0x10;
+ }
+ PORTB = (PORTB & ~0x07) | current_layer_;
+ PORTD |= 0x20;
+ ++current_layer_;
+ current_layer = current_layer_ & 0x07;
+ PORTD |= 0x08; // layer, should be done in the end and must be after latch
+}
+
+void tmp2cube (void);
+// Take input from a computer and load it onto the cube buffer
+void rs232(void)
+{
+ int tempval;
+ int x = 0;
+ int y = 0;
+ int escape = 0;
+
+ while (1)
+ {
+ // Switch state on red LED for debugging
+ // Should switch state every time the code
+ // is waiting for a byte to be received.
+ //LED_PORT ^= LED_RED;
+
+ // Wait until a byte has been received
+ while ( !(UCSRA & (1<<RXC)) );
+
+ // Load the received byte from rs232 into a buffer.
+ tempval = UDR;
+
+ // Uncommet this to echo data back to the computer
+ // for debugging purposes.
+ //UDR = tempval;
+
+ // Every time the cube receives a 0xff byte,
+ // it goes into sync escape mode.
+ // if a 0x00 byte is then received, the x and y counters
+ // are reset to 0. This way the x and y counters are
+ // always the same on the computer and in the cube.
+ // To send an 0xff byte, you have to send it twice!
+
+ // Go into sync escape mode
+ if (tempval == 0xff)
+ {
+ // Wait for the next byte
+ while ( !(UCSRA & (1<<RXC)) );
+ // Get the next byte
+ tempval = UDR;
+
+ // Sync signal is received.
+ // Reset x and y counters to 0.
+ if (tempval == 0x00)
+ {
+ x = 0;
+ y = 0;
+ escape = 1;
+ }
+ // if no 0x00 byte is received, proceed with
+ // the byte we just received.
+ }
+
+ if (escape == 0)
+ {
+ // Load data into the current position in the buffer
+ fb[x][y] = tempval;
+
+ // Check if we have reached the limits of the buffer array.
+ if (y == 7)
+ {
+ if (x == 7)
+ {
+ // All data is loaded. Reset both counters
+ y = 0;
+ x = 0;
+ // Copy the data onto the cube.
+ tmp2cube();
+ } else
+ {
+ // A layer is loaded, reset y and increment x.
+ x++;
+ y = 0;
+ }
+ } else
+ {
+ // We are in the middle of loading a layer. increment y.
+ y++;
+ }
+
+ } else
+ {
+ escape = 0;
+ }
+ }
+}
+
+
+
+
+/*****************************************************************************
+ * MAIN
+ *****************************************************************************/
+
+int main()
+{
+ /*
+ * =======================================================================
+ * Initialisation
+ * =======================================================================
+ */
+
+ //*** init time management
+ TCNT0 = 0; // init timer count to 0
+ TCCR0 |= 0x03; // prescaler: 64
+ TIMSK |= 0x01; // enable timer 0 overflow interrupt
+
+ // Timer 2
+ // Frame buffer interrupt
+ // 14745600/128/11 = 10472.72 interrupts per second
+ // 10472.72/8 = 1309 frames per second
+ OCR2 = 11; // interrupt at counter = 10
+ TCCR2 |= (1 << CS20) | (0 << CS21) | (1 << CS22); // Prescaler = 128.
+ TCCR2 |= (1 << WGM21); // CTC mode. Reset counter when OCR2 is reached.
+ TCNT2 = 0x00; // initial counter value = 0;
+ TIMSK |= (1 << OCIE2); // Enable CTC interrupt
+
+ PORTD = 0;
+ PORTB = 0;
+ PORTC = 0;
+ DDRD = 0xff;
+ DDRB = 0xff;
+ DDRC = 0xff;
+
+ /*
+ * =======================================================================
+ * Serial port init
+ * =======================================================================
+ */
+
+ // Initiate uart
+ // USART Baud rate is defined in MYUBRR
+ //UBRRH = BAUD_PRESCALE >> 8;
+ //UBRRL = BAUD_PRESCALE;
+ //// UCSRC - USART control register
+ //// bit 7-6 sync/ascyn 00 = async, 01 = sync
+ //// bit 5-4 parity 00 = disabled
+ //// bit 3 stop bits 0 = 1 bit 1 = 2 bits
+ //// bit 2-1 frame length 11 = 8
+ //// bit 0 clock polarity = 0
+ ////UCSRC = 0b10000110;
+ //// Enable RS232, tx and rx
+ //UCSRB = (1<<RXEN)|(1<<TXEN);
+ //UCSRC=(1<<URSEL)|(3<<UCSZ0);
+ ////UDR = 0x00; // send an empty byte to indicate powerup.
+
+#if 1
+#define BAUDRATE 38400
+#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)
+ UBRRH = (uint8_t)(BAUD_PRESCALLER>>8);
+ UBRRL = (uint8_t)(BAUD_PRESCALLER);
+ //UBRRH = (uint8_t)(0);
+ //UBRRL = (uint8_t)(0);
+ UCSRC = (1<<URSEL)|(3<<UCSZ0);
+ UCSRB = (1<<RXEN)|(1<<TXEN);
+#undef BAUDRATE
+#undef BAUD_PRESCALLER
+#endif
+
+ //*** set interupts
+ sei();
+
+ /*
+ * =======================================================================
+ * MAIN LOOP
+ * =======================================================================
+ */
+
+ //while (1) { delay(1000); UDR = 'a'; }
+ //while (1) { UDR = 'a'; }
+ //DDRD |= 0x02; while (1) { delay(1000); PORTD ^= 0x02; }
+
+ rs232();
+ //while (1)
+ //{
+ // // Show the effects in a predefined order
+ // for (char i=0; i<EFFECTS_TOTAL; i++)
+ // launch_effect(i);
+
+ // // Show the effects in a random order.
+ // // Comment the two lines above and uncomment this
+ // // if you want the effects in a random order.
+ // //launch_effect(rand()%EFFECTS_TOTAL);
+ //}
+
+
+ for (;;) {
+
+ //clear_led();
+ //delay_ms(1000);
+ for (unsigned char z = 0; z < 8; ++z) {
+ for (unsigned char y = 0; y < 8; ++y) {
+ cube[y][z] = 0xFF;
+ }
+ }
+ //continue;
+ delay(5000);
+
+ clear_led();
+ for (char z = 0; z < 8; ++z) {
+ for (char y = 0; y < 8; ++y) {
+ for (char x = 0; x < 8; ++x) {
+ set_led(x, y, z, true);
+ //delay(5);
+ delay(100);
+ //delay(500);
+ //delay(1000);
+ //delay_ms(1000);
+ }
+ }
+ }
+
+ // Show the effects in a predefined order
+ //for (char i=0; i<EFFECTS_TOTAL; i++)
+ //launch_effect(i);
+ //sendvoxels_rand_z(20,220,2000);
+ //effect_rain(100);
+ //effect_random_filler(5,1);
+ //effect_z_updown(20,1000);
+ //effect_wormsqueeze (2, AXIS_Z, -1, 100, 1000);
+ //effect_blinky2();
+
+
+ // Show the effects in a random order.
+ // Comment the two lines above and uncomment this
+ // if you want the effects in a random order.
+ //launch_effect(rand()%EFFECTS_TOTAL);
+
+ //effect_boxside_randsend_parallel (AXIS_X, 0, 150, 1);
+ //effect_boxside_randsend_parallel (AXIS_X, 1, 150, 1);
+ //effect_boxside_randsend_parallel (AXIS_Y, 0, 150, 1);
+ //effect_boxside_randsend_parallel (AXIS_Y, 1, 150, 1);
+ //effect_boxside_randsend_parallel (AXIS_Z, 0, 150, 1);
+ //effect_boxside_randsend_parallel (AXIS_Z, 1, 150, 1);
+
+
+ //delay(1000);
+ //PORTB ^= 0x01;
+ }
+
+ return 0; // normally never return, just to be complient with c99 standard
+}
diff --git a/avr-test2/src/main.cpp.bakup b/avr-test2/src/main.cpp.bakup
new file mode 100644
index 0000000..825c74d
--- /dev/null
+++ b/avr-test2/src/main.cpp.bakup
@@ -0,0 +1,447 @@
+/* (c) copyright N.C. 2011 */
+
+// ATMEL ATMEGA8
+//
+// +-\/-+
+// (RESET) PC6 1| |28 PC5 (ADC5/SCL)
+// (RXD) PD0 2| |27 PC4 (ADC4/SDA)
+// (TXD) PD1 3| |26 PC3 (ADC3)
+// (INT0) PD2 4| |25 PC2 (ADC2)
+// (INT1) PD3 5| |24 PC1 (ADC1)
+// (XCK/T0) PD4 6| |23 PC0 (ADC0)
+// VCC 7| |22 GND
+// GND 8| |21 AREF
+// (XTAL1/TOSC1) PB6 9| |20 AVCC
+// (XTAL2/TOSC2) PB7 10| |19 PB5 (SCK)
+// (T1) PD5 11| |18 PB4 (MISO)
+// (AIN0) PD6 12| |17 PB3 (MOSI/OC2)
+// (AIN1) PD7 13| |16 PB2 (SS/OC1B)
+// (ICP1) PB0 14| |15 PB1 (OC1A)
+// +----+
+
+extern "C" {
+#include <avr/io.h>
+#include <avr/interrupt.h>
+
+#include <stdlib.h> // rand
+
+
+#include "main.h"
+#include "effect.h"
+#include "launch_effect.h"
+//#include "draw.h"
+
+}
+
+//int myrand() { return rand(); }
+
+#define CUBE_SIZE 8
+
+//#define AXIS_X 1
+//#define AXIS_Y 2
+//#define AXIS_Z 3
+
+volatile unsigned char cube[8][8];
+//volatile unsigned char current_layer = 0;
+extern volatile unsigned char current_layer;
+volatile bool in_wait = false;
+
+volatile unsigned char fb[CUBE_SIZE][CUBE_SIZE];
+/*****************************************************************************
+ * TIME MANAGEMENT
+ *****************************************************************************/
+
+#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
+#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
+#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
+
+// 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 uint32_t timer0_overflow_count = 0;
+volatile uint32_t timer0_millis = 0;
+//static uint8_t timer0_fract = 0;
+
+
+ISR(TIMER0_OVF_vect)
+{
+ // copy these to local variables so they can be stored in registers
+ // (volatile variables must be read from memory on every access)
+ uint32_t m = timer0_millis;
+ //uint8_t f = timer0_fract;
+ static uint8_t timer0_fract = 0;
+
+ m += MILLIS_INC;
+ //f += FRACT_INC;
+ timer0_fract += FRACT_INC;
+ //if (f >= FRACT_MAX) {
+ if (timer0_fract >= FRACT_MAX) {
+ //f -= FRACT_MAX;
+ timer0_fract -= FRACT_MAX;
+ ++m;
+ }
+
+ //timer0_fract = f;
+ timer0_millis = m;
+ //timer0_overflow_count++;
+
+//static uint32_t last_time = 0;
+ //if (timer0_overflow_count & 0x1)
+ //if (m - last_time >= 5) {
+ //debounce_keys(); // called nearly each 2ms (0,002048s)
+ //last_time = m;
+ //}
+}
+
+/*
+inline uint32_t millis()
+{
+ uint32_t 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;
+}
+*/
+
+inline uint32_t millis()
+{
+ return timer0_millis;
+}
+
+void delay(uint32_t ms)
+{
+ in_wait = true;
+ uint32_t time1 = millis();
+ while ((millis()) - time1 < ms);
+ in_wait = false;
+}
+//void delay_ms(uint16_t x)
+//{
+// in_wait = true;
+// uint8_t y, z;
+// for ( ; x > 0 ; x--){
+// for ( y = 0 ; y < 90 ; y++){
+// for ( z = 0 ; z < 6 ; z++){
+// asm volatile ("nop");
+// }
+// }
+// }
+// in_wait = false;
+//}
+
+
+/*****************************************************************************
+ * ACCESSORS
+ *****************************************************************************/
+
+unsigned char inrange(int x, int y, int z);
+void set_led(unsigned char x, unsigned char y, unsigned char z, bool on)
+{
+
+ if (!inrange(x, y, z)) {
+ return;
+ }
+
+ /*
+ assert(x >= 0 && x <= 7);
+ assert(y >= 0 && y <= 7);
+ assert(z >= 0 && z <= 7);
+ */
+
+ if (on) {
+ cube[y][z] |= ((unsigned char)1) << x;
+ }
+ else {
+ cube[y][z] &= ~(((unsigned char)1) << x);
+ }
+}
+
+void clear_led()
+{
+ for (unsigned char z = 0; z < 8; ++z) {
+ for (unsigned char y = 0; y < 8; ++y) {
+ cube[y][z] = 0;
+ }
+ }
+}
+
+/*****************************************************************************
+ * RENDER
+ *****************************************************************************/
+
+ISR(TIMER2_COMP_vect)
+{
+ //if (!in_wait) return;
+ PORTD &= ~0x20; // layer and latch low
+ unsigned char current_layer_ = current_layer;
+ for (unsigned char j = 0; j < 8; ++j) {
+ //for (char j = 0; j < 4; ++j) {
+ unsigned char val = cube[j][current_layer_];
+ PORTD &= ~0x10;
+ PORTC = val;
+ PORTD = (PORTD & ~0xC0) | (val & 0xC0);
+ PORTD |= 0x10;
+ }
+ PORTB = (PORTB & ~0x07) | current_layer_;
+ PORTD |= 0x20;
+ ++current_layer_;
+ current_layer = current_layer_ & 0x07;
+ //if (current_layer_ > 7) current_layer_ = 0;
+ //current_layer = current_layer_;
+ //PORTC |= 0x28; // layer and latch high
+}
+
+void tmp2cube (void);
+// Take input from a computer and load it onto the cube buffer
+void rs232(void)
+{
+ int tempval;
+ int x = 0;
+ int y = 0;
+ int escape = 0;
+
+ while (1)
+ {
+ // Switch state on red LED for debugging
+ // Should switch state every time the code
+ // is waiting for a byte to be received.
+ //LED_PORT ^= LED_RED;
+
+ // Wait until a byte has been received
+ while ( !(UCSRA & (1<<RXC)) );
+
+ // Load the received byte from rs232 into a buffer.
+ tempval = UDR;
+
+ // Uncommet this to echo data back to the computer
+ // for debugging purposes.
+ UDR = tempval;
+
+ // Every time the cube receives a 0xff byte,
+ // it goes into sync escape mode.
+ // if a 0x00 byte is then received, the x and y counters
+ // are reset to 0. This way the x and y counters are
+ // always the same on the computer and in the cube.
+ // To send an 0xff byte, you have to send it twice!
+
+ // Go into sync escape mode
+ if (tempval == 0xff)
+ {
+ // Wait for the next byte
+ while ( !(UCSRA & (1<<RXC)) );
+ // Get the next byte
+ tempval = UDR;
+
+ // Sync signal is received.
+ // Reset x and y counters to 0.
+ if (tempval == 0x00)
+ {
+ x = 0;
+ y = 0;
+ escape = 1;
+ }
+ // if no 0x00 byte is received, proceed with
+ // the byte we just received.
+ }
+
+ if (escape == 0)
+ {
+ // Load data into the current position in the buffer
+ fb[x][y] = tempval;
+
+ // Check if we have reached the limits of the buffer array.
+ if (y == 7)
+ {
+ if (x == 7)
+ {
+ // All data is loaded. Reset both counters
+ y = 0;
+ x = 0;
+ // Copy the data onto the cube.
+ tmp2cube();
+ } else
+ {
+ // A layer is loaded, reset y and increment x.
+ x++;
+ y = 0;
+ }
+ } else
+ {
+ // We are in the middle of loading a layer. increment y.
+ y++;
+ }
+
+ } else
+ {
+ escape = 0;
+ }
+ }
+}
+
+
+
+
+/*****************************************************************************
+ * MAIN
+ *****************************************************************************/
+#define USART_BAUDRATE 115200
+#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
+//#define BAUD_PRESCALE 51
+int main()
+{
+ /*
+ * =======================================================================
+ * Initialisation
+ * =======================================================================
+ */
+
+ //*** init time management
+ TCNT0 = 0; // init timer count to 0
+ TCCR0 |= 0x03; // prescaler: 64
+ TIMSK |= 0x01; // enable timer 0 overflow interrupt
+
+ // Timer 2
+ // Frame buffer interrupt
+ // 14745600/128/11 = 10472.72 interrupts per second
+ // 10472.72/8 = 1309 frames per second
+ OCR2 = 11; // interrupt at counter = 10
+ TCCR2 |= (1 << CS20) | (0 << CS21) | (1 << CS22); // Prescaler = 128.
+ TCCR2 |= (1 << WGM21); // CTC mode. Reset counter when OCR2 is reached.
+ TCNT2 = 0x00; // initial counter value = 0;
+ TIMSK |= (1 << OCIE2); // Enable CTC interrupt
+
+ PORTD = 0;
+ PORTB = 0;
+ PORTC = 0;
+ DDRD = 0xff;
+ DDRB = 0xff;
+ DDRC = 0xff;
+
+ /*
+ * =======================================================================
+ * Serial port init
+ * =======================================================================
+ */
+
+ // Initiate uart
+ // USART Baud rate is defined in MYUBRR
+ //UBRRH = BAUD_PRESCALE >> 8;
+ //UBRRL = BAUD_PRESCALE;
+ //// UCSRC - USART control register
+ //// bit 7-6 sync/ascyn 00 = async, 01 = sync
+ //// bit 5-4 parity 00 = disabled
+ //// bit 3 stop bits 0 = 1 bit 1 = 2 bits
+ //// bit 2-1 frame length 11 = 8
+ //// bit 0 clock polarity = 0
+ ////UCSRC = 0b10000110;
+ //// Enable RS232, tx and rx
+ //UCSRB = (1<<RXEN)|(1<<TXEN);
+ //UCSRC=(1<<URSEL)|(3<<UCSZ0);
+ ////UDR = 0x00; // send an empty byte to indicate powerup.
+
+#define BAUDRATE 9600
+#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)
+ // try again...
+ UBRRH = (uint8_t)(BAUD_PRESCALLER>>8);
+ UBRRL = (uint8_t)(BAUD_PRESCALLER);
+ UCSRC = (1<<URSEL)|(3<<UCSZ0);
+
+ UCSRB = (1<<RXEN)|(1<<TXEN);
+#undef BAUDRATE
+#undef BAUD_PRESCALLER
+
+ //*** set interupts
+ //sei();
+
+ /*
+ * =======================================================================
+ * MAIN LOOP
+ * =======================================================================
+ */
+
+ rs232();
+ //while (1)
+ //{
+ // // Show the effects in a predefined order
+ // for (char i=0; i<EFFECTS_TOTAL; i++)
+ // launch_effect(i);
+
+ // // Show the effects in a random order.
+ // // Comment the two lines above and uncomment this
+ // // if you want the effects in a random order.
+ // //launch_effect(rand()%EFFECTS_TOTAL);
+ //}
+
+
+ for (;;) {
+
+ //clear_led();
+ //delay_ms(1000);
+ for (unsigned char z = 0; z < 8; ++z) {
+ for (unsigned char y = 0; y < 8; ++y) {
+ cube[y][z] = 0xFF;
+ }
+ }
+ //continue;
+ delay(5000);
+
+ clear_led();
+ for (char z = 0; z < 8; ++z) {
+ for (char y = 0; y < 8; ++y) {
+ for (char x = 0; x < 8; ++x) {
+ set_led(x, y, z, true);
+ //delay(5);
+ delay(100);
+ //delay(500);
+ //delay(1000);
+ //delay_ms(1000);
+ }
+ }
+ }
+
+ // Show the effects in a predefined order
+ //for (char i=0; i<EFFECTS_TOTAL; i++)
+ //launch_effect(i);
+ //sendvoxels_rand_z(20,220,2000);
+ //effect_rain(100);
+ //effect_random_filler(5,1);
+ //effect_z_updown(20,1000);
+ //effect_wormsqueeze (2, AXIS_Z, -1, 100, 1000);
+ //effect_blinky2();
+
+
+ // Show the effects in a random order.
+ // Comment the two lines above and uncomment this
+ // if you want the effects in a random order.
+ //launch_effect(rand()%EFFECTS_TOTAL);
+
+ //effect_boxside_randsend_parallel (AXIS_X, 0, 150, 1);
+ //effect_boxside_randsend_parallel (AXIS_X, 1, 150, 1);
+ //effect_boxside_randsend_parallel (AXIS_Y, 0, 150, 1);
+ //effect_boxside_randsend_parallel (AXIS_Y, 1, 150, 1);
+ //effect_boxside_randsend_parallel (AXIS_Z, 0, 150, 1);
+ //effect_boxside_randsend_parallel (AXIS_Z, 1, 150, 1);
+
+
+ //delay(1000);
+ //PORTB ^= 0x01;
+ }
+
+ return 0; // normally never return, just to be complient with c99 standard
+}
diff --git a/avr-test2/src/main.h b/avr-test2/src/main.h
new file mode 100644
index 0000000..94d3564
--- /dev/null
+++ b/avr-test2/src/main.h
@@ -0,0 +1,50 @@
+/* (c) copyright N.C. 2011
+ * vim: ts=2 sw=2 et ai
+ */
+
+#ifndef MAIN_H
+#define MAIN_H
+
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+#include <avr/interrupt.h>
+#include <stdlib.h>
+
+#include "cube.h"
+
+// Define USART stuff
+//#define FOSC 14745600
+#define FOSC 16000000
+#define BAUD 38400
+#define MYUBRR (((((FOSC * 10) / (16L * BAUD)) + 5) / 10) - 1)
+
+#define DATA_BUS PORTA
+#define LAYER_SELECT PORTC
+#define LATCH_ADDR PORTB
+#define LATCH_MASK 0x07
+#define LATCH_MASK_INV 0xf8
+#define OE_PORT PORTB
+#define OE_MASK 0x08
+
+// Red led on D2
+#define LED_RED 0x04
+// Green led D3
+#define LED_GREEN 0x08
+// Program led on D4
+#define LED_PGM 0x10;
+// Leds connected to port D
+#define LED_PORT PORTD
+// Rs232 button on D5
+#define RS232_BTN 0x20
+// Main button on B4
+#define MAIN_BTN 0x10
+
+void ioinit (void);
+void bootmsg (void);
+
+volatile unsigned char current_layer;
+volatile unsigned char pgm_mode;
+void rs232(void);
+unsigned int bootwait (void);
+#endif
+