Skip to content

Commit 54d4f3a

Browse files
Add some missing pio functions (#2074)
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 46283dd commit 54d4f3a

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)