src-avr: Improve speed of LCD transfers, add hex-code character input
[fw/altos] / ao-bringup-avr / ao-blink.c
index 4d726fd9c60be63eb5772234b0990229d254abee..12b1abfc00a6e49f899655091d6b16a18f538e27 100644 (file)
 
 #include <avr/io.h>
 #include <avr/interrupt.h>
+#define TEENSY 0
+#if TEENSY
 #define F_CPU 16000000UL       // 16 MHz
+#else
+#define F_CPU  8000000UL       // 8 MHz
+#endif
 #include <util/delay.h>
 
 #define LEDOUT         PORTB7
 #define LEDDDR         DDRB
 #define LEDDDRPIN      DD7
 
-int main(void)
+static void
+adc_start(void);
+
+ISR(TIMER1_COMPA_vect)
+{
+       adc_start();
+}
+
+static void
+timer1_init(void)
+{
+       TCCR1A = ((0 << WGM11) |        /* CTC mode, OCR1A */
+                 (0 << WGM10));        /* CTC mode, OCR1A */
+       TCCR1B = ((0 << ICNC1) |        /* no input capture noise canceler */
+                 (0 << ICES1) |        /* input capture on falling edge (don't care) */
+                 (0 << WGM13) |        /* CTC mode, OCR1A */
+                 (1 << WGM12) |        /* CTC mode, OCR1A */
+                 (3 << CS10));         /* clk/64 from prescaler */
+
+#if TEENSY
+       OCR1A = 2500;                   /* 16MHz clock */
+#else
+       OCR1A = 1250;                   /* 8MHz clock */
+#endif
+
+       TIMSK1 = (1 << OCIE1A);         /* Interrupt on compare match */
+}
+
+static void
+clock_init(void)
 {
        /* disable RC clock */
        CLKSEL0 &= ~(1 << RCE);
@@ -58,20 +92,82 @@ int main(void)
                  (0x4 << PDIV0));      /* 48MHz PLL clock */
 
        /* Set the frequency of the crystal */
+#if TEENSY
        PLLCSR |= (1 << PINDIV);        /* For 16MHz crystal on Teensy board */
-       // PLLCSR &= ~(1 << PINDIV);    /* For 8MHz crystal on TeleScience board */
+#else
+       PLLCSR &= ~(1 << PINDIV);       /* For 8MHz crystal on TeleScience board */
+#endif
 
        /* Enable the PLL */
        PLLCSR |= (1 << PLLE);
        while (!(PLLCSR & (1 << PLOCK)))
                ;
+}
+
+static void
+timer0_init(void)
+{
+       TCCR0A = ((1 << COM0A1) |
+                 (0 << COM0A0) |
+                 (1 << WGM01) |
+                 (1 << WGM00));
+
+       OCR0A = 0x10;
+       OCR0B = 0;
+       TIMSK0 = 0;
+
+       TCCR0B = ((0 << WGM02) |
+                 (5 << CS00));
+}
+
+ISR(ADC_vect)
+{
+       OCR0A = ADCH;
+}
+
+#define ADC_CHANNEL    0x25            /* Channel ADC13 */
+#define ADC_CHANNEL_LOW(c)     (((c) & 0x1f) << MUX0)
+#define ADC_CHANNEL_HIGH(c)    ((((c) & 0x20) >> 5) << MUX5)
+
+#define ADCSRA_INIT    ((1 << ADEN) |          /* Enable ADC */                \
+                        (0 << ADATE) |         /* No auto ADC trigger */       \
+                        (1 << ADIE) |          /* Enable interrupt */  \
+                        (6 << ADPS0))          /* Prescale clock by 64 */
+
+#define ADCSRB_INIT    ((0 << ADHSM) |         /* No high-speed mode */ \
+                        (0 << ACME) |          /* Some comparitor thing */ \
+                        (0 << ADTS0))          /* Free running mode (don't care) */
+
+static void
+adc_start(void)
+{
+       ADMUX = ((0 << REFS1) |                         /* AVcc reference */
+                (1 << REFS0) |                         /* AVcc reference */
+                (1 << ADLAR) |                         /* Left-shift results */
+                (ADC_CHANNEL_LOW(ADC_CHANNEL)));       /* Select channel */
+
+       ADCSRB = ADCSRB_INIT | ADC_CHANNEL_HIGH(ADC_CHANNEL);
+
+       ADCSRA = ADCSRA_INIT | (1 << ADSC);             /* Start conversion */
+}
+
+static void
+adc_init(void)
+{
+       ADCSRA = ADCSRA_INIT;
+       ADCSRB = ADCSRB_INIT;
+       DIDR0 |= (1 << 0);
+}
+
+int main(void)
+{
+       clock_init();
+       adc_init();
+       timer1_init();
+       timer0_init();
 
        LEDDDR |= (1 << LEDDDRPIN);
 
-       while (1) {
-               LEDPORT |= (1 << LEDOUT);
-               _delay_ms(1000);
-               LEDPORT &= ~(1 << LEDOUT);
-               _delay_ms(1000);
-       }
+       for (;;)
+               ;
 }