summaryrefslogtreecommitdiffstats
path: root/radiator-plc/stm32/app/1wire.c
diff options
context:
space:
mode:
Diffstat (limited to 'radiator-plc/stm32/app/1wire.c')
-rw-r--r--radiator-plc/stm32/app/1wire.c384
1 files changed, 384 insertions, 0 deletions
diff --git a/radiator-plc/stm32/app/1wire.c b/radiator-plc/stm32/app/1wire.c
new file mode 100644
index 0000000..dd66e92
--- /dev/null
+++ b/radiator-plc/stm32/app/1wire.c
@@ -0,0 +1,384 @@
+#include "project.h"
+
+#define GPIO_PORT GPIOB
+#define GPIO GPIO1
+
+#define BIT_ZERO '0'
+#define BIT_ONE '1'
+#define BIT_UNKNOWN 'U'
+#define BIT_CONFLICT 'C'
+
+
+static inline void
+low (void)
+{
+ CLEAR (GPIO);
+}
+
+static inline void
+hiz (void)
+{
+ SET (GPIO);
+}
+
+static inline int
+get (void)
+{
+ return ! !GET (GPIO);
+}
+
+/*Returns 1 if timeout - waits ~100ms */
+static inline int
+wait_hiz (void)
+{
+ unsigned int timeout = 10000;
+ hiz();
+
+ while (!get()) {
+ timeout--;
+
+ if (! (timeout--))
+ return 1;
+
+ delay_us (10);
+ }
+
+ return 0;
+}
+
+
+/* returns 1 if nothing on bus or error */
+int
+onewire_reset (void)
+{
+ int ret;
+ cm_disable_interrupts();
+ low();
+ delay_us (600);
+ hiz();
+ delay_us (65);
+ ret = get();
+
+ if (wait_hiz())
+ ret = 1;
+
+ delay_us (100);
+ cm_enable_interrupts();
+ return ret;
+}
+
+void
+onewire_one (void)
+{
+ cm_disable_interrupts();
+ low();
+ delay_us (10);
+ hiz();
+ delay_us (90);
+ cm_enable_interrupts();
+}
+
+void
+onewire_zero (void)
+{
+ cm_disable_interrupts();
+ low();
+ delay_us (90);
+ hiz();
+ delay_us (10);
+ cm_enable_interrupts();
+}
+
+int
+onewire_read (void)
+{
+ int ret;
+ cm_disable_interrupts();
+ low();
+ delay_us (10);
+ hiz();
+ delay_us (20);
+ ret = get();
+ delay_us (70);
+ cm_enable_interrupts();
+ return ret;
+}
+
+
+void
+onewire_write_byte (uint8_t v)
+{
+ int c;
+
+ for (c = 0; c < 8; ++c) {
+ if (v & 1)
+ onewire_one();
+ else
+ onewire_zero();
+
+ v >>= 1;
+ }
+}
+
+uint8_t
+onewire_read_byte (void)
+{
+ uint8_t v = 0;
+ int c;
+
+ for (c = 0; c < 8; ++c) {
+ v >>= 1;
+
+ if (onewire_read())
+ v |= 0x80;
+ }
+
+
+ return v;
+}
+
+void
+onewire_read_bytes (uint8_t *buf, int n)
+{
+ while (n--)
+ * (buf++) = onewire_read_byte();
+}
+
+
+void
+onewire_write_bytes (const uint8_t *buf, int n)
+{
+ while (n--)
+ onewire_write_byte (* (buf++));
+}
+
+
+int onewire_select (const Onewire_addr *a)
+{
+ if (!a)
+ onewire_write_byte (ONEWIRE_SKIP_ROM);
+ else {
+ onewire_write_byte (ONEWIRE_MATCH_ROM);
+ onewire_write_bytes (a->a, 8);
+ }
+
+ return 0;
+}
+
+
+int onewire_reset_and_select (const Onewire_addr *a)
+{
+ if (onewire_reset())
+ return 1;
+
+ if (onewire_select (a))
+ return 1;
+
+ return 0;
+}
+
+
+
+int onewire_wait_complete (unsigned timeout)
+{
+ while (! (onewire_read())) {
+ delay_ms (10);
+
+ if (! (timeout--))
+ return 1;
+ }
+
+ return 0;
+}
+
+
+
+int
+onewire_check_crc (uint8_t *buf, int n, uint8_t v)
+{
+ uint8_t crc = 0;
+ int i;
+
+ while (n--) {
+ uint8_t v = * (buf++);
+
+ for (i = 0; i < 8; ++i) {
+ uint8_t mix = (crc ^ v) & 0x01;
+ crc >>= 1;
+
+ if (mix)
+ crc ^= 0x8C;
+
+ v >>= 1;
+ }
+ }
+
+ return ! (crc == v);
+
+}
+
+static int onewire_conduct_search (uint8_t *bits)
+{
+ unsigned i, ir, r;
+
+ if (onewire_reset())
+ return -1;
+
+ onewire_write_byte (ONEWIRE_SEARCH_ROM);
+
+
+ for (i = 0; i < 64; ++i) {
+
+ r = onewire_read();
+ ir = onewire_read();
+
+#if 0
+
+ if ((i == 27) || (i == 24) || (i == 39))
+ ir = r = 0;
+
+#endif
+
+ switch (bits[i]) {
+ case BIT_UNKNOWN:
+
+ if (!r && ir) { /* Zero */
+ bits[i] = BIT_ZERO;
+ onewire_zero();
+ } else if (r && !ir) { /*One */
+ bits[i] = BIT_ONE;
+ onewire_one();
+ } else if (r && ir) /*Nothing here */
+ return -1;
+
+ else if (!r && !ir) { /*Both */
+ bits[i] = BIT_CONFLICT;
+ onewire_zero();
+ }
+
+ break;
+
+ case BIT_CONFLICT:
+ if (!r && !ir) /*Both */
+ onewire_zero();
+ else
+ return -1;
+
+ break;
+
+ case BIT_ZERO:
+ if (!r)
+ onewire_zero();
+ else
+ return -1;
+
+ break;
+
+ case BIT_ONE:
+ if (!ir)
+ onewire_one();
+ else
+ return -1;
+
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int onewire_next (uint8_t *bits)
+{
+ unsigned i;
+
+ for (i = 0; i < 64; ++i) {
+
+ if (bits[63 - i] == BIT_CONFLICT) {
+ bits[63 - i] = BIT_ONE;
+ return 1;
+ }
+
+ bits[63 - i] = BIT_UNKNOWN;
+ }
+
+ return 0;
+}
+
+static void onewire_bits_to_a (uint8_t *bits, Onewire_addr *a)
+{
+ unsigned i, j, c;
+
+ for (i = 0, j = 0; i < 8; ++i) {
+
+ a->a[i] = 0;
+
+ for (c = 1; c < 0x100; c <<= 1, ++j) {
+ if (bits[j] == BIT_ONE)
+ a->a[i] |= c;
+ }
+ }
+}
+
+int onewire_search (void)
+{
+ uint8_t bits[64];
+ Onewire_addr a;
+ int r, c;
+
+
+ printf ("One wire search\n");
+ //delay_ms (2000);
+
+ memset (bits, BIT_UNKNOWN, sizeof (bits));
+
+ do {
+ r = onewire_conduct_search (bits);
+
+ if (!r) {
+ onewire_bits_to_a (bits, &a);
+ c = onewire_check_crc (&a.a[0], 7, a.a[7]);
+
+ if (!c) {
+ printf ("O: {0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x}\r\n",
+ a.a[0],
+ a.a[1],
+ a.a[2],
+ a.a[3],
+ a.a[4],
+ a.a[5],
+ a.a[6],
+ a.a[7]);
+ }
+
+ }
+
+ } while (onewire_next (bits));
+
+
+
+
+
+
+ return 0;
+}
+
+
+void
+onewire_init (void)
+{
+ MAP_OUTPUT_OD_SLOW (GPIO);
+
+ hiz();
+ delay_us (20);
+ printf ("hiz -> %d\n", get());
+
+ low();
+
+ delay_us (20);
+ printf ("low -> %d\n", get());
+
+ hiz();
+ delay_us (20);
+
+
+}