summaryrefslogtreecommitdiffstats
path: root/boiler-monster/stm32/app/ot_phy_rx.c
diff options
context:
space:
mode:
Diffstat (limited to 'boiler-monster/stm32/app/ot_phy_rx.c')
-rw-r--r--boiler-monster/stm32/app/ot_phy_rx.c177
1 files changed, 177 insertions, 0 deletions
diff --git a/boiler-monster/stm32/app/ot_phy_rx.c b/boiler-monster/stm32/app/ot_phy_rx.c
new file mode 100644
index 0000000..9348d24
--- /dev/null
+++ b/boiler-monster/stm32/app/ot_phy_rx.c
@@ -0,0 +1,177 @@
+#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);
+
+}
+
+
+