Skip to content

Commit

Permalink
OneWireNg_PicoRP2040PIO: destructor added (#72)
Browse files Browse the repository at this point in the history
  • Loading branch information
pstolarz authored Jan 28, 2025
1 parent d07750b commit 3a52f61
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 3 deletions.
52 changes: 51 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ devices.
* [`OneWireNg_BitBang`](#arch_bb)
* [`OneWireNg_PLATFORM`](#arch_plat)
* [RP2040 drivers](#arch_rp2040)
* [RP2040 PIO driver controlling many buses](#arch_rp2040pio_multi_bus)
* [OneWire compatibility](#ow)
* [DallasTemperature library](#ow_dallas)
* [License](#license)
Expand Down Expand Up @@ -451,12 +452,61 @@ header which tries to detect platform the compilation is proceeded and:
interface for RP2040 MCU using Programmable I/O (PIO) peripheral. Second type
of driver supporting RP2040 platform is `OneWireNg_PicoRP2040` bit-banging
driver. Use `CONFIG_RP2040_PIO_DRIVER` configuration parameter to setup a
specific driver for the platform.
specific driver for the platform (by default `CONFIG_RP2040_PIO_DRIVER` configures
the PIO driver as default one for RP2040 MCU).

NOTE: There are observed problems with Pico SDK's serial output (USB,
UART) while using the bit-banging driver in `TIMING_STRICT` mode (see
`CONFIG_BITBANG_TIMING`).

<a name="arch_rp2040pio_multi_bus"></a>
#### RP2040 PIO driver controlling many buses

Number of GPIOs which may be handled by `OneWireNg_PicoRP2040PIO` driver objects
is limited to:

* 8 - if `CONFIG_RP2040_PIOSM_NUM_USED` is set to `1`. In this is case 4 drivers
are handled by RP2040's `PIO0` and 4 by `PIO1`.
* 4 - if `CONFIG_RP2040_PIOSM_NUM_USED` is set to `2` (this is the default value
for the configuration parameter). In this is case 2 drivers are handled by
RP2040's `PIO0` and 2 by `PIO1`.

NOTE: The above limits assume the RP2040's PIO is not used by other programs
occupying its resources. In such case the limits are of course lower.

The following code presents how to create the PIO drivers controlling multiple
buses (dynamic allocation version).

```cpp
constexpr bool INT_PULLUP = false;

// the driver is handled by PIO0/SM0
OneWireNg *ow1 = new OneWireNg_PicoRP2040PIO(PIN1, INT_PULLUP, 0);

// create more drivers handled by PIO0/SM1..3
// the drivers reuse PIO0 program loaded by driver ow1
OneWireNg *ow2 = new OneWireNg_PicoRP2040PIO(PIN2, INT_PULLUP, (OneWireNg_PicoRP2040PIO&)*ow1);
#if CONFIG_RP2040_PIOSM_NUM_USED <= 1
OneWireNg *ow3 = new OneWireNg_PicoRP2040PIO(PIN3, INT_PULLUP, (OneWireNg_PicoRP2040PIO&)*ow1);
OneWireNg *ow4 = new OneWireNg_PicoRP2040PIO(PIN4, INT_PULLUP, (OneWireNg_PicoRP2040PIO&)*ow1);
#endif

// the driver is handled by PIO1/SM0
OneWireNg *ow5 = new OneWireNg_PicoRP2040PIO(PIN5, INT_PULLUP, 1);

// create more drivers handled by PIO1/SM1..3
// the drivers reuse PIO1 program loaded by driver ow5
OneWireNg *ow6 = new OneWireNg_PicoRP2040PIO(PIN6, INT_PULLUP, (OneWireNg_PicoRP2040PIO&)*ow5);
#if CONFIG_RP2040_PIOSM_NUM_USED <= 1
OneWireNg *ow7 = new OneWireNg_PicoRP2040PIO(PIN7, INT_PULLUP, (OneWireNg_PicoRP2040PIO&)*ow5);
OneWireNg *ow8 = new OneWireNg_PicoRP2040PIO(PIN8, INT_PULLUP, (OneWireNg_PicoRP2040PIO&)*ow5);
#endif
```

NOTE: In the above example drivers `ow2`..`ow4` use `ow1` as a base driver,
which means the `ow1` must live as long as the dependant drivers. Similarly
with `ow6`..`ow8` and `ow5` driver.

<a name="ow"></a>
## OneWire compatibility

Expand Down
2 changes: 1 addition & 1 deletion src/OneWire.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021,2022 Piotr Stolarz
* Copyright (c) 2021,2022,2025 Piotr Stolarz
* OneWireNg: Arduino 1-wire service library
*
* Distributed under the 2-clause BSD License (the License)
Expand Down
38 changes: 37 additions & 1 deletion src/platform/OneWireNg_PicoRP2040PIO.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 Piotr Stolarz
* Copyright (c) 2022,2025 Piotr Stolarz
* OneWireNg: Arduino 1-wire service library
*
* Distributed under the 2-clause BSD License (the License)
Expand Down Expand Up @@ -68,6 +68,8 @@ class OneWireNg_PicoRP2040PIO: public OneWireNg
_sm2 = pio_claim_unused_sm(_pio, true);
#endif

_pioBound = false;
_progOwner = true;
_exeProg = INVALID_PROG;

powerBus(false);
Expand Down Expand Up @@ -134,6 +136,10 @@ class OneWireNg_PicoRP2040PIO: public OneWireNg
* - New service will use its own 1 or 2 state machine(s), depending on
* @c CONFIG_RP2040_PIOSM_NUM_USED configuration.
*
* @warning While creating the service object using this constructor
* the @c base object MUST exist for the lifetime of the newly
* created object.
*
* @note The routine enables create up to 2 or 4 (depending on @c
* CONFIG_RP2040_PIOSM_NUM_USED configuration) 1-wire services
* handled by different pins for a single PIO peripheral.
Expand All @@ -150,6 +156,8 @@ class OneWireNg_PicoRP2040PIO: public OneWireNg
_sm2 = pio_claim_unused_sm(_pio, true);
#endif

_pioBound = false;
_progOwner = false;
_exeProg = INVALID_PROG;

powerBus(false);
Expand Down Expand Up @@ -187,6 +195,31 @@ class OneWireNg_PicoRP2040PIO: public OneWireNg
#endif
}

/**
* Clean-up PIO resources while destroying the service.
*/
~OneWireNg_PicoRP2040PIO()
{
/* disclaim unused PIO SM(s) */
pio_sm_set_enabled(_pio, _sm1, false);
pio_sm_unclaim(_pio, _sm1);
#if CONFIG_RP2040_PIOSM_NUM_USED > 1
pio_sm_set_enabled(_pio, _sm2, false);
pio_sm_unclaim(_pio, _sm2);
#endif
/*
* Dispose the PIO programs only in case the object is in ownership
* of them. Since OD uses the same PIO programs as STD mode, free
* STD programs only.
*/
if (_progOwner) {
pio_remove_program(_pio, &w1_reset_program, _addrs[RESET_STD]);
pio_remove_program(_pio, &w1_touch0_program, _addrs[TOUCH0_STD]);
pio_remove_program(_pio, &w1_touch1_program, _addrs[TOUCH1_STD]);
_progOwner = false;
}
}

/**
* Transmit reset cycle on the 1-wire bus.
*/
Expand Down Expand Up @@ -320,6 +353,9 @@ class OneWireNg_PicoRP2040PIO: public OneWireNg
/** w1-bus GPIO bound to PIO flag */
bool _pioBound;

/** PIO programs ownership indicator */
bool _progOwner;

/** PIO's w1 programs addresses */
uint _addrs[PROGS_NUM];

Expand Down

0 comments on commit 3a52f61

Please sign in to comment.