summaryrefslogtreecommitdiff
path: root/usb-1wire/usb-1wire.c
diff options
context:
space:
mode:
Diffstat (limited to 'usb-1wire/usb-1wire.c')
-rw-r--r--usb-1wire/usb-1wire.c226
1 files changed, 197 insertions, 29 deletions
diff --git a/usb-1wire/usb-1wire.c b/usb-1wire/usb-1wire.c
index a383ef1..6fed4f5 100644
--- a/usb-1wire/usb-1wire.c
+++ b/usb-1wire/usb-1wire.c
@@ -1,8 +1,10 @@
/*
- * spreadspace avr utils
+ * spreadspace avr utils - usb-1wire example
*
*
- * Copyright (C) 2013 Christian Pointner <equinox@spreadspace.org>
+ * Copyright (C) 2013 Bernhard Tittelbach <xro@realraum.at>
+ * basically this is refactored and enhanced code from:
+ * http://www.pjrc.com/teensy/td_libs_OneWire.html
*
* This file is part of spreadspace avr utils.
*
@@ -24,45 +26,211 @@
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
-#include <avr/power.h>
+#include <util/delay.h>
#include <stdio.h>
#include "util.h"
#include "led.h"
#include "usbio.h"
+#include "onewire.h"
+
+#define MAX_OWI_DEVICES 3
+
+uint8_t owi_addr_[MAX_OWI_DEVICES][8];
+uint8_t num_owi_dev_found_;
+
+void discoverOWIBus(void)
+{
+ uint8_t d=0;
+ led_on();
+
+ printf("Searching OW Bus ");
+ num_owi_dev_found_ = 0;
+ if (owi_reset())
+ printf(" !something is there! ");
+ owi_reset_search();
+ _delay_ms(250);
+
+ //Search only for DS1820 temp sensors
+ owi_target_search(DS1820_FAMILY_ID);
+
+ while ( owi_search(owi_addr_[ d ]))
+ {
+ d++;
+ printf("%d. found, ", d);
+ led_toggle();
+ if ( d >= MAX_OWI_DEVICES)
+ break;
+ }
+ num_owi_dev_found_ = d;
+ printf(" done \r\n");
+ printf("%d devices found\r\n", d);
+
+ for (d=0; d<num_owi_dev_found_; d++)
+ {
+ printf("OW Dev #%d: addr = ", d);
+ for (uint8_t a=0; a<8; a++)
+ printf("%02x ", owi_addr_[d][a]);
+ if (owi_crc8(owi_addr_[d], 7) == owi_addr_[d][7])
+ printf(" CRC OK");
+ else
+ printf(" CRC ERROR");
+ printf("\r\n");
+ }
+ led_off();
+}
+
+void tempToUSB(uint8_t resolution)
+{
+ uint8_t data[9];
+ int16_t celsius = 0;
+ int16_t raw = 0;
+ uint8_t type_s, cfg;
+ uint8_t d=0;
+ uint8_t cfg_res=12;
+ uint8_t crc_result = 0;
+
+ led_on();
+
+ owi_reset();
+ //we assume we do NOT use parasitic power, so we can issue
+ //commands while other sensors are already busy converting
+ for (d=0; d<num_owi_dev_found_; d++)
+ {
+ owi_select(owi_addr_[d]);
+
+ owi_write(DS1820_WRITE_SCRATCHPAD, 0);
+ owi_write(0xFF, 0);
+ owi_write(0x7F, 0);
+ owi_write(resolution | 0x1F, 0);
+ owi_reset();
+ owi_select(owi_addr_[d]);
+ owi_write(DS1820_START_CONVERSION, 0);
+ }
+
+ switch (resolution)
+ {
+ case DS1820_RESOLUTION_9BITS: _delay_ms(DS1820_TCONV_MS_9BITS); break;
+ case DS1820_RESOLUTION_10BITS: _delay_ms(DS1820_TCONV_MS_10BITS); break;
+ case DS1820_RESOLUTION_11BITS: _delay_ms(DS1820_TCONV_MS_11BITS); break;
+ default: _delay_ms(DS1820_TCONV_MS_12BITS); break;
+ }
+
+ if (owi_reset()) //reset is needed
+ printf("Sensor present\r\n");
+ else
+ printf("Sensor NOT present\r\n");
+
+ for (d=0; d<num_owi_dev_found_; d++)
+ {
+ owi_select(owi_addr_[d]);
+ owi_write(DS1820_READ_SCRATCHPAD, 0); // Read Scratchpad
+ printf("Data: ");
+ for (uint8_t i = 0; i < 9; i++) { // we need 9 bytes
+ data[i] = owi_read();
+ printf("%02x " , data[i]);
+ }
+ crc_result = owi_crc8(data,8);
+ printf(" crc: %x is %s\r\n" , crc_result, (crc_result == data[8])? "OK": "ERRORENOUS");
+
+ // the first ROM byte indicates which chip
+ switch (owi_addr_[d][0])
+ {
+ case 0x10:
+ //~ Serial.println(" Chip = DS18S20"); // or old DS1820
+ type_s = 1;
+ break;
+ case 0x28:
+ //~ Serial.println(" Chip = DS18B20");
+ type_s = 0;
+ break;
+ case 0x22:
+ //~ Serial.println(" Chip = DS1822");
+ type_s = 0;
+ break;
+ default:
+ continue;
+ }
+
+ // Convert the data to actual temperature
+ // because the result is a 16 bit signed integer, it should
+ // be stored to an "int16_t" type, which is always 16 bits
+ // even when compiled on a 32 bit processor.
+ raw = (data[1] << 8) | data[0];
+ if (type_s)
+ {
+ raw = raw << 3; // 9 bit resolution default
+ if (data[7] == 0x10) {
+ // "count remain" gives full 12 bit resolution
+ raw = (raw & 0xFFF0) + 12 - data[6];
+ }
+ } else {
+ cfg = (data[4] & 0x60);
+ // at lower res, the low bits are undefined, so let's zero them
+ if (cfg == 0x00)
+ {
+ raw = raw & ~7; // 9 bit resolution, 93.75 ms
+ cfg_res = 9;
+ }
+ else if (cfg == 0x20)
+ {
+ raw = raw & ~3; // 10 bit res, 187.5 ms
+ cfg_res = 10;
+ }
+ else if (cfg == 0x40)
+ {
+ raw = raw & ~1; // 11 bit res, 375 ms
+ cfg_res = 11;
+ }
+ //// default is 12 bit resolution, 750 ms conversion time
+ }
+ celsius = raw / 16;
+
+ printf("Temperature: raw %d, celsius: %d, resolution: %d bits\r\n", raw, celsius, cfg_res);
+ }
+ led_off();
+}
+
+
void handle_cmd(uint8_t cmd)
{
- switch(cmd) {
- case '0': led_off(); break;
- case '1': led_on(); break;
- case 't': led_toggle(); break;
- case 'r': reset2bootloader(); break;
- default: printf("error\r\n"); return;
- }
- printf("ok\r\n");
+ switch(cmd) {
+ case '0': discoverOWIBus(); break;
+ case '1': tempToUSB(DS1820_RESOLUTION_9BITS); break;
+ case '2': tempToUSB(DS1820_RESOLUTION_10BITS); break;
+ case '3': tempToUSB(DS1820_RESOLUTION_11BITS); break;
+ case '4': tempToUSB(DS1820_RESOLUTION_12BITS); break;
+ case 'r': reset2bootloader(); break;
+ default: printf("error\r\n"); return;
+ }
+ printf("ok\r\n");
}
int main(void)
{
- MCUSR &= ~(1 << WDRF);
- wdt_disable();
-
- cpu_init();
- led_init();
- usbio_init();
- sei();
-
- for(;;) {
- int16_t BytesReceived = usbio_bytes_received();
- while(BytesReceived > 0) {
- int ReceivedByte = fgetc(stdin);
- if(ReceivedByte != EOF) {
- handle_cmd(ReceivedByte);
- }
- BytesReceived--;
- }
+ MCUSR &= ~(1 << WDRF);
+ wdt_disable();
+
+ cpu_init();
+ led_init();
+ usbio_init();
+ sei();
+ DDRC &= ~7;
+ owi_init(7, &PINC);
+
+ for(;;)
+ {
+ int16_t BytesReceived = usbio_bytes_received();
+ while(BytesReceived > 0)
+ {
+ int ReceivedByte = fgetc(stdin);
+ if(ReceivedByte != EOF) {
+ handle_cmd(ReceivedByte);
+ }
+ BytesReceived--;
+ }
usbio_task();
- }
+ }
}