aboutsummaryrefslogtreecommitdiffstats
path: root/avr-test/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'avr-test/src/main.cpp')
-rw-r--r--avr-test/src/main.cpp508
1 files changed, 508 insertions, 0 deletions
diff --git a/avr-test/src/main.cpp b/avr-test/src/main.cpp
new file mode 100644
index 0000000..6f3d6ba
--- /dev/null
+++ b/avr-test/src/main.cpp
@@ -0,0 +1,508 @@
+/* (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
+}
+
+//char myrand()
+//{
+// static short rand = 0;
+// rand=(rand*109+89)%251;
+// return rand;
+//}
+
+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 F_CPU 8000000UL
+
+#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)
+//{
+// 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;
+// }
+//}
+
+//bool get_led(unsigned char x, unsigned char y, unsigned char z)
+//{
+// /*
+// assert(x >= 0 && x <= 7);
+// assert(y >= 0 && y <= 7);
+// assert(z >= 0 && z <= 7);
+// */
+//
+// if (inrange(x, y, z)) {
+// return cube[y][z] & (1 << x);
+// }
+//
+// return false;
+//}
+
+//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;
+// PORTC &= ~0x28; // layer and latch low
+// unsigned char current_layer_ = current_layer;
+//
+// for (char j = 0; j < 8; ++j) {
+// //for (char j = 0; j < 4; ++j) {
+// unsigned char val = cube[7-j][current_layer_];
+// //unsigned char val2 = cube[3-j][current_layer_];
+// for (char i = 0; i < 8; ++i/*, val >>= 1*/) {
+// PORTC &= ~0x10;
+// //PORTD = (PORTD & ~0x80) | ((val2 << (7-i)) & 0x80);
+// PORTB = (PORTB & ~0x01) | ((val >> i) & 0x01);
+// //PORTB |= 0x01;
+//
+// //PORTD |= 0x80;
+// //PORTD = (PORTD & ~0x40) | (((val << (7-i)) & 0x80) >> 1);
+// PORTC |= 0x10;
+// }
+// }
+//
+// PORTC = (PORTC & ~0x07) | current_layer_;
+// ++current_layer_;
+// current_layer = current_layer_ & 0x07;
+//
+// PORTC |= 0x28; // layer and latch high
+//}
+
+ISR(TIMER2_COMP_vect)
+{
+ //if (!in_wait) return;
+ PORTC &= ~0x28; // layer and latch low
+ unsigned char current_layer_ = current_layer;
+
+ for (unsigned char j = 7; j < 255; --j) {
+ //for (char j = 0; j < 4; ++j) {
+ unsigned char val = cube[j][current_layer_];
+ PORTC &= ~0x10;
+ PORTB = (PORTB & ~0x01) | ((val ) & 0x01);
+ PORTC |= 0x10;
+ PORTC &= ~0x10;
+ PORTB = (PORTB & ~0x01) | ((val >> 1) & 0x01);
+ PORTC |= 0x10;
+ PORTC &= ~0x10;
+ PORTB = (PORTB & ~0x01) | ((val >> 2) & 0x01);
+ PORTC |= 0x10;
+ PORTC &= ~0x10;
+ PORTB = (PORTB & ~0x01) | ((val >> 3) & 0x01);
+ PORTC |= 0x10;
+ PORTC &= ~0x10;
+ PORTB = (PORTB & ~0x01) | ((val >> 4) & 0x01);
+ PORTC |= 0x10;
+ PORTC &= ~0x10;
+ PORTB = (PORTB & ~0x01) | ((val >> 5) & 0x01);
+ PORTC |= 0x10;
+ PORTC &= ~0x10;
+ PORTB = (PORTB & ~0x01) | ((val >> 6) & 0x01);
+ PORTC |= 0x10;
+ PORTC &= ~0x10;
+ PORTB = (PORTB & ~0x01) | ((val >> 7) & 0x01);
+ //PORTD = val;
+ PORTC |= 0x10;
+ }
+
+ PORTC = (PORTC & ~0x07) | current_layer_ | 0x28;
+ ++current_layer_;
+ if (current_layer_ > 7) current_layer_ = 0;
+ //current_layer = current_layer_ & 0x07;
+ current_layer = current_layer_;
+
+ //PORTC |= 0x28; // layer and latch high
+}
+
+
+
+//void draw_positions_axis (char axis, unsigned char positions[64], int invert)
+//{
+// int x, y, p;
+//
+// //fill(0x00);
+// clear_led();
+//
+// 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);
+// set_led(x, y, p, true);
+//
+// if (axis == AXIS_Y)
+// //setvoxel(x,p,y);
+// set_led(x,p,y, true);
+//
+// if (axis == AXIS_X)
+// set_led(p,y,x, true);
+// }
+// }
+//
+//}
+
+
+
+
+//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 = myrand()%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);
+//
+// }
+//
+//}
+
+
+
+/*****************************************************************************
+ * MAIN
+ *****************************************************************************/
+#include "main.h"
+#include "effect.h"
+#include "draw.h"
+
+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;
+
+ //*** set interupts
+ sei();
+
+ /*
+ * =======================================================================
+ * MAIN LOOP
+ * =======================================================================
+ */
+
+ 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(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);
+
+ for (char i = 0; i < 10; ++i) {
+ 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);
+ }
+
+ continue;
+
+ //return;
+ 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);
+ }
+ }
+ }
+
+ //delay(1000);
+ //PORTB ^= 0x01;
+ }
+
+ return 0; // normally never return, just to be complient with c99 standard
+}