trennfix/sw: More versatile file structure
[eisenbahn.git] / trennfix / sw / mm_switch.c
diff --git a/trennfix/sw/mm_switch.c b/trennfix/sw/mm_switch.c
deleted file mode 100644 (file)
index cb7b4f7..0000000
+++ /dev/null
@@ -1,330 +0,0 @@
-/******************************************************************************
- *
- *  Trennfix firmware -  mm_switch.c
- *
- *  Maerklin Motorola switch command receiver
- *
- *  Copyright (C) 2017 Philipp Hachtmann
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- *****************************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <avr/io.h>
-#include <avr/eeprom.h>
-#include <avr/interrupt.h>
-#include <avr/pgmspace.h>
-
-#include <util/delay.h>
-#include <stdint.h>
-
-#include "hardware.h"
-#include "mm_switch.h"
-
-// #define DEBUG_TIMEOUT
-#ifdef DEBUG_TIMEOUT
-#define MON(val) setpin(PIN_DRIVE, val)
-#else
-#define MON(xx) ({0;})
-#endif
-
-
-/*
- * Lookup decoder number.
- *
- */
-
-static uint8_t lookup_nibble(uint8_t mm_nibble)
-{
-       switch(mm_nibble) {
-       case 0x0: return 0;
-       case 0xc: return 1;
-       case 0x8: return 2;
-       case 0x3: return 3;
-       case 0xf: return 4;
-       case 0xb: return 5;
-       case 0x2: return 6;
-       case 0xe: return 7;
-       case 0xa: return 8;
-       default: return 0;
-       }
-       return 0;
-}
-
-static uint8_t lookup_decoder(uint8_t mm_byte)
-{
-       uint8_t low;
-       uint8_t high;
-       if (mm_byte == 0)
-               return 100;
-       low = lookup_nibble(mm_byte >> 4);
-       high = lookup_nibble(mm_byte & 0xf);
-       if (!low)
-               return 0;
-       return 9 * high + low;
-}
-
-static uint8_t lookup_command(uint8_t mm_byte)
-{
-       switch(mm_byte) {
-       case 0xc3: return 1;
-       case 0x03: return 2;
-       case 0xf3: return 3;
-       case 0x33: return 4;
-       case 0xcf: return 5;
-       case 0x0f: return 6;
-       case 0xff: return 7;
-       case 0x3f: return 8;
-       default:
-               return 0;
-        }
-}
-
-
-static __attribute__((unused)) void mm_switch_init(void)
-{
-       /* Get rid of the 1/8 clock prescaler */
-       CLKPR = (1 << CLKPCE);
-       CLKPR = 0;
-               
-       GIMSK |= _BV(PCIE); /* Enable pin change interrupt */
-       PCMSK = _BV(PCINT4);  /* PB4, Rail sense input */
-
-        TCCR0A = 0; /* This is normal mode */
-       TCCR0B = 0; /* Timer off */
-       TIMSK |= _BV(OCIE0A); /* Get a match interrupt */
-       TIMSK |= _BV(TOV0);   /* Overflow interrupt */
-       
-       /* We need 13 + 45 us delay, That's 464 clocks @8MHz*/
-       OCR0A = 91; /* Prescaler 8 is used */
-
-       /* Timer 1 for timeout */
-       /* We set it to 1024us by prescaler 64 and running full 256 */
-       TCCR1 = 7;
-       TIMSK |= _BV(TOIE1); /* Overflow interrupt */
-}
-
-static volatile uint8_t shift_command;
-static volatile uint8_t shift_function;
-static volatile uint8_t shift_address;
-static volatile uint8_t shift_command_first;
-static volatile uint8_t shift_address_first;
-
-/* We will shift from right to left.
- * XXXXXXXX        XX          XXXXXXXX
- * shift_address   shift_function  shift_command
- *
- * The bits 7 downto 2 of shift_function are ignored.
- */
-
-volatile uint8_t bitno = 0;
-
-static void __attribute__((unused)) trigger(void)
-{
-       setpin(PIN_DRIVE, 1);
-       _delay_us(4);
-       setpin(PIN_DRIVE, 0);
-       _delay_us(4);
-}
-
-enum recstate {
-       IDLE = 0,
-       FIRST_FAST_SAMPLE,
-       FIRST_SLOW_SAMPLE, /* If clock arrives, we stay on the fast path! */
-       FAST_SAMPLE,
-       FAST_WAIT_FOR_CLOCK,
-       SLOW_SAMPLE,
-       SLOW_WAIT_FOR_CLOCK,
-};
-
-static enum recstate recstate = IDLE;
-
-static inline 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;
-}
-
-
-ISR(TIMER0_COMPA_vect) {
-       static uint8_t patience = 0;
-       static uint8_t address_last = 0xff;
-       static uint8_t function_last = 0xff;
-       static uint8_t command_last = 0xff;
-
-       switch(recstate) {
-       case FIRST_FAST_SAMPLE:
-               recstate = FIRST_SLOW_SAMPLE;
-               TSTART_CLK_TO_SAMPLE_FAST; /* Will not run out in fast! */
-               break;
-
-       case FIRST_SLOW_SAMPLE:
-               bitno = 0;
-
-       case SLOW_SAMPLE:
-               recstate = SLOW_WAIT_FOR_CLOCK;
-               TSTART_CLK_TO_SAMPLE_SLOW;
-               break;
-       
-       case FAST_SAMPLE:
-               recstate = FAST_WAIT_FOR_CLOCK;
-               TSTART_CLK_TO_SAMPLE_FAST;
-               break;
-
-       case FAST_WAIT_FOR_CLOCK: /* A timeout! */
-               if (patience) {
-                       patience--;
-                       TSTART_CLK_TO_SAMPLE_FAST;
-                       return;
-               }
-               recstate = IDLE;
-               TSTOP;
-               return;
-
-       case SLOW_WAIT_FOR_CLOCK:
-               if (patience) {
-                       patience--;
-                       TSTART_CLK_TO_SAMPLE_SLOW;
-                       return;
-               }
-       default:
-               TSTOP;
-               recstate = IDLE;
-               return;
-       }
-       
-       shift(MM_SENSE);
-       bitno++;
-
-       if (bitno == 18) { /* Save first received word */
-               shift_command_first = shift_command;
-               shift_address_first = shift_address;
-               patience = 18;
-
-       } 
-
-       if (bitno == 36) {
-               if ((shift_command == shift_command_first) &&
-                   (shift_address == shift_address_first)) {
-                       if ((shift_address != address_last) || (shift_command != command_last) ||
-                           shift_function != function_last) {
-
-                               uint8_t addr =  lookup_decoder(shift_address);
-                               
-                               if (recstate == SLOW_WAIT_FOR_CLOCK) {
-                                       mm_switch_drive(addr, shift_function, shift_command);
-                               }
-                       
-               
-                               if (recstate == FAST_WAIT_FOR_CLOCK && addr) {
-                                       uint8_t command = lookup_command(shift_command);
-                                       /* Congratulations, we have a valid command */
-                                       mm_switch_command(addr, command);
-                               }
-                       }
-                       address_last = shift_address;
-                       function_last = shift_function;
-                       command_last = shift_command;
-               }
-               
-       }
-}
-
-//void __attribute((weak)) mm_switch_drive(uint8_t address, uint8_t function, uint8_t command);
-
-ISR(BADISR_vect)
-{
-       while(1) {
-               /*
-               setpin(PIN_LED, 1);
-               _delay_ms(30);
-               setpin(PIN_LED, 0);
-               _delay_ms(30);
-               setpin(PIN_LED, 1);
-               _delay_ms(30);
-               setpin(PIN_LED, 0);
-               _delay_ms(2000);
-               */
-       }
-}
-
-ISR(TIM0_OVF_vect)
-{
-       return;
-       while(1) {
-               setpin(PIN_LED, 1);
-               _delay_ms(30);
-               setpin(PIN_LED, 0);
-               _delay_ms(300);
-       }
-       
-}
-
-
-/* Pin change interrupt vector */
-void mm_pinchange_handler(void)
-{
-       static uint8_t sense_last;
-
-       if (MM_SENSE == sense_last)
-               return;
-       sense_last = MM_SENSE;
-       if (!sense_last)
-               return;
-
-       switch(recstate) {
-       case IDLE:
-               bitno = 0;
-               recstate = FIRST_FAST_SAMPLE;
-               TSTART_CLK_TO_SAMPLE_FAST;
-               break;
-       case FIRST_SLOW_SAMPLE:
-               recstate = FAST_SAMPLE;
-               TSTART_CLK_TO_SAMPLE_FAST;
-               break;
-       case FAST_WAIT_FOR_CLOCK:
-               recstate = FAST_SAMPLE;
-               TSTART_CLK_TO_SAMPLE_FAST;
-               break;
-       case SLOW_WAIT_FOR_CLOCK:
-               recstate = SLOW_SAMPLE;
-               TSTART_CLK_TO_SAMPLE_SLOW;
-               break;
-
-               /* Not expected */
-       case FIRST_FAST_SAMPLE:
-       case FAST_SAMPLE:
-       case SLOW_SAMPLE:
-       default:
-               break;
-       }
-}
-
-/******************************************************************************
- *                        The end :-)
- */
-
-
-