From: Philipp Hachtmann Date: Thu, 23 Feb 2017 05:11:15 +0000 (+0100) Subject: trennfix/sw: Fixed a bit beauty. X-Git-Url: http://gitweb.hachti.de/?p=eisenbahn.git;a=commitdiff_plain;h=27b551dd35833b1cf4c3d76d27ba403527ac8e15 trennfix/sw: Fixed a bit beauty. Signed-off-by: Philipp Hachtmann --- diff --git a/trennfix/sw/mk/trennfix_0.4.mk b/trennfix/sw/mk/trennfix_0.4.mk index 977af7a..b4a097c 100644 --- a/trennfix/sw/mk/trennfix_0.4.mk +++ b/trennfix/sw/mk/trennfix_0.4.mk @@ -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 diff --git a/trennfix/sw/mm/include/mm/mm_switch.h b/trennfix/sw/mm/include/mm/mm_switch.h index 35e1484..561a112 100644 --- a/trennfix/sw/mm/include/mm/mm_switch.h +++ b/trennfix/sw/mm/include/mm/mm_switch.h @@ -4,36 +4,29 @@ #include #include -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 diff --git a/trennfix/sw/mm/src/mm_switch.c b/trennfix/sw/mm/src/mm_switch.c index 34819e5..937cd23 100644 --- a/trennfix/sw/mm/src/mm_switch.c +++ b/trennfix/sw/mm/src/mm_switch.c @@ -54,15 +54,16 @@ #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 :-) */ diff --git a/trennfix/sw/src/main.c b/trennfix/sw/src/main.c index 04935fc..3e7d265 100644 --- a/trennfix/sw/src/main.c +++ b/trennfix/sw/src/main.c @@ -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) {