Closed ToSa27 closed 9 years ago
Removing the fast pin access via register/mask and instead using the slow pinMode/digitalRead/digitalWrite functions seems to be a work-around (definitely not a good solution though). The easiest way to test that is to comment the block of defines in OneWire.h:
/*
#elif defined(__ESP8266_EX__)
#define PIN_TO_BASEREG(pin) (portOutputRegister(digitalPinToPort(pin)))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint8_t
#define IO_REG_ASM
#define DIRECT_READ(base, mask) (((*((base)+GPIO_IN_ADDRESS)) & (mask)) ? 1 : 0)
#define DIRECT_MODE_INPUT(base, mask) ((*((base)+GPIO_ENABLE_ADDRESS)) &= ~(mask))
#define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+GPIO_ENABLE_ADDRESS)) |= (mask))
#define DIRECT_WRITE_LOW(base, mask) ((*(base)) &= ~(mask))
#define DIRECT_WRITE_HIGH(base, mask) ((*(base)) |= (mask))
*/
#else
#define PIN_TO_BASEREG(pin) NULL
#define PIN_TO_BITMASK(pin) (pin)
#define IO_REG_TYPE uint16_t
#define IO_REG_ASM
#define DIRECT_READ(base, mask) ((digitalRead(mask) > 0) ? 1 : 0)
#define DIRECT_MODE_INPUT(base, mask) (pinMode(mask, INPUT))
#define DIRECT_MODE_OUTPUT(base, mask) (pinMode(mask, OUTPUT))
#define DIRECT_WRITE_LOW(base, mask) (digitalWrite(mask, LOW))
#define DIRECT_WRITE_HIGH(base, mask) (digitalWrite(mask, HIGH))
#endif
Hello. Thank you. Can you reproduce this with direct pin switching code (portOutputRegister, digitalPinToBitMask) without using additional libraries?
I'll give that a try and report back.
Separate question: did you define ARDUINO somewhere? It appears that all code blocks like this:
#if ARDUINO >= 100
... do something ...
#else
... do something else ...
#endif
actually end up proceeding the second block because ARDUINO is not defined at all. Is that by purpose - you might end up using code that is just kept for compatibility with very old arduino core versions?
It is reproducible with the code below not using any library. The defines are copied from OneWire.h though and I would guess these defines are part of the problem...
[code]
IO_REG_TYPE bitmask; volatile IO_REG_TYPE *baseReg;
void init() { Serial.begin(SERIAL_BAUD_RATE); Serial.systemDebugOutput(true);
bitmask = PIN_TO_BITMASK(WORK_PIN);
baseReg = PIN_TO_BASEREG(WORK_PIN);
Serial.println("DIRECT_MODE_OUTPUT");
DIRECT_MODE_OUTPUT(baseReg, bitmask);
Serial.println("DIRECT_MODE_OUTPUT done");
delay(5000);
Serial.println("DIRECT_WRITE_HIGH");
DIRECT_WRITE_HIGH(baseReg, bitmask); // <== here GPIO4 goes high (even if pin is 12)
Serial.println("DIRECT_WRITE_HIGH done");
delay(5000);
} [/code]
It is for sure the logic in SmingCore\pins_arduino.h that causes the issues and need to be adjusted. For example:
#define digitalPinToPort(P) ( P < 0 ? NOT_A_PIN : ( (int)P < 8 ? PA : ( (int)P < 16 ? PB : ( (int)P == 16 ? PC : NOT_A_PIN ) ) ) )
#define digitalPinToBitMask(P) ( (int)P < 8 ? _BV((int)P) : ( P < 16 ? _BV( (int)P-8 ) : 1) )
#define STD_GPIO_OUT (PERIPHS_GPIO_BASEADDR + GPIO_OUT_ADDRESS)
#define STD_GPIO_IN (PERIPHS_GPIO_BASEADDR + GPIO_IN_ADDRESS)
#define STD_GPIO_ENABLE (PERIPHS_GPIO_BASEADDR + GPIO_ENABLE_ADDRESS)
#define portOutputRegister(P) ( ((volatile uint8_t*)(P != PC ? STD_GPIO_OUT : RTC_GPIO_OUT)) + ( ( ((int)P) == PB ) ? 1 : 0) )
#define portInputRegister(P) ( ((volatile uint8_t*)(P != PC ? STD_GPIO_IN : RTC_GPIO_IN_DATA)) + ( ( ((int)P) == PB ) ? 1 : 0) )
#define portModeRegister(P) ( ((volatile uint8_t*)(P != PC ? STD_GPIO_ENABLE : RTC_GPIO_ENABLE)) + ( ( ((int)P) == PB ) ? 1 : 0) ) // Stored bits: 0=In, 1=Out
the ESP8266 gpio registers are 16 bit wide - GPIO0...GPIO15 all covered within one register (see ESP8266 wiki).
I guess it's all working fine for pin 0..7 but starts causing issues for 8.. Just a few libraries actually use these functions which is probably why it wasn't reported earlier.
This issue has been inactive for a long period and is being closed. If the issue is still valid please open a new with complete description
The OneWire library impacts pins other than the one pin selected. Easy to reproduce on an ESP-12:
The LED at GPIO4 turns on when the OneWire library searches for devices and then turns off again.