From a31091d88c8d2456816caedb681e250fb93d1a7a Mon Sep 17 00:00:00 2001 From: MightyPork Date: Mon, 11 May 2015 02:55:04 +0200 Subject: [PATCH] set_low to pin_low, added onewire support --- lib/iopins.c | 92 ++++++++++---------- lib/iopins.h | 10 +-- lib/lcd.c | 16 ++-- lib/onewire.h | 235 ++++++++++++++++++++++++++++++++++++++++++++++++++ lib/wsrgb.c | 8 +- 5 files changed, 298 insertions(+), 63 deletions(-) create mode 100644 lib/onewire.h diff --git a/lib/iopins.c b/lib/iopins.c index f775e6f..2b3934b 100644 --- a/lib/iopins.c +++ b/lib/iopins.c @@ -148,59 +148,59 @@ void set_pin_n(const uint8_t pin, const uint8_t v) } } -void set_low_n(const uint8_t pin) +void pin_low_n(const uint8_t pin) { switch(pin) { - case 0: set_low(0); return; - case 1: set_low(1); return; - case 2: set_low(2); return; - case 3: set_low(3); return; - case 4: set_low(4); return; - case 5: set_low(5); return; - case 6: set_low(6); return; - case 7: set_low(7); return; - case 8: set_low(8); return; - case 9: set_low(9); return; - case 10: set_low(10); return; - case 11: set_low(11); return; - case 12: set_low(12); return; - case 13: set_low(13); return; - case 14: set_low(14); return; - case 15: set_low(15); return; - case 16: set_low(16); return; - case 17: set_low(17); return; - case 18: set_low(18); return; - case 19: set_low(19); return; - case 20: set_low(20); return; - case 21: set_low(21); return; + case 0: pin_low(0); return; + case 1: pin_low(1); return; + case 2: pin_low(2); return; + case 3: pin_low(3); return; + case 4: pin_low(4); return; + case 5: pin_low(5); return; + case 6: pin_low(6); return; + case 7: pin_low(7); return; + case 8: pin_low(8); return; + case 9: pin_low(9); return; + case 10: pin_low(10); return; + case 11: pin_low(11); return; + case 12: pin_low(12); return; + case 13: pin_low(13); return; + case 14: pin_low(14); return; + case 15: pin_low(15); return; + case 16: pin_low(16); return; + case 17: pin_low(17); return; + case 18: pin_low(18); return; + case 19: pin_low(19); return; + case 20: pin_low(20); return; + case 21: pin_low(21); return; } } -void set_high_n(const uint8_t pin) +void pin_high_n(const uint8_t pin) { switch(pin) { - case 0: set_high(0); return; - case 1: set_high(1); return; - case 2: set_high(2); return; - case 3: set_high(3); return; - case 4: set_high(4); return; - case 5: set_high(5); return; - case 6: set_high(6); return; - case 7: set_high(7); return; - case 8: set_high(8); return; - case 9: set_high(9); return; - case 10: set_high(10); return; - case 11: set_high(11); return; - case 12: set_high(12); return; - case 13: set_high(13); return; - case 14: set_high(14); return; - case 15: set_high(15); return; - case 16: set_high(16); return; - case 17: set_high(17); return; - case 18: set_high(18); return; - case 19: set_high(19); return; - case 20: set_high(20); return; - case 21: set_high(21); return; + case 0: pin_high(0); return; + case 1: pin_high(1); return; + case 2: pin_high(2); return; + case 3: pin_high(3); return; + case 4: pin_high(4); return; + case 5: pin_high(5); return; + case 6: pin_high(6); return; + case 7: pin_high(7); return; + case 8: pin_high(8); return; + case 9: pin_high(9); return; + case 10: pin_high(10); return; + case 11: pin_high(11); return; + case 12: pin_high(12); return; + case 13: pin_high(13); return; + case 14: pin_high(14); return; + case 15: pin_high(15); return; + case 16: pin_high(16); return; + case 17: pin_high(17); return; + case 18: pin_high(18); return; + case 19: pin_high(19); return; + case 20: pin_high(20); return; + case 21: pin_high(21); return; } } diff --git a/lib/iopins.h b/lib/iopins.h index acd57ae..3cabadd 100644 --- a/lib/iopins.h +++ b/lib/iopins.h @@ -73,7 +73,7 @@ void as_input_n(const uint8_t pin); /** Configure pin as input, with pull-up enabled */ -#define as_input_pu(pin) { as_input(pin); set_high(pin); } +#define as_input_pu(pin) { as_input(pin); pin_high(pin); } void as_input_pu_n(const uint8_t pin); @@ -88,13 +88,13 @@ void set_pin_n(const uint8_t pin, const uint8_t v); /** Write 0 to a pin */ -#define set_low(pin) cbi( _port(pin), _pn(pin) ) -void set_low_n(const uint8_t pin); +#define pin_low(pin) cbi( _port(pin), _pn(pin) ) +void pin_low_n(const uint8_t pin); /** Write 1 to a pin */ -#define set_high(pin) sbi( _port(pin), _pn(pin) ) -void set_high_n(const uint8_t pin); +#define pin_high(pin) sbi( _port(pin), _pn(pin) ) +void pin_high_n(const uint8_t pin); /** Toggle a pin state */ diff --git a/lib/lcd.c b/lib/lcd.c index 4332e5a..a9ceb13 100644 --- a/lib/lcd.c +++ b/lib/lcd.c @@ -100,9 +100,9 @@ void lcd_init() /** Send a pulse on the ENABLE line */ void _lcd_clk() { - set_high(LCD_E); + pin_high(LCD_E); delay_ns(450); - set_low(LCD_E); + pin_low(LCD_E); } @@ -111,7 +111,7 @@ void _lcd_mode_r() { if (_lcd_mode == 1) return; // already in R mode - set_high(LCD_RW); + pin_high(LCD_RW); as_input_pu(LCD_D7); as_input_pu(LCD_D6); @@ -127,7 +127,7 @@ void _lcd_mode_w() { if (_lcd_mode == 0) return; // already in W mode - set_low(LCD_RW); + pin_low(LCD_RW); as_output(LCD_D7); as_output(LCD_D6); @@ -159,7 +159,7 @@ uint8_t _lcd_read_byte() void lcd_command(uint8_t bb) { _lcd_wait_bf(); - set_low(LCD_RS); // select instruction register + pin_low(LCD_RS); // select instruction register _lcd_write_byte(bb); // send instruction byte } @@ -186,7 +186,7 @@ void lcd_write(uint8_t bb) } _lcd_wait_bf(); - set_high(LCD_RS); // select data register + pin_high(LCD_RS); // select data register _lcd_write_byte(bb); // send data byte } @@ -194,7 +194,7 @@ void lcd_write(uint8_t bb) /** Read BF & Address */ uint8_t lcd_read_bf_addr() { - set_low(LCD_RS); + pin_low(LCD_RS); return _lcd_read_byte(); } @@ -204,7 +204,7 @@ uint8_t lcd_read() { if (_addrtype == TEXT) _pos.x++; - set_high(LCD_RS); + pin_high(LCD_RS); return _lcd_read_byte(); } diff --git a/lib/onewire.h b/lib/onewire.h new file mode 100644 index 0000000..f0fd2c0 --- /dev/null +++ b/lib/onewire.h @@ -0,0 +1,235 @@ +#pragma once + +#include +#include +#include +#include + +#include "lib/iopins.h" +#include "lib/uart.h" +#include "lib/stream.h" + +#define SKIP_ROM 0xCC +#define CONVERT_T 0x44 +#define READ_SCRATCHPAD 0xBE + + +/** Perform bus reset. Returns true if any device is connected */ +bool ow_reset(const uint8_t pin) +{ + as_output_n(pin); + pin_low_n(pin); + _delay_us(480); + + as_input_pu_n(pin); + _delay_us(70); + + const bool a = get_pin_n(pin); + + _delay_us(410); + + return a; +} + + +/** Send a single bit */ +void ow_tx_bit(const uint8_t pin, const bool bit) +{ + as_output_n(pin); + pin_low_n(pin); + + if (bit) { + _delay_us(6); + as_input_pu_n(pin); + _delay_us(64); + } else { + _delay_us(60); + as_input_pu_n(pin); + _delay_us(10); + } +} + + +/** Send a single byte */ +void ow_send(const uint8_t pin, const uint8_t byte) +{ + for (uint8_t i = 0; i < 8; i++) + { + ow_tx_bit(pin, (byte >> i) & 0x01); + } +} + + +/** Read a single bit */ +bool ow_rx_bit(const uint8_t pin) +{ + as_output_n(pin); + pin_low_n(pin); + _delay_us(6); + + as_input_pu_n(pin); + _delay_us(9); + + const bool a = get_pin_n(pin); + + _delay_us(55); + + return a; +} + + +/** Read a single byte */ +uint8_t ow_read(const uint8_t pin) +{ + uint8_t byte = 0; + + for (uint8_t i = 0; i < 8; i++) + { + byte = (byte >> 1) | (ow_rx_bit(pin) << 7); + } + + return byte; +} + + +/** Wait until the device is ready. Returns false on timeout */ +bool ow_wait_ready(const uint8_t pin) +{ + uint16_t timeout = 700; + as_input_pu_n(pin); + + while (--timeout > 0) + { + if (is_high_n(pin)) return true; + _delay_ms(1); + } + + return false; +} + + +/** Read bytes into an array */ +void ow_read_arr(const uint8_t pin, uint8_t* array, const uint8_t count) +{ + for (uint8_t i = 0; i < count; i++) + { + array[i] = ow_read(pin); + } +} + + + +// ---------- CRC utils ---------- + +/* + Dallas 1-wire CRC routines for Arduino with examples of usage. + The 16-bit routine is new. + The 8-bit routine is from http://github.com/paeaetech/paeae/tree/master/Libraries/ds2482/ + + Copyright (C) 2010 Kairama Inc + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +// Dallas 1-wire 16-bit CRC calculation. Developed from Maxim Application Note 27. + +/** Compute a CRC16 checksum */ +uint16_t crc16( uint8_t *data, uint8_t len) +{ + uint16_t crc = 0; + + for (uint8_t i = 0; i < len; i++) + { + uint8_t inbyte = data[i]; + for (uint8_t j = 0; j < 8; j++) + { + uint8_t mix = (crc ^ inbyte) & 0x01; + crc = crc >> 1; + if (mix) + crc = crc ^ 0xA001; + + inbyte = inbyte >> 1; + } + } + return crc; +} + + +// The 1-Wire CRC scheme is described in Maxim Application Note 27: +// "Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products" + +/** Compute a CRC8 checksum */ +uint8_t crc8(uint8_t *addr, uint8_t len) +{ + uint8_t crc = 0; + + for (uint8_t i = 0; i < len; i++) + { + uint8_t inbyte = addr[i]; + for (uint8_t j = 0; j < 8; j++) + { + uint8_t mix = (crc ^ inbyte) & 0x01; + crc >>= 1; + if (mix) + crc ^= 0x8C; + + inbyte >>= 1; + } + } + + return crc; +} + + +// --- utils for DS1820 --- + +#define TEMP_ERROR -32768 + +/** Read temperature in 0.0625°C, or TEMP_ERROR on error */ +int16_t ds1820_read_temp(uint8_t pin) +{ + ow_send(pin, READ_SCRATCHPAD); + uint8_t bytes[9]; + ow_read_arr(pin, bytes, 9); + + put_nl(uart); + + uint8_t crc = crc8(bytes, 8); + if (crc != bytes[8]) { + return TEMP_ERROR; + } else { + int16_t a = ((bytes[1] << 8) | bytes[0]) >> 1; + a = a << 4; + a += (16 - bytes[6]) & 0x0F; + a -= 0x04; + + return a; + } +} + +/** Read temperature in 0.1°C, or TEMP_ERROR on error */ +int16_t ds1820_read_temp_c(uint8_t pin) +{ + int32_t temp = ds1820_read_temp(pin); + + if (temp == TEMP_ERROR) + return TEMP_ERROR; + + temp *= 625; + uint16_t rem = temp % 1000; + temp /= 1000; + if (rem >= 500) temp++; + + return (int16_t) temp; +} + diff --git a/lib/wsrgb.c b/lib/wsrgb.c index f0c27cd..8eb2507 100644 --- a/lib/wsrgb.c +++ b/lib/wsrgb.c @@ -27,16 +27,16 @@ void ws_send_byte(const uint8_t bb) { for (volatile int8_t i = 7; i >= 0; --i) { if ((bb) & (1 << i)) { - set_high(WS_PIN); + pin_high(WS_PIN); delay_ns_c(WS_T_1H, -2); - set_low(WS_PIN); + pin_low(WS_PIN); delay_ns_c(WS_T_1L, -10); } else { - set_high(WS_PIN); + pin_high(WS_PIN); delay_ns_c(WS_T_0H, -2); - set_low(WS_PIN); + pin_low(WS_PIN); delay_ns_c(WS_T_0L, -10); } }