summaryrefslogtreecommitdiffstats
path: root/boiler-monster/stm32/app/1wire.c
diff options
context:
space:
mode:
Diffstat (limited to 'boiler-monster/stm32/app/1wire.c')
-rw-r--r--boiler-monster/stm32/app/1wire.c392
1 files changed, 392 insertions, 0 deletions
diff --git a/boiler-monster/stm32/app/1wire.c b/boiler-monster/stm32/app/1wire.c
new file mode 100644
index 0000000..c374c5c
--- /dev/null
+++ b/boiler-monster/stm32/app/1wire.c
@@ -0,0 +1,392 @@
+#include "project.h"
+
+#define USART2_TX GPIO_USART2_TX
+#define USART2_TX_PORT GPIOA
+
+#define BIT_ZERO '0'
+#define BIT_ONE '1'
+#define BIT_UNKNOWN 'U'
+#define BIT_CONFLICT 'C'
+
+
+static int poke;
+static volatile unsigned exchange_timeout;
+
+void onewire_tick (void)
+{
+ static unsigned ticker;
+
+ if (exchange_timeout)
+ exchange_timeout--;
+
+
+ ticker++;
+
+ if (ticker < MS_TO_TICKS (5000))
+ return;
+
+ ticker = 0;
+ poke = 1;
+
+
+}
+
+
+static unsigned usart_send_ready (uint32_t usart)
+{
+ return (USART_SR (usart) & USART_SR_TXE);
+}
+
+
+static unsigned usart_recv_ready (uint32_t usart)
+{
+ return (USART_SR (usart) & USART_SR_RXNE);
+}
+
+
+
+static int onewire_exchange (int tx, unsigned timeout)
+{
+ int rx;
+ (void) USART_SR (USART2);
+ (void) usart_recv (USART2);
+
+
+ exchange_timeout = MS_TO_TICKS (timeout);
+
+ while (!usart_send_ready (USART2))
+ if (!exchange_timeout)
+ return -1;
+
+ usart_send (USART2, tx);
+
+ exchange_timeout = MS_TO_TICKS (timeout);
+
+ while (!usart_recv_ready (USART2))
+ if (!exchange_timeout)
+ return -1;
+
+
+ rx = usart_recv (USART2);
+
+ return rx;
+
+}
+
+/* returns 1 if nothing on bus or error */
+int
+onewire_reset (void)
+{
+ int ret;
+
+ usart_set_baudrate (USART2, 9600);
+ delay_ms (1);
+ ret = onewire_exchange (0xf0, 60);
+ usart_set_baudrate (USART2, 115200);
+ delay_ms (1);
+
+ return (ret == 0xf0);
+}
+
+static void
+onewire_one (void)
+{
+ onewire_exchange (0xff, 3);
+}
+
+static void
+onewire_zero (void)
+{
+ onewire_exchange (0x00, 3);
+}
+
+static int
+onewire_read (void)
+{
+ uint8_t rx;
+
+ rx = onewire_exchange (0xff, 3);
+
+ return (rx == 0xff);
+}
+
+
+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 */
+ //MEH;
+ return -1;
+ } else if (!r && !ir) { /*Both */
+ bits[i] = BIT_CONFLICT;
+ onewire_zero();
+ }
+
+ break;
+
+ case BIT_CONFLICT:
+ if (!r && !ir) /*Both */
+ onewire_zero();
+ else {
+ //MEH;
+ return -1;
+ }
+
+ break;
+
+ case BIT_ZERO:
+ if (!r)
+ onewire_zero();
+ else {
+ //MEH;
+ return -1;
+ }
+
+ break;
+
+ case BIT_ONE:
+ if (!ir)
+ onewire_one();
+ else {
+ //MEH;
+ 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;
+
+ 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 ("QO: {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_AF_OD (USART2_TX);
+
+ usart_set_baudrate (USART2, 115200);
+ usart_set_databits (USART2, 8);
+ usart_set_stopbits (USART2, USART_STOPBITS_1);
+ usart_set_parity (USART2, USART_PARITY_NONE);
+ usart_set_flow_control (USART2, USART_FLOWCONTROL_NONE);
+ usart_set_mode (USART2, USART_MODE_TX_RX);
+
+ USART_CR3 (USART2) |= USART_CR3_HDSEL;
+
+ usart_enable (USART2);
+}