Draft: Add 1-Wire driver
Contribution description
This patch adds a 1-Wire driver which can handle multiple driver implementations. Included in the patch is a soft 1-Wire driver implementation.
Testing procedure
TODO
Issues/PRs references
- PR #18051 was an earlier attempt of mine.
- PR #14897 was an attempt that predated my first attempt. I used it as a starting point this time. Although, not much of it actually remains.
Nice PR ! I don't think we need to define a test for the high-level API. IMO, it will be good enough to glue it to some low level driver and ensure the hardware works as expected. Can I test this PR with a DS18B20 probe ?
I don't think we need to define a test for the high-level API. IMO, it will be good enough to glue it to some low level driver and ensure the hardware works as expected.
Ok. I don't know much about RIOT's test system yet. I will work on getting up to speed and write some tests for this PR.
Can I test this PR with a DS18B20 probe ?
The onewire_search() and onewire_read_rom() should work on a ds18b20 device. I plan to convert the ds18 driver over to use this new API, but haven't yet (that will be a different PR probably). Once that's done then you'll be able to read the device's temperature using the ds18 driver via this new onewire API.
The way I've been testing this API and driver so far is with a ds2433 and driver. The ds2433 driver is functional, but still needs work before I submit it for PR.
I think the test would need some more instructions, in a README.md file or so. I wasn't really sure how to get it working three weeks ago and wasn't successful in doing so 😅
Yeah, the test is not really complete as is. After writing the test, I realized what a pain it is to define a bus and its params. So I'm reworking that now. I also went ahead and ported the ds18 driver to use the onewire API (coming in a separate PR). I've re-worked the API to use less RAM and ROM when only one back-end is enabled too. You should see some changes in this PR once I am finished. Pretty close...
At this point. I don't expect to make any more big changes to the driver code. The test code still needs some work and doc. I'm also scratching my head on how the test could be made to be common as it really could be used to test any onewire backend. I hate the thought of each new backend just copying the test and have a bunch of near duplicates.
Can I test this PR with a DS18B20 probe ?
@dylad : a few years later, yes. See my WIP branch for that.
Unfortunately I don't have the Discovery at hand, but I tried with an nRF52840DK and a Nucleo-L152RE and L073RZ.
The nRF52840DK just doesn't work, it does not recognize the DS18B20. Neither with the tests/drivers/onewire test (after I added an unconditional .pin = GPIO_PIN(0,3), to the struct) nor with the tests/drivers/ds18 (same modification).
This is the log (with ENABLE_DEBUG = 1 in the drivers/onewire/onewire.c):
2025-05-07 14:37:29,551 # main(): This is RIOT! (Version: 2025.04-devel-500-g42e08-add-driver-onewire)
2025-05-07 14:37:29,552 # _onewire_init
2025-05-07 14:37:29,555 # onewire_write: f0
2025-05-07 14:37:29,578 # found device: 0000000000000000
2025-05-07 14:37:29,581 # onewire_write: f0
2025-05-07 14:37:29,605 # failure to enumerate device: EBADMSG
The same happens on other GPIO pins as well and also with an external 4.7k Pull Up.
It appears like some data is exchanged on the bus, but idk enough about OneWire to tell what might be the fault here.
Without external Pullup:
With Pullup:
For good measure I tried with an 1k Pullup, but that leads to the same result.
The sensor is a fake, but it does work. I checked it with an Arduino Uno and this tool: https://github.com/cpetrich/counterfeit_DS18B20
Sensor ROM and Current Scratchpad Content:
1. 28-54-DE-15-C0-21-08-3D, 28-0821C015DE54: 50/05/4B/46/7F/FF/0C/10/1C 85.00 oC
Number of Sensors: 1.
The Nucleos crash with a failed assertion:
2025-05-07 14:33:03,551 # main(): This is RIOT! (Version: 2025.04-devel-500-g42e08-add-driver-onewire)
2025-05-07 14:33:03,554 # 0x8001537 => FAILED ASSERTION.
cbuec@W11nMate:~/RIOTstuff/riot-onewire/RIOT/tests/drivers/onewire$ arm-none-eabi-objdump -d --start-address 0x8001520 --stop-address 0x8001564 bin/nucleo-l073rz/tests_onewire.elf
bin/nucleo-l073rz/tests_onewire.elf: file format elf32-littlearm
Disassembly of section .text:
08001520 <_onewire_write_bits+0x44>:
8001520: 08001341 .word 0x08001341
8001524: 0800135d .word 0x0800135d
08001528 <soft_onewire_init>:
8001528: b570 push {r4, r5, r6, lr}
800152a: 0004 movs r4, r0
800152c: 000d movs r5, r1
800152e: 2800 cmp r0, #0
8001530: d101 bne.n 8001536 <soft_onewire_init+0xe>
8001532: f7ff f83d bl 80005b0 <_assert_panic>
8001536: 2900 cmp r1, #0
8001538: d0fb beq.n 8001532 <soft_onewire_init+0xa>
800153a: f7ff fbe1 bl 8000d00 <_onewire_init>
800153e: 2301 movs r3, #1
8001540: 425b negs r3, r3
8001542: 60a3 str r3, [r4, #8]
8001544: 4a05 ldr r2, [pc, #20] ; (800155c <soft_onewire_init+0x34>)
8001546: 0023 movs r3, r4
8001548: 4905 ldr r1, [pc, #20] ; (8001560 <soft_onewire_init+0x38>)
800154a: 68a8 ldr r0, [r5, #8]
800154c: f7ff fd2a bl 8000fa4 <timer_init>
8001550: 2800 cmp r0, #0
8001552: d1ee bne.n 8001532 <soft_onewire_init+0xa>
8001554: 6820 ldr r0, [r4, #0]
8001556: f7ff fe89 bl 800126c <_bus_release.isra.0>
800155a: bd70 pop {r4, r5, r6, pc}
800155c: 08001265 .word 0x08001265
8001560: 000f4240 .word 0x000f4240
So it seems like it is the first assertion in the soft_onewire_init function.
Murdock results
:x: FAILED
42e088ca9daa7241ad31731d5ab51b4f268be501 WIP: drivers/soft_onewire: add tests
| Success | Failures | Total | Runtime |
|---|---|---|---|
| 4569 | 0 | 9811 | 05m:30s |