123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580 |
- #include <Arduino.h>
- #include "OneWire.h"
- #include "util/OneWire_direct_gpio.h"
- void OneWire::begin(uint8_t pin)
- {
- pinMode(pin, INPUT);
- bitmask = PIN_TO_BITMASK(pin);
- baseReg = PIN_TO_BASEREG(pin);
- #if ONEWIRE_SEARCH
- reset_search();
- #endif
- }
- uint8_t OneWire::reset(void)
- {
- IO_REG_TYPE mask IO_REG_MASK_ATTR = bitmask;
- volatile IO_REG_TYPE *reg IO_REG_BASE_ATTR = baseReg;
- uint8_t r;
- uint8_t retries = 125;
- noInterrupts();
- DIRECT_MODE_INPUT(reg, mask);
- interrupts();
-
- do {
- if (--retries == 0) return 0;
- delayMicroseconds(2);
- } while ( !DIRECT_READ(reg, mask));
- noInterrupts();
- DIRECT_WRITE_LOW(reg, mask);
- DIRECT_MODE_OUTPUT(reg, mask);
- interrupts();
- delayMicroseconds(480);
- noInterrupts();
- DIRECT_MODE_INPUT(reg, mask);
- delayMicroseconds(70);
- r = !DIRECT_READ(reg, mask);
- interrupts();
- delayMicroseconds(410);
- return r;
- }
- void OneWire::write_bit(uint8_t v)
- {
- IO_REG_TYPE mask IO_REG_MASK_ATTR = bitmask;
- volatile IO_REG_TYPE *reg IO_REG_BASE_ATTR = baseReg;
- if (v & 1) {
- noInterrupts();
- DIRECT_WRITE_LOW(reg, mask);
- DIRECT_MODE_OUTPUT(reg, mask);
- delayMicroseconds(10);
- DIRECT_WRITE_HIGH(reg, mask);
- interrupts();
- delayMicroseconds(55);
- } else {
- noInterrupts();
- DIRECT_WRITE_LOW(reg, mask);
- DIRECT_MODE_OUTPUT(reg, mask);
- delayMicroseconds(65);
- DIRECT_WRITE_HIGH(reg, mask);
- interrupts();
- delayMicroseconds(5);
- }
- }
- uint8_t OneWire::read_bit(void)
- {
- IO_REG_TYPE mask IO_REG_MASK_ATTR = bitmask;
- volatile IO_REG_TYPE *reg IO_REG_BASE_ATTR = baseReg;
- uint8_t r;
- noInterrupts();
- DIRECT_MODE_OUTPUT(reg, mask);
- DIRECT_WRITE_LOW(reg, mask);
- delayMicroseconds(3);
- DIRECT_MODE_INPUT(reg, mask);
- delayMicroseconds(10);
- r = DIRECT_READ(reg, mask);
- interrupts();
- delayMicroseconds(53);
- return r;
- }
- void OneWire::write(uint8_t v, uint8_t power ) {
- uint8_t bitMask;
- for (bitMask = 0x01; bitMask; bitMask <<= 1) {
- OneWire::write_bit( (bitMask & v)?1:0);
- }
- if ( !power) {
- noInterrupts();
- DIRECT_MODE_INPUT(baseReg, bitmask);
- DIRECT_WRITE_LOW(baseReg, bitmask);
- interrupts();
- }
- }
- void OneWire::write_bytes(const uint8_t *buf, uint16_t count, bool power ) {
- for (uint16_t i = 0 ; i < count ; i++)
- write(buf[i]);
- if (!power) {
- noInterrupts();
- DIRECT_MODE_INPUT(baseReg, bitmask);
- DIRECT_WRITE_LOW(baseReg, bitmask);
- interrupts();
- }
- }
- uint8_t OneWire::read() {
- uint8_t bitMask;
- uint8_t r = 0;
- for (bitMask = 0x01; bitMask; bitMask <<= 1) {
- if ( OneWire::read_bit()) r |= bitMask;
- }
- return r;
- }
- void OneWire::read_bytes(uint8_t *buf, uint16_t count) {
- for (uint16_t i = 0 ; i < count ; i++)
- buf[i] = read();
- }
- void OneWire::select(const uint8_t rom[8])
- {
- uint8_t i;
- write(0x55);
- for (i = 0; i < 8; i++) write(rom[i]);
- }
- void OneWire::skip()
- {
- write(0xCC);
- }
- void OneWire::depower()
- {
- noInterrupts();
- DIRECT_MODE_INPUT(baseReg, bitmask);
- interrupts();
- }
- #if ONEWIRE_SEARCH
- void OneWire::reset_search()
- {
-
- LastDiscrepancy = 0;
- LastDeviceFlag = false;
- LastFamilyDiscrepancy = 0;
- for(int i = 7; ; i--) {
- ROM_NO[i] = 0;
- if ( i == 0) break;
- }
- }
- void OneWire::target_search(uint8_t family_code)
- {
-
- ROM_NO[0] = family_code;
- for (uint8_t i = 1; i < 8; i++)
- ROM_NO[i] = 0;
- LastDiscrepancy = 64;
- LastFamilyDiscrepancy = 0;
- LastDeviceFlag = false;
- }
- bool OneWire::search(uint8_t *newAddr, bool search_mode )
- {
- uint8_t id_bit_number;
- uint8_t last_zero, rom_byte_number;
- bool search_result;
- uint8_t id_bit, cmp_id_bit;
- unsigned char rom_byte_mask, search_direction;
-
- id_bit_number = 1;
- last_zero = 0;
- rom_byte_number = 0;
- rom_byte_mask = 1;
- search_result = false;
-
- if (!LastDeviceFlag) {
-
- if (!reset()) {
-
- LastDiscrepancy = 0;
- LastDeviceFlag = false;
- LastFamilyDiscrepancy = 0;
- return false;
- }
-
- if (search_mode == true) {
- write(0xF0);
- } else {
- write(0xEC);
- }
-
- do
- {
-
- id_bit = read_bit();
- cmp_id_bit = read_bit();
-
- if ((id_bit == 1) && (cmp_id_bit == 1)) {
- break;
- } else {
-
- if (id_bit != cmp_id_bit) {
- search_direction = id_bit;
- } else {
-
-
- if (id_bit_number < LastDiscrepancy) {
- search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0);
- } else {
-
- search_direction = (id_bit_number == LastDiscrepancy);
- }
-
- if (search_direction == 0) {
- last_zero = id_bit_number;
-
- if (last_zero < 9)
- LastFamilyDiscrepancy = last_zero;
- }
- }
-
-
- if (search_direction == 1)
- ROM_NO[rom_byte_number] |= rom_byte_mask;
- else
- ROM_NO[rom_byte_number] &= ~rom_byte_mask;
-
- write_bit(search_direction);
-
-
- id_bit_number++;
- rom_byte_mask <<= 1;
-
- if (rom_byte_mask == 0) {
- rom_byte_number++;
- rom_byte_mask = 1;
- }
- }
- }
- while(rom_byte_number < 8);
-
- if (!(id_bit_number < 65)) {
-
- LastDiscrepancy = last_zero;
-
- if (LastDiscrepancy == 0) {
- LastDeviceFlag = true;
- }
- search_result = true;
- }
- }
-
- if (!search_result || !ROM_NO[0]) {
- LastDiscrepancy = 0;
- LastDeviceFlag = false;
- LastFamilyDiscrepancy = 0;
- search_result = false;
- } else {
- for (int i = 0; i < 8; i++) newAddr[i] = ROM_NO[i];
- }
- return search_result;
- }
- #endif
- #if ONEWIRE_CRC
- #if ONEWIRE_CRC8_TABLE
- static const uint8_t PROGMEM dscrc2x16_table[] = {
- 0x00, 0x5E, 0xBC, 0xE2, 0x61, 0x3F, 0xDD, 0x83,
- 0xC2, 0x9C, 0x7E, 0x20, 0xA3, 0xFD, 0x1F, 0x41,
- 0x00, 0x9D, 0x23, 0xBE, 0x46, 0xDB, 0x65, 0xF8,
- 0x8C, 0x11, 0xAF, 0x32, 0xCA, 0x57, 0xE9, 0x74
- };
- uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len)
- {
- uint8_t crc = 0;
- while (len--) {
- crc = *addr++ ^ crc;
- crc = pgm_read_byte(dscrc2x16_table + (crc & 0x0f)) ^
- pgm_read_byte(dscrc2x16_table + 16 + ((crc >> 4) & 0x0f));
- }
- return crc;
- }
- #else
- uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len)
- {
- uint8_t crc = 0;
- while (len--) {
- #if defined(__AVR__)
- crc = _crc_ibutton_update(crc, *addr++);
- #else
- uint8_t inbyte = *addr++;
- for (uint8_t i = 8; i; i--) {
- uint8_t mix = (crc ^ inbyte) & 0x01;
- crc >>= 1;
- if (mix) crc ^= 0x8C;
- inbyte >>= 1;
- }
- #endif
- }
- return crc;
- }
- #endif
- #if ONEWIRE_CRC16
- bool OneWire::check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc)
- {
- crc = ~crc16(input, len, crc);
- return (crc & 0xFF) == inverted_crc[0] && (crc >> 8) == inverted_crc[1];
- }
- uint16_t OneWire::crc16(const uint8_t* input, uint16_t len, uint16_t crc)
- {
- #if defined(__AVR__)
- for (uint16_t i = 0 ; i < len ; i++) {
- crc = _crc16_update(crc, input[i]);
- }
- #else
- static const uint8_t oddparity[16] =
- { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
- for (uint16_t i = 0 ; i < len ; i++) {
-
-
- uint16_t cdata = input[i];
- cdata = (cdata ^ crc) & 0xff;
- crc >>= 8;
- if (oddparity[cdata & 0x0F] ^ oddparity[cdata >> 4])
- crc ^= 0xC001;
- cdata <<= 6;
- crc ^= cdata;
- cdata <<= 1;
- crc ^= cdata;
- }
- #endif
- return crc;
- }
- #endif
- #endif
|