#include "project.h" #define OT_THM_IN GPIO6 #define OT_THM_IN_PORT GPIOB #define OT_BLR_IN GPIO7 #define OT_BLR_IN_PORT GPIOB #define OT_RX_IRQ NVIC_EXTI9_5_IRQ typedef struct rx_phy { uint32_t last_cycle; int last_v; unsigned half_bits; unsigned data_bits; int frame_error; uint8_t data[10]; int parity; } RX_Phy; static RX_Phy p_thm, p_blr; static uint32_t cycle_diff (uint32_t a, uint32_t b) { return b - a; } static void ot_phy_rx_bit (RX_Phy *p) { if (p->half_bits & 1) p->frame_error = 1; if (!p->half_bits) { if (!p->last_v) p->frame_error = 1; return; } if (p->data_bits < 32) { if (p->last_v) p->data[p->data_bits >> 3] |= 0x80 >> (p->data_bits & 7); p->parity ^= p->last_v; } else if (p->data_bits == 32) { if ((!p->last_v) || (p->parity)) p->frame_error = 1; led_blink(); if (p == &p_thm) ot_rx_thm (p->data, p->frame_error); else ot_rx_blr (p->data, p->frame_error); } p->data_bits++; } static void ot_phy_rx_worker (RX_Phy *p, int v) { uint32_t now, diff; if (v == p->last_v) return; now = dwt_read_cycle_counter(); diff = cycle_diff (p->last_cycle, now); if (diff < 10000) return; if (diff < 50000) { if (! (p->half_bits & 1)) ot_phy_rx_bit (p); p->half_bits++; } else if (diff < 85000) { p->half_bits++; ot_phy_rx_bit (p); p->half_bits++; } else { p->parity = 0; p->half_bits = 0; p->frame_error = 0; p->data_bits = 0; memset (p->data, 0, sizeof (p->data)); } p->last_cycle = now; p->last_v = v; } void exti9_5_isr (void) { int v; if (EXTI_PR & OT_THM_IN) { EXTI_PR = OT_THM_IN; v = !GET (OT_THM_IN); #if 0 if (v) CLEAR (OT_BLR_OUT); else SET (OT_BLR_OUT); #endif ot_phy_rx_worker (&p_thm, v); } if (EXTI_PR & OT_BLR_IN) { EXTI_PR = OT_BLR_IN; v = !GET (OT_BLR_IN); #if 0 if (v) CLEAR (OT_THM_OUT); else SET (OT_THM_OUT); #endif ot_phy_rx_worker (&p_blr, v); } return; } void ot_phy_rx_tick (void) { } void ot_phy_rx_init (void) { MAP_INPUT_PU (OT_THM_IN); MAP_INPUT_PU (OT_BLR_IN); exti_select_source (OT_THM_IN, OT_THM_IN_PORT); exti_set_trigger (OT_THM_IN, EXTI_TRIGGER_BOTH); exti_enable_request (OT_THM_IN); exti_reset_request (OT_THM_IN); exti_select_source (OT_BLR_IN, OT_BLR_IN_PORT); exti_set_trigger (OT_BLR_IN, EXTI_TRIGGER_BOTH); exti_enable_request (OT_BLR_IN); exti_reset_request (OT_BLR_IN); nvic_enable_irq (OT_RX_IRQ); }