Closed caternuson closed 6 years ago
I think it is beyond OneWire
. I ran this test for DigitalInOut
, since that is all that shared-modules/bitbangio/OneWire
is doing:
Adafruit CircuitPython 3.0.0-alpha.1-737-gd1b3c3c-dirty on 2018-06-22; Metro M4 Express with samd51j19
>>> import board, digitalio
>>> d = digitalio.DigitalInOut(board.D11)
>>> d.switch_to_output(True, digitalio.DriveMode.PUSH_PULL)
>>> d.switch_to_input()
>>>
Same flatline result:
The 3.x change in DigitalInOut
that I have a hunch is causing this, is a switch to using hri_port_set_PINCFG_DRVSTR_bit
to set the pin config in switch_to_output
. Then for whatever reason, gpio_set_function
in switch_to_input
isn't overriding the pin config.
I'm going to dip into the ASF4/datasheet to see if any documentation supports this.
NOTE: while i'm on a dirty, oldish 3.x, I verified it includes the same digitalio code as RC0. also, for whatever reason, my tags never update anyway. this is post 3.alpha-6 firmware. 🤷♂️
The DRVSTR bit setting thing was added about eight months ago, but the code was wrong for PBxx pins initially. It worked OK for PAxx pins. That was fixed 2 months ago.
btw if you want to update your tags, you can do git pull --tags
or git fetch --tags
.
@sommersoft How did you decide to do digitalio.DriveMode.PUSH_PULL
and give no args to switch_to_input()
?
shared-module/bitbangio/OneWire.c` does this:
void shared_module_bitbangio_onewire_write_bit(bitbangio_onewire_obj_t* self,
bool bit) {
common_hal_mcu_disable_interrupts();
common_hal_digitalio_digitalinout_switch_to_output(&self->pin, false, DRIVE_MODE_OPEN_DRAIN);
common_hal_mcu_delay_us(bit? 6 : 60);
common_hal_digitalio_digitalinout_switch_to_input(&self->pin, PULL_NONE);
common_hal_mcu_delay_us(bit? 64 : 10);
common_hal_mcu_enable_interrupts();
}
which is more like
d = digitalio.DigitalInOut(board.D11)
d.switch_to_output(False, digitalio.DriveMode.OPEN_DRAIN)
# sleep 6 or 60 usecs
d.switch_to_input(digitalio.Pull.NONE)
# sleep 64 or 10 usecs
My initial test with OPEN_DRAIN
didn't pull the pin high, since I'm using the pin directly. If I were using a OW device, the slave would be pulling it high; at least that is my understanding. So, I forced it with PUSH_PULL
.
The no arg switch_to_input
is because it defaults to PULL_NONE
anyway.
I was really just trying to force the behavior of switching between modes, and being able to capture it with the Saleae.
Yep! That was my bad. Using switch_to_input(pull=Pull.DOWN)
fixes my test. Disregard my rambling... 😄
I spent time on this and have OneWire working, if a bit erratically, with a DS18B20 temp sensor. Two issues:
common_hal_digitalinout_set_pull()
worked differently in 2.x vs. 3.0. In 2.x it always sets the port direction to input. In 3.0 it just set the pull-up/down/none bits, without forcing the direction to input. common_hal_digitalio_digitalinout_switch_to_input()
was depending on the direction change, because it wasn't doing it itself explicitly. (Thanks to @sommersoft for looking around here, which caused me to look at it all carefully.)shared_module_bitbangio_onewire_read_bit()
there is a delay of 6us. There was already a comment that it should be 9 but 9 didn't work. I just commented out the delay completely and reads of the sensor work most of the time, though sometimes I get a CRC error.Given the strict timing, perhaps using pulseio would be better, if possible.
Thanks everyone!
Yep. Looks good:
Adafruit CircuitPython 3.0.0-rc.0-13-gf1248dc on 2018-06-29; Adafruit ItsyBitsy M0 Express with samd21g18
>>> import board, busio
>>> ow = busio.OneWire(board.D7)
>>> ow.write_bit(1)
DS18B20 checks out:
Adafruit CircuitPython 3.0.0-rc.0-13-gf1248dc on 2018-06-29; Adafruit ItsyBitsy M0 Express with samd21g18
>>> import board
>>> from adafruit_onewire.bus import OneWireBus
>>> import adafruit_ds18x20
>>> ow_bus = OneWireBus(board.D7)
>>> devices = ow_bus.scan()
>>> ds18b20 = adafruit_ds18x20.DS18X20(ow_bus, devices[0])
>>> ds18b20.temperature
24.5
DS2413 checks out:
Adafruit CircuitPython 3.0.0-rc.0-13-gf1248dc on 2018-06-29; Adafruit ItsyBitsy M0 Express with samd21g18
>>> import board
>>> from adafruit_onewire.bus import OneWireBus
>>> import adafruit_ds2413
>>> ow_bus = OneWireBus(board.D7)
>>> ds = adafruit_ds2413.DS2413(ow_bus, ow_bus.scan()[0])
>>> ds.IOA.direction = adafruit_ds2413.INPUT
>>> ds.IOA.value
True
>>> ds.IOA.value
False
REF: https://forums.adafruit.com/viewtopic.php?f=60&t=137405
D5 is a special pin on the Itsy, but even using D7 for testing indicates something is not working:
CP 2.3.1
CP 3.0.0 rc0