42a94254e5
sry mehr ging heute einfach nicht mehr.... wir sollten um schnell was zu haben mal eine solche kacke runtercoden, und das senden dann dementsprechend machen.... ich schlage vor das eine msg immer 2 byte lang ist ... sowas wie adresse, keycode ... oder eben einfach eine temperatur oder wtf.... jedenfalls feste länge....
313 lines
4.9 KiB
C
313 lines
4.9 KiB
C
#include <pentabug/hal.h>
|
|
|
|
#include <avr/io.h>
|
|
#include <avr/interrupt.h>
|
|
|
|
#include <pentabug/lifecycle.h>
|
|
|
|
#include <pentabug/timer.h>
|
|
|
|
static volatile uint8_t ir_active = 0;
|
|
static volatile int16_t wait_time = 0;
|
|
|
|
static uint8_t timerdivider;
|
|
|
|
static uint8_t button_count[2];
|
|
static uint8_t button_pressed[2];
|
|
|
|
// interrupt for button handling, every 10ms
|
|
ISR(TIMER2_COMPA_vect,ISR_NOBLOCK) {
|
|
uint8_t i = 0;
|
|
|
|
for(i = 0; i < 2; ++i) {
|
|
// button pressed?
|
|
if(PINB & (1 << i)) {
|
|
// pressed for more than 50ms is a click
|
|
if(button_count[i] > 5 && button_count[i] < 100) {
|
|
button_pressed[i] = 1;
|
|
}
|
|
|
|
// not pressed, reset
|
|
button_count[i] = 0;
|
|
} else {
|
|
//.count time pressed
|
|
++button_count[i];
|
|
}
|
|
|
|
// 1s pressed, request next app
|
|
if(button_count[i] == 100) {
|
|
next_app(i ? 1 : -1);
|
|
}
|
|
}
|
|
}
|
|
|
|
ISR(TIMER0_COMPA_vect) {
|
|
// (2*38)kHz ISR
|
|
//generate 38kHz signal:
|
|
if(ir_active) {
|
|
PORTD ^= 1 << 2;
|
|
}
|
|
timerdivider ++;
|
|
|
|
//quaterdivider for wait_ms
|
|
if(!(timerdivider & 0x03)) {
|
|
--wait_time;
|
|
}
|
|
|
|
}
|
|
|
|
#if 0
|
|
pinchangeportisr(ireingangport)
|
|
{
|
|
if pinchanged is ir input:
|
|
if ir inactive
|
|
irrstate = IRR_IDLE
|
|
return
|
|
time_since_last = timedivider - oldtime //2d handle overflow
|
|
|
|
//State machine:
|
|
select (irrstate){
|
|
case ( IRR_IDLE):
|
|
irrstate = IRR_AWAIT_START_COMP;
|
|
…
|
|
break;
|
|
case (IRR_AWAIT_START_COMP):
|
|
//check for transition in time
|
|
if (time_since_last > IR_MAX_STARTBIT_TICKS)
|
|
{
|
|
irrstate = IRR_GET_BIT_FIRSTHALF;
|
|
bitnum = 0;
|
|
} else { irrstate = IRR_IDLE // errorreset}
|
|
break;
|
|
case (IRR_GET_BIT_FIRSTHALF)
|
|
//check beeing in time
|
|
// -> buffer bit[bitnum]
|
|
// else reset
|
|
irrstate = IRR_GET_BIT_SECHALF;
|
|
break;
|
|
case (IRR_GET_BIT_SECHALF)
|
|
//check beeing in time
|
|
// -> inc bitnum
|
|
// -> irrstate = (maxbits)?IRR_GET_STOP_COND:IRR_GET_BIT_FIRSTHALF;
|
|
// else reset
|
|
…
|
|
break;
|
|
case (IRR_GET_STOP_COND):
|
|
//check beeing in time <- need macro for this :-)
|
|
//-> mark received done and set ir inactive (mainloop has to poll done or idle loop callback registration?)
|
|
//-> else reset
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
void init_hw(void) {
|
|
// we need to get real fast (8MHz) to handle 38kHz IR frequency ...
|
|
|
|
CLKPR = 0b10000000;
|
|
CLKPR = 0b00000000;
|
|
|
|
// IR timer
|
|
|
|
TIMSK0 |= (1 << OCIE0A);
|
|
|
|
// calculated and works, but frequency is a little bit off?
|
|
OCR0A = 105;
|
|
|
|
TCCR0A = (1 << WGM01);
|
|
TCCR0B = (1 << CS00);
|
|
|
|
// button timer
|
|
|
|
TIMSK2 |= (1 << OCIE2A);
|
|
|
|
OCR2A = 70;
|
|
|
|
TCCR2A = (1 << WGM01);
|
|
TCCR2B = (1 << CS22) | (1 << CS21) | (1 << CS20);
|
|
|
|
// activate interrupts
|
|
|
|
sei();
|
|
}
|
|
|
|
void reset_hw(void) {
|
|
stop_timer();
|
|
|
|
// 0: S1
|
|
// 1: S2
|
|
// 6: MOTOR
|
|
// 7: BUZZR
|
|
PORTB = (1 << 0) | (1 << 1) | (1 << 7);
|
|
DDRB = (1 << 6) | (1 << 7);
|
|
|
|
// 0: BUZGND
|
|
// 2: LED2
|
|
// 3: LED2 (+)
|
|
PORTC = (1 << 2) | (1 << 3);
|
|
DDRC = (1 << 0) | (1 << 2) | (1 << 3);
|
|
|
|
// 2: IRSEND
|
|
// 3: IRRECV
|
|
// 4: LED
|
|
PORTD = (1 << 4);
|
|
DDRD = (1 << 2) | (1 << 4);
|
|
|
|
// do not carry button state
|
|
|
|
button_pressed[0] = 0;
|
|
button_pressed[1] = 0;
|
|
|
|
// turn ir off
|
|
|
|
ir_off();
|
|
|
|
// disable adc
|
|
|
|
ADCSRA &= ~(1 << ADEN);
|
|
}
|
|
|
|
uint8_t button_state(uint8_t btn) {
|
|
return !(PINB & (1 << btn));
|
|
}
|
|
|
|
uint8_t button_clicked(uint8_t btn) {
|
|
uint8_t clicked = button_pressed[btn];
|
|
button_pressed[btn] = 0;
|
|
return clicked;
|
|
}
|
|
|
|
void button_reset(uint8_t btn) {
|
|
button_pressed[btn] = 0;
|
|
}
|
|
|
|
void led_set(uint8_t led, uint8_t state) {
|
|
if(state) {
|
|
led_on(led);
|
|
} else {
|
|
led_off(led);
|
|
}
|
|
}
|
|
|
|
void led_on(uint8_t led) {
|
|
if(led == RIGHT) {
|
|
PORTC &= ~(1 << 2);
|
|
} else {
|
|
PORTD &= ~(1 << 4);
|
|
}
|
|
}
|
|
|
|
void led_off(uint8_t led) {
|
|
if(led == RIGHT) {
|
|
PORTC |= 1 << 2;
|
|
} else {
|
|
PORTD |= 1 << 4;
|
|
}
|
|
}
|
|
|
|
void led_inv(uint8_t led) {
|
|
if(led == RIGHT) {
|
|
PORTC ^= 1 << 2;
|
|
} else {
|
|
PORTD ^= 1 << 4;
|
|
}
|
|
}
|
|
|
|
uint8_t led_state(uint8_t led) {
|
|
if(led == RIGHT) {
|
|
return !(PORTC & (1 << 2));
|
|
} else {
|
|
return !(PORTD & (1 << 4));
|
|
}
|
|
}
|
|
|
|
void motor_set(uint8_t state) {
|
|
if(state) {
|
|
motor_on();
|
|
} else {
|
|
motor_off();
|
|
}
|
|
}
|
|
|
|
void motor_on(void) {
|
|
PORTB |= 1 << 6;
|
|
}
|
|
|
|
void motor_off(void) {
|
|
PORTB &= ~(1 << 6);
|
|
}
|
|
|
|
void motor_inv(void) {
|
|
PORTB ^= 1 << 6;
|
|
}
|
|
|
|
void buzzer_up(void) {
|
|
PORTB |= 1 << 7;
|
|
PORTC &= ~(1 << 0);
|
|
}
|
|
|
|
void buzzer_down(void) {
|
|
PORTB &= ~(1 << 7);
|
|
PORTC |= 1 << 0;
|
|
}
|
|
|
|
void buzzer_inv(void) {
|
|
PORTB ^= 1 << 7;
|
|
PORTC ^= 1 << 0;
|
|
}
|
|
|
|
void buzzer_off(void) {
|
|
PORTB &= ~(1 << 7);
|
|
PORTC &= ~(1 << 0);
|
|
}
|
|
|
|
|
|
// uses the 76k ISR dividet by 4 -> 4 * 19 == 76
|
|
void wait_ms(uint16_t ms) {
|
|
wait_time = ms * (int16_t) 19;
|
|
while(wait_time > 0) {
|
|
test_stop_app();
|
|
}
|
|
}
|
|
|
|
void wait_ticks(int16_t ticks) {
|
|
wait_time = ticks;
|
|
|
|
while(wait_time > 0) {
|
|
test_stop_app();
|
|
}
|
|
}
|
|
|
|
void ir_on(void) {
|
|
ir_active = 1;
|
|
}
|
|
|
|
void ir_off(void) {
|
|
ir_active = 0;
|
|
PORTD &= ~(1 << 2);
|
|
}
|
|
|
|
void ir_inv(void) {
|
|
if(ir_active) {
|
|
ir_off();
|
|
} else {
|
|
ir_on();
|
|
}
|
|
}
|
|
|
|
void ir_set(uint8_t state) {
|
|
if(state) {
|
|
ir_on();
|
|
} else {
|
|
ir_off();
|
|
}
|
|
}
|
|
|
|
uint8_t ir_recv(void) {
|
|
return !(PIND & (1 << 3));
|
|
}
|
|
|