Skip to content

Commit bd89df1

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 bd89df1

File tree

3 files changed

+86
-7
lines changed

3 files changed

+86
-7
lines changed

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

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,15 @@ 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+
#if PICO_PIO_USE_GPIO_BASE
714+
valid_params_if(HARDWARE_PIO, (pinmask & ~(0xffffffffull << pio_get_gpio_base(pio))) == 0);
715+
#else
716+
valid_params_if(HARDWARE_PIO, (pinmask & ~0xffffffffull) == 0);
717+
#endif
718+
}
719+
711720
/*! \brief Apply a state machine configuration to a state machine
712721
* \ingroup hardware_pio
713722
*
@@ -1717,20 +1726,36 @@ static inline void pio_sm_clear_fifos(PIO pio, uint sm) {
17171726
* before restoring the state machine's pin configuration to what it was.
17181727
*
17191728
* This method is provided as a convenience to set initial pin states, and should not be used against a state machine that is enabled.
1729+
* Note: This method only works for pins < 32. To use with pins >= 32 call pio_sm_set_pins64
17201730
*
17211731
* \param pio The PIO instance; e.g. \ref pio0 or \ref pio1
17221732
* \param sm State machine index (0..3) to use
17231733
* \param pin_values the pin values to set
17241734
*/
17251735
void pio_sm_set_pins(PIO pio, uint sm, uint32_t pin_values);
17261736

1737+
/*! \brief Use a state machine to set a value on all pins for the PIO instance
1738+
* \ingroup hardware_pio
1739+
*
1740+
* This method repeatedly reconfigures the target state machine's pin configuration and executes 'set' instructions to set values on all 32 pins,
1741+
* before restoring the state machine's pin configuration to what it was.
1742+
*
1743+
* This method is provided as a convenience to set initial pin states, and should not be used against a state machine that is enabled.
1744+
*
1745+
* \param pio The PIO instance; e.g. \ref pio0 or \ref pio1
1746+
* \param sm State machine index (0..3) to use
1747+
* \param pin_values the pin values to set
1748+
*/
1749+
void pio_sm_set_pins64(PIO pio, uint sm, uint64_t pin_values);
1750+
17271751
/*! \brief Use a state machine to set a value on multiple pins for the PIO instance
17281752
* \ingroup hardware_pio
17291753
*
17301754
* This method repeatedly reconfigures the target state machine's pin configuration and executes 'set' instructions to set values on up to 32 pins,
17311755
* before restoring the state machine's pin configuration to what it was.
17321756
*
17331757
* This method is provided as a convenience to set initial pin states, and should not be used against a state machine that is enabled.
1758+
* Note: This method only works for pins < 32. To use with pins >= 32 call pio_sm_set_pins_with_mask64
17341759
*
17351760
* \param pio The PIO instance; e.g. \ref pio0 or \ref pio1
17361761
* \param sm State machine index (0..3) to use
@@ -1739,13 +1764,29 @@ void pio_sm_set_pins(PIO pio, uint sm, uint32_t pin_values);
17391764
*/
17401765
void pio_sm_set_pins_with_mask(PIO pio, uint sm, uint32_t pin_values, uint32_t pin_mask);
17411766

1767+
/*! \brief Use a state machine to set a value on multiple pins for the PIO instance
1768+
* \ingroup hardware_pio
1769+
*
1770+
* This method repeatedly reconfigures the target state machine's pin configuration and executes 'set' instructions to set values on up to 32 pins,
1771+
* before restoring the state machine's pin configuration to what it was.
1772+
*
1773+
* This method is provided as a convenience to set initial pin states, and should not be used against a state machine that is enabled.
1774+
*
1775+
* \param pio The PIO instance; e.g. \ref pio0 or \ref pio1
1776+
* \param sm State machine index (0..3) to use
1777+
* \param pin_values the pin values to set (if the corresponding bit in pin_mask is set)
1778+
* \param pin_mask a bit for each pin to indicate whether the corresponding pin_value for that pin should be applied.
1779+
*/
1780+
void pio_sm_set_pins_with_mask64(PIO pio, uint sm, uint64_t pin_values, uint64_t pin_mask);
1781+
17421782
/*! \brief Use a state machine to set the pin directions for multiple pins for the PIO instance
17431783
* \ingroup hardware_pio
17441784
*
17451785
* This method repeatedly reconfigures the target state machine's pin configuration and executes 'set' instructions to set pin directions on up to 32 pins,
17461786
* before restoring the state machine's pin configuration to what it was.
17471787
*
17481788
* This method is provided as a convenience to set initial pin directions, and should not be used against a state machine that is enabled.
1789+
* Note: This method only works for pins < 32. To use with pins >= 32 call pio_sm_set_pindirs_with_mask64
17491790
*
17501791
* \param pio The PIO instance; e.g. \ref pio0 or \ref pio1
17511792
* \param sm State machine index (0..3) to use
@@ -1754,6 +1795,21 @@ void pio_sm_set_pins_with_mask(PIO pio, uint sm, uint32_t pin_values, uint32_t p
17541795
*/
17551796
void pio_sm_set_pindirs_with_mask(PIO pio, uint sm, uint32_t pin_dirs, uint32_t pin_mask);
17561797

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

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)