trennfix/sw: Fixed a bit beauty.
authorPhilipp Hachtmann <hachti@hachti.de>
Thu, 23 Feb 2017 05:11:15 +0000 (06:11 +0100)
committerPhilipp Hachtmann <hachti@hachti.de>
Tue, 18 Apr 2023 20:03:20 +0000 (22:03 +0200)
Signed-off-by: Philipp Hachtmann <hachti@hachti.de>
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 977af7a77b94088d873c69a7bc8e2e6eedda4380..b4a097cb18cbf056305fcbe285097a04fc71af2e 100644 (file)
@@ -26,8 +26,9 @@ EFUSE=0xff
 
 #CFLAGS+= -DMM_FILTER_REPEATED
 CFLAGS+= -DUSE_REGISTER_VARS
+CFLAGS+= -DMM_USE_REGISTER_VARS
 CFLAGS+= -DWITH_EEPROM_UPDATE
-CFLAGS+= -DWITH_PWM
+#CFLAGS+= -DWITH_PWM
 CFLAGS+= -DWITH_SOUND
 CFLAGS+= -DWITH_INITIAL_PULSE
 
index 35e14844250997029c2d5f4eb0c258c375e2b45d..561a1129afc091466a131c50bb7672f546aaca7d 100644 (file)
@@ -4,36 +4,29 @@
 #include <stdint.h>
 #include <config/hardware.h>
 
-enum mm_recstate {
-       MM_IDLE = 0,
-       MM_FIRST_FAST_SAMPLE,
-       MM_FIRST_SLOW_SAMPLE, /* If clock arrives, we stay on the fast path! */
-       MM_FAST_SAMPLE,
-       MM_FAST_WAIT_FOR_CLOCK,
-       MM_SLOW_SAMPLE_DELAY,
-       MM_SLOW_SAMPLE,
-       MM_SLOW_WAIT_FOR_CLOCK_DELAY,
-       MM_SLOW_WAIT_FOR_CLOCK,
-};
+#define MM_FLAVOR_DRIVE 0
+#define MM_FLAVOR_SWITCH 1
 
 #ifdef MM_USE_REGISTER_VARS
 
 uint8_t register shift_command  asm("r2");
 uint8_t register shift_function asm("r3");
 uint8_t register shift_address asm("r4");
-uint8_t register recstate asm("r5");
-uint8_t register bitno asm("r6");
-uint8_t register sense_last asm("r8");
-uint8_t register time_h asm("r9");
-uint8_t register time_l asm("r10");
-uint8_t register bit_val asm("r11");
+uint8_t register mm_polarity asm("r5");
+uint8_t register mm_bitno asm("r6");
+uint8_t register mm_last_was_short asm("r8");
+uint8_t register mm_time_h asm("r9");
+uint8_t register mm_time_l asm("r10");
+uint8_t register mm_bit_val asm("r11");
+uint8_t register mm_flavor asm("r14");
 
 static void inline __attribute((unused)) mm_init(void)
 {
-       bitno = 0;
-       recstate = MM_IDLE;
-       time_h = 0;
-       bit_val = 23;
+       mm_bitno = 0;
+       mm_time_h = 0;
+       mm_bit_val = 23;
+       mm_polarity = 1;
+       mm_last_was_short = 0;
 }
 
 #else
index 34819e5d626071098f1d6ca1660163799f15eb0d..937cd23571eb4f187dbcecde18831c9edf30f088 100644 (file)
 
 #ifndef MM_USE_REGISTER_VARS
 
-static volatile uint8_t bitno = 0;
+static volatile uint8_t mm_bitno = 0;
 static uint8_t shift_command;
 static uint8_t shift_function;
 static uint8_t shift_address;
-static  enum mm_recstate recstate = MM_IDLE;
-static uint8_t sense_last = 23;
-uint8_t time_h = 0;
-uint8_t time_l = 0;
-uint8_t bit_val = 23;
+uint8_t mm_time_h = 0;
+uint8_t mm_time_l = 0;
+uint8_t mm_bit_val = 23;
+static uint8_t mm_flavor;
+static uint8_t mm_polarity = 1;
+static uint8_t mm_last_was_short = 0;
 
 #endif
 
@@ -90,13 +91,20 @@ static uint8_t __attribute__((unused)) lookup_decoder(uint8_t mm_byte)
 {
        uint8_t low;
        uint8_t high;
+       uint8_t retval;
+
        if (mm_byte == 0)
                return 80;
        low = lookup_nibble(mm_byte >> 4);
        high = lookup_nibble(mm_byte & 0xf);
        if (!low)
                return 0;
-       return 9 * high + low;
+
+       /*      retval = 9 * high + low; */
+       retval = high << 3;
+       retval += high;
+       retval += low;
+       return retval;
 }
 
 static uint8_t __attribute__((unused)) lookup_command(uint8_t mm_command)
@@ -184,9 +192,26 @@ static uint8_t __attribute__((unused)) lookup_command(uint8_t mm_command)
  * shift_address   shift_function  shift_command
  *
  * The bits 7 downto 2 of shift_function are ignored.
+ *
+ * First comes the C implementation of the shift routine.
+ * It is usually not used anymore, but I left it for
+ * illustration purposes.
+ * The real shift function is written in assembly and saves many instructions.
  */
-#define SAVE_ANOTHER_40_BYTES
-#ifdef SAVE_ANOTHER_40_BYTES
+#if 0
+void shift(uint8_t value)
+{
+       shift_address <<= 1;
+       if (shift_function & 2)
+               shift_address |= 1;
+       shift_function <<= 1;
+       if (shift_command & 0x80)
+               shift_function |= 1;
+       shift_command <<= 1;
+       if (value)
+               shift_command |= 1;
+}
+#else
 
 void shift(uint8_t value)
 {
@@ -203,31 +228,9 @@ void shift(uint8_t value)
            "2" (shift_address), [val] "r" (value)
            );
 }
-
-#else /* This is what we do to shift */
-
-void shift(uint8_t value)
-{
-       shift_address <<= 1;
-       if (shift_function & 2)
-               shift_address |= 1;
-       shift_function <<= 1;
-       if (shift_command & 0x80)
-               shift_function |= 1;
-       shift_command <<= 1;
-       if (value)
-               shift_command |= 1;
-}
 #endif
 
-static volatile uint8_t mm_rec_tolerated_timeouts;
-
-#define MM_SLOW 0
-#define MM_FAST 1
-
-static uint8_t style;
-
-void mm_feed_bit(uint8_t bit, uint8_t seen_style)
+static void mm_feed_bit(uint8_t bit, uint8_t seen_style)
 {
        static volatile uint8_t shift_command_first;
        static volatile uint8_t shift_function_first;
@@ -235,68 +238,44 @@ void mm_feed_bit(uint8_t bit, uint8_t seen_style)
        uint8_t address;
        uint8_t command;
 
-#ifdef MM_FILTER_REPEATED
-       static uint8_t address_last = 0xff;
-       static uint8_t function_last = 0xff;
-       static uint8_t command_last = 0xff;
-#endif
-
-       if (bitno == 0)
-               style = seen_style;
+       if (mm_bitno == 0)
+               mm_flavor = seen_style;
        else
-               if (seen_style != style) {
-                       bitno = 0;
+               if (seen_style != mm_flavor) {
+                       mm_bitno = 0;
                        return;
                }
                        
        shift(bit);
-       bitno++;
-       if (bitno == 18) { /* Save first received word */
+       mm_bitno++;
+       if (mm_bitno == 18) { /* Save first received word */
                shift_address_first  = shift_address;
                shift_function_first = shift_function;
                shift_command_first  = shift_command;
-               mm_rec_tolerated_timeouts = 18;
        } 
 
-       if (bitno == 36) {
+       if (mm_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
-                               if (style == MM_SLOW) {
-                                       address = lookup_decoder(shift_address);
-                                       mm_switch_drive(address, shift_function, shift_command);
-                               } else {
-                                       trigger();
-
-                                       command = lookup_command(shift_command);
-                                       mm_switch_command(address, command);
-                               }                               
-                               bitno = 0;
-#ifdef MM_FILTER_REPEATED
-                       }
-                       address_last   = shift_address;
-                       function_last  = shift_function;
-                       command_last   = shift_command;
-#endif
+                       address = lookup_decoder(shift_address);
+                       if (mm_flavor == MM_FLAVOR_DRIVE) {
+                               mm_switch_drive(address, shift_function,
+                                               shift_command);
+                       } else {
+                               trigger();
+                               command = lookup_command(shift_command);
+                               mm_switch_command(address, command);
+                       }                               
                }
                
        }
 }
 
-ISR(__vector_timer_extra) {
-       //trigger();
-}
-
 /*
  *  The timeout interrupt vector does nothing else
- *  than incrementing the time_h round counter.
+ *  than incrementing the mm_time_h round counter.
  *
  *  It is written in naked assembly because we want to avoid pushing
  *  and popping of all upper registers.
@@ -309,17 +288,16 @@ void __attribute__((naked)) MM_TIMER_INT_VECT(void)
            "inc %[th]          \n\t"
 #else
            "push r1            \n\t"
-           "lds r1, time_h     \n\t"
+           "lds r1, mm_time_h     \n\t"
            "inc r1             \n\t"
-           "sts  time_h, r1    \n\t"
+           "sts  mm_time_h, r1    \n\t"
            "pop r1             \n\t"
 #endif
            "out __SREG__, r0    \n\t"
            "pop r0              \n\t"
-           //      "rjmp __vector_timer_extra \n\t"
            "reti                \n\t"
 #ifdef MM_USE_REGISTER_VARS
-           :: [th] "r" (time_h)
+           :: [th] "r" (mm_time_h)
 #endif
            );
 }
@@ -335,12 +313,12 @@ void __attribute__((naked)) PCINT0_vect(void)
 #ifdef MM_USE_REGISTER_VARS
        asm("in %[tl], %[tmr]   \n\t"
            "rjmp __vector_pinchange  \n\t"
-           :: [tl] "r" (time_l), [tmr] "I" (_SFR_IO_ADDR(TCNT0))
+           :: [tl] "r" (mm_time_l), [tmr] "I" (_SFR_IO_ADDR(TCNT0))
            );
 #else
        asm("push r0         \n\t"
            "in r0, %[tmr]   \n\t"
-           "sts time_l, r0  \n\t"
+           "sts mm_time_l, r0  \n\t"
            "pop r0          \n\t"
            "rjmp __vector_pinchange  \n\t"
            :: [tmr] "I" (_SFR_IO_ADDR(TCNT0))
@@ -351,20 +329,19 @@ void __attribute__((naked)) PCINT0_vect(void)
 /* Pin change interrupt vector, here we have a bit more time */
 ISR(__vector_pinchange){
        /* First kill off that timer */
-
        MM_TSTART;  /* Restart timer */
        
        /* Account for not yet handled timer overflow */
        if (TIFR & _BV(TOV0)) {
-               time_h++;
+               mm_time_h++;
                TIFR |= _BV(TOV0);
        }
        
-       bit_val = !MM_SENSE;
+       mm_bit_val = !MM_SENSE;
 
-       uint16_t duration = time_h << 8;
-       duration += time_l;
-       time_h = 0;
+       uint16_t duration = mm_time_h << 8;
+       duration += mm_time_l;
+       mm_time_h = 0;
 
        /*
         * The nominal length of a bit cycle is 208 us.
@@ -381,44 +358,40 @@ ISR(__vector_pinchange){
 
 #define D_MATCH(d, v) ((duration > (d * 2 - 2 * v)) && (duration < (d * 2 + 2 * v)))
 
-       static uint8_t mm_positive = 1;
-       static uint8_t last_was_short = 0;
-
        if (D_MATCH(26, 4)) {
-               if (last_was_short)
-                       mm_positive = bit_val;
-               last_was_short = 1;
+               if (mm_last_was_short)
+                       mm_polarity = mm_bit_val;
+               mm_last_was_short = 1;
 
-               if (bit_val == mm_positive)
-                       mm_feed_bit(0, MM_SLOW);
+               if (mm_bit_val == mm_polarity)
+                       mm_feed_bit(0, MM_FLAVOR_DRIVE);
        } else {
-               last_was_short = 0;
+               mm_last_was_short = 0;
        }
 
-       if (style == MM_SLOW) {
-               if (duration > 4000) { /* Maerklin inter package timeout 2ms */
-                       bitno = 0;
+       if (mm_flavor == MM_FLAVOR_DRIVE) {
+               if (duration > 4096) { /* Maerklin inter package timeout 2ms */
+                       mm_bitno = 0;
                        goto done;
                }
        } else {
                if (duration > 2000) { /* Maerklin inter package timeout 1ms */
-                       bitno = 0;
+                       mm_bitno = 0;
                        goto done;
                }
        }
        
-       if (bit_val != mm_positive)
+       if (mm_bit_val != mm_polarity)
                goto done;
 
-       if (D_MATCH(182, 25)) mm_feed_bit(1, MM_SLOW);
-       
-       if (D_MATCH(91, 17)) {mm_feed_bit(1, MM_FAST);}
-       if (D_MATCH(13, 4)) {mm_feed_bit(0, MM_FAST);}
-
+       if (D_MATCH(182, 25)) mm_feed_bit(1, MM_FLAVOR_DRIVE);
+       if (D_MATCH(91, 17))  mm_feed_bit(1, MM_FLAVOR_SWITCH);
+       if (D_MATCH(13, 4))   mm_feed_bit(0, MM_FLAVOR_SWITCH);
  done:
        mm_switch_pinchange_callback();
  }
 
+
 void __attribute__((weak))mm_switch_pinchange_callback(void)
 {
 }
@@ -433,7 +406,6 @@ void __attribute__((weak))mm_switch_command(uint8_t address, uint8_t command)
 }
 
 
-
 /******************************************************************************
  *                        The end :-)
  */
index 04935fc0651e535c37a6b9da9e6896a3bba5d709..3e7d2650d5af052d263b5bbf47dd725d62fb0b69 100644 (file)
@@ -427,9 +427,9 @@ void shift(uint8_t mu);
 #define DRIVE_ON   {OCR1B = PWM_CYCLE - config.on_duty_cycle;}
 #define DRIVE_FULL {OCR1B = 0;}
 #else
-#define DRIVE_OFF  {setpin(PIN_DRIVE, 0);}
+#define DRIVE_OFF  {setpin(PIN_DRIVE, 0); setpin(PIN_LED, 0);}
 #define DRIVE_ON   {setpin(PIN_DRIVE, 1); setpin(PIN_LED, 1);}
-#define DRIVE_FULL {setpin(PIN_DRIVE, 1); setpin(PIN_LED, 0);}
+#define DRIVE_FULL {setpin(PIN_DRIVE, 1); setpin(PIN_LED, 1);}
 #endif
 
 int main(void) {