diff --git a/fw_test/README.md b/fw_test/README.md index 7dd4580..04fdd30 100644 --- a/fw_test/README.md +++ b/fw_test/README.md @@ -1,15 +1,19 @@ # Test firmware -Use this firmware to test all hardware components of a Pentabug. Add a -`pentatonic` extension and press all buttons. The buttons test the following -components (from left to right): +Use this firmware to test all hardware components of a Pentabug. It can test +nearly all hardware features of the device. -* flash LED 1 -* send IR signal; receiving this signal flashes LED 2 -* plays (lower) tone using BUZGND -* plays (higher) tone using BUZZR -* starts the vibration motor +The following things exist in all modes: -This test should catch most obvious errors, but not all possible errors. Some -pinouts are not tested (e.g. JP3 and some pins of JP4 and JP5). +* right LED is on when IR signals are received (use a remote or first mode to + test) +* pressing the right button activates next mode + +Here is a description what happens on a right button press in which mode: + +* activate left LED and send IR signal +* activates motor +* plays sound using BUZZGND +* activates all pins on the extension board for a short time (add a penetatonic + to get feedback on all but one of those pins) diff --git a/fw_test/main.c b/fw_test/main.c index 2e61742..81947af 100644 --- a/fw_test/main.c +++ b/fw_test/main.c @@ -7,31 +7,71 @@ #define ever (;;) -#define follow(from_port, from_pin, to_port, to_pin) { if(from_port & (1 << from_pin)) to_port &= ~(1 << to_pin); else to_port |= 1 << to_pin; } -#define not_follow(from_port, from_pin, to_port, to_pin) { if(from_port & (1 << from_pin)) to_port |= 1 << to_pin; else to_port &= ~(1 << to_pin); } +#define follow(active, to_port, to_pin) { if(active) to_port &= ~(1 << to_pin); else to_port |= 1 << to_pin; } +#define not_follow(active, to_port, to_pin) { if(active) to_port |= 1 << to_pin; else to_port &= ~(1 << to_pin); } + +#define FLASH(port, pin) { port &= ~(1 << pin); _delay_ms(50); port |= 1 << pin;} + +static volatile uint32_t button_state = 0; +static volatile uint8_t next_mode = 0; +static volatile uint8_t ir_active = 0; + +enum test_modes { + PHOTONS, + MOTOR, + AUDIO, + SHIELD, + // the end ... wrap + MODE_MAX, +}; ISR(TIMER0_COMPA_vect) { - PORTD ^= 1 << 2; + if(ir_active) { + PORTD ^= 1 << 2; + } else { + PORTD &= ~(1 << 2); + } + + if(PINB & (1 << 1)) { + button_state = 0; + } else { + ++button_state; + } + + if(button_state == (38l * 1000 / 2)) { + next_mode = 1; + } +} + +static void reset_hw(void) { + // 0: S1 + // 1: S2 + // 2: SHIELD + // 7: BUZZR + PORTB = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 7); + DDRB = (1 << 2) | (1 << 7); + + // 0: BUZGND + // 2: LED2 + // 3: LED2 (+) + // 4: SHIELD + // 5: SHIELD + PORTC = (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5); + DDRC = (1 << 0) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5); + + // 2: IR + // 4: LED + // 5: SHIELD + // 6: SHIELD + // 7: SHIELD + PORTD = (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7); + DDRD = (1 << 2) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7); + } int main(void) { uint8_t vib_delay = 0; - // init and stuff - - PORTB |= (1 << 6) | (1 << 7); - PORTC |= (1 << 0) | (1 << 2) | (1 << 3); - - DDRB |= (1 << 6) | (1 << 7); - DDRC |= (1 << 0) | (1 << 2) | (1 << 3); - DDRD |= (1 << 2) | (1 << 4); - - // pullups - - PORTB |= (1 << 0) | (1 << 1) | (1 << 2); - PORTC |= (1 << 4) | (1 << 5); - PORTD |= (1 << 5) | (1 << 6) | (1 << 7); - // we need to get real fast (8MHz) to handle 38kHz IR frequency ... CLKPR = 0b10000000; @@ -40,60 +80,89 @@ int main(void) { // initialize timer TIMSK0 |= (1 << OCIE0A); + + // calculated and works, but frequency is a little bit off? OCR0A = 105; + TCCR0A = (1 << WGM01); + TCCR0B = (1 << CS00); + + reset_hw(); + // no prescaler sei(); // looping + enum test_modes mode = PHOTONS; + for ever { - // LED by button + // next mode? - not_follow(PIND, 5, PORTD, 4); - - // LED by IR - - not_follow(PIND, 3, PORTC, 2); - - // vibration - - follow(PINC, 4, PORTB, 6); - - // higher buzzer - - if(!(PINC & (1 << 5))) { - PORTB ^= 1 << 7; - } else { - PORTB &= ~(1 << 7); - } - - // lower buzzer - - vib_delay ^= 1; - - if(!(PIND & (1 << 7))) { - if(vib_delay) { - PORTC ^= 1 << 0; + if(next_mode) { + // cleanup + switch(mode) { + case PHOTONS: + ir_active = 0; + break; + case MOTOR: + case AUDIO: + case SHIELD: + break; + case MODE_MAX: break; } - } else { - PORTC &= ~(1 << 0); + + reset_hw(); + + ++mode; + + if(mode == MODE_MAX) { + mode = 0; + } + + uint32_t i; + for(i = 0; i < 50; ++i) { + PORTB ^= 1 << 7; + _delay_ms(1); + } + + next_mode = 0; } - // send IR + uint8_t button = !(PINB & (1 << 0)); - if(!(PIND & (1 << 6))) { - TCCR0A = (1 << WGM01); - TCCR0B = (1 << CS00); - } else { - TCCR0B = 0; - PORTD &= ~(1 << 2); + not_follow(PIND & (1 << 3), PORTC, 2); + + switch(mode) { + case PHOTONS: + ir_active = button; + follow(button, PORTD, 4); + break; + case MOTOR: + not_follow(button, PORTB, 6); + break; + case AUDIO: + { + if(button) { + PORTC ^= 1 << 0; + _delay_ms(2); + } + + break; + } + case SHIELD: + if(button) { + FLASH(PORTB, 2); + FLASH(PORTD, 5); + FLASH(PORTD, 6); + FLASH(PORTD, 7); + FLASH(PORTC, 5); + FLASH(PORTC, 4); + } + break; + case MODE_MAX: break; } - - // wait - - _delay_ms(1); } /* never return 0; */