aboutsummaryrefslogtreecommitdiffstats
path: root/avr-test/src/main.c.old
diff options
context:
space:
mode:
Diffstat (limited to 'avr-test/src/main.c.old')
-rw-r--r--avr-test/src/main.c.old285
1 files changed, 285 insertions, 0 deletions
diff --git a/avr-test/src/main.c.old b/avr-test/src/main.c.old
new file mode 100644
index 0000000..be31861
--- /dev/null
+++ b/avr-test/src/main.c.old
@@ -0,0 +1,285 @@
+/*
+ * Code to controll an 8x8x8 ledcube using avr
+ * http://www.instructables.com/id/Led-Cube-8x8x8/
+ * See lisence.txt for lisence.
+ */
+#include "main.h"
+#include "effect.h"
+#include "launch_effect.h"
+#include "draw.h"
+
+// Main loop
+// the AVR enters this function at boot time
+int main (void)
+{
+
+ // This function initiates IO ports, timers, interrupts and
+ // serial communications
+ ioinit();
+
+ // This variable specifies which layer is currently being drawn by the
+ // cube interrupt routine. We assign a value to it to make sure it's not >7.
+ current_layer = 1;
+
+ int i;
+
+ // Boot wait
+ // This function serves 3 purposes
+ // 1) We delay starting up any interrupts, as drawing the cube causes a lot
+ // noise that can confuse the ISP programmer.
+ // 2) Listen for button press. One button means go into rs232 mode,
+ // The other means go into autonomous mode and start doing stuff.
+ // 3) Random seed. The bootwait function counts forever from 0 to 255.
+ // Whenever you press the button, this counter stops, and the number it
+ // stopped at is used as a random seed. This ensures true randomness at
+ // every boot. Without this (or some similar process) the cube would
+ // produce the same "random" sequence every time
+ i = bootwait();
+
+ // Enable interrupts
+ // This starts the routine that draws the cube content
+ sei();
+
+ // Result for bootwait() is 2:
+ // Go to rs232 mode. this function loops forever.
+ if (i == 2)
+ {
+ rs232();
+ }
+
+ // Result of bootwait() is something other than 2:
+ // Do awesome effects. Loop forever.
+ while (1)
+ {
+ // Show the effects in a predefined order
+ for (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);
+ }
+
+}
+
+/*
+ * Multiplexer/framebuffer routine
+ * This function is called by an interrupt generated by timer 2.
+ * Every time it runs, it does the following:
+ * 1) Disable the output for the multiplexer array.
+ * 2) Turn of all layers.
+ * 3) Load the current layer from the cube buffer onto the
+ * multiplexer array.
+ * 4) Enable output from the multiplexer array.
+ * 5) Turn on the current layer.
+ * 6) Increment the current_layer variable, so the next layer is
+ * drawn the next time this function runs.
+*/
+
+ISR(TIMER2_COMP_vect)
+{
+ int i;
+
+ LAYER_SELECT = 0x00; // Turn all cathode layers off. (all transistors off)
+ OE_PORT |= OE_MASK; // Set OE high, disabling all outputs on latch array
+
+ // Loop through all 8 bytes of data in the current layer
+ // and latch it onto the cube.
+ for (i = 0; i < 8; i++)
+ {
+ // Set the data on the data-bus of the latch array.
+ PORTA = cube[current_layer][i];
+ // Increment the latch address chip, 74HC138, to create
+ // a rising edge (LOW to HIGH) on the current latch.
+ LATCH_ADDR = (LATCH_ADDR & LATCH_MASK_INV) | (LATCH_MASK & (i+1));
+ }
+
+ OE_PORT &= ~OE_MASK; // Set OE low, enabling outputs on the latch array
+ LAYER_SELECT = (0x01 << current_layer); // Transistor ON for current layer
+
+ // Increment the curren_layer counter so that the next layer is
+ // drawn the next time this function runs.
+ current_layer++;
+ // We want to count from 0-7, so set it to 0 when it reaches 8.
+ if (current_layer == 8)
+ current_layer = 0;
+}
+
+
+void ioinit (void)
+{
+ DDRA = 0xff; // DATA bus output
+ DDRB = 0xef; // Button on B4
+ DDRC = 0xff; // Layer select output
+ DDRD = 0xdf; // Button on D5
+
+
+ PORTA = 0x00; // Set data bus off
+ PORTC = 0x00; // Set layer select off
+ PORTB = 0x10; // Enable pull up on button.
+ PORTD = 0x20; // Enable pull up on button.
+
+
+ // Timer 2
+ // Frame buffer interrupt
+ // 14745600/128/11 = 10472.72 interrupts per second
+ // 10472.72/8 = 1309 frames per second
+ OCR2 = 10; // interrupt at counter = 10
+ TCCR2 |= (1 << CS20) | (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
+
+
+
+ // Initiate RS232
+ // USART Baud rate is defined in MYUBRR
+ UBRRH = MYUBRR >> 8;
+ UBRRL = MYUBRR;
+ // 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);
+ UDR = 0x00; // send an empty byte to indicate powerup.
+
+
+}
+
+// Boot wait function
+// This function does 3 things:
+// 1) Delay startup of interrupt. I've had some problems with in circuit
+// serial programming when the cube was running. I guess switching all
+// those LEDs on and off generates some noise.
+// 2) Set a random random seed based on the delay between boot time and
+// the time you press a button.
+// 3) Select mode of operation, autonomous or rs232 controlled.
+unsigned int bootwait (void)
+{
+ // All the LED_PORT... code blinks the red and green status LEDs.
+
+ unsigned int x = 0;
+ LED_PORT |= LED_GREEN;
+ while (1)
+ {
+ x++; // increment x by one.
+ srand(x); // use counter x as random seed
+
+ delay_ms(1000);
+ LED_PORT &= ~LED_GREEN; // green off, red on
+ LED_PORT |= LED_RED;
+
+ // Listen for button presses and return with the
+ // apropriate number.
+ if (!(PIND & RS232_BTN))
+ return 2;
+
+ if (!(PINB & MAIN_BTN))
+ return 1;
+
+ delay_ms(1000);
+ LED_PORT &= ~LED_RED; // red off, green on
+ LED_PORT |= LED_GREEN;
+
+ // Same as above. I do it twise because there are two delays
+ // in this loop, used for the red and green led blinking..
+ if (!(PIND & RS232_BTN))
+ return 2;
+
+ if (!(PINB & MAIN_BTN))
+ return 1;
+ }
+}
+
+// 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;
+ }
+ }
+}
+
+