trennfix/sw: Was not as beautiful as expected. Now it's better!
authorPhilipp Hachtmann <hachti@hachti.de>
Tue, 14 Feb 2017 13:11:49 +0000 (14:11 +0100)
committerPhilipp Hachtmann <hachti@hachti.de>
Tue, 18 Apr 2023 20:03:20 +0000 (22:03 +0200)
Working in 2K single timer both mm speeds on both attiny25 and attiny85.

With PWM

Signed-off-by: Philipp Hachtmann <hachti@hachti.de>
trennfix/sw/Makefile
trennfix/sw/config/trennfix_0.4.h
trennfix/sw/include/pin_magic.h
trennfix/sw/mk/trennfix_0.4.mk
trennfix/sw/mm/include/mm/mm_switch.h
trennfix/sw/mm/src/mm_switch.c
trennfix/sw/src/main.c

index e8e59d2affda1cca890b6f64bca21d7a71c3cff5..f096339946b8f6ae2413ec2310a1c93b8c6c8303 100644 (file)
@@ -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 ----------------
index 964853e2ec2f3ff80dbec5ed1d5a126382ee3a3a..b0c78157b65925bd4a105e93a68f50cf2be3223c 100644 (file)
@@ -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");
index a6d0b4bb29a8e54c7ebb262ea67995629c53f6c6..09838b01bd1b0b67e0c0df429809a2aa27c979f6 100644 (file)
@@ -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))
 
index 27d0204719e6515eca7e72130811f0c936563ff7..977af7a77b94088d873c69a7bc8e2e6eedda4380 100644 (file)
@@ -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
index f7f0d159c463bf1eca9fbe9fb238642032a41b72..83d718bb31db2590df33b5b0e4bfee2a624e5cde 100644 (file)
@@ -2,6 +2,7 @@
 #define MM_SWITCH_H
 
 #include <stdint.h>
+#include <config/hardware.h>
 
 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
index 4be3e3652f2d34afc64a255384eeab691e74f7e0..4bda4730a30e4d57c1a7f9e4e369edb5b7a86917 100644 (file)
 #include <config/hardware.h>
 #include <mm/mm_switch.h>
 
-/*
- *    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)
index c61741e6b22632ba2ac997c58a2a33952dffb54f..04935fc0651e535c37a6b9da9e6896a3bba5d709 100644 (file)
@@ -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();