#include <avr/sleep.h>
#include <avr/interrupt.h>
-uint16_t pwmee EEMEM;
volatile uint16_t adcval;
+unsigned char pwmval = 0x28;
+uint16_t pwmints = 0;
volatile struct
{
}
intflags;
+static void inline led_on()
+{
+ DDRB |= _BV( PB5 );
+}
+
+static void inline led_off()
+{
+ DDRB &= ~_BV( PB5 );
+}
-unsigned char debug EEMEM = 1;
+/* ------------ Logging/Debugging ----------- */
-ISR(ADC_vect)
+unsigned char debug_state EEMEM;
+
+static void inline debug_setstate(unsigned char val)
{
- adcval = ADCW;
- ADCSRA &= ~_BV(ADIE); /* disable ADC interrupt */
- intflags.adc_int = 1;
+ eeprom_write_byte(&debug_state, val);
}
-ISR(TIMER1_OVF_vect)
+#define LOG_BUFFER 192
+uint16_t log_buffer[LOG_BUFFER] EEMEM;
+uint16_t log_buffer_count;
+
+static void inline init_log()
{
- TIMSK &= ~_BV(TOIE1);
- intflags.pwm_int = 1;
+ debug_setstate(1);
+ log_buffer_count = 0;
+}
+
+static void log_word(uint16_t word) {
+ if (log_buffer_count == LOG_BUFFER) {
+ debug_setstate(0x42);
+ log_buffer_count++;
+ }
+ if (log_buffer_count >= LOG_BUFFER)
+ return;
+
+ eeprom_write_word(&log_buffer[log_buffer_count], word);
+ log_buffer_count++;
+}
+
+/* ------------ Timer ----------- */
+
+uint16_t clock = 0;
+
+static void inline init_tmr()
+{
+ TCCR0A = _BV(WGM00);
+ TCCR0B = _BV(CS02) | _BV(CS00); // 1 kHz
+ OCR0A = 10; // 100 Hz
+ TIMSK |= _BV(OCIE0A);
+ DDRA |= _BV( PA0 );
+
+ clock = 0;
+}
+
+static void inline tmr_handler()
+{
+ unsigned char c = clock & 0x7F;
+ ++clock;
+
+ if (c == 10 || c == 30)
+ led_on();
+
+ if (c == 20 || c == 40)
+ led_off();
+
+ log_word(adcval);
+ if (adcval != 0xFFEE) {
+ adcval = 0xFFEE;
+
+ ADCSRA |= _BV(ADIE) | _BV(ADSC);
+ }
}
ISR(TIMER0_COMPA_vect)
{
- intflags.tmr_int = 1;
+ tmr_handler();
}
-struct {
- unsigned char intensity :2;
- unsigned char length :6;
-} pattern[] = { {1, 2}, {0, 4}, { 1, 2 }, {0, 15}, {0, 0} };
-
+/* ------------ PWM ----------- */
+
static void inline init_pwm()
{
+ /* Async clock */
+ PLLCSR = _BV(LSM) | _BV(PLLE);
+ _delay_ms(1);
+ while (PLLCSR & _BV(PLOCK) == 0)
+ ;
+ PLLCSR |= _BV(PCKE);
+
TCCR1C = _BV(COM1D0) | _BV(COM1D1) | _BV(PWM1D);
TCCR1A = _BV(COM1A0) | _BV(COM1A1) | _BV(COM1B0) | _BV(COM1B1) | _BV(PWM1A) | _BV(PWM1B);
- TCCR1B = 0x80| _BV(CS13) | _BV(CS11);
- TC1H = 0x03;
+ // TCCR1B = 0x80| _BV(CS13) | _BV(CS11);
+ TCCR1B = 0x80 | _BV(CS10);
OCR1C = 0xFF;
- OCR1D = OCR1B = OCR1A = 0x40;
+ OCR1D = OCR1B = OCR1A = pwmval;
TCNT1 = 0;
- DDRB |= _BV( PB5 ) | _BV( PB1 ) | _BV( PB3 );
+ DDRB |= _BV( PB5 );
PORTB &= ~(_BV( PB5 ) | _BV( PB1 ) | _BV( PB3 ));
- TIMSK |= _BV(TOIE1);
+
+ led_off();
+ // TIMSK |= _BV(TOIE1);
}
+#if 0
+static void inline pwm_handler()
+{
+ TCNT1 = 0;
+ OCR1D = pwmval;
+}
+
+ISR(TIMER1_OVF_vect)
+{
+ TIMSK &= ~_BV(TOIE1);
+ pwm_handler();
+}
+#endif
+
+/* ------------ A/D Converter ----------- */
+
static void inline init_adc()
{
ADCSRA = _BV(ADEN) | _BV(ADATE) | _BV(ADPS1) | _BV(ADPS0);
DIDR0 = _BV(ADC1D) | _BV(AREFD);
}
-static void inline init_tmr()
+static void inline adc_handler()
{
- TCCR0A = _BV(WGM00);
- TCCR0B = _BV(CS02); // | _BV(CS00);
- OCR0A = 0x80;
- TIMSK |= _BV(OCIE0A);
- DDRA |= _BV( PA0 );
-}
+ static unsigned char last_pwmval = 0;
+ static unsigned char counter = 0;
+ uint16_t tmp = pwmval;
+ static uint16_t discard = 5;
-int main(void)
-{
- char seen = 0;
- char pcount, ppos;
-
- init_pwm();
- init_adc();
- init_tmr();
+ adcval = ADCW;
+ ADCSRA &= ~_BV(ADIE); /* disable ADC interrupt */
+#if 0
+ if (--discard > 0)
+ goto out;
- ppos = 0;
- pcount = pattern[ppos].length;
- if (pattern[ppos].intensity) {
- PORTA |= _BV( PA0 );
- }
+ if (adcval > 0x300)
+ tmp = 3*tmp/4;
+ else if (adcval > 0x280)
+ tmp = 7*tmp/8;
+ else if (adcval > 0x201)
+ tmp--;
+ else if (adcval < 0x100)
+ tmp = 5*tmp/4;
+ else if (adcval < 0x180)
+ tmp = 9*tmp/8;
+ else if (adcval < 0x1ff)
+ tmp++;
- while (1) {
- unsigned char pwmhi, pwmlo;
+ if (tmp > 0xFF)
+ tmp = 0xFF;
+ if (tmp == 0)
+ tmp = 1;
- if (intflags.adc_int) {
- intflags.adc_int = 0;
+ counter++;
+ if ((last_pwmval > tmp && last_pwmval - tmp > 10)
+ || (last_pwmval < tmp && tmp - last_pwmval > 10)
+ || (counter > 2)) {
+ counter = 0;
+
+ if (rv_count < BUFFER-1) {
+ eeprom_write_word(&readval[rv_count++], adcval);
+ eeprom_write_word(&readval[rv_count++], pwmval);
+ if (rv_count >= BUFFER)
+ eeprom_write_byte(&debug, 42);
+ }
+ }
- if (adcval > 0x3C0)
- adcval = 0x3C0;
- if (adcval < 1)
- adcval = 1;
- pwmhi = adcval >> 8;
- pwmlo = adcval & 0xFF;
+ last_pwmval = pwmval;
+ pwmval = tmp;
- TC1H = pwmhi;
- OCR1D = pwmlo;
+ if (pwmval != last_pwmval) {
+ TIMSK |= _BV(TOIE1);
+
+ discard = 1000;
+ } else {
+ discard = 0;
+ }
- TC1H = pwmhi;
- OCR1B = pwmlo;
+out:
+ //TIMSK |= _BV(TOIE1);
+ ADCSRA |= _BV(ADIE) | _BV(ADSC);
+#endif
+}
- TC1H = pwmhi;
- OCR1A = pwmlo;
+ISR(ADC_vect)
+{
+ adc_handler();
+}
- TIMSK |= _BV(TOIE1);
+#if 0
+ if (--pcount == 0) {
+ ppos++;
+ pcount = pattern[ppos].length;
+ if (!pcount) {
+ ppos = 0;
+ pcount = pattern[ppos].length;
}
-
- if (intflags.pwm_int) {
- intflags.pwm_int = 0;
- ADCSRA |= _BV(ADIE) | _BV(ADSC);
+ if (pattern[ppos].intensity) {
+ PORTA |= _BV(PA0);
+ } else {
+ PORTA &= ~_BV(PA0);
}
+ }
+#endif
- if (intflags.tmr_int) {
- intflags.tmr_int = 0;
- if (--pcount == 0) {
- ppos++;
- pcount = pattern[ppos].length;
- if (!pcount) {
- ppos = 0;
- pcount = pattern[ppos].length;
- }
- if (pattern[ppos].intensity) {
- PORTA |= _BV(PA0);
- } else {
- PORTA &= ~_BV(PA0);
- }
- }
- }
+int main(void)
+{
+ char seen = 0;
+ char pcount, ppos;
+ unsigned char adcidx = 0;
+ uint16_t adcvals[16];
- sei();
- sleep_mode();
- cli();
+ init_log();
+ init_pwm();
+ init_adc();
+ init_tmr();
+
+ debug_setstate(2);
+
+ sei();
+ while (1)
+ ; //sleep_mode();
#if 0
if (!seen) {
seen = 1;
eeprom_write_byte(&debug, 2);
}
#endif
- }
DDRA |= _BV( PA0 );
while( 1 ) {
PORTA |= _BV( PA0 );
- _delay_ms(2000);
+ _delay_ms(200);
PORTA &=~ _BV( PA0 );
- _delay_ms(2000);
}
}