replace OneWire

This commit is contained in:
MichaelDvP
2022-05-02 11:19:48 +02:00
parent dc9c21fc65
commit 0c6c7f999f
4 changed files with 484 additions and 565 deletions

View File

@@ -1,4 +1,8 @@
/* /*
taken from:s
https://github.com/arendst/Tasmota/blob/development/lib/lib_basic/OneWire-Stickbreaker/OneWire.cpp
modified for ems-esp old lib compatibility
Copyright (c) 2007, Jim Studt (original old version - many contributors since) Copyright (c) 2007, Jim Studt (original old version - many contributors since)
The latest version of this library may be found at: The latest version of this library may be found at:
@@ -32,6 +36,17 @@ private email about OneWire).
OneWire is now very mature code. No changes other than adding OneWire is now very mature code. No changes other than adding
definitions for newer hardware support are anticipated. definitions for newer hardware support are anticipated.
=======
Version 2.3.3 ESP32 Stickbreaker 06MAY2019
Add a #ifdef to isolate ESP32 mods
Version 2.3.1 ESP32 everslick 30APR2018
add IRAM_ATTR attribute to write_bit/read_bit to fix icache miss delay
https://github.com/espressif/arduino-esp32/issues/1335
Version 2.3 ESP32 stickbreaker 28DEC2017
adjust to use portENTER_CRITICAL(&mux) instead of noInterrupts();
adjust to use portEXIT_CRITICAL(&mux) instead of Interrupts();
Version 2.3: Version 2.3:
Unknown chip fallback mode, Roger Clark Unknown chip fallback mode, Roger Clark
Teensy-LC compatibility, Paul Stoffregen Teensy-LC compatibility, Paul Stoffregen
@@ -139,12 +154,20 @@ sample code bearing this copyright.
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
*/ */
#include <Arduino.h>
#include "OneWire.h" #include "OneWire.h"
#include "OneWire_direct_gpio.h"
#pragma GCC diagnostic push #ifdef ESP32
#pragma GCC diagnostic ignored "-Wunused-variable" #define t_noInterrupts() \
{ \
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; \
portENTER_CRITICAL(&mux)
#define t_interrupts() \
portEXIT_CRITICAL(&mux); \
}
#else
#define t_noInterrupts noInterrupts
#define t_interrupts interrupts
#endif
void OneWire::begin(uint8_t pin) { void OneWire::begin(uint8_t pin) {
pinMode(pin, INPUT); pinMode(pin, INPUT);
@@ -155,6 +178,7 @@ void OneWire::begin(uint8_t pin) {
#endif #endif
} }
// Perform the onewire reset function. We will wait up to 250uS for // 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 // the bus to come high, if it doesn't then it is broken or shorted
// and we return a 0; // and we return a 0;
@@ -162,18 +186,18 @@ void OneWire::begin(uint8_t pin) {
// Returns 1 if a device asserted a presence pulse, 0 otherwise. // Returns 1 if a device asserted a presence pulse, 0 otherwise.
// //
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
uint8_t IRAM_ATTR OneWire::reset(void) { uint8_t IRAM_ATTR OneWire::reset(void)
#else #else
uint8_t OneWire::reset(void) { uint8_t OneWire::reset(void)
#endif #endif
{
IO_REG_TYPE mask IO_REG_MASK_ATTR = bitmask; IO_REG_TYPE mask IO_REG_MASK_ATTR = bitmask;
volatile IO_REG_TYPE * reg IO_REG_BASE_ATTR = baseReg; volatile IO_REG_TYPE * reg IO_REG_BASE_ATTR = baseReg;
uint8_t r; uint8_t r;
uint8_t retries = 125; uint8_t retries = 125;
t_noInterrupts();
noInterrupts();
DIRECT_MODE_INPUT(reg, mask); DIRECT_MODE_INPUT(reg, mask);
interrupts(); t_interrupts();
// wait until the wire is high... just in case // wait until the wire is high... just in case
do { do {
if (--retries == 0) if (--retries == 0)
@@ -181,16 +205,14 @@ uint8_t OneWire::reset(void) {
delayMicroseconds(2); delayMicroseconds(2);
} while (!DIRECT_READ(reg, mask)); } while (!DIRECT_READ(reg, mask));
noInterrupts(); t_noInterrupts();
DIRECT_WRITE_LOW(reg, mask); DIRECT_WRITE_LOW(reg, mask);
DIRECT_MODE_OUTPUT(reg, mask); // drive output low DIRECT_MODE_OUTPUT(reg, mask); // drive output low
interrupts();
delayMicroseconds(480); delayMicroseconds(480);
noInterrupts();
DIRECT_MODE_INPUT(reg, mask); // allow it to float DIRECT_MODE_INPUT(reg, mask); // allow it to float
delayMicroseconds(70); delayMicroseconds(70);
r = !DIRECT_READ(reg, mask); r = !DIRECT_READ(reg, mask);
interrupts(); t_interrupts();
delayMicroseconds(410); delayMicroseconds(410);
return r; return r;
} }
@@ -200,28 +222,29 @@ uint8_t OneWire::reset(void) {
// more certain timing. // more certain timing.
// //
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
void IRAM_ATTR OneWire::write_bit(uint8_t v) { void IRAM_ATTR OneWire::write_bit(uint8_t v)
#else #else
void OneWire::write_bit(uint8_t v) { void OneWire::write_bit(uint8_t v)
#endif #endif
{
IO_REG_TYPE mask IO_REG_MASK_ATTR = bitmask; IO_REG_TYPE mask IO_REG_MASK_ATTR = bitmask;
volatile IO_REG_TYPE * reg IO_REG_BASE_ATTR = baseReg; volatile IO_REG_TYPE * reg IO_REG_BASE_ATTR = baseReg;
if (v & 1) { if (v & 1) {
noInterrupts(); t_noInterrupts();
DIRECT_WRITE_LOW(reg, mask); DIRECT_WRITE_LOW(reg, mask);
DIRECT_MODE_OUTPUT(reg, mask); // drive output low DIRECT_MODE_OUTPUT(reg, mask); // drive output low
delayMicroseconds(10); delayMicroseconds(10);
DIRECT_WRITE_HIGH(reg, mask); // drive output high DIRECT_WRITE_HIGH(reg, mask); // drive output high
interrupts(); t_interrupts();
delayMicroseconds(55); delayMicroseconds(55);
} else { } else {
noInterrupts(); t_noInterrupts();
DIRECT_WRITE_LOW(reg, mask); DIRECT_WRITE_LOW(reg, mask);
DIRECT_MODE_OUTPUT(reg, mask); // drive output low DIRECT_MODE_OUTPUT(reg, mask); // drive output low
delayMicroseconds(65); delayMicroseconds(65);
DIRECT_WRITE_HIGH(reg, mask); // drive output high DIRECT_WRITE_HIGH(reg, mask); // drive output high
interrupts(); t_interrupts();
delayMicroseconds(5); delayMicroseconds(5);
} }
} }
@@ -231,22 +254,23 @@ void OneWire::write_bit(uint8_t v) {
// more certain timing. // more certain timing.
// //
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
uint8_t IRAM_ATTR OneWire::read_bit(void) { uint8_t IRAM_ATTR OneWire::read_bit(void)
#else #else
uint8_t OneWire::read_bit(void) { uint8_t OneWire::read_bit(void)
#endif #endif
{
IO_REG_TYPE mask IO_REG_MASK_ATTR = bitmask; IO_REG_TYPE mask IO_REG_MASK_ATTR = bitmask;
volatile IO_REG_TYPE * reg IO_REG_BASE_ATTR = baseReg; volatile IO_REG_TYPE * reg IO_REG_BASE_ATTR = baseReg;
uint8_t r; uint8_t r;
noInterrupts(); t_noInterrupts();
DIRECT_MODE_OUTPUT(reg, mask); DIRECT_MODE_OUTPUT(reg, mask);
DIRECT_WRITE_LOW(reg, mask); DIRECT_WRITE_LOW(reg, mask);
delayMicroseconds(3); delayMicroseconds(3);
DIRECT_MODE_INPUT(reg, mask); // let pin float, pull up will raise DIRECT_MODE_INPUT(reg, mask); // let pin float, pull up will raise
delayMicroseconds(10); delayMicroseconds(10);
r = DIRECT_READ(reg, mask); r = DIRECT_READ(reg, mask);
interrupts(); t_interrupts();
delayMicroseconds(53); delayMicroseconds(53);
return r; return r;
} }
@@ -265,10 +289,10 @@ void OneWire::write(uint8_t v, uint8_t power /* = 0 */) {
OneWire::write_bit((bitMask & v) ? 1 : 0); OneWire::write_bit((bitMask & v) ? 1 : 0);
} }
if (!power) { if (!power) {
noInterrupts(); t_noInterrupts();
DIRECT_MODE_INPUT(baseReg, bitmask); DIRECT_MODE_INPUT(baseReg, bitmask);
DIRECT_WRITE_LOW(baseReg, bitmask); DIRECT_WRITE_LOW(baseReg, bitmask);
interrupts(); t_interrupts();
} }
} }
@@ -276,10 +300,10 @@ void OneWire::write_bytes(const uint8_t * buf, uint16_t count, bool power /* = 0
for (uint16_t i = 0; i < count; i++) for (uint16_t i = 0; i < count; i++)
write(buf[i]); write(buf[i]);
if (!power) { if (!power) {
noInterrupts(); t_noInterrupts();
DIRECT_MODE_INPUT(baseReg, bitmask); DIRECT_MODE_INPUT(baseReg, bitmask);
DIRECT_WRITE_LOW(baseReg, bitmask); DIRECT_WRITE_LOW(baseReg, bitmask);
interrupts(); t_interrupts();
} }
} }
@@ -322,9 +346,9 @@ void OneWire::skip() {
} }
void OneWire::depower() { void OneWire::depower() {
noInterrupts(); t_noInterrupts();
DIRECT_MODE_INPUT(baseReg, bitmask); DIRECT_MODE_INPUT(baseReg, bitmask);
interrupts(); t_interrupts();
} }
#if ONEWIRE_SEARCH #if ONEWIRE_SEARCH
@@ -336,7 +360,7 @@ void OneWire::depower() {
void OneWire::reset_search() { void OneWire::reset_search() {
// reset the search state // reset the search state
LastDiscrepancy = 0; LastDiscrepancy = 0;
LastDeviceFlag = false; LastDeviceFlag = FALSE;
LastFamilyDiscrepancy = 0; LastFamilyDiscrepancy = 0;
for (int i = 7;; i--) { for (int i = 7;; i--) {
ROM_NO[i] = 0; ROM_NO[i] = 0;
@@ -355,7 +379,7 @@ void OneWire::target_search(uint8_t family_code) {
ROM_NO[i] = 0; ROM_NO[i] = 0;
LastDiscrepancy = 64; LastDiscrepancy = 64;
LastFamilyDiscrepancy = 0; LastFamilyDiscrepancy = 0;
LastDeviceFlag = false; LastDeviceFlag = FALSE;
} }
// //
@@ -374,10 +398,9 @@ void OneWire::target_search(uint8_t family_code) {
// Return TRUE : device found, ROM number in ROM_NO buffer // Return TRUE : device found, ROM number in ROM_NO buffer
// FALSE : device not found, end of search // FALSE : device not found, end of search
// //
bool OneWire::search(uint8_t * newAddr, bool search_mode /* = true */) { uint8_t OneWire::search(uint8_t * newAddr, bool search_mode /* = true */) {
uint8_t id_bit_number; uint8_t id_bit_number;
uint8_t last_zero, rom_byte_number; uint8_t last_zero, rom_byte_number, search_result;
bool search_result;
uint8_t id_bit, cmp_id_bit; uint8_t id_bit, cmp_id_bit;
unsigned char rom_byte_mask, search_direction; unsigned char rom_byte_mask, search_direction;
@@ -387,7 +410,7 @@ bool OneWire::search(uint8_t * newAddr, bool search_mode /* = true */) {
last_zero = 0; last_zero = 0;
rom_byte_number = 0; rom_byte_number = 0;
rom_byte_mask = 1; rom_byte_mask = 1;
search_result = false; search_result = 0;
// if the last call was not the last one // if the last call was not the last one
if (!LastDeviceFlag) { if (!LastDeviceFlag) {
@@ -395,11 +418,10 @@ bool OneWire::search(uint8_t * newAddr, bool search_mode /* = true */) {
if (!reset()) { if (!reset()) {
// reset the search // reset the search
LastDiscrepancy = 0; LastDiscrepancy = 0;
LastDeviceFlag = false; LastDeviceFlag = FALSE;
LastFamilyDiscrepancy = 0; LastFamilyDiscrepancy = 0;
return false; return FALSE;
} }
// issue the search command // issue the search command
if (search_mode == true) { if (search_mode == true) {
write(0xF0); // NORMAL SEARCH write(0xF0); // NORMAL SEARCH
@@ -414,21 +436,21 @@ bool OneWire::search(uint8_t * newAddr, bool search_mode /* = true */) {
cmp_id_bit = read_bit(); cmp_id_bit = read_bit();
// check for no devices on 1-wire // check for no devices on 1-wire
if ((id_bit == 1) && (cmp_id_bit == 1)) { if ((id_bit == 1) && (cmp_id_bit == 1))
break; break;
} else { else {
// all devices coupled have 0 or 1 // all devices coupled have 0 or 1
if (id_bit != cmp_id_bit) { if (id_bit != cmp_id_bit)
search_direction = id_bit; // bit write value for search search_direction = id_bit; // bit write value for search
} else { else {
// if this discrepancy if before the Last Discrepancy // if this discrepancy if before the Last Discrepancy
// on a previous next then pick the same as last time // on a previous next then pick the same as last time
if (id_bit_number < LastDiscrepancy) { if (id_bit_number < LastDiscrepancy)
search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0); search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0);
} else { else
// if equal to last pick 1, if not then pick 0 // if equal to last pick 1, if not then pick 0
search_direction = (id_bit_number == LastDiscrepancy); search_direction = (id_bit_number == LastDiscrepancy);
}
// if 0 was picked then record its position in LastZero // if 0 was picked then record its position in LastZero
if (search_direction == 0) { if (search_direction == 0) {
last_zero = id_bit_number; last_zero = id_bit_number;
@@ -461,31 +483,29 @@ bool OneWire::search(uint8_t * newAddr, bool search_mode /* = true */) {
} }
} }
} while (rom_byte_number < 8); // loop until through all ROM bytes 0-7 } while (rom_byte_number < 8); // loop until through all ROM bytes 0-7
// if the search was successful then // if the search was successful then
if (!(id_bit_number < 65)) { if (!(id_bit_number < 65)) {
// search successful so set LastDiscrepancy,LastDeviceFlag,search_result // search successful so set LastDiscrepancy,LastDeviceFlag,search_result
LastDiscrepancy = last_zero; LastDiscrepancy = last_zero;
// check for last device // check for last device
if (LastDiscrepancy == 0) { if (LastDiscrepancy == 0)
LastDeviceFlag = true; LastDeviceFlag = TRUE;
}
search_result = true; search_result = TRUE;
} }
} }
// if no device found then reset counters so next 'search' will be like a first // if no device found then reset counters so next 'search' will be like a first
if (!search_result || !ROM_NO[0]) { if (!search_result || !ROM_NO[0]) {
LastDiscrepancy = 0; LastDiscrepancy = 0;
LastDeviceFlag = false; LastDeviceFlag = FALSE;
LastFamilyDiscrepancy = 0; LastFamilyDiscrepancy = 0;
search_result = false; search_result = FALSE;
} else { } else {
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
newAddr[i] = ROM_NO[i]; newAddr[i] = ROM_NO[i];
} }
// depower(); // https://github.com/PaulStoffregen/OneWire/pull/80
return search_result; return search_result;
} }
@@ -497,28 +517,40 @@ bool OneWire::search(uint8_t * newAddr, bool search_mode /* = true */) {
// //
#if ONEWIRE_CRC8_TABLE #if ONEWIRE_CRC8_TABLE
// Dow-CRC using polynomial X^8 + X^5 + X^4 + X^0 // This table comes from Dallas sample code where it is freely reusable,
// Tiny 2x16 entry CRC table created by Arjen Lentz // though Copyright (C) 2000 Dallas Semiconductor Corporation
// See http://lentz.com.au/blog/calculating-crc-with-a-tiny-32-entry-lookup-table static const uint8_t PROGMEM dscrc_table[] = {0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, 157, 195, 33, 127, 252, 162,
static const uint8_t PROGMEM dscrc2x16_table[] = {0x00, 0x5E, 0xBC, 0xE2, 0x61, 0x3F, 0xDD, 0x83, 0xC2, 0x9C, 0x7E, 0x20, 0xA3, 0xFD, 0x1F, 0x41, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, 35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3,
0x00, 0x9D, 0x23, 0xBE, 0x46, 0xDB, 0x65, 0xF8, 0x8C, 0x11, 0xAF, 0x32, 0xCA, 0x57, 0xE9, 0x74}; 128, 222, 60, 98, 190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, 70, 24,
250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, 219, 133, 103, 57, 186, 228, 6, 88,
25, 71, 165, 251, 120, 38, 196, 154, 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152,
122, 36, 248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, 140, 210, 48, 110,
237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205, 17, 79, 173, 243, 112, 46, 204, 146, 211, 141,
111, 49, 178, 236, 14, 80, 175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, 202, 148, 118, 40, 171, 245,
23, 73, 8, 86, 180, 234, 105, 55, 213, 139, 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119,
244, 170, 72, 22, 233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168, 116, 42,
200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53};
//
// Compute a Dallas Semiconductor 8 bit CRC. These show up in the ROM // Compute a Dallas Semiconductor 8 bit CRC. These show up in the ROM
// and the registers. (Use tiny 2x16 entry CRC table) // and the registers. (note: this might better be done without to
// table, it would probably be smaller and certainly fast enough
// 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 OneWire::crc8(const uint8_t * addr, uint8_t len) {
uint8_t crc = 0; uint8_t crc = 0;
while (len--) { while (len--) {
crc = *addr++ ^ crc; // just re-using crc as intermediate crc = pgm_read_byte(dscrc_table + (crc ^ *addr++));
crc = pgm_read_byte(dscrc2x16_table + (crc & 0x0f)) ^ pgm_read_byte(dscrc2x16_table + 16 + ((crc >> 4) & 0x0f));
} }
return crc; return crc;
} }
#else #else
// //
// Compute a Dallas Semiconductor 8 bit CRC directly. // Compute a Dallas Semiconductor 8 bit CRC directly.
// this is much slower, but a little smaller, than the lookup table. // this is much slower, but much smaller, than the lookup table.
// //
uint8_t OneWire::crc8(const uint8_t * addr, uint8_t len) { uint8_t OneWire::crc8(const uint8_t * addr, uint8_t len) {
uint8_t crc = 0; uint8_t crc = 0;
@@ -574,8 +606,4 @@ uint16_t OneWire::crc16(const uint8_t * input, uint16_t len, uint16_t crc) {
return crc; return crc;
} }
#endif #endif
#endif #endif
#pragma GCC diagnostic pop

View File

@@ -1,16 +1,14 @@
#ifndef OneWire_h #ifndef OneWire_h
#define OneWire_h #define OneWire_h
#ifdef __cplusplus #include <inttypes.h>
#include <stdint.h>
#if defined(__AVR__) #if defined(__AVR__)
#include <util/crc16.h> #include <util/crc16.h>
#endif #endif
#if ARDUINO >= 100 #if ARDUINO >= 100
#include <Arduino.h> // for delayMicroseconds, digitalPinToBitMask, etc #include "Arduino.h" // for delayMicroseconds, digitalPinToBitMask, etc
#else #else
#include "WProgram.h" // for delayMicroseconds #include "WProgram.h" // for delayMicroseconds
#include "pins_arduino.h" // for digitalPinToBitMask, etc #include "pins_arduino.h" // for digitalPinToBitMask, etc
@@ -42,7 +40,7 @@
// old versions of OneWire). If you disable this, a slower // old versions of OneWire). If you disable this, a slower
// but very compact algorithm is used. // but very compact algorithm is used.
#ifndef ONEWIRE_CRC8_TABLE #ifndef ONEWIRE_CRC8_TABLE
#define ONEWIRE_CRC8_TABLE 1 #define ONEWIRE_CRC8_TABLE 0
#endif #endif
// You can allow 16-bit CRC checks by defining this to 1 // You can allow 16-bit CRC checks by defining this to 1
@@ -51,8 +49,388 @@
#define ONEWIRE_CRC16 1 #define ONEWIRE_CRC16 1
#endif #endif
// Board-specific macros for direct GPIO #ifndef FALSE
#include "OneWire_direct_regtype.h" #define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
// Platform specific I/O definitions
#if defined(__AVR__)
#define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin)))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint8_t
#define IO_REG_BASE_ATTR asm("r30")
#define IO_REG_MASK_ATTR
#define DIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
#define DIRECT_MODE_INPUT(base, mask) ((*((base) + 1)) &= ~(mask))
#define DIRECT_MODE_OUTPUT(base, mask) ((*((base) + 1)) |= (mask))
#define DIRECT_WRITE_LOW(base, mask) ((*((base) + 2)) &= ~(mask))
#define DIRECT_WRITE_HIGH(base, mask) ((*((base) + 2)) |= (mask))
#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK66FX1M0__) || defined(__MK64FX512__)
#define PIN_TO_BASEREG(pin) (portOutputRegister(pin))
#define PIN_TO_BITMASK(pin) (1)
#define IO_REG_TYPE uint8_t
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR __attribute__((unused))
#define DIRECT_READ(base, mask) (*((base) + 512))
#define DIRECT_MODE_INPUT(base, mask) (*((base) + 640) = 0)
#define DIRECT_MODE_OUTPUT(base, mask) (*((base) + 640) = 1)
#define DIRECT_WRITE_LOW(base, mask) (*((base) + 256) = 1)
#define DIRECT_WRITE_HIGH(base, mask) (*((base) + 128) = 1)
#elif defined(__MKL26Z64__)
#define PIN_TO_BASEREG(pin) (portOutputRegister(pin))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint8_t
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR
#define DIRECT_READ(base, mask) ((*((base) + 16) & (mask)) ? 1 : 0)
#define DIRECT_MODE_INPUT(base, mask) (*((base) + 20) &= ~(mask))
#define DIRECT_MODE_OUTPUT(base, mask) (*((base) + 20) |= (mask))
#define DIRECT_WRITE_LOW(base, mask) (*((base) + 8) = (mask))
#define DIRECT_WRITE_HIGH(base, mask) (*((base) + 4) = (mask))
#elif defined(__SAM3X8E__) || defined(__SAM3A8C__) || defined(__SAM3A4C__)
// Arduino 1.5.1 may have a bug in delayMicroseconds() on Arduino Due.
// http://arduino.cc/forum/index.php/topic,141030.msg1076268.html#msg1076268
// If you have trouble with OneWire on Arduino Due, please check the
// status of delayMicroseconds() before reporting a bug in OneWire!
#define PIN_TO_BASEREG(pin) (&(digitalPinToPort(pin)->PIO_PER))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint32_t
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR
#define DIRECT_READ(base, mask) (((*((base) + 15)) & (mask)) ? 1 : 0)
#define DIRECT_MODE_INPUT(base, mask) ((*((base) + 5)) = (mask))
#define DIRECT_MODE_OUTPUT(base, mask) ((*((base) + 4)) = (mask))
#define DIRECT_WRITE_LOW(base, mask) ((*((base) + 13)) = (mask))
#define DIRECT_WRITE_HIGH(base, mask) ((*((base) + 12)) = (mask))
#ifndef PROGMEM
#define PROGMEM
#endif
#ifndef pgm_read_byte
#define pgm_read_byte(addr) (*(const uint8_t *)(addr))
#endif
#elif defined(__PIC32MX__)
#define PIN_TO_BASEREG(pin) (portModeRegister(digitalPinToPort(pin)))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint32_t
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR
#define DIRECT_READ(base, mask) (((*(base + 4)) & (mask)) ? 1 : 0) //PORTX + 0x10
#define DIRECT_MODE_INPUT(base, mask) ((*(base + 2)) = (mask)) //TRISXSET + 0x08
#define DIRECT_MODE_OUTPUT(base, mask) ((*(base + 1)) = (mask)) //TRISXCLR + 0x04
#define DIRECT_WRITE_LOW(base, mask) ((*(base + 8 + 1)) = (mask)) //LATXCLR + 0x24
#define DIRECT_WRITE_HIGH(base, mask) ((*(base + 8 + 2)) = (mask)) //LATXSET + 0x28
#elif defined(ARDUINO_ARCH_ESP8266)
// Special note: I depend on the ESP community to maintain these definitions and
// submit good pull requests. I can not answer any ESP questions or help you
// resolve any problems related to ESP chips. Please do not contact me and please
// DO NOT CREATE GITHUB ISSUES for ESP support. All ESP questions must be asked
// on ESP community forums.
#define PIN_TO_BASEREG(pin) ((volatile uint32_t *)GPO)
#define PIN_TO_BITMASK(pin) (1 << pin)
#define IO_REG_TYPE uint32_t
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR
#define DIRECT_READ(base, mask) ((GPI & (mask)) ? 1 : 0) //GPIO_IN_ADDRESS
#define DIRECT_MODE_INPUT(base, mask) (GPE &= ~(mask)) //GPIO_ENABLE_W1TC_ADDRESS
#define DIRECT_MODE_OUTPUT(base, mask) (GPE |= (mask)) //GPIO_ENABLE_W1TS_ADDRESS
#define DIRECT_WRITE_LOW(base, mask) (GPOC = (mask)) //GPIO_OUT_W1TC_ADDRESS
#define DIRECT_WRITE_HIGH(base, mask) (GPOS = (mask)) //GPIO_OUT_W1TS_ADDRESS
#elif defined(ARDUINO_ARCH_ESP32)
#include <driver/rtc_io.h>
#define PIN_TO_BASEREG(pin) (0)
#define PIN_TO_BITMASK(pin) (pin)
#define IO_REG_TYPE uint32_t
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR
static inline __attribute__((always_inline)) IO_REG_TYPE directRead(IO_REG_TYPE pin) {
#if CONFIG_IDF_TARGET_ESP32C3
return (GPIO.in.val >> pin) & 0x1;
#else // plain ESP32
if (pin < 32)
return (GPIO.in >> pin) & 0x1;
else if (pin < 46)
return (GPIO.in1.val >> (pin - 32)) & 0x1;
#endif
return 0;
}
static inline __attribute__((always_inline)) void directWriteLow(IO_REG_TYPE pin) {
#if CONFIG_IDF_TARGET_ESP32C3
GPIO.out_w1tc.val = ((uint32_t)1 << pin);
#else // plain ESP32
if (pin < 32)
GPIO.out_w1tc = ((uint32_t)1 << pin);
else if (pin < 46)
GPIO.out1_w1tc.val = ((uint32_t)1 << (pin - 32));
#endif
}
static inline __attribute__((always_inline)) void directWriteHigh(IO_REG_TYPE pin) {
#if CONFIG_IDF_TARGET_ESP32C3
GPIO.out_w1ts.val = ((uint32_t)1 << pin);
#else // plain ESP32
if (pin < 32)
GPIO.out_w1ts = ((uint32_t)1 << pin);
else if (pin < 46)
GPIO.out1_w1ts.val = ((uint32_t)1 << (pin - 32));
#endif
}
static inline __attribute__((always_inline)) void directModeInput(IO_REG_TYPE pin) {
#if CONFIG_IDF_TARGET_ESP32C3
GPIO.enable_w1tc.val = ((uint32_t)1 << (pin));
#else
if (digitalPinIsValid(pin)) {
#if ESP_IDF_VERSION_MAJOR < 4 // IDF 3.x ESP32/PICO-D4
uint32_t rtc_reg(rtc_gpio_desc[pin].reg);
if (rtc_reg) // RTC pins PULL settings
{
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].mux);
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].pullup | rtc_gpio_desc[pin].pulldown);
}
//#elif ESP_IDF_VERSION_MAJOR > 3 // ESP32-S2 needs IDF 4.2 or later
// int8_t rtc_io = esp32_gpioMux[pin].rtc;
// uint32_t rtc_reg = (rtc_io != -1)?rtc_io_desc[rtc_io].reg:0;
// if ( rtc_reg ) // RTC pins PULL settings
// {
// ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].mux);
// ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].pullup | rtc_io_desc[rtc_io].pulldown);
// }
#endif
// Input
if (pin < 32)
GPIO.enable_w1tc = ((uint32_t)1 << pin);
else
GPIO.enable1_w1tc.val = ((uint32_t)1 << (pin - 32));
// uint32_t pinFunction((uint32_t)2 << FUN_DRV_S); // what are the drivers?
// pinFunction |= FUN_IE; // input enable but required for output as well?
// pinFunction |= ((uint32_t)PIN_FUNC_GPIO << MCU_SEL_S);
// ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = pinFunction;
// GPIO.pin[pin].val = 0;
}
#endif
}
static inline __attribute__((always_inline)) void directModeOutput(IO_REG_TYPE pin) {
#if CONFIG_IDF_TARGET_ESP32C3
GPIO.enable_w1ts.val = ((uint32_t)1 << (pin));
#else
if (digitalPinIsValid(pin) && pin <= 33) // pins above 33 can be only inputs
{
#if ESP_IDF_VERSION_MAJOR < 4 // IDF 3.x ESP32/PICO-D4
uint32_t rtc_reg(rtc_gpio_desc[pin].reg);
if (rtc_reg) // RTC pins PULL settings
{
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].mux);
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].pullup | rtc_gpio_desc[pin].pulldown);
}
//#elif ESP_IDF_VERSION_MAJOR > 3 // ESP32-S2 needs IDF 4.2 or later
// int8_t rtc_io = esp32_gpioMux[pin].rtc;
// uint32_t rtc_reg = (rtc_io != -1)?rtc_io_desc[rtc_io].reg:0;
// if ( rtc_reg ) // RTC pins PULL settings
// {
// ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].mux);
// ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].pullup | rtc_io_desc[rtc_io].pulldown);
// }
#endif
// Output
if (pin < 32)
GPIO.enable_w1ts = ((uint32_t)1 << pin);
else // already validated to pins <= 33
GPIO.enable1_w1ts.val = ((uint32_t)1 << (pin - 32));
// uint32_t pinFunction((uint32_t)2 << FUN_DRV_S); // what are the drivers?
// pinFunction |= FUN_IE; // input enable but required for output as well?
// pinFunction |= ((uint32_t)PIN_FUNC_GPIO << MCU_SEL_S);
// ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = pinFunction;
// GPIO.pin[pin].val = 0;
}
#endif
}
#define DIRECT_READ(base, pin) directRead(pin)
#define DIRECT_WRITE_LOW(base, pin) directWriteLow(pin)
#define DIRECT_WRITE_HIGH(base, pin) directWriteHigh(pin)
#define DIRECT_MODE_INPUT(base, pin) directModeInput(pin)
#define DIRECT_MODE_OUTPUT(base, pin) directModeOutput(pin)
//#warning "ESP32 OneWire testing"
#elif defined(__SAMD21G18A__)
#define PIN_TO_BASEREG(pin) portModeRegister(digitalPinToPort(pin))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint32_t
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR
#define DIRECT_READ(base, mask) (((*((base) + 8)) & (mask)) ? 1 : 0)
#define DIRECT_MODE_INPUT(base, mask) ((*((base) + 1)) = (mask))
#define DIRECT_MODE_OUTPUT(base, mask) ((*((base) + 2)) = (mask))
#define DIRECT_WRITE_LOW(base, mask) ((*((base) + 5)) = (mask))
#define DIRECT_WRITE_HIGH(base, mask) ((*((base) + 6)) = (mask))
#elif defined(RBL_NRF51822)
#define PIN_TO_BASEREG(pin) (0)
#define PIN_TO_BITMASK(pin) (pin)
#define IO_REG_TYPE uint32_t
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR
#define DIRECT_READ(base, pin) nrf_gpio_pin_read(pin)
#define DIRECT_WRITE_LOW(base, pin) nrf_gpio_pin_clear(pin)
#define DIRECT_WRITE_HIGH(base, pin) nrf_gpio_pin_set(pin)
#define DIRECT_MODE_INPUT(base, pin) nrf_gpio_cfg_input(pin, NRF_GPIO_PIN_NOPULL)
#define DIRECT_MODE_OUTPUT(base, pin) nrf_gpio_cfg_output(pin)
#elif defined(__arc__) /* Arduino101/Genuino101 specifics */
#include "scss_registers.h"
#include "portable.h"
#include "avr/pgmspace.h"
#define GPIO_ID(pin) (g_APinDescription[pin].ulGPIOId)
#define GPIO_TYPE(pin) (g_APinDescription[pin].ulGPIOType)
#define GPIO_BASE(pin) (g_APinDescription[pin].ulGPIOBase)
#define DIR_OFFSET_SS 0x01
#define DIR_OFFSET_SOC 0x04
#define EXT_PORT_OFFSET_SS 0x0A
#define EXT_PORT_OFFSET_SOC 0x50
/* GPIO registers base address */
#define PIN_TO_BASEREG(pin) ((volatile uint32_t *)g_APinDescription[pin].ulGPIOBase)
#define PIN_TO_BITMASK(pin) pin
#define IO_REG_TYPE uint32_t
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR
static inline __attribute__((always_inline)) IO_REG_TYPE directRead(volatile IO_REG_TYPE * base, IO_REG_TYPE pin) {
IO_REG_TYPE ret;
if (SS_GPIO == GPIO_TYPE(pin)) {
ret = READ_ARC_REG(((IO_REG_TYPE)base + EXT_PORT_OFFSET_SS));
} else {
ret = MMIO_REG_VAL_FROM_BASE((IO_REG_TYPE)base, EXT_PORT_OFFSET_SOC);
}
return ((ret >> GPIO_ID(pin)) & 0x01);
}
static inline __attribute__((always_inline)) void directModeInput(volatile IO_REG_TYPE * base, IO_REG_TYPE pin) {
if (SS_GPIO == GPIO_TYPE(pin)) {
WRITE_ARC_REG(READ_ARC_REG((((IO_REG_TYPE)base) + DIR_OFFSET_SS)) & ~(0x01 << GPIO_ID(pin)), ((IO_REG_TYPE)(base) + DIR_OFFSET_SS));
} else {
MMIO_REG_VAL_FROM_BASE((IO_REG_TYPE)base, DIR_OFFSET_SOC) &= ~(0x01 << GPIO_ID(pin));
}
}
static inline __attribute__((always_inline)) void directModeOutput(volatile IO_REG_TYPE * base, IO_REG_TYPE pin) {
if (SS_GPIO == GPIO_TYPE(pin)) {
WRITE_ARC_REG(READ_ARC_REG(((IO_REG_TYPE)(base) + DIR_OFFSET_SS)) | (0x01 << GPIO_ID(pin)), ((IO_REG_TYPE)(base) + DIR_OFFSET_SS));
} else {
MMIO_REG_VAL_FROM_BASE((IO_REG_TYPE)base, DIR_OFFSET_SOC) |= (0x01 << GPIO_ID(pin));
}
}
static inline __attribute__((always_inline)) void directWriteLow(volatile IO_REG_TYPE * base, IO_REG_TYPE pin) {
if (SS_GPIO == GPIO_TYPE(pin)) {
WRITE_ARC_REG(READ_ARC_REG(base) & ~(0x01 << GPIO_ID(pin)), base);
} else {
MMIO_REG_VAL(base) &= ~(0x01 << GPIO_ID(pin));
}
}
static inline __attribute__((always_inline)) void directWriteHigh(volatile IO_REG_TYPE * base, IO_REG_TYPE pin) {
if (SS_GPIO == GPIO_TYPE(pin)) {
WRITE_ARC_REG(READ_ARC_REG(base) | (0x01 << GPIO_ID(pin)), base);
} else {
MMIO_REG_VAL(base) |= (0x01 << GPIO_ID(pin));
}
}
#define DIRECT_READ(base, pin) directRead(base, pin)
#define DIRECT_MODE_INPUT(base, pin) directModeInput(base, pin)
#define DIRECT_MODE_OUTPUT(base, pin) directModeOutput(base, pin)
#define DIRECT_WRITE_LOW(base, pin) directWriteLow(base, pin)
#define DIRECT_WRITE_HIGH(base, pin) directWriteHigh(base, pin)
#elif defined(__riscv)
/*
* Tested on highfive1
*
* Stable results are achieved operating in the
* two high speed modes of the highfive1. It
* seems to be less reliable in slow mode.
*/
#define PIN_TO_BASEREG(pin) (0)
#define PIN_TO_BITMASK(pin) digitalPinToBitMask(pin)
#define IO_REG_TYPE uint32_t
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR
static inline __attribute__((always_inline)) IO_REG_TYPE directRead(IO_REG_TYPE mask) {
return ((GPIO_REG(GPIO_INPUT_VAL) & mask) != 0) ? 1 : 0;
}
static inline __attribute__((always_inline)) void directModeInput(IO_REG_TYPE mask) {
GPIO_REG(GPIO_OUTPUT_XOR) &= ~mask;
GPIO_REG(GPIO_IOF_EN) &= ~mask;
GPIO_REG(GPIO_INPUT_EN) |= mask;
GPIO_REG(GPIO_OUTPUT_EN) &= ~mask;
}
static inline __attribute__((always_inline)) void directModeOutput(IO_REG_TYPE mask) {
GPIO_REG(GPIO_OUTPUT_XOR) &= ~mask;
GPIO_REG(GPIO_IOF_EN) &= ~mask;
GPIO_REG(GPIO_INPUT_EN) &= ~mask;
GPIO_REG(GPIO_OUTPUT_EN) |= mask;
}
static inline __attribute__((always_inline)) void directWriteLow(IO_REG_TYPE mask) {
GPIO_REG(GPIO_OUTPUT_VAL) &= ~mask;
}
static inline __attribute__((always_inline)) void directWriteHigh(IO_REG_TYPE mask) {
GPIO_REG(GPIO_OUTPUT_VAL) |= mask;
}
#define DIRECT_READ(base, mask) directRead(mask)
#define DIRECT_WRITE_LOW(base, mask) directWriteLow(mask)
#define DIRECT_WRITE_HIGH(base, mask) directWriteHigh(mask)
#define DIRECT_MODE_INPUT(base, mask) directModeInput(mask)
#define DIRECT_MODE_OUTPUT(base, mask) directModeOutput(mask)
#else
#define PIN_TO_BASEREG(pin) (0)
#define PIN_TO_BITMASK(pin) (pin)
#define IO_REG_TYPE unsigned int
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR
#define DIRECT_READ(base, pin) digitalRead(pin)
#define DIRECT_WRITE_LOW(base, pin) digitalWrite(pin, LOW)
#define DIRECT_WRITE_HIGH(base, pin) digitalWrite(pin, HIGH)
#define DIRECT_MODE_INPUT(base, pin) pinMode(pin, INPUT)
#define DIRECT_MODE_OUTPUT(base, pin) pinMode(pin, OUTPUT)
#warning "OneWire. Fallback mode. Using API calls for pinMode,digitalRead and digitalWrite. Operation of this library is not guaranteed on this architecture."
#endif
class OneWire { class OneWire {
private: private:
@@ -64,7 +442,7 @@ class OneWire {
unsigned char ROM_NO[8]; unsigned char ROM_NO[8];
uint8_t LastDiscrepancy; uint8_t LastDiscrepancy;
uint8_t LastFamilyDiscrepancy; uint8_t LastFamilyDiscrepancy;
bool LastDeviceFlag; uint8_t LastDeviceFlag;
#endif #endif
public: public:
@@ -78,11 +456,7 @@ class OneWire {
// Perform a 1-Wire reset cycle. Returns 1 if a device responds // 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 // with a presence pulse. Returns 0 if there is no device or the
// bus is shorted or otherwise held low for more than 250uS // bus is shorted or otherwise held low for more than 250uS
#ifdef ARDUINO_ARCH_ESP32
uint8_t IRAM_ATTR reset(void);
#else
uint8_t reset(void); uint8_t reset(void);
#endif
// Issue a 1-Wire rom select command, you do the reset first. // Issue a 1-Wire rom select command, you do the reset first.
void select(const uint8_t rom[8]); void select(const uint8_t rom[8]);
@@ -105,18 +479,11 @@ class OneWire {
// Write a bit. The bus is always left powered at the end, see // Write a bit. The bus is always left powered at the end, see
// note in write() about that. // note in write() about that.
#ifdef ARDUINO_ARCH_ESP32
void IRAM_ATTR write_bit(uint8_t v);
#else
void write_bit(uint8_t v); void write_bit(uint8_t v);
#endif
// Read a bit. // Read a bit.
#ifdef ARDUINO_ARCH_ESP32
uint8_t IRAM_ATTR read_bit(void);
#else
uint8_t read_bit(void); uint8_t read_bit(void);
#endif
// Stop forcing power onto the bus. You only need to do this if // 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 // 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 // and aren't about to do another read or write. You would rather
@@ -138,7 +505,7 @@ class OneWire {
// might be a good idea to check the CRC to make sure you didn't // 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 // get garbage. The order is deterministic. You will always get
// the same devices in the same order. // the same devices in the same order.
bool search(uint8_t * newAddr, bool search_mode = true); uint8_t search(uint8_t * newAddr, bool search_mode = true);
#endif #endif
#if ONEWIRE_CRC #if ONEWIRE_CRC
@@ -186,10 +553,4 @@ class OneWire {
#endif #endif
}; };
// Prevent this name from leaking into Arduino sketches
#ifdef IO_REG_TYPE
#undef IO_REG_TYPE
#endif #endif
#endif // __cplusplus
#endif // OneWire_h

View File

@@ -1,415 +0,0 @@
#ifndef OneWire_Direct_GPIO_h
#define OneWire_Direct_GPIO_h
// This header should ONLY be included by OneWire.cpp. These defines are
// meant to be private, used within OneWire.cpp, but not exposed to Arduino
// sketches or other libraries which may include OneWire.h.
#include <stdint.h>
// Platform specific I/O definitions
#if defined(__AVR__)
#define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin)))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint8_t
#define IO_REG_BASE_ATTR asm("r30")
#define IO_REG_MASK_ATTR
#if defined(__AVR_ATmega4809__)
#define DIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
#define DIRECT_MODE_INPUT(base, mask) ((*((base)-8)) &= ~(mask))
#define DIRECT_MODE_OUTPUT(base, mask) ((*((base)-8)) |= (mask))
#define DIRECT_WRITE_LOW(base, mask) ((*((base)-4)) &= ~(mask))
#define DIRECT_WRITE_HIGH(base, mask) ((*((base)-4)) |= (mask))
#else
#define DIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
#define DIRECT_MODE_INPUT(base, mask) ((*((base) + 1)) &= ~(mask))
#define DIRECT_MODE_OUTPUT(base, mask) ((*((base) + 1)) |= (mask))
#define DIRECT_WRITE_LOW(base, mask) ((*((base) + 2)) &= ~(mask))
#define DIRECT_WRITE_HIGH(base, mask) ((*((base) + 2)) |= (mask))
#endif
#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK66FX1M0__) || defined(__MK64FX512__)
#define PIN_TO_BASEREG(pin) (portOutputRegister(pin))
#define PIN_TO_BITMASK(pin) (1)
#define IO_REG_TYPE uint8_t
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR __attribute__((unused))
#define DIRECT_READ(base, mask) (*((base) + 512))
#define DIRECT_MODE_INPUT(base, mask) (*((base) + 640) = 0)
#define DIRECT_MODE_OUTPUT(base, mask) (*((base) + 640) = 1)
#define DIRECT_WRITE_LOW(base, mask) (*((base) + 256) = 1)
#define DIRECT_WRITE_HIGH(base, mask) (*((base) + 128) = 1)
#elif defined(__MKL26Z64__)
#define PIN_TO_BASEREG(pin) (portOutputRegister(pin))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint8_t
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR
#define DIRECT_READ(base, mask) ((*((base) + 16) & (mask)) ? 1 : 0)
#define DIRECT_MODE_INPUT(base, mask) (*((base) + 20) &= ~(mask))
#define DIRECT_MODE_OUTPUT(base, mask) (*((base) + 20) |= (mask))
#define DIRECT_WRITE_LOW(base, mask) (*((base) + 8) = (mask))
#define DIRECT_WRITE_HIGH(base, mask) (*((base) + 4) = (mask))
#elif defined(__IMXRT1052__) || defined(__IMXRT1062__)
#define PIN_TO_BASEREG(pin) (portOutputRegister(pin))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint32_t
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR
#define DIRECT_READ(base, mask) ((*((base) + 2) & (mask)) ? 1 : 0)
#define DIRECT_MODE_INPUT(base, mask) (*((base) + 1) &= ~(mask))
#define DIRECT_MODE_OUTPUT(base, mask) (*((base) + 1) |= (mask))
#define DIRECT_WRITE_LOW(base, mask) (*((base) + 34) = (mask))
#define DIRECT_WRITE_HIGH(base, mask) (*((base) + 33) = (mask))
#elif defined(__SAM3X8E__) || defined(__SAM3A8C__) || defined(__SAM3A4C__)
// Arduino 1.5.1 may have a bug in delayMicroseconds() on Arduino Due.
// http://arduino.cc/forum/index.php/topic,141030.msg1076268.html#msg1076268
// If you have trouble with OneWire on Arduino Due, please check the
// status of delayMicroseconds() before reporting a bug in OneWire!
#define PIN_TO_BASEREG(pin) (&(digitalPinToPort(pin)->PIO_PER))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint32_t
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR
#define DIRECT_READ(base, mask) (((*((base) + 15)) & (mask)) ? 1 : 0)
#define DIRECT_MODE_INPUT(base, mask) ((*((base) + 5)) = (mask))
#define DIRECT_MODE_OUTPUT(base, mask) ((*((base) + 4)) = (mask))
#define DIRECT_WRITE_LOW(base, mask) ((*((base) + 13)) = (mask))
#define DIRECT_WRITE_HIGH(base, mask) ((*((base) + 12)) = (mask))
#ifndef PROGMEM
#define PROGMEM
#endif
#ifndef pgm_read_byte
#define pgm_read_byte(addr) (*(const uint8_t *)(addr))
#endif
#elif defined(__PIC32MX__)
#define PIN_TO_BASEREG(pin) (portModeRegister(digitalPinToPort(pin)))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint32_t
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR
#define DIRECT_READ(base, mask) (((*(base + 4)) & (mask)) ? 1 : 0) //PORTX + 0x10
#define DIRECT_MODE_INPUT(base, mask) ((*(base + 2)) = (mask)) //TRISXSET + 0x08
#define DIRECT_MODE_OUTPUT(base, mask) ((*(base + 1)) = (mask)) //TRISXCLR + 0x04
#define DIRECT_WRITE_LOW(base, mask) ((*(base + 8 + 1)) = (mask)) //LATXCLR + 0x24
#define DIRECT_WRITE_HIGH(base, mask) ((*(base + 8 + 2)) = (mask)) //LATXSET + 0x28
#elif defined(ARDUINO_ARCH_ESP8266)
// Special note: I depend on the ESP community to maintain these definitions and
// submit good pull requests. I can not answer any ESP questions or help you
// resolve any problems related to ESP chips. Please do not contact me and please
// DO NOT CREATE GITHUB ISSUES for ESP support. All ESP questions must be asked
// on ESP community forums.
#define PIN_TO_BASEREG(pin) ((volatile uint32_t *)GPO)
#define PIN_TO_BITMASK(pin) (1 << pin)
#define IO_REG_TYPE uint32_t
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR
#define DIRECT_READ(base, mask) ((GPI & (mask)) ? 1 : 0) //GPIO_IN_ADDRESS
#define DIRECT_MODE_INPUT(base, mask) (GPE &= ~(mask)) //GPIO_ENABLE_W1TC_ADDRESS
#define DIRECT_MODE_OUTPUT(base, mask) (GPE |= (mask)) //GPIO_ENABLE_W1TS_ADDRESS
#define DIRECT_WRITE_LOW(base, mask) (GPOC = (mask)) //GPIO_OUT_W1TC_ADDRESS
#define DIRECT_WRITE_HIGH(base, mask) (GPOS = (mask)) //GPIO_OUT_W1TS_ADDRESS
#elif defined(ARDUINO_ARCH_ESP32)
#include <driver/rtc_io.h>
#define PIN_TO_BASEREG(pin) (0)
#define PIN_TO_BITMASK(pin) (pin)
#define IO_REG_TYPE uint32_t
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR
#if __has_include("esp_arduino_version.h")
#include "esp_arduino_version.h"
#if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2, 0, 0)
#define rtc_gpio_desc rtc_io_desc
#endif
#endif
static inline __attribute__((always_inline)) IO_REG_TYPE directRead(IO_REG_TYPE pin) {
if (pin < 32)
return (GPIO.in >> pin) & 0x1;
else if (pin < 40)
return (GPIO.in1.val >> (pin - 32)) & 0x1;
return 0;
}
static inline __attribute__((always_inline)) void directWriteLow(IO_REG_TYPE pin) {
if (pin < 32)
GPIO.out_w1tc = ((uint32_t)1 << pin);
else if (pin < 34)
GPIO.out1_w1tc.val = ((uint32_t)1 << (pin - 32));
}
static inline __attribute__((always_inline)) void directWriteHigh(IO_REG_TYPE pin) {
if (pin < 32)
GPIO.out_w1ts = ((uint32_t)1 << pin);
else if (pin < 34)
GPIO.out1_w1ts.val = ((uint32_t)1 << (pin - 32));
}
static inline __attribute__((always_inline)) void directModeInput(IO_REG_TYPE pin) {
if (digitalPinIsValid(pin)) {
uint32_t rtc_reg(rtc_gpio_desc[pin].reg);
if (rtc_reg) // RTC pins PULL settings
{
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].mux);
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].pullup | rtc_gpio_desc[pin].pulldown);
}
if (pin < 32)
GPIO.enable_w1tc = ((uint32_t)1 << pin);
else
GPIO.enable1_w1tc.val = ((uint32_t)1 << (pin - 32));
uint32_t pinFunction((uint32_t)2 << FUN_DRV_S); // what are the drivers?
pinFunction |= FUN_IE; // input enable but required for output as well?
pinFunction |= ((uint32_t)2 << MCU_SEL_S);
ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = pinFunction;
GPIO.pin[pin].val = 0;
}
}
static inline __attribute__((always_inline)) void directModeOutput(IO_REG_TYPE pin) {
if (digitalPinIsValid(pin) && pin <= 33) // pins above 33 can be only inputs
{
uint32_t rtc_reg(rtc_gpio_desc[pin].reg);
if (rtc_reg) // RTC pins PULL settings
{
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].mux);
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].pullup | rtc_gpio_desc[pin].pulldown);
}
if (pin < 32)
GPIO.enable_w1ts = ((uint32_t)1 << pin);
else // already validated to pins <= 33
GPIO.enable1_w1ts.val = ((uint32_t)1 << (pin - 32));
uint32_t pinFunction((uint32_t)2 << FUN_DRV_S); // what are the drivers?
pinFunction |= FUN_IE; // input enable but required for output as well?
pinFunction |= ((uint32_t)2 << MCU_SEL_S);
ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = pinFunction;
GPIO.pin[pin].val = 0;
}
}
#define DIRECT_READ(base, pin) directRead(pin)
#define DIRECT_WRITE_LOW(base, pin) directWriteLow(pin)
#define DIRECT_WRITE_HIGH(base, pin) directWriteHigh(pin)
#define DIRECT_MODE_INPUT(base, pin) directModeInput(pin)
#define DIRECT_MODE_OUTPUT(base, pin) directModeOutput(pin)
// https://github.com/PaulStoffregen/OneWire/pull/47
// https://github.com/stickbreaker/OneWire/commit/6eb7fc1c11a15b6ac8c60e5671cf36eb6829f82c
#ifdef interrupts
#undef interrupts
#endif
#ifdef noInterrupts
#undef noInterrupts
#endif
#define noInterrupts() \
{ \
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; \
portENTER_CRITICAL(&mux)
#define interrupts() \
portEXIT_CRITICAL(&mux); \
}
//#warning "ESP32 OneWire testing"
#elif defined(ARDUINO_ARCH_STM32)
#define PIN_TO_BASEREG(pin) (0)
#define PIN_TO_BITMASK(pin) ((uint32_t)digitalPinToPinName(pin))
#define IO_REG_TYPE uint32_t
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR
#define DIRECT_READ(base, pin) digitalReadFast((PinName)pin)
#define DIRECT_WRITE_LOW(base, pin) digitalWriteFast((PinName)pin, LOW)
#define DIRECT_WRITE_HIGH(base, pin) digitalWriteFast((PinName)pin, HIGH)
#define DIRECT_MODE_INPUT(base, pin) pin_function((PinName)pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0))
#define DIRECT_MODE_OUTPUT(base, pin) pin_function((PinName)pin, STM_PIN_DATA(STM_MODE_OUTPUT_PP, GPIO_NOPULL, 0))
#elif defined(__SAMD21G18A__)
#define PIN_TO_BASEREG(pin) portModeRegister(digitalPinToPort(pin))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint32_t
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR
#define DIRECT_READ(base, mask) (((*((base) + 8)) & (mask)) ? 1 : 0)
#define DIRECT_MODE_INPUT(base, mask) ((*((base) + 1)) = (mask))
#define DIRECT_MODE_OUTPUT(base, mask) ((*((base) + 2)) = (mask))
#define DIRECT_WRITE_LOW(base, mask) ((*((base) + 5)) = (mask))
#define DIRECT_WRITE_HIGH(base, mask) ((*((base) + 6)) = (mask))
#elif defined(__ASR6501__)
#define PIN_IN_PORT(pin) (pin % PIN_NUMBER_IN_PORT)
#define PORT_FROM_PIN(pin) (pin / PIN_NUMBER_IN_PORT)
#define PORT_OFFSET(port) (PORT_REG_SHFIT * port)
#define PORT_ADDRESS(pin) (CYDEV_GPIO_BASE + PORT_OFFSET(PORT_FROM_PIN(pin)))
#define PIN_TO_BASEREG(pin) (0)
#define PIN_TO_BITMASK(pin) (pin)
#define IO_REG_TYPE uint32_t
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR
#define DIRECT_READ(base, pin) CY_SYS_PINS_READ_PIN(PORT_ADDRESS(pin) + 4, PIN_IN_PORT(pin))
#define DIRECT_WRITE_LOW(base, pin) CY_SYS_PINS_CLEAR_PIN(PORT_ADDRESS(pin), PIN_IN_PORT(pin))
#define DIRECT_WRITE_HIGH(base, pin) CY_SYS_PINS_SET_PIN(PORT_ADDRESS(pin), PIN_IN_PORT(pin))
#define DIRECT_MODE_INPUT(base, pin) CY_SYS_PINS_SET_DRIVE_MODE(PORT_ADDRESS(pin) + 8, PIN_IN_PORT(pin), CY_SYS_PINS_DM_DIG_HIZ)
#define DIRECT_MODE_OUTPUT(base, pin) CY_SYS_PINS_SET_DRIVE_MODE(PORT_ADDRESS(pin) + 8, PIN_IN_PORT(pin), CY_SYS_PINS_DM_STRONG)
#elif defined(RBL_NRF51822)
#define PIN_TO_BASEREG(pin) (0)
#define PIN_TO_BITMASK(pin) (pin)
#define IO_REG_TYPE uint32_t
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR
#define DIRECT_READ(base, pin) nrf_gpio_pin_read(pin)
#define DIRECT_WRITE_LOW(base, pin) nrf_gpio_pin_clear(pin)
#define DIRECT_WRITE_HIGH(base, pin) nrf_gpio_pin_set(pin)
#define DIRECT_MODE_INPUT(base, pin) nrf_gpio_cfg_input(pin, NRF_GPIO_PIN_NOPULL)
#define DIRECT_MODE_OUTPUT(base, pin) nrf_gpio_cfg_output(pin)
#elif defined(__arc__) /* Arduino101/Genuino101 specifics */
#include "scss_registers.h"
#include "portable.h"
#include "avr/pgmspace.h"
#define GPIO_ID(pin) (g_APinDescription[pin].ulGPIOId)
#define GPIO_TYPE(pin) (g_APinDescription[pin].ulGPIOType)
#define GPIO_BASE(pin) (g_APinDescription[pin].ulGPIOBase)
#define DIR_OFFSET_SS 0x01
#define DIR_OFFSET_SOC 0x04
#define EXT_PORT_OFFSET_SS 0x0A
#define EXT_PORT_OFFSET_SOC 0x50
/* GPIO registers base address */
#define PIN_TO_BASEREG(pin) ((volatile uint32_t *)g_APinDescription[pin].ulGPIOBase)
#define PIN_TO_BITMASK(pin) pin
#define IO_REG_TYPE uint32_t
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR
static inline __attribute__((always_inline)) IO_REG_TYPE directRead(volatile IO_REG_TYPE * base, IO_REG_TYPE pin) {
IO_REG_TYPE ret;
if (SS_GPIO == GPIO_TYPE(pin)) {
ret = READ_ARC_REG(((IO_REG_TYPE)base + EXT_PORT_OFFSET_SS));
} else {
ret = MMIO_REG_VAL_FROM_BASE((IO_REG_TYPE)base, EXT_PORT_OFFSET_SOC);
}
return ((ret >> GPIO_ID(pin)) & 0x01);
}
static inline __attribute__((always_inline)) void directModeInput(volatile IO_REG_TYPE * base, IO_REG_TYPE pin) {
if (SS_GPIO == GPIO_TYPE(pin)) {
WRITE_ARC_REG(READ_ARC_REG((((IO_REG_TYPE)base) + DIR_OFFSET_SS)) & ~(0x01 << GPIO_ID(pin)), ((IO_REG_TYPE)(base) + DIR_OFFSET_SS));
} else {
MMIO_REG_VAL_FROM_BASE((IO_REG_TYPE)base, DIR_OFFSET_SOC) &= ~(0x01 << GPIO_ID(pin));
}
}
static inline __attribute__((always_inline)) void directModeOutput(volatile IO_REG_TYPE * base, IO_REG_TYPE pin) {
if (SS_GPIO == GPIO_TYPE(pin)) {
WRITE_ARC_REG(READ_ARC_REG(((IO_REG_TYPE)(base) + DIR_OFFSET_SS)) | (0x01 << GPIO_ID(pin)), ((IO_REG_TYPE)(base) + DIR_OFFSET_SS));
} else {
MMIO_REG_VAL_FROM_BASE((IO_REG_TYPE)base, DIR_OFFSET_SOC) |= (0x01 << GPIO_ID(pin));
}
}
static inline __attribute__((always_inline)) void directWriteLow(volatile IO_REG_TYPE * base, IO_REG_TYPE pin) {
if (SS_GPIO == GPIO_TYPE(pin)) {
WRITE_ARC_REG(READ_ARC_REG(base) & ~(0x01 << GPIO_ID(pin)), base);
} else {
MMIO_REG_VAL(base) &= ~(0x01 << GPIO_ID(pin));
}
}
static inline __attribute__((always_inline)) void directWriteHigh(volatile IO_REG_TYPE * base, IO_REG_TYPE pin) {
if (SS_GPIO == GPIO_TYPE(pin)) {
WRITE_ARC_REG(READ_ARC_REG(base) | (0x01 << GPIO_ID(pin)), base);
} else {
MMIO_REG_VAL(base) |= (0x01 << GPIO_ID(pin));
}
}
#define DIRECT_READ(base, pin) directRead(base, pin)
#define DIRECT_MODE_INPUT(base, pin) directModeInput(base, pin)
#define DIRECT_MODE_OUTPUT(base, pin) directModeOutput(base, pin)
#define DIRECT_WRITE_LOW(base, pin) directWriteLow(base, pin)
#define DIRECT_WRITE_HIGH(base, pin) directWriteHigh(base, pin)
#elif defined(__riscv)
/*
* Tested on highfive1
*
* Stable results are achieved operating in the
* two high speed modes of the highfive1. It
* seems to be less reliable in slow mode.
*/
#define PIN_TO_BASEREG(pin) (0)
#define PIN_TO_BITMASK(pin) digitalPinToBitMask(pin)
#define IO_REG_TYPE uint32_t
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR
static inline __attribute__((always_inline)) IO_REG_TYPE directRead(IO_REG_TYPE mask) {
return ((GPIO_REG(GPIO_INPUT_VAL) & mask) != 0) ? 1 : 0;
}
static inline __attribute__((always_inline)) void directModeInput(IO_REG_TYPE mask) {
GPIO_REG(GPIO_OUTPUT_XOR) &= ~mask;
GPIO_REG(GPIO_IOF_EN) &= ~mask;
GPIO_REG(GPIO_INPUT_EN) |= mask;
GPIO_REG(GPIO_OUTPUT_EN) &= ~mask;
}
static inline __attribute__((always_inline)) void directModeOutput(IO_REG_TYPE mask) {
GPIO_REG(GPIO_OUTPUT_XOR) &= ~mask;
GPIO_REG(GPIO_IOF_EN) &= ~mask;
GPIO_REG(GPIO_INPUT_EN) &= ~mask;
GPIO_REG(GPIO_OUTPUT_EN) |= mask;
}
static inline __attribute__((always_inline)) void directWriteLow(IO_REG_TYPE mask) {
GPIO_REG(GPIO_OUTPUT_VAL) &= ~mask;
}
static inline __attribute__((always_inline)) void directWriteHigh(IO_REG_TYPE mask) {
GPIO_REG(GPIO_OUTPUT_VAL) |= mask;
}
#define DIRECT_READ(base, mask) directRead(mask)
#define DIRECT_WRITE_LOW(base, mask) directWriteLow(mask)
#define DIRECT_WRITE_HIGH(base, mask) directWriteHigh(mask)
#define DIRECT_MODE_INPUT(base, mask) directModeInput(mask)
#define DIRECT_MODE_OUTPUT(base, mask) directModeOutput(mask)
#else
#define PIN_TO_BASEREG(pin) (0)
#define PIN_TO_BITMASK(pin) (pin)
#define IO_REG_TYPE unsigned int
#define IO_REG_BASE_ATTR
#define IO_REG_MASK_ATTR
#define DIRECT_READ(base, pin) digitalRead(pin)
#define DIRECT_WRITE_LOW(base, pin) digitalWrite(pin, LOW)
#define DIRECT_WRITE_HIGH(base, pin) digitalWrite(pin, HIGH)
#define DIRECT_MODE_INPUT(base, pin) pinMode(pin, INPUT)
#define DIRECT_MODE_OUTPUT(base, pin) pinMode(pin, OUTPUT)
#warning "OneWire. Fallback mode. Using API calls for pinMode,digitalRead and digitalWrite. Operation of this library is not guaranteed on this architecture."
#endif
#endif

View File

@@ -1,55 +0,0 @@
#ifndef OneWire_Direct_RegType_h
#define OneWire_Direct_RegType_h
#include <stdint.h>
// Platform specific I/O register type
#if defined(__AVR__)
#define IO_REG_TYPE uint8_t
#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK66FX1M0__) || defined(__MK64FX512__)
#define IO_REG_TYPE uint8_t
#elif defined(__IMXRT1052__) || defined(__IMXRT1062__)
#define IO_REG_TYPE uint32_t
#elif defined(__MKL26Z64__)
#define IO_REG_TYPE uint8_t
#elif defined(__SAM3X8E__) || defined(__SAM3A8C__) || defined(__SAM3A4C__)
#define IO_REG_TYPE uint32_t
#elif defined(__PIC32MX__)
#define IO_REG_TYPE uint32_t
#elif defined(ARDUINO_ARCH_ESP8266)
#define IO_REG_TYPE uint32_t
#elif defined(ARDUINO_ARCH_ESP32)
#define IO_REG_TYPE uint32_t
#define IO_REG_MASK_ATTR
#elif defined(ARDUINO_ARCH_STM32)
#define IO_REG_TYPE uint32_t
#elif defined(__SAMD21G18A__)
#define IO_REG_TYPE uint32_t
#elif defined(__ASR6501__)
#define IO_REG_TYPE uint32_t
#elif defined(RBL_NRF51822)
#define IO_REG_TYPE uint32_t
#elif defined(__arc__) /* Arduino101/Genuino101 specifics */
#define IO_REG_TYPE uint32_t
#elif defined(__riscv)
#define IO_REG_TYPE uint32_t
#else
#define IO_REG_TYPE unsigned int
#endif
#endif