Multiple cleanups/tweaks for onewire driver

Use onewire_addr_t for onewire addresses
Move internal defines out of onewire.h
Remove global variables for search state
use taskENTER_CRITICAL instead of portDISABLE_INTERRUPTS
remove unnecessary onewire_init function
Remove unnecessary critical sections
Use GPIO_OUT_OPEN_DRAIN
reformat/style cleanup
This commit is contained in:
Alex Stewart 2016-03-14 21:59:39 -07:00
parent 02c35d8a71
commit a2b9d688ea
4 changed files with 304 additions and 359 deletions

View file

@ -12,8 +12,6 @@
// DS18B20 driver
#include "ds18b20/ds18b20.h"
// Onewire init
#include "onewire/onewire.h"
void print_temperature(void *pvParameters)
{
@ -26,8 +24,6 @@ void print_temperature(void *pvParameters)
// Use GPIO 13 as one wire pin.
uint8_t GPIO_FOR_ONE_WIRE = 13;
onewire_init(GPIO_FOR_ONE_WIRE);
while(1) {
// Search all DS18B20, return its amount and feed 't' structure with result data.
amount = ds18b20_read_all(GPIO_FOR_ONE_WIRE, t);

View file

@ -17,27 +17,28 @@
#define DS1820_CONVERT_T 0x44
uint8_t ds18b20_read_all(uint8_t pin, ds_sensor_t *result) {
uint8_t addr[8];
onewire_addr_t addr;
onewire_search_t search;
uint8_t sensor_id = 0;
onewire_reset_search(pin);
onewire_search_start(&search);
while(onewire_search(pin, addr)){
uint8_t crc = onewire_crc8(addr, 7);
if (crc != addr[7]){
printf("CRC check failed: %02X %02X\n", addr[7], crc);
while ((addr = onewire_search_next(&search, pin)) != ONEWIRE_NONE) {
uint8_t crc = onewire_crc8((uint8_t *)&addr, 7);
if (crc != (addr >> 56)){
printf("CRC check failed: %02X %02X\n", (unsigned)(addr >> 56), crc);
return 0;
}
onewire_reset(pin);
onewire_select(pin, addr);
onewire_write(pin, DS1820_CONVERT_T, ONEWIRE_DEFAULT_POWER);
onewire_write(pin, DS1820_CONVERT_T);
vTaskDelay(750 / portTICK_RATE_MS);
onewire_reset(pin);
onewire_select(pin, addr);
onewire_write(pin, DS1820_READ_SCRATCHPAD, ONEWIRE_DEFAULT_POWER);
onewire_write(pin, DS1820_READ_SCRATCHPAD);
uint8_t get[10];
@ -71,15 +72,14 @@ uint8_t ds18b20_read_all(uint8_t pin, ds_sensor_t *result) {
float ds18b20_read_single(uint8_t pin) {
onewire_reset(pin);
onewire_write(pin, DS1820_SKIP_ROM, ONEWIRE_DEFAULT_POWER);
onewire_write(pin, DS1820_CONVERT_T, ONEWIRE_DEFAULT_POWER);
onewire_skip_rom(pin);
onewire_write(pin, DS1820_CONVERT_T);
vTaskDelay(750 / portTICK_RATE_MS);
onewire_reset(pin);
onewire_write(pin, DS1820_SKIP_ROM, ONEWIRE_DEFAULT_POWER);
onewire_write(pin, DS1820_READ_SCRATCHPAD, ONEWIRE_DEFAULT_POWER);
onewire_skip_rom(pin);
onewire_write(pin, DS1820_READ_SCRATCHPAD);
uint8_t get[10];

View file

@ -1,206 +1,176 @@
#include "onewire.h"
// global search state
static unsigned char ROM_NO[ONEWIRE_NUM][8];
static uint8_t LastDiscrepancy[ONEWIRE_NUM];
static uint8_t LastFamilyDiscrepancy[ONEWIRE_NUM];
static uint8_t LastDeviceFlag[ONEWIRE_NUM];
void onewire_init(uint8_t pin)
{
gpio_enable(pin, GPIO_INPUT);
onewire_reset_search(pin);
}
#include "string.h"
#include "task.h"
#include "esp/gpio.h"
// Perform the onewire reset function. We will wait up to 250uS for
// the bus to come high, if it doesn't then it is broken or shorted
// and we return a 0;
// and we return false;
//
// Returns 1 if a device asserted a presence pulse, 0 otherwise.
// Returns true if a device asserted a presence pulse, false otherwise.
//
uint8_t onewire_reset(uint8_t pin)
{
uint8_t r;
uint8_t retries = 125;
bool onewire_reset(int pin) {
bool r;
const int retries = 50;
noInterrupts();
DIRECT_MODE_INPUT(pin);
interrupts();
// wait until the wire is high... just in case
do {
if (--retries == 0) return 0;
delayMicroseconds(2);
} while ( !DIRECT_READ(pin));
gpio_enable(pin, GPIO_OUT_OPEN_DRAIN);
gpio_write(pin, 1);
// wait until the wire is high... just in case
for (int i = 0; i < retries; i++) {
if (gpio_read(pin)) break;
sdk_os_delay_us(5);
}
if (!gpio_read(pin)) {
// Bus shorted?
return false;
}
noInterrupts();
DIRECT_WRITE_LOW(pin);
DIRECT_MODE_OUTPUT(pin); // drive output low
interrupts();
delayMicroseconds(480);
noInterrupts();
DIRECT_MODE_INPUT(pin); // allow it to float
delayMicroseconds(70);
r = !DIRECT_READ(pin);
interrupts();
delayMicroseconds(410);
return r;
gpio_write(pin, 0);
sdk_os_delay_us(480);
taskENTER_CRITICAL();
gpio_write(pin, 1); // allow it to float
sdk_os_delay_us(70);
r = !gpio_read(pin);
taskEXIT_CRITICAL();
// Wait for all devices to finish pulling the bus low before returning
for (int i = 0; i < retries; i++) {
if (gpio_read(pin)) break;
sdk_os_delay_us(5);
}
sdk_os_delay_us(2);
return r;
}
// Write a bit. Port and bit is used to cut lookup time and provide
// more certain timing.
//
static void onewire_write_bit(uint8_t pin, uint8_t v)
{
if (v & 1) {
noInterrupts();
DIRECT_WRITE_LOW(pin);
DIRECT_MODE_OUTPUT(pin); // drive output low
delayMicroseconds(10);
DIRECT_WRITE_HIGH(pin); // drive output high
interrupts();
delayMicroseconds(55);
} else {
noInterrupts();
DIRECT_WRITE_LOW(pin);
DIRECT_MODE_OUTPUT(pin); // drive output low
delayMicroseconds(65);
DIRECT_WRITE_HIGH(pin); // drive output high
interrupts();
delayMicroseconds(5);
}
static void onewire_write_bit(int pin, uint8_t v) {
//TODO: should verify that the bus is high before starting
if (v & 1) {
taskENTER_CRITICAL();
gpio_write(pin, 0); // drive output low
sdk_os_delay_us(10);
gpio_write(pin, 1); // allow output high
taskEXIT_CRITICAL();
sdk_os_delay_us(55);
} else {
taskENTER_CRITICAL();
gpio_write(pin, 0); // drive output low
sdk_os_delay_us(65);
gpio_write(pin, 1); // allow output high
taskEXIT_CRITICAL();
}
sdk_os_delay_us(1);
}
// Read a bit. Port and bit is used to cut lookup time and provide
// more certain timing.
//
static uint8_t onewire_read_bit(uint8_t pin)
{
uint8_t r;
static int onewire_read_bit(int pin) {
int r;
noInterrupts();
DIRECT_MODE_OUTPUT(pin);
DIRECT_WRITE_LOW(pin);
delayMicroseconds(3);
DIRECT_MODE_INPUT(pin); // let pin float, pull up will raise
delayMicroseconds(10);
r = DIRECT_READ(pin);
interrupts();
delayMicroseconds(53);
return r;
//TODO: should verify that the bus is high before starting
taskENTER_CRITICAL();
gpio_write(pin, 0);
sdk_os_delay_us(2);
gpio_write(pin, 1); // let pin float, pull up will raise
sdk_os_delay_us(11);
r = gpio_read(pin); // Must sample within 15us of start
taskEXIT_CRITICAL();
sdk_os_delay_us(48);
return r;
}
// Write a byte. The writing code uses the active drivers to raise the
// pin high, if you need power after the write (e.g. DS18S20 in
// parasite power mode) then set 'power' to 1, otherwise the pin will
// go tri-state at the end of the write to avoid heating in a short or
// other mishap.
// Write a byte. The writing code uses open-drain mode and expects the pullup
// resistor to pull the line high when not driven low. If you need strong
// power after the write (e.g. DS18B20 in parasite power mode) then call
// onewire_power() after this is complete to actively drive the line high.
//
void onewire_write(uint8_t pin, uint8_t v, uint8_t power /* = 0 */) {
uint8_t bitMask;
void onewire_write(int pin, uint8_t v) {
uint8_t bitMask;
for (bitMask = 0x01; bitMask; bitMask <<= 1) {
onewire_write_bit(pin, (bitMask & v)?1:0);
}
if ( !power) {
noInterrupts();
DIRECT_MODE_INPUT(pin);
DIRECT_WRITE_LOW(pin);
interrupts();
}
for (bitMask = 0x01; bitMask; bitMask <<= 1) {
onewire_write_bit(pin, (bitMask & v)?1:0);
}
}
void onewire_write_bytes(uint8_t pin, const uint8_t *buf, uint16_t count, bool power /* = 0 */) {
uint16_t i;
for (i = 0 ; i < count ; i++)
onewire_write(pin, buf[i], ONEWIRE_DEFAULT_POWER);
if (!power) {
noInterrupts();
DIRECT_MODE_INPUT(pin);
DIRECT_WRITE_LOW(pin);
interrupts();
}
void onewire_write_bytes(int pin, const uint8_t *buf, size_t count) {
size_t i;
for (i = 0 ; i < count ; i++) {
onewire_write(pin, buf[i]);
}
}
// Read a byte
//
uint8_t onewire_read(uint8_t pin) {
uint8_t bitMask;
uint8_t r = 0;
uint8_t onewire_read(int pin) {
uint8_t bitMask;
uint8_t r = 0;
for (bitMask = 0x01; bitMask; bitMask <<= 1) {
if (onewire_read_bit(pin)) r |= bitMask;
}
return r;
for (bitMask = 0x01; bitMask; bitMask <<= 1) {
if (onewire_read_bit(pin)) r |= bitMask;
}
return r;
}
void onewire_read_bytes(uint8_t pin, uint8_t *buf, uint16_t count) {
uint16_t i;
for (i = 0 ; i < count ; i++)
buf[i] = onewire_read(pin);
void onewire_read_bytes(int pin, uint8_t *buf, size_t count) {
size_t i;
for (i = 0 ; i < count ; i++) {
buf[i] = onewire_read(pin);
}
}
// Do a ROM select
//
void onewire_select(uint8_t pin, const uint8_t rom[8])
{
void onewire_select(int pin, onewire_addr_t rom) {
uint8_t i;
onewire_write(pin, 0x55, ONEWIRE_DEFAULT_POWER); // Choose ROM
onewire_write(pin, 0x55); // Choose ROM
for (i = 0; i < 8; i++) onewire_write(pin, rom[i], ONEWIRE_DEFAULT_POWER);
for (i = 0; i < 8; i++) {
onewire_write(pin, rom & 0xff);
rom >>= 8;
}
}
// Do a ROM skip
//
void onewire_skip(uint8_t pin)
{
onewire_write(pin, 0xCC, ONEWIRE_DEFAULT_POWER); // Skip ROM
void onewire_skip_rom(int pin) {
onewire_write(pin, 0xCC); // Skip ROM
}
void onewire_depower(uint8_t pin)
{
noInterrupts();
DIRECT_MODE_INPUT(pin);
interrupts();
void onewire_power(int pin) {
gpio_enable(pin, GPIO_OUTPUT);
gpio_write(pin, 1);
}
// You need to use this function to start a search again from the beginning.
// You do not need to do it for the first search, though you could.
//
void onewire_reset_search(uint8_t pin)
{
// reset the search state
LastDiscrepancy[pin] = 0;
LastDeviceFlag[pin] = 0;
LastFamilyDiscrepancy[pin] = 0;
int i;
for(i = 7; ; i--) {
ROM_NO[pin][i] = 0;
if ( i == 0) break;
}
void onewire_depower(int pin) {
gpio_enable(pin, GPIO_OUT_OPEN_DRAIN);
}
void onewire_search_start(onewire_search_t *search) {
// reset the search state
memset(search, 0, sizeof(*search));
}
// Setup the search to find the device type 'family_code' on the next call
// to search(*newAddr) if it is present.
//
void onewire_target_search(uint8_t pin, uint8_t family_code)
{
// set the search state to find SearchFamily type devices
ROM_NO[pin][0] = family_code;
uint8_t i;
for (i = 1; i < 8; i++)
ROM_NO[pin][i] = 0;
LastDiscrepancy[pin] = 64;
LastFamilyDiscrepancy[pin] = 0;
LastDeviceFlag[pin] = 0;
void onewire_search_prefix(onewire_search_t *search, uint8_t family_code) {
uint8_t i;
search->rom_no[0] = family_code;
for (i = 1; i < 8; i++) {
search->rom_no[i] = 0;
}
search->last_discrepancy = 64;
search->last_device_found = false;
}
// Perform a search. If this function returns a '1' then it has
// enumerated the next device and you may retrieve the ROM from the
// OneWire::address variable. If there are no devices, no further
// Perform a search. If the next device has been successfully enumerated, its
// ROM address will be returned. If there are no devices, no further
// devices, or something horrible happens in the middle of the
// enumeration then a 0 is returned. If a new device is found then
// its address is copied to newAddr. Use OneWire::reset_search() to
// enumeration then ONEWIRE_NONE is returned. Use OneWire::reset_search() to
// start over.
//
// --- Replaced by the one from the Dallas Semiconductor web site ---
@ -210,129 +180,115 @@ void onewire_target_search(uint8_t pin, uint8_t family_code)
// Return 1 : device found, ROM number in ROM_NO buffer
// 0 : device not found, end of search
//
uint8_t onewire_search(uint8_t pin, uint8_t *newAddr)
{
uint8_t id_bit_number;
uint8_t last_zero, rom_byte_number, search_result;
uint8_t id_bit, cmp_id_bit;
onewire_addr_t onewire_search_next(onewire_search_t *search, int pin) {
uint8_t id_bit_number;
uint8_t last_zero, search_result;
int rom_byte_number;
uint8_t id_bit, cmp_id_bit;
onewire_addr_t addr;
unsigned char rom_byte_mask, search_direction;
unsigned char rom_byte_mask, search_direction;
// initialize for search
id_bit_number = 1;
last_zero = 0;
rom_byte_number = 0;
rom_byte_mask = 1;
search_result = 0;
// initialize for search
id_bit_number = 1;
last_zero = 0;
rom_byte_number = 0;
rom_byte_mask = 1;
search_result = 0;
// if the last call was not the last one
if (!LastDeviceFlag[pin])
{
// 1-Wire reset
if (!onewire_reset(pin))
{
// reset the search
LastDiscrepancy[pin] = 0;
LastDeviceFlag[pin] = 0;
LastFamilyDiscrepancy[pin] = 0;
return 0;
}
// if the last call was not the last one
if (!search->last_device_found) {
// 1-Wire reset
if (!onewire_reset(pin)) {
// reset the search
search->last_discrepancy = 0;
search->last_device_found = false;
return ONEWIRE_NONE;
}
// issue the search command
onewire_write(pin, 0xF0, ONEWIRE_DEFAULT_POWER);
// issue the search command
onewire_write(pin, 0xF0);
// loop to do the search
do
{
// read a bit and its complement
id_bit = onewire_read_bit(pin);
cmp_id_bit = onewire_read_bit(pin);
// loop to do the search
do {
// read a bit and its complement
id_bit = onewire_read_bit(pin);
cmp_id_bit = onewire_read_bit(pin);
// check for no devices on 1-wire
if ((id_bit == 1) && (cmp_id_bit == 1))
break;
else
{
// all devices coupled have 0 or 1
if (id_bit != cmp_id_bit)
search_direction = id_bit; // bit write value for search
else
{
// if this discrepancy if before the Last Discrepancy
// on a previous next then pick the same as last time
if (id_bit_number < LastDiscrepancy[pin])
search_direction = ((ROM_NO[pin][rom_byte_number] & rom_byte_mask) > 0);
else
// if equal to last pick 1, if not then pick 0
search_direction = (id_bit_number == LastDiscrepancy[pin]);
// check for no devices on 1-wire
if ((id_bit == 1) && (cmp_id_bit == 1)) {
break;
} else {
// all devices coupled have 0 or 1
if (id_bit != cmp_id_bit) {
search_direction = id_bit; // bit write value for search
} else {
// if this discrepancy if before the Last Discrepancy
// on a previous next then pick the same as last time
if (id_bit_number < search->last_discrepancy) {
search_direction = ((search->rom_no[rom_byte_number] & rom_byte_mask) > 0);
} else {
// if equal to last pick 1, if not then pick 0
search_direction = (id_bit_number == search->last_discrepancy);
}
// if 0 was picked then record its position in LastZero
if (search_direction == 0)
{
last_zero = id_bit_number;
// if 0 was picked then record its position in LastZero
if (search_direction == 0) {
last_zero = id_bit_number;
}
}
// check for Last discrepancy in family
if (last_zero < 9)
LastFamilyDiscrepancy[pin] = last_zero;
}
// set or clear the bit in the ROM byte rom_byte_number
// with mask rom_byte_mask
if (search_direction == 1) {
search->rom_no[rom_byte_number] |= rom_byte_mask;
} else {
search->rom_no[rom_byte_number] &= ~rom_byte_mask;
}
// serial number search direction write bit
onewire_write_bit(pin, search_direction);
// increment the byte counter id_bit_number
// and shift the mask rom_byte_mask
id_bit_number++;
rom_byte_mask <<= 1;
// if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
if (rom_byte_mask == 0) {
rom_byte_number++;
rom_byte_mask = 1;
}
}
} while (rom_byte_number < 8); // loop until through all ROM bytes 0-7
// if the search was successful then
if (!(id_bit_number < 65)) {
// search successful so set last_discrepancy,last_device_found,search_result
search->last_discrepancy = last_zero;
// check for last device
if (search->last_discrepancy == 0) {
search->last_device_found = true;
}
// set or clear the bit in the ROM byte rom_byte_number
// with mask rom_byte_mask
if (search_direction == 1)
ROM_NO[pin][rom_byte_number] |= rom_byte_mask;
else
ROM_NO[pin][rom_byte_number] &= ~rom_byte_mask;
search_result = 1;
}
}
// serial number search direction write bit
onewire_write_bit(pin, search_direction);
// increment the byte counter id_bit_number
// and shift the mask rom_byte_mask
id_bit_number++;
rom_byte_mask <<= 1;
// if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
if (rom_byte_mask == 0)
{
rom_byte_number++;
rom_byte_mask = 1;
}
}
}
while(rom_byte_number < 8); // loop until through all ROM bytes 0-7
// if the search was successful then
if (!(id_bit_number < 65))
{
// search successful so set LastDiscrepancy,LastDeviceFlag,search_result
LastDiscrepancy[pin] = last_zero;
// check for last device
if (LastDiscrepancy[pin] == 0)
LastDeviceFlag[pin] = 1;
search_result = 1;
}
}
// if no device found then reset counters so next 'search' will be like a first
if (!search_result || !ROM_NO[pin][0])
{
LastDiscrepancy[pin] = 0;
LastDeviceFlag[pin] = 0;
LastFamilyDiscrepancy[pin] = 0;
search_result = 0;
}
else
{
for (rom_byte_number = 0; rom_byte_number < 8; rom_byte_number++)
{
newAddr[rom_byte_number] = ROM_NO[pin][rom_byte_number];
//printf("Ok I found something at %d - %x...\n",rom_byte_number, newAddr[rom_byte_number]);
}
}
return search_result;
// if no device found then reset counters so next 'search' will be like a first
if (!search_result || !search->rom_no[0]) {
search->last_discrepancy = 0;
search->last_device_found = false;
return ONEWIRE_NONE;
} else {
addr = 0;
for (rom_byte_number = 7; rom_byte_number >= 0; rom_byte_number--) {
addr = (addr << 8) | search->rom_no[rom_byte_number];
}
//printf("Ok I found something at %08x%08x...\n", (uint32_t)(addr >> 32), (uint32_t)addr);
}
return addr;
}
// The 1-Wire CRC scheme is described in Maxim Application Note 27:
@ -371,41 +327,38 @@ static const uint8_t dscrc_table[] = {
// compared to all those delayMicrosecond() calls. But I got
// confused, so I use this table from the examples.)
//
uint8_t onewire_crc8(const uint8_t *addr, uint8_t len)
{
uint8_t crc = 0;
uint8_t onewire_crc8(const uint8_t *data, uint8_t len) {
uint8_t crc = 0;
while (len--) {
crc = pgm_read_byte(dscrc_table + (crc ^ *addr++));
}
return crc;
while (len--) {
crc = pgm_read_byte(dscrc_table + (crc ^ *data++));
}
return crc;
}
#else
//
// Compute a Dallas Semiconductor 8 bit CRC directly.
// this is much slower, but much smaller, than the lookup table.
//
uint8_t onewire_crc8(const uint8_t *addr, uint8_t len)
{
uint8_t crc = 0;
while (len--) {
uint8_t inbyte = *addr++;
uint8_t i;
for (i = 8; i; i--) {
uint8_t mix = (crc ^ inbyte) & 0x01;
crc >>= 1;
if (mix) crc ^= 0x8C;
inbyte >>= 1;
}
}
return crc;
uint8_t onewire_crc8(const uint8_t *data, uint8_t len) {
uint8_t crc = 0;
while (len--) {
uint8_t inbyte = *data++;
for (int i = 8; i; i--) {
uint8_t mix = (crc ^ inbyte) & 0x01;
crc >>= 1;
if (mix) crc ^= 0x8C;
inbyte >>= 1;
}
}
return crc;
}
#endif
// Compute the 1-Wire CRC16 and compare it against the received CRC.
// Example usage (reading a DS2408):
// // Put everything in a buffer so we can compute the CRC easily.
// // Put everything in a buffer so we can compute the CRC easily.
// uint8_t buf[13];
// buf[0] = 0xF0; // Read PIO Registers
// buf[1] = 0x88; // LSB address
@ -423,9 +376,8 @@ uint8_t onewire_crc8(const uint8_t *addr, uint8_t len)
// *not* at a 16-bit integer.
// @param crc - The crc starting value (optional)
// @return 1, iff the CRC matches.
bool onewire_check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc)
{
crc = ~onewire_crc16(input, len, crc);
bool onewire_check_crc16(const uint8_t* input, size_t len, const uint8_t* inverted_crc, uint16_t crc_iv) {
uint16_t crc = ~onewire_crc16(input, len, crc_iv);
return (crc & 0xFF) == inverted_crc[0] && (crc >> 8) == inverted_crc[1];
}
@ -441,8 +393,8 @@ bool onewire_check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inve
// @param len - How many bytes to use.
// @param crc - The crc starting value (optional)
// @return The CRC16, as defined by Dallas Semiconductor.
uint16_t onewire_crc16(const uint8_t* input, uint16_t len, uint16_t crc)
{
uint16_t onewire_crc16(const uint8_t* input, size_t len, uint16_t crc_iv) {
uint16_t crc = crc_iv;
static const uint8_t oddparity[16] =
{ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
@ -463,4 +415,4 @@ uint16_t onewire_crc16(const uint8_t* input, uint16_t len, uint16_t crc)
crc ^= cdata;
}
return crc;
}
}

View file

@ -29,75 +29,72 @@
#define ONEWIRE_CRC8_TABLE 0
#endif
// Platform specific I/O definitions
#define noInterrupts portDISABLE_INTERRUPTS
#define interrupts portENABLE_INTERRUPTS
#define delayMicroseconds sdk_os_delay_us
typedef uint64_t onewire_addr_t;
#define DIRECT_READ(pin) gpio_read(pin)
#define DIRECT_MODE_INPUT(pin) gpio_enable(pin, GPIO_INPUT)
#define DIRECT_MODE_OUTPUT(pin) gpio_enable(pin, GPIO_OUTPUT)
#define DIRECT_WRITE_LOW(pin) gpio_write(pin, 0)
#define DIRECT_WRITE_HIGH(pin) gpio_write(pin, 1)
typedef struct {
uint8_t rom_no[8];
uint8_t last_discrepancy;
bool last_device_found;
} onewire_search_t;
void onewire_init(uint8_t pin);
// The following is an invalid ROM address that will never occur in a device
// (CRC mismatch), and so can be useful as an indicator for "no-such-device",
// etc.
#define ONEWIRE_NONE ((onewire_addr_t)(0xffffffffffffffffLL))
// Perform a 1-Wire reset cycle. Returns 1 if a device responds
// with a presence pulse. Returns 0 if there is no device or the
// bus is shorted or otherwise held low for more than 250uS
uint8_t onewire_reset(uint8_t pin);
bool onewire_reset(int pin);
// Issue a 1-Wire rom select command, you do the reset first.
void onewire_select(uint8_t pin, const uint8_t rom[8]);
void onewire_select(int pin, const onewire_addr_t rom);
// Issue a 1-Wire rom skip command, to address all on bus.
void onewire_skip(uint8_t pin);
void onewire_skip_rom(int pin);
// Write a byte. If 'power' is one then the wire is held high at
// the end for parasitically powered devices. You are responsible
// for eventually depowering it by calling depower() or doing
// another read or write.
void onewire_write(uint8_t pin, uint8_t v, uint8_t power);
// Write a byte. The writing code uses open-drain mode and expects the pullup
// resistor to pull the line high when not driven low. If you need strong
// power after the write (e.g. DS18B20 in parasite power mode) then call
// onewire_power() after this is complete to actively drive the line high.
void onewire_write(int pin, uint8_t v);
void onewire_write_bytes(uint8_t pin, const uint8_t *buf, uint16_t count, bool power);
void onewire_write_bytes(int pin, const uint8_t *buf, size_t count);
// Read a byte.
uint8_t onewire_read(uint8_t pin);
uint8_t onewire_read(int pin);
void onewire_read_bytes(uint8_t pin, uint8_t *buf, uint16_t count);
void onewire_read_bytes(int pin, uint8_t *buf, size_t count);
// Write a bit. The bus is always left powered at the end, see
// note in write() about that.
// void onewire_write_bit(uint8_t pin, uint8_t v);
// Read a bit.
// uint8_t onewire_read_bit(uint8_t pin);
// Actively drive the bus high to provide extra power for certain operations of
// parasitically-powered devices.
void onewire_power(int pin);
// Stop forcing power onto the bus. You only need to do this if
// you used the 'power' flag to write() or used a write_bit() call
// and aren't about to do another read or write. You would rather
// not leave this powered if you don't have to, just in case
// someone shorts your bus.
void onewire_depower(uint8_t pin);
// you previously called onewire_power() to drive the bus high and now want to
// allow it to float instead. Note that onewire_reset() will also
// automatically depower the bus first, so you do not need to call this first
// if you just want to start a new operation.
void onewire_depower(int pin);
// Clear the search state so that if will start from the beginning again.
void onewire_reset_search(uint8_t pin);
void onewire_search_start(onewire_search_t *search);
// Setup the search to find the device type 'family_code' on the next call
// to search(*newAddr) if it is present.
void onewire_target_search(uint8_t pin, uint8_t family_code);
void onewire_search_prefix(onewire_search_t *search, uint8_t family_code);
// Look for the next device. Returns 1 if a new address has been
// returned. A zero might mean that the bus is shorted, there are
// no devices, or you have already retrieved all of them. It
// might be a good idea to check the CRC to make sure you didn't
// get garbage. The order is deterministic. You will always get
// the same devices in the same order.
uint8_t onewire_search(uint8_t pin, uint8_t *newAddr);
// Look for the next device. Returns the address of the next device on the bus,
// or ONEWIRE_NONE if there is no next address. ONEWIRE_NONE might mean that
// the bus is shorted, there are no devices, or you have already retrieved all
// of them. It might be a good idea to check the CRC to make sure you didn't
// get garbage. The order is deterministic. You will always get the same
// devices in the same order.
onewire_addr_t onewire_search_next(onewire_search_t *search, int pin);
// Compute a Dallas Semiconductor 8 bit CRC, these are used in the
// ROM and scratchpad registers.
uint8_t onewire_crc8(const uint8_t *addr, uint8_t len);
uint8_t onewire_crc8(const uint8_t *data, uint8_t len);
// Compute the 1-Wire CRC16 and compare it against the received CRC.
// Example usage (reading a DS2408):
@ -117,9 +114,9 @@ uint8_t onewire_crc8(const uint8_t *addr, uint8_t len);
// @param inverted_crc - The two CRC16 bytes in the received data.
// This should just point into the received data,
// *not* at a 16-bit integer.
// @param crc - The crc starting value (optional)
// @param crc_iv - The crc starting value (optional)
// @return True, iff the CRC matches.
bool onewire_check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc);
bool onewire_check_crc16(const uint8_t* input, size_t len, const uint8_t* inverted_crc, uint16_t crc_iv);
// Compute a Dallas Semiconductor 16 bit CRC. This is required to check
// the integrity of data received from many 1-Wire devices. Note that the
@ -131,8 +128,8 @@ bool onewire_check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inve
// byte order than the two bytes you get from 1-Wire.
// @param input - Array of bytes to checksum.
// @param len - How many bytes to use.
// @param crc - The crc starting value (optional)
// @param crc_iv - The crc starting value (optional)
// @return The CRC16, as defined by Dallas Semiconductor.
uint16_t onewire_crc16(const uint8_t* input, uint16_t len, uint16_t crc);
uint16_t onewire_crc16(const uint8_t* input, size_t len, uint16_t crc_iv);
#endif