Skip to content

Commit 96a0353

Browse files
committed
Add some missing pio functions
Adds some 64 versions to work with rp2350b and more than 32 pins. Change cyw43 code to use the new function. Fixes #1834
1 parent c4b55f6 commit 96a0353

File tree

3 files changed

+83
-7
lines changed

3 files changed

+83
-7
lines changed

src/rp2_common/hardware_pio/include/hardware/pio.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,12 @@ static inline uint pio_get_gpio_base(PIO pio) {
708708
#endif
709709
}
710710

711+
static inline void check_pio_pin_mask64(__unused PIO pio, __unused uint64_t pinmask) {
712+
// check no pins are set in the mask which are incompatible with the pio
713+
valid_params_if(HARDWARE_PIO, (pio_get_gpio_base(pio) == 0 || ((pinmask & ((1ull << pio_get_gpio_base(pio)) - 1)) == 0)) &&
714+
(pinmask & ~((1ull << NUM_BANK0_GPIOS) - 1)) == 0);
715+
}
716+
711717
/*! \brief Apply a state machine configuration to a state machine
712718
* \ingroup hardware_pio
713719
*
@@ -1717,20 +1723,36 @@ static inline void pio_sm_clear_fifos(PIO pio, uint sm) {
17171723
* before restoring the state machine's pin configuration to what it was.
17181724
*
17191725
* This method is provided as a convenience to set initial pin states, and should not be used against a state machine that is enabled.
1726+
* Note: This method only works for pins < 32. To use with pins >= 32 call pio_sm_set_pins64
17201727
*
17211728
* \param pio The PIO instance; e.g. \ref pio0 or \ref pio1
17221729
* \param sm State machine index (0..3) to use
17231730
* \param pin_values the pin values to set
17241731
*/
17251732
void pio_sm_set_pins(PIO pio, uint sm, uint32_t pin_values);
17261733

1734+
/*! \brief Use a state machine to set a value on all pins for the PIO instance
1735+
* \ingroup hardware_pio
1736+
*
1737+
* This method repeatedly reconfigures the target state machine's pin configuration and executes 'set' instructions to set values on all 32 pins,
1738+
* before restoring the state machine's pin configuration to what it was.
1739+
*
1740+
* This method is provided as a convenience to set initial pin states, and should not be used against a state machine that is enabled.
1741+
*
1742+
* \param pio The PIO instance; e.g. \ref pio0 or \ref pio1
1743+
* \param sm State machine index (0..3) to use
1744+
* \param pin_values the pin values to set
1745+
*/
1746+
void pio_sm_set_pins64(PIO pio, uint sm, uint64_t pin_values);
1747+
17271748
/*! \brief Use a state machine to set a value on multiple pins for the PIO instance
17281749
* \ingroup hardware_pio
17291750
*
17301751
* This method repeatedly reconfigures the target state machine's pin configuration and executes 'set' instructions to set values on up to 32 pins,
17311752
* before restoring the state machine's pin configuration to what it was.
17321753
*
17331754
* This method is provided as a convenience to set initial pin states, and should not be used against a state machine that is enabled.
1755+
* Note: This method only works for pins < 32. To use with pins >= 32 call pio_sm_set_pins_with_mask64
17341756
*
17351757
* \param pio The PIO instance; e.g. \ref pio0 or \ref pio1
17361758
* \param sm State machine index (0..3) to use
@@ -1739,6 +1761,21 @@ void pio_sm_set_pins(PIO pio, uint sm, uint32_t pin_values);
17391761
*/
17401762
void pio_sm_set_pins_with_mask(PIO pio, uint sm, uint32_t pin_values, uint32_t pin_mask);
17411763

1764+
/*! \brief Use a state machine to set a value on multiple pins for the PIO instance
1765+
* \ingroup hardware_pio
1766+
*
1767+
* This method repeatedly reconfigures the target state machine's pin configuration and executes 'set' instructions to set values on up to 32 pins,
1768+
* before restoring the state machine's pin configuration to what it was.
1769+
*
1770+
* This method is provided as a convenience to set initial pin states, and should not be used against a state machine that is enabled.
1771+
*
1772+
* \param pio The PIO instance; e.g. \ref pio0 or \ref pio1
1773+
* \param sm State machine index (0..3) to use
1774+
* \param pin_values the pin values to set (if the corresponding bit in pin_mask is set)
1775+
* \param pin_mask a bit for each pin to indicate whether the corresponding pin_value for that pin should be applied.
1776+
*/
1777+
void pio_sm_set_pins_with_mask64(PIO pio, uint sm, uint64_t pin_values, uint64_t pin_mask);
1778+
17421779
/*! \brief Use a state machine to set the pin directions for multiple pins for the PIO instance
17431780
* \ingroup hardware_pio
17441781
*
@@ -1754,6 +1791,22 @@ void pio_sm_set_pins_with_mask(PIO pio, uint sm, uint32_t pin_values, uint32_t p
17541791
*/
17551792
void pio_sm_set_pindirs_with_mask(PIO pio, uint sm, uint32_t pin_dirs, uint32_t pin_mask);
17561793

1794+
/*! \brief Use a state machine to set the pin directions for multiple pins for the PIO instance
1795+
* \ingroup hardware_pio
1796+
*
1797+
* This method repeatedly reconfigures the target state machine's pin configuration and executes 'set' instructions to set pin directions on up to 32 pins,
1798+
* before restoring the state machine's pin configuration to what it was.
1799+
*
1800+
* This method is provided as a convenience to set initial pin directions, and should not be used against a state machine that is enabled.
1801+
* Note: This method only works for pins < 32. To use with pins >= 32 call pio_sm_set_pindirs_with_mask64
1802+
*
1803+
* \param pio The PIO instance; e.g. \ref pio0 or \ref pio1
1804+
* \param sm State machine index (0..3) to use
1805+
* \param pin_dirs the pin directions to set - 1 = out, 0 = in (if the corresponding bit in pin_mask is set)
1806+
* \param pin_mask a bit for each pin to indicate whether the corresponding pin_value for that pin should be applied.
1807+
*/
1808+
void pio_sm_set_pindirs_with_mask64(PIO pio, uint sm, uint64_t pin_dirs, uint64_t pin_mask);
1809+
17571810
/*! \brief Use a state machine to set the same pin direction for multiple consecutive pins for the PIO instance
17581811
* \ingroup hardware_pio
17591812
*

src/rp2_common/hardware_pio/pio.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,13 +205,22 @@ void pio_clear_instruction_memory(PIO pio) {
205205
hw_claim_unlock(save);
206206
}
207207

208+
void pio_sm_set_pins(PIO pio, uint sm, uint32_t pins) {
209+
pio_sm_set_pins64(pio, sm, pins);
210+
}
211+
208212
// Set the value of all PIO pins. This is done by forcibly executing
209213
// instructions on a "victim" state machine, sm. Ideally you should choose one
210214
// which is not currently running a program. This is intended for one-time
211215
// setup of initial pin states.
212-
void pio_sm_set_pins(PIO pio, uint sm, uint32_t pins) {
216+
void pio_sm_set_pins64(PIO pio, uint sm, uint64_t pins) {
213217
check_pio_param(pio);
214218
check_sm_param(sm);
219+
check_pio_pin_mask64(pio, pins);
220+
221+
#if PICO_PIO_USE_GPIO_BASE
222+
pins >>= pio_get_gpio_base(pio);
223+
#endif
215224
uint32_t pinctrl_saved = pio->sm[sm].pinctrl;
216225
uint32_t execctrl_saved = pio->sm[sm].execctrl;
217226
hw_clear_bits(&pio->sm[sm].execctrl, 1u << PIO_SM0_EXECCTRL_OUT_STICKY_LSB);
@@ -232,8 +241,17 @@ void pio_sm_set_pins(PIO pio, uint sm, uint32_t pins) {
232241
}
233242

234243
void pio_sm_set_pins_with_mask(PIO pio, uint sm, uint32_t pinvals, uint32_t pin_mask) {
244+
pio_sm_set_pins_with_mask64(pio, sm, pinvals, pin_mask);
245+
}
246+
247+
void pio_sm_set_pins_with_mask64(PIO pio, uint sm, uint64_t pinvals, uint64_t pin_mask) {
235248
check_pio_param(pio);
236249
check_sm_param(sm);
250+
check_pio_pin_mask64(pio, pin_mask);
251+
#if PICO_PIO_USE_GPIO_BASE
252+
pinvals >>= pio_get_gpio_base(pio);
253+
pin_mask >>= pio_get_gpio_base(pio);
254+
#endif
237255
uint32_t pinctrl_saved = pio->sm[sm].pinctrl;
238256
uint32_t execctrl_saved = pio->sm[sm].execctrl;
239257
hw_clear_bits(&pio->sm[sm].execctrl, 1u << PIO_SM0_EXECCTRL_OUT_STICKY_LSB);
@@ -250,8 +268,17 @@ void pio_sm_set_pins_with_mask(PIO pio, uint sm, uint32_t pinvals, uint32_t pin_
250268
}
251269

252270
void pio_sm_set_pindirs_with_mask(PIO pio, uint sm, uint32_t pindirs, uint32_t pin_mask) {
271+
pio_sm_set_pindirs_with_mask64(pio, sm, pindirs, pin_mask);
272+
}
273+
274+
void pio_sm_set_pindirs_with_mask64(PIO pio, uint sm, uint64_t pindirs, uint64_t pin_mask) {
253275
check_pio_param(pio);
254276
check_sm_param(sm);
277+
check_pio_pin_mask64(pio, pin_mask);
278+
#if PICO_PIO_USE_GPIO_BASE
279+
pindirs >>= pio_get_gpio_base(pio);
280+
pin_mask >>= pio_get_gpio_base(pio);
281+
#endif
255282
uint32_t pinctrl_saved = pio->sm[sm].pinctrl;
256283
uint32_t execctrl_saved = pio->sm[sm].execctrl;
257284
hw_clear_bits(&pio->sm[sm].execctrl, 1u << PIO_SM0_EXECCTRL_OUT_STICKY_LSB);

src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -250,9 +250,7 @@ int cyw43_spi_transfer(cyw43_int_t *self, const uint8_t *tx, size_t tx_length, u
250250
pio_sm_set_enabled(bus_data->pio, bus_data->pio_sm, false);
251251
pio_sm_set_wrap(bus_data->pio, bus_data->pio_sm, bus_data->pio_offset, bus_data->pio_offset + SPI_OFFSET_END - 1);
252252
pio_sm_clear_fifos(bus_data->pio, bus_data->pio_sm);
253-
pio_sm_set_pindirs_with_mask(bus_data->pio, bus_data->pio_sm,
254-
1u << (CYW43_PIN_WL_DATA_OUT - pio_get_gpio_base(bus_data->pio)),
255-
1u << (CYW43_PIN_WL_DATA_OUT - pio_get_gpio_base(bus_data->pio)));
253+
pio_sm_set_pindirs_with_mask64(bus_data->pio, bus_data->pio_sm, 1ull << CYW43_PIN_WL_DATA_OUT, 1ull << CYW43_PIN_WL_DATA_OUT);
256254
pio_sm_restart(bus_data->pio, bus_data->pio_sm);
257255
pio_sm_clkdiv_restart(bus_data->pio, bus_data->pio_sm);
258256
pio_sm_put(bus_data->pio, bus_data->pio_sm, tx_length * 8 - 1);
@@ -294,9 +292,7 @@ int cyw43_spi_transfer(cyw43_int_t *self, const uint8_t *tx, size_t tx_length, u
294292
pio_sm_set_enabled(bus_data->pio, bus_data->pio_sm, false);
295293
pio_sm_set_wrap(bus_data->pio, bus_data->pio_sm, bus_data->pio_offset, bus_data->pio_offset + SPI_OFFSET_LP1_END - 1);
296294
pio_sm_clear_fifos(bus_data->pio, bus_data->pio_sm);
297-
pio_sm_set_pindirs_with_mask(bus_data->pio, bus_data->pio_sm,
298-
1u << (CYW43_PIN_WL_DATA_OUT - pio_get_gpio_base(bus_data->pio)),
299-
1u << (CYW43_PIN_WL_DATA_OUT - pio_get_gpio_base(bus_data->pio)));
295+
pio_sm_set_pindirs_with_mask64(bus_data->pio, bus_data->pio_sm, 1ull << CYW43_PIN_WL_DATA_OUT, 1ull << CYW43_PIN_WL_DATA_OUT);
300296
pio_sm_restart(bus_data->pio, bus_data->pio_sm);
301297
pio_sm_clkdiv_restart(bus_data->pio, bus_data->pio_sm);
302298
pio_sm_put(bus_data->pio, bus_data->pio_sm, tx_length * 8 - 1);

0 commit comments

Comments
 (0)