summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
27b551d)
Signed-off-by: Philipp Hachtmann <hachti@hachti.de>
/*
* Configuration for mm receiver code.
*/
/*
* Configuration for mm receiver code.
*/
-#define MM_SENSE (!PINVAL(PIN_SENSE))
+#define MM_SENSE (PINVAL(PIN_SENSE))
#define MM_TIMER_INT_VECT TIMER0_OVF_vect
#define MM_TSTART { \
#define MM_TIMER_INT_VECT TIMER0_OVF_vect
#define MM_TSTART { \
-#CFLAGS+= -DMM_FILTER_REPEATED
CFLAGS+= -DUSE_REGISTER_VARS
CFLAGS+= -DMM_USE_REGISTER_VARS
CFLAGS+= -DWITH_EEPROM_UPDATE
CFLAGS+= -DUSE_REGISTER_VARS
CFLAGS+= -DMM_USE_REGISTER_VARS
CFLAGS+= -DWITH_EEPROM_UPDATE
uint8_t register shift_address asm("r4");
uint8_t register mm_polarity asm("r5");
uint8_t register mm_bitno asm("r6");
uint8_t register shift_address asm("r4");
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_time_h asm("r9");
uint8_t register mm_time_l asm("r10");
uint8_t register mm_bit_val asm("r11");
mm_time_h = 0;
mm_bit_val = 23;
mm_polarity = 1;
mm_time_h = 0;
mm_bit_val = 23;
mm_polarity = 1;
*
*/
#if !defined(MM_TSTART) || !defined(MM_SENSE) || !defined(MM_TIMER_INT_VECT)
*
*/
#if !defined(MM_TSTART) || !defined(MM_SENSE) || !defined(MM_TIMER_INT_VECT)
#error Missing needed MM_... macro!
#error Missing needed MM_... macro!
#endif
/*
* Private global variables
*/
#endif
/*
* Private global variables
*/
+enum recmode {
+ INIT,
+ ARMED,
+ MM_SLOW,
+ MM_FAST,
+ DCC,
+};
+enum recmode recmode = INIT;
+
#ifndef MM_USE_REGISTER_VARS
static volatile uint8_t mm_bitno = 0;
#ifndef MM_USE_REGISTER_VARS
static volatile uint8_t mm_bitno = 0;
uint8_t mm_bit_val = 23;
static uint8_t mm_flavor;
static uint8_t mm_polarity = 1;
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;
-static void mm_feed_bit(uint8_t bit, uint8_t seen_style)
+static void mm_feed_bit(uint8_t bit)
{
static volatile uint8_t shift_command_first;
static volatile uint8_t shift_function_first;
{
static volatile uint8_t shift_command_first;
static volatile uint8_t shift_function_first;
uint8_t address;
uint8_t command;
uint8_t address;
uint8_t command;
- if (mm_bitno == 0)
- mm_flavor = seen_style;
- else
- if (seen_style != mm_flavor) {
- mm_bitno = 0;
- return;
- }
-
if (mm_bitno == 18) { /* Save first received word */
shift_address_first = shift_address;
shift_function_first = shift_function;
if (mm_bitno == 18) { /* Save first received word */
shift_address_first = shift_address;
shift_function_first = shift_function;
(shift_address == shift_address_first) &&
(shift_function == shift_function_first)) {
address = lookup_decoder(shift_address);
(shift_address == shift_address_first) &&
(shift_function == shift_function_first)) {
address = lookup_decoder(shift_address);
- if (mm_flavor == MM_FLAVOR_DRIVE) {
+ if (recmode == MM_SLOW) {
+ trigger();
+
mm_switch_drive(address, shift_function,
shift_command);
} else {
mm_switch_drive(address, shift_function,
shift_command);
} else {
command = lookup_command(shift_command);
mm_switch_command(address, command);
}
command = lookup_command(shift_command);
mm_switch_command(address, command);
}
"in r0, __SREG__ \n\t"
#ifdef MM_USE_REGISTER_VARS
"inc %[th] \n\t"
"in r0, __SREG__ \n\t"
#ifdef MM_USE_REGISTER_VARS
"inc %[th] \n\t"
+ "brne nover \n\t"
+ "dec %[th] \n\t"
+ "nover: \n\t"
- "lds r1, mm_time_h \n\t"
+ "lds r1, mm_time_h \n\t"
+ "brne nover \n\t"
+ "dec r1 \n\t"
+ "nover: \n\t"
"sts mm_time_h, r1 \n\t"
"pop r1 \n\t"
#endif
"sts mm_time_h, r1 \n\t"
"pop r1 \n\t"
#endif
/* Pin change interrupt vector, here we have a bit more time */
ISR(__vector_pinchange){
/* 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 */
/* First kill off that timer */
MM_TSTART; /* Restart timer */
/* Account for not yet handled timer overflow */
- if (TIFR & _BV(TOV0)) {
- mm_time_h++;
- TIFR |= _BV(TOV0);
- }
-
- mm_bit_val = !MM_SENSE;
- uint16_t duration = mm_time_h << 8;
+ duration = mm_time_h << 8;
* Reality seems to look not as that exact. I measure
* 26us for the clock pulse, but 196 for the long pulse.
*
* Reality seems to look not as that exact. I measure
* 26us for the clock pulse, but 196 for the long pulse.
*
+ * Keep in mind: Time is counted in 500ns steps.
+ *
#define D_MATCH(d, v) ((duration > (d * 2 - 2 * v)) && (duration < (d * 2 + 2 * v)))
#define D_MATCH(d, v) ((duration > (d * 2 - 2 * v)) && (duration < (d * 2 + 2 * v)))
- if (D_MATCH(26, 4)) {
- if (mm_last_was_short)
- mm_polarity = mm_bit_val;
- mm_last_was_short = 1;
-
- if (mm_bit_val == mm_polarity)
- mm_feed_bit(0, MM_FLAVOR_DRIVE);
- } else {
- mm_last_was_short = 0;
- }
-
- if (mm_flavor == MM_FLAVOR_DRIVE) {
- if (duration > 4096) { /* Maerklin inter package timeout 2ms */
- mm_bitno = 0;
- goto done;
+ switch(recmode) {
+ case INIT:
+ default:
+ break;
+ case ARMED:
+ /* Maerklin only interested when signal is 1 */
+ if (mm_bit_val == mm_polarity) {
+ /* Fast short MM pulse (logical 0) */
+ if (D_MATCH(13, 4)){
+ recmode = MM_FAST;
+ mm_feed_bit(0);
+ goto done;
+ }
+
+ /* Slow short MM pulse (logical 0) */
+ if (D_MATCH(26, 4)) {
+ recmode = MM_SLOW;
+ mm_feed_bit(0);
+ goto done;
+ }
+
+ /* Fast long MM pulse (logical 1) */
+ if (D_MATCH(91, 17)) {
+ recmode = MM_FAST;
+ mm_feed_bit(1);
+ goto done;
+ }
+
+ /* Slow long MM pulse (logical 1) */
+ if (D_MATCH(182, 25)) {
+ recmode = MM_SLOW;
+ mm_feed_bit(1);
+ goto done;
+ }
+ }
+ break;
+
+ case MM_FAST:
+ if (mm_bit_val == mm_polarity) {
+
+ /* Fast short MM pulse (logical 0) */
+ if (D_MATCH(13, 4)){
+ mm_feed_bit(0);
+ goto done;
+ }
+ /* Fast long MM pulse (logical 1) */
+ if (D_MATCH(91, 17)) {
+ mm_feed_bit(1);
+ goto done;
+ }
+ } else {
+ if (D_MATCH(13, 4))
+ goto done;
+ if (D_MATCH(91, 17))
+ goto done;
+
+ if (D_MATCH(700, 200))
+ goto done;
- } else {
- if (duration > 2000) { /* Maerklin inter package timeout 1ms */
- mm_bitno = 0;
- goto done;
+ break;
+
+ case MM_SLOW:
+ if (mm_bit_val == mm_polarity) {
+ /* Slow short MM pulse (logical 0) */
+ if (D_MATCH(26, 4)) {
+ mm_feed_bit(0);
+ goto done;
+ }
+ /* Slow long MM pulse (logical 1) */
+ if (D_MATCH(182, 40)) {
+ mm_feed_bit(1);
+ goto done;
+ }
+ } else {
+ if (D_MATCH(26, 4))
+ goto done;
+ if (D_MATCH(182, 40))
+ goto done;
+
+ /* Accepted inter package gap */
+ if (D_MATCH(1400, 400))
+ goto done;
-
- if (mm_bit_val != mm_polarity)
- goto done;
- 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);
+ /*
+ * If we have reached here, our pulse comes in somehow unexpected.
+ * We kill of everything by re-arming the state machine.
+ */
+ /* Start over receiver */
+ mm_bitno = 0;
+ mm_polarity = !mm_bit_val;
+ recmode = ARMED;
done:
mm_switch_pinchange_callback();
}
done:
mm_switch_pinchange_callback();
}