From d004797881150c78f98703be19b68e27eabed6d1 Mon Sep 17 00:00:00 2001 From: Philipp Hachtmann Date: Tue, 14 Feb 2017 14:11:49 +0100 Subject: [PATCH] trennfix/sw: Was not as beautiful as expected. Now it's better! Working in 2K single timer both mm speeds on both attiny25 and attiny85. With PWM Signed-off-by: Philipp Hachtmann --- trennfix/sw/Makefile | 2 +- trennfix/sw/config/trennfix_0.4.h | 49 +++++++---- trennfix/sw/include/pin_magic.h | 3 +- trennfix/sw/mk/trennfix_0.4.mk | 2 - trennfix/sw/mm/include/mm/mm_switch.h | 4 +- trennfix/sw/mm/src/mm_switch.c | 121 ++++++++++++-------------- trennfix/sw/src/main.c | 41 ++++----- 7 files changed, 114 insertions(+), 108 deletions(-) diff --git a/trennfix/sw/Makefile b/trennfix/sw/Makefile index e8e59d2..f096339 100644 --- a/trennfix/sw/Makefile +++ b/trennfix/sw/Makefile @@ -216,7 +216,7 @@ AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY) AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE) AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) -AVRDUDE_FLAGS += -B 2 +AVRDUDE_FLAGS += -B 6 #---------------- Debugging Options ---------------- diff --git a/trennfix/sw/config/trennfix_0.4.h b/trennfix/sw/config/trennfix_0.4.h index 964853e..b0c7815 100644 --- a/trennfix/sw/config/trennfix_0.4.h +++ b/trennfix/sw/config/trennfix_0.4.h @@ -6,15 +6,14 @@ #define PIN_LED _PIN(PORTB, PORTB2) #define PIN_SENSE _PIN(PORTB, PORTB4) #define PIN_DRIVE _PIN(PORTB, PORTB3) -//#define PIN_DRIVE PIN_LED #define PIN_BTN _PIN(PORTB, PB1) - +#define PIN_TRIGGER _PIN(PORTB, PB0) #define BTN_PRESSED (!PINVAL(PIN_BTN)) -#define START_TIMER0 ({TCNT0 = 0; TCCR0B = 2;}) -#define START_TIMER1 ({TCNT1 = 1; TCCR1 = 7; GTCCR |= 2;}) #define STOP_TIMER1 ({TCCR1 = 0; TCNT1 = 1;}) +#define PWM_CYCLE 21 + static inline void setup_hw(void) { /* Turn off the 1/8 clock prescaler - now running at 16MHz*/ @@ -25,6 +24,7 @@ static inline void setup_hw(void) INPUT_PIN(PIN_BTN); OUTPUT_PIN(PIN_DRIVE); OUTPUT_PIN(PIN_LED); + OUTPUT_PIN(PIN_TRIGGER); setpin(PIN_BTN, 1); /* Need pullup */ GIMSK |= _BV(PCIE); /* Enable pin change interrupt for sense port */ @@ -35,14 +35,16 @@ static inline void setup_hw(void) /* Setup timer 0, used for mm_switch */ TCCR0A = 0; /* Normal mode */ - TCCR0B = 0; /* Timer off */ + TCCR0B = 2; /* Prescaler 8 */ TIMSK |= _BV(OCIE0A); /* Get a match interrupt */ + OCR0A = 100; TCCR0B = 2; #ifdef WITH_PWM /* Timer 1 as PWM */ - OCR1C = 14; - OCR1B = 14; - TCCR1 = 0x6; + OCR1C = PWM_CYCLE; + OCR1B = PWM_CYCLE; + TCCR1 = 0x5; + GTCCR |= _BV(PWM1B) | _BV(COM1B0); #endif @@ -54,25 +56,36 @@ static inline void setup_hw(void) * Can be altered to use the LED. * */ -static void __attribute__((unused)) trigger(void) +static inline void __attribute__((unused)) trigger(void) +{ + setpin(PIN_TRIGGER, 1); + setpin(PIN_TRIGGER, 0); +} + + +static inline void __attribute__((unused)) trigger_on(void) +{ + setpin(PIN_TRIGGER, 1); +} + +static inline void __attribute__((unused)) trigger_off(void) { - setpin(PIN_DRIVE, 1); - _delay_us(4); - setpin(PIN_DRIVE, 0); - _delay_us(4); + setpin(PIN_TRIGGER, 0); } /* * Configuration for mm receiver code. */ - #define MM_SENSE (!PINVAL(PIN_SENSE)) -#define MM_TSTART ({TCNT0 = 0; GTCCR |= 1; OCR0A = 115; TCCR0B = 2;}) #define MM_TIMER_INT_VECT TIMER0_COMPA_vect -/* Costs 38 bytes program memory */ -#define MM_FILTER_REPEATED -#define USE_EEPROM_UPDATE +#define MM_TSTART { \ + GTCCR |= _BV(TSM) | _BV(PSR0); \ + TCNT0 = 0; \ + TIFR |= _BV(OCF0A); \ + GTCCR &= ~_BV(TSM); \ + } + #ifdef USE_REGISTER_VARS uint8_t register drive_on asm("r8"); diff --git a/trennfix/sw/include/pin_magic.h b/trennfix/sw/include/pin_magic.h index a6d0b4b..09838b0 100644 --- a/trennfix/sw/include/pin_magic.h +++ b/trennfix/sw/include/pin_magic.h @@ -16,7 +16,8 @@ struct __ph_pin__ { #define PINON(pin) (*pin.addr |= _BV(pin.bitno)) #define PINOFF(pin) (*pin.addr &= ~_BV(pin.bitno)) -#define PINVAL(pin) (*(pin.addr - 2) & _BV(pin.bitno) ? 1 : 0) +//#define PINVAL(pin) (*(pin.addr - 2) & _BV(pin.bitno) ? 1 : 0) +#define PINVAL(pin) (*(pin.addr - 2) & _BV(pin.bitno)) #define setpin(pin, val) ((val) ? PINON(pin) : PINOFF(pin)) diff --git a/trennfix/sw/mk/trennfix_0.4.mk b/trennfix/sw/mk/trennfix_0.4.mk index 27d0204..977af7a 100644 --- a/trennfix/sw/mk/trennfix_0.4.mk +++ b/trennfix/sw/mk/trennfix_0.4.mk @@ -25,8 +25,6 @@ LFUSE=0x61 EFUSE=0xff #CFLAGS+= -DMM_FILTER_REPEATED -CFLAGS+= -DMM_USE_REGISTER_VARS - CFLAGS+= -DUSE_REGISTER_VARS CFLAGS+= -DWITH_EEPROM_UPDATE CFLAGS+= -DWITH_PWM diff --git a/trennfix/sw/mm/include/mm/mm_switch.h b/trennfix/sw/mm/include/mm/mm_switch.h index f7f0d15..83d718b 100644 --- a/trennfix/sw/mm/include/mm/mm_switch.h +++ b/trennfix/sw/mm/include/mm/mm_switch.h @@ -2,6 +2,7 @@ #define MM_SWITCH_H #include +#include enum mm_recstate { MM_IDLE = 0, @@ -63,7 +64,6 @@ void mm_switch_drive_cb(uint8_t address, uint8_t speed, uint8_t functions, uint8 void mm_switch_drive(uint8_t decoder, uint8_t function, uint8_t command); -void mm_pinchange_handler(void); - +void mm_switch_pinchange_callback(void); #endif diff --git a/trennfix/sw/mm/src/mm_switch.c b/trennfix/sw/mm/src/mm_switch.c index 4be3e36..4bda473 100644 --- a/trennfix/sw/mm/src/mm_switch.c +++ b/trennfix/sw/mm/src/mm_switch.c @@ -36,10 +36,6 @@ #include #include -/* - * Private data types - */ - /* * @@ -237,7 +233,6 @@ ISR(MM_TIMER_INT_VECT) { static uint8_t function_last = 0xff; static uint8_t command_last = 0xff; #endif - MM_TSTART; switch(recstate) { @@ -252,30 +247,27 @@ ISR(MM_TIMER_INT_VECT) { recstate = MM_SLOW_WAIT_FOR_CLOCK_DELAY; break; + case MM_SLOW_WAIT_FOR_CLOCK_DELAY: + recstate = MM_SLOW_WAIT_FOR_CLOCK; + return; + case MM_FAST_SAMPLE: recstate = MM_FAST_WAIT_FOR_CLOCK; break; case MM_FAST_WAIT_FOR_CLOCK: /* A timeout! */ - if (mm_rec_tolerated_timeouts) { + if (mm_rec_tolerated_timeouts) mm_rec_tolerated_timeouts--; - } else { + else recstate = MM_IDLE; - - } return; case MM_SLOW_SAMPLE_DELAY: recstate = MM_SLOW_SAMPLE; return; - case MM_SLOW_WAIT_FOR_CLOCK_DELAY: - recstate = MM_SLOW_WAIT_FOR_CLOCK; - return; - case MM_SLOW_WAIT_FOR_CLOCK: if (mm_rec_tolerated_timeouts) { - trigger(); mm_rec_tolerated_timeouts--; recstate = MM_SLOW_WAIT_FOR_CLOCK_DELAY; return; @@ -285,7 +277,7 @@ ISR(MM_TIMER_INT_VECT) { case MM_IDLE: return; } - + shift(MM_SENSE); bitno++; @@ -294,28 +286,27 @@ ISR(MM_TIMER_INT_VECT) { shift_function_first = shift_function; shift_command_first = shift_command; mm_rec_tolerated_timeouts = 18; - trigger(); + } if (bitno == 36) { if ((shift_command == shift_command_first) && (shift_address == shift_address_first) && (shift_function == shift_function_first)) { + #ifdef MM_FILTER_REPEATED if ((shift_address != address_last) || (shift_command != command_last) || shift_function != function_last) { #endif address = lookup_decoder(shift_address); - if (recstate == MM_SLOW_WAIT_FOR_CLOCK_DELAY) { - trigger(); mm_switch_drive(address, shift_function, shift_command); } else if (recstate == MM_FAST_WAIT_FOR_CLOCK) { - trigger(); command = lookup_command(shift_command); mm_switch_command(address, command); } + recstate = MM_IDLE; #ifdef MM_FILTER_REPEATED } address_last = shift_address; @@ -357,60 +348,62 @@ ISR(TIM0_OVF_vect) } +uint8_t register sense_last asm("r9"); + + /* Pin change interrupt vector */ -void mm_pinchange_handler(void) -{ +ISR(PCINT0_vect){ static uint8_t sense_last; - - if (MM_SENSE == sense_last) - return; + if (MM_SENSE && !sense_last) { + MM_TSTART; + switch(recstate) { + case MM_IDLE: + bitno = 0; + recstate = MM_FIRST_FAST_SAMPLE; + break; + + case MM_FIRST_SLOW_SAMPLE: + recstate = MM_FAST_SAMPLE; + break; + + case MM_FAST_WAIT_FOR_CLOCK: + recstate = MM_FAST_SAMPLE; + mm_rec_tolerated_timeouts = 0; + break; + + case MM_SLOW_WAIT_FOR_CLOCK_DELAY: /* If clock comes early */ + recstate = MM_SLOW_SAMPLE_DELAY; + break; + + case MM_SLOW_WAIT_FOR_CLOCK: + recstate = MM_SLOW_SAMPLE_DELAY; + mm_rec_tolerated_timeouts = 0; + break; + + case MM_SLOW_SAMPLE_DELAY: + recstate = MM_SLOW_SAMPLE; + break; + + /* Not expected */ + case MM_FIRST_FAST_SAMPLE: + case MM_FAST_SAMPLE: + case MM_SLOW_SAMPLE: + recstate = MM_IDLE; + default: + break; + } + } sense_last = MM_SENSE; - if (!sense_last) - return; - - MM_TSTART; - - switch(recstate) { - case MM_IDLE: - bitno = 0; - recstate = MM_FIRST_FAST_SAMPLE; - break; - - case MM_FIRST_SLOW_SAMPLE: - recstate = MM_FAST_SAMPLE; - break; - - case MM_FAST_WAIT_FOR_CLOCK: - recstate = MM_FAST_SAMPLE; - mm_rec_tolerated_timeouts = 0; - break; - - case MM_SLOW_WAIT_FOR_CLOCK_DELAY: /* If clock comes early */ - recstate = MM_SLOW_WAIT_FOR_CLOCK; - break; + mm_switch_pinchange_callback(); + } - case MM_SLOW_WAIT_FOR_CLOCK: - recstate = MM_SLOW_SAMPLE_DELAY; - mm_rec_tolerated_timeouts = 0; - break; - - case MM_SLOW_SAMPLE_DELAY: - recstate = MM_SLOW_SAMPLE; - break; - /* Not expected */ - case MM_FIRST_FAST_SAMPLE: - case MM_FAST_SAMPLE: - case MM_SLOW_SAMPLE: - recstate = MM_IDLE; - default: - break; - } +void __attribute__((weak))mm_switch_pinchange_callback(void) +{ } void __attribute__((weak))mm_switch_drive(uint8_t decoder, uint8_t function, uint8_t command) { - while(1); } void __attribute__((weak))mm_switch_command(uint8_t address, uint8_t command) diff --git a/trennfix/sw/src/main.c b/trennfix/sw/src/main.c index c61741e..04935fc 100644 --- a/trennfix/sw/src/main.c +++ b/trennfix/sw/src/main.c @@ -99,16 +99,18 @@ void play_tone(uint8_t divisor, uint8_t duration, uint8_t pause) uint16_t c; TCCR1 = 0x8; OCR1C = divisor; - OCR1B = divisor / 2; + c = (divisor * 2) / 3; + OCR1B = c; for (c = 0; c < duration - pause; c++) _delay_ms(2); - OCR1B = 255; - OCR1C = 14; + TCCR1 = 0x6; + OCR1C = PWM_CYCLE; + OCR1B = 12; for (c = 0; c < pause; c++) _delay_ms(2); TCCR1 = 0x6; - OCR1C = 14; - OCR1B = 14; + OCR1C = PWM_CYCLE; + OCR1B = PWM_CYCLE; } static void tone_enter(void) @@ -139,8 +141,8 @@ static void snd_on(void) static void snd_off(void) { TCCR1 = 0x6; - OCR1C = 14; - OCR1B = 14; + OCR1C = PWM_CYCLE; + OCR1B = PWM_CYCLE; } #else @@ -165,11 +167,10 @@ static void save_config(void) #endif } -ISR(PCINT0_vect){ +void mm_switch_pinchange_callback(void) +{ static uint8_t btn_last = 0; - mm_pinchange_handler(); - if (BTN_PRESSED && !btn_last) { config.learn_mode++; config.learn_mode %= LM_END; @@ -179,7 +180,7 @@ ISR(PCINT0_vect){ static uint8_t get_speed(uint8_t command) { - uint8_t b1, b3, b5, b7; + uint8_t b1, b3, b5, b7; b1 = ((command & 0x80) != 0); b3 = ((command & 0x20) != 0); @@ -188,8 +189,7 @@ static uint8_t get_speed(uint8_t command) //if ((b1 != b2) || (b2 != b3) || (b3 != b4) || (b5 != b6) || (b7 != b8)) // return 0xff; - - return (b1 + b3*2 + b5*4 +b7*8); + return (b1 + b3 * 2 + b5 * 4 +b7 * 8); } @@ -224,15 +224,19 @@ void mm_switch_drive(uint8_t loco, uint8_t function, uint8_t command) } alert_last = (speed == 1); break; + case 50: if (speed) - speed -= 1; - + speed = speed - 1; + if (config.learn_mode == LM_EASY_MODE) { config.initial_pulse = speed; } break; case 51: + if (speed) + speed = speed - 1; + if (config.learn_mode == LM_EASY_MODE) config.on_duty_cycle = speed; break; @@ -419,8 +423,8 @@ void mm_switch_command(uint8_t decoder, uint8_t command) void shift(uint8_t mu); #ifdef WITH_PWM -#define DRIVE_OFF {OCR1B = 14;} -#define DRIVE_ON {OCR1B = 14 - config.on_duty_cycle;} +#define DRIVE_OFF {OCR1B = PWM_CYCLE;} +#define DRIVE_ON {OCR1B = PWM_CYCLE - config.on_duty_cycle;} #define DRIVE_FULL {OCR1B = 0;} #else #define DRIVE_OFF {setpin(PIN_DRIVE, 0);} @@ -436,7 +440,6 @@ int main(void) { uint8_t drive_slope = 0; #endif - #ifdef USE_REGISTER_VARS drive_on = 0; #endif @@ -456,7 +459,6 @@ int main(void) { config.learn_mode = LM_LEARN_ON_KEY; } sei(); - while (1) { drive_start: @@ -488,7 +490,6 @@ int main(void) { config.learn_mode > LM_LEARN_OP_MODE) continue; - for (i = 0; i < config.learn_mode; i++) { setpin(PIN_LED, 1); snd_on(); -- 2.32.0