Extra param-checking for hardware_pio library (switch asserts to valid_params_if, and add additional checks)
This commit is contained in:
parent
e5d61f1ad3
commit
786be7524a
@ -108,6 +108,10 @@ static inline void check_sm_param(__unused uint sm) {
|
|||||||
valid_params_if(PIO, sm < NUM_PIO_STATE_MACHINES);
|
valid_params_if(PIO, sm < NUM_PIO_STATE_MACHINES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void check_pio_param(__unused PIO pio) {
|
||||||
|
valid_params_if(PIO, pio == pio0 || pio == pio1);
|
||||||
|
}
|
||||||
|
|
||||||
/*! \brief Set the 'out' pins in a state machine configuration
|
/*! \brief Set the 'out' pins in a state machine configuration
|
||||||
* \ingroup sm_config
|
* \ingroup sm_config
|
||||||
*
|
*
|
||||||
@ -118,8 +122,8 @@ static inline void check_sm_param(__unused uint sm) {
|
|||||||
* \param out_count 0-32 Number of pins to set.
|
* \param out_count 0-32 Number of pins to set.
|
||||||
*/
|
*/
|
||||||
static inline void sm_config_set_out_pins(pio_sm_config *c, uint out_base, uint out_count) {
|
static inline void sm_config_set_out_pins(pio_sm_config *c, uint out_base, uint out_count) {
|
||||||
assert(out_base < 32);
|
valid_params_if(PIO, out_base < 32);
|
||||||
assert(out_count <= 32);
|
valid_params_if(PIO, out_count <= 32);
|
||||||
c->pinctrl = (c->pinctrl & ~(PIO_SM0_PINCTRL_OUT_BASE_BITS | PIO_SM0_PINCTRL_OUT_COUNT_BITS)) |
|
c->pinctrl = (c->pinctrl & ~(PIO_SM0_PINCTRL_OUT_BASE_BITS | PIO_SM0_PINCTRL_OUT_COUNT_BITS)) |
|
||||||
(out_base << PIO_SM0_PINCTRL_OUT_BASE_LSB) |
|
(out_base << PIO_SM0_PINCTRL_OUT_BASE_LSB) |
|
||||||
(out_count << PIO_SM0_PINCTRL_OUT_COUNT_LSB);
|
(out_count << PIO_SM0_PINCTRL_OUT_COUNT_LSB);
|
||||||
@ -135,8 +139,8 @@ static inline void sm_config_set_out_pins(pio_sm_config *c, uint out_base, uint
|
|||||||
* \param set_count 0-5 Number of pins to set.
|
* \param set_count 0-5 Number of pins to set.
|
||||||
*/
|
*/
|
||||||
static inline void sm_config_set_set_pins(pio_sm_config *c, uint set_base, uint set_count) {
|
static inline void sm_config_set_set_pins(pio_sm_config *c, uint set_base, uint set_count) {
|
||||||
assert(set_base < 32);
|
valid_params_if(PIO, set_base < 32);
|
||||||
assert(set_count <= 5);
|
valid_params_if(PIO, set_count <= 5);
|
||||||
c->pinctrl = (c->pinctrl & ~(PIO_SM0_PINCTRL_SET_BASE_BITS | PIO_SM0_PINCTRL_SET_COUNT_BITS)) |
|
c->pinctrl = (c->pinctrl & ~(PIO_SM0_PINCTRL_SET_BASE_BITS | PIO_SM0_PINCTRL_SET_COUNT_BITS)) |
|
||||||
(set_base << PIO_SM0_PINCTRL_SET_BASE_LSB) |
|
(set_base << PIO_SM0_PINCTRL_SET_BASE_LSB) |
|
||||||
(set_count << PIO_SM0_PINCTRL_SET_COUNT_LSB);
|
(set_count << PIO_SM0_PINCTRL_SET_COUNT_LSB);
|
||||||
@ -151,7 +155,7 @@ static inline void sm_config_set_set_pins(pio_sm_config *c, uint set_base, uint
|
|||||||
* \param in_base 0-31 First pin to use as input
|
* \param in_base 0-31 First pin to use as input
|
||||||
*/
|
*/
|
||||||
static inline void sm_config_set_in_pins(pio_sm_config *c, uint in_base) {
|
static inline void sm_config_set_in_pins(pio_sm_config *c, uint in_base) {
|
||||||
assert(in_base < 32);
|
valid_params_if(PIO, in_base < 32);
|
||||||
c->pinctrl = (c->pinctrl & ~PIO_SM0_PINCTRL_IN_BASE_BITS) |
|
c->pinctrl = (c->pinctrl & ~PIO_SM0_PINCTRL_IN_BASE_BITS) |
|
||||||
(in_base << PIO_SM0_PINCTRL_IN_BASE_LSB);
|
(in_base << PIO_SM0_PINCTRL_IN_BASE_LSB);
|
||||||
}
|
}
|
||||||
@ -165,7 +169,7 @@ static inline void sm_config_set_in_pins(pio_sm_config *c, uint in_base) {
|
|||||||
* \param sideset_base 0-31 base pin for 'side set'
|
* \param sideset_base 0-31 base pin for 'side set'
|
||||||
*/
|
*/
|
||||||
static inline void sm_config_set_sideset_pins(pio_sm_config *c, uint sideset_base) {
|
static inline void sm_config_set_sideset_pins(pio_sm_config *c, uint sideset_base) {
|
||||||
assert(sideset_base < 32);
|
valid_params_if(PIO, sideset_base < 32);
|
||||||
c->pinctrl = (c->pinctrl & ~PIO_SM0_PINCTRL_SIDESET_BASE_BITS) |
|
c->pinctrl = (c->pinctrl & ~PIO_SM0_PINCTRL_SIDESET_BASE_BITS) |
|
||||||
(sideset_base << PIO_SM0_PINCTRL_SIDESET_BASE_LSB);
|
(sideset_base << PIO_SM0_PINCTRL_SIDESET_BASE_LSB);
|
||||||
}
|
}
|
||||||
@ -179,8 +183,8 @@ static inline void sm_config_set_sideset_pins(pio_sm_config *c, uint sideset_bas
|
|||||||
* \param pindirs True if the side set affects pin directions rather than values
|
* \param pindirs True if the side set affects pin directions rather than values
|
||||||
*/
|
*/
|
||||||
static inline void sm_config_set_sideset(pio_sm_config *c, uint bit_count, bool optional, bool pindirs) {
|
static inline void sm_config_set_sideset(pio_sm_config *c, uint bit_count, bool optional, bool pindirs) {
|
||||||
assert(bit_count <= 5);
|
valid_params_if(PIO, bit_count <= 5);
|
||||||
assert(!optional || bit_count >= 1);
|
valid_params_if(PIO, !optional || bit_count >= 1);
|
||||||
c->pinctrl = (c->pinctrl & ~PIO_SM0_PINCTRL_SIDESET_COUNT_BITS) |
|
c->pinctrl = (c->pinctrl & ~PIO_SM0_PINCTRL_SIDESET_COUNT_BITS) |
|
||||||
(bit_count << PIO_SM0_PINCTRL_SIDESET_COUNT_LSB);
|
(bit_count << PIO_SM0_PINCTRL_SIDESET_COUNT_LSB);
|
||||||
|
|
||||||
@ -240,8 +244,8 @@ static inline void sm_config_set_clkdiv_int_frac(pio_sm_config *c, uint16_t div_
|
|||||||
* if the instruction does not itself update the program_counter
|
* if the instruction does not itself update the program_counter
|
||||||
*/
|
*/
|
||||||
static inline void sm_config_set_wrap(pio_sm_config *c, uint wrap_target, uint wrap) {
|
static inline void sm_config_set_wrap(pio_sm_config *c, uint wrap_target, uint wrap) {
|
||||||
assert(wrap < PIO_INSTRUCTION_COUNT);
|
valid_params_if(PIO, wrap < PIO_INSTRUCTION_COUNT);
|
||||||
assert(wrap_target < PIO_INSTRUCTION_COUNT);
|
valid_params_if(PIO, wrap_target < PIO_INSTRUCTION_COUNT);
|
||||||
c->execctrl = (c->execctrl & ~(PIO_SM0_EXECCTRL_WRAP_TOP_BITS | PIO_SM0_EXECCTRL_WRAP_BOTTOM_BITS)) |
|
c->execctrl = (c->execctrl & ~(PIO_SM0_EXECCTRL_WRAP_TOP_BITS | PIO_SM0_EXECCTRL_WRAP_BOTTOM_BITS)) |
|
||||||
(wrap_target << PIO_SM0_EXECCTRL_WRAP_BOTTOM_LSB) |
|
(wrap_target << PIO_SM0_EXECCTRL_WRAP_BOTTOM_LSB) |
|
||||||
(wrap << PIO_SM0_EXECCTRL_WRAP_TOP_LSB);
|
(wrap << PIO_SM0_EXECCTRL_WRAP_TOP_LSB);
|
||||||
@ -254,7 +258,7 @@ static inline void sm_config_set_wrap(pio_sm_config *c, uint wrap_target, uint w
|
|||||||
* \param pin The raw GPIO pin number to use as the source for a `jmp pin` instruction
|
* \param pin The raw GPIO pin number to use as the source for a `jmp pin` instruction
|
||||||
*/
|
*/
|
||||||
static inline void sm_config_set_jmp_pin(pio_sm_config *c, uint pin) {
|
static inline void sm_config_set_jmp_pin(pio_sm_config *c, uint pin) {
|
||||||
assert(pin < 32);
|
valid_params_if(PIO, pin < 32);
|
||||||
c->execctrl = (c->execctrl & ~PIO_SM0_EXECCTRL_JMP_PIN_BITS) |
|
c->execctrl = (c->execctrl & ~PIO_SM0_EXECCTRL_JMP_PIN_BITS) |
|
||||||
(pin << PIO_SM0_EXECCTRL_JMP_PIN_LSB);
|
(pin << PIO_SM0_EXECCTRL_JMP_PIN_LSB);
|
||||||
}
|
}
|
||||||
@ -304,7 +308,7 @@ static inline void sm_config_set_out_shift(pio_sm_config *c, bool shift_right, b
|
|||||||
* \param join Specifies the join type. \see enum pio_fifo_join
|
* \param join Specifies the join type. \see enum pio_fifo_join
|
||||||
*/
|
*/
|
||||||
static inline void sm_config_set_fifo_join(pio_sm_config *c, enum pio_fifo_join join) {
|
static inline void sm_config_set_fifo_join(pio_sm_config *c, enum pio_fifo_join join) {
|
||||||
assert(join >= 0 && join <= 2);
|
valid_params_if(PIO, join >= 0 && join <= 2);
|
||||||
c->shiftctrl = (c->shiftctrl & (uint)~(PIO_SM0_SHIFTCTRL_FJOIN_TX_BITS | PIO_SM0_SHIFTCTRL_FJOIN_RX_BITS)) |
|
c->shiftctrl = (c->shiftctrl & (uint)~(PIO_SM0_SHIFTCTRL_FJOIN_TX_BITS | PIO_SM0_SHIFTCTRL_FJOIN_RX_BITS)) |
|
||||||
(((uint)join) << PIO_SM0_SHIFTCTRL_FJOIN_TX_LSB);
|
(((uint)join) << PIO_SM0_SHIFTCTRL_FJOIN_TX_LSB);
|
||||||
}
|
}
|
||||||
@ -377,6 +381,7 @@ static inline pio_sm_config pio_get_default_sm_config(void) {
|
|||||||
* \param config the configuration to apply
|
* \param config the configuration to apply
|
||||||
*/
|
*/
|
||||||
static inline void pio_sm_set_config(PIO pio, uint sm, const pio_sm_config *config) {
|
static inline void pio_sm_set_config(PIO pio, uint sm, const pio_sm_config *config) {
|
||||||
|
check_pio_param(pio);
|
||||||
check_sm_param(sm);
|
check_sm_param(sm);
|
||||||
pio->sm[sm].clkdiv = config->clkdiv;
|
pio->sm[sm].clkdiv = config->clkdiv;
|
||||||
pio->sm[sm].execctrl = config->execctrl;
|
pio->sm[sm].execctrl = config->execctrl;
|
||||||
@ -391,7 +396,7 @@ static inline void pio_sm_set_config(PIO pio, uint sm, const pio_sm_config *conf
|
|||||||
* \return the PIO instance number (either 0 or 1)
|
* \return the PIO instance number (either 0 or 1)
|
||||||
*/
|
*/
|
||||||
static inline uint pio_get_index(PIO pio) {
|
static inline uint pio_get_index(PIO pio) {
|
||||||
assert(pio == pio0 || pio == pio1);
|
check_pio_param(pio);
|
||||||
return pio == pio1 ? 1 : 0;
|
return pio == pio1 ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,7 +413,8 @@ static inline uint pio_get_index(PIO pio) {
|
|||||||
* \param pin the GPIO pin whose function select to set
|
* \param pin the GPIO pin whose function select to set
|
||||||
*/
|
*/
|
||||||
static inline void pio_gpio_init(PIO pio, uint pin) {
|
static inline void pio_gpio_init(PIO pio, uint pin) {
|
||||||
assert(pio == pio0 || pio == pio1);
|
check_pio_param(pio);
|
||||||
|
valid_params_if(PIO, pin < 32);
|
||||||
gpio_set_function(pin, pio == pio0 ? GPIO_FUNC_PIO0 : GPIO_FUNC_PIO1);
|
gpio_set_function(pin, pio == pio0 ? GPIO_FUNC_PIO0 : GPIO_FUNC_PIO1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -420,7 +426,7 @@ static inline void pio_gpio_init(PIO pio, uint pin) {
|
|||||||
* \param is_tx true for sending data to the state machine, false for received data from the state machine
|
* \param is_tx true for sending data to the state machine, false for received data from the state machine
|
||||||
*/
|
*/
|
||||||
static inline uint pio_get_dreq(PIO pio, uint sm, bool is_tx) {
|
static inline uint pio_get_dreq(PIO pio, uint sm, bool is_tx) {
|
||||||
assert(pio == pio0 || pio == pio1);
|
check_pio_param(pio);
|
||||||
check_sm_param(sm);
|
check_sm_param(sm);
|
||||||
return sm + (is_tx ? 0 : NUM_PIO_STATE_MACHINES) + (pio == pio0 ? DREQ_PIO0_TX0 : DREQ_PIO1_TX0);
|
return sm + (is_tx ? 0 : NUM_PIO_STATE_MACHINES) + (pio == pio0 ? DREQ_PIO0_TX0 : DREQ_PIO1_TX0);
|
||||||
}
|
}
|
||||||
@ -515,6 +521,8 @@ void pio_sm_init(PIO pio, uint sm, uint initial_pc, const pio_sm_config *config)
|
|||||||
* \param enabled true to enable the state machine; false to disable
|
* \param enabled true to enable the state machine; false to disable
|
||||||
*/
|
*/
|
||||||
static inline void pio_sm_set_enabled(PIO pio, uint sm, bool enabled) {
|
static inline void pio_sm_set_enabled(PIO pio, uint sm, bool enabled) {
|
||||||
|
check_pio_param(pio);
|
||||||
|
check_sm_param(sm);
|
||||||
pio->ctrl = (pio->ctrl & ~(1u << sm)) | (bool_to_bit(enabled) << sm);
|
pio->ctrl = (pio->ctrl & ~(1u << sm)) | (bool_to_bit(enabled) << sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -532,6 +540,7 @@ static inline void pio_sm_set_enabled(PIO pio, uint sm, bool enabled) {
|
|||||||
* \param enabled true to enable the state machines; false to disable
|
* \param enabled true to enable the state machines; false to disable
|
||||||
*/
|
*/
|
||||||
static inline void pio_set_sm_mask_enabled(PIO pio, uint32_t mask, bool enabled) {
|
static inline void pio_set_sm_mask_enabled(PIO pio, uint32_t mask, bool enabled) {
|
||||||
|
check_pio_param(pio);
|
||||||
pio->ctrl = (pio->ctrl & ~mask) | (enabled ? mask : 0u);
|
pio->ctrl = (pio->ctrl & ~mask) | (enabled ? mask : 0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -545,6 +554,8 @@ static inline void pio_set_sm_mask_enabled(PIO pio, uint32_t mask, bool enabled)
|
|||||||
* \param sm State machine index (0..3)
|
* \param sm State machine index (0..3)
|
||||||
*/
|
*/
|
||||||
static inline void pio_sm_restart(PIO pio, uint sm) {
|
static inline void pio_sm_restart(PIO pio, uint sm) {
|
||||||
|
check_pio_param(pio);
|
||||||
|
check_sm_param(sm);
|
||||||
pio->ctrl |= 1u << (PIO_CTRL_SM_RESTART_LSB + sm);
|
pio->ctrl |= 1u << (PIO_CTRL_SM_RESTART_LSB + sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -558,6 +569,7 @@ static inline void pio_sm_restart(PIO pio, uint sm) {
|
|||||||
* \param mask bit mask of state machine indexes to modify the enabled state of
|
* \param mask bit mask of state machine indexes to modify the enabled state of
|
||||||
*/
|
*/
|
||||||
static inline void pio_restart_sm_mask(PIO pio, uint32_t mask) {
|
static inline void pio_restart_sm_mask(PIO pio, uint32_t mask) {
|
||||||
|
check_pio_param(pio);
|
||||||
pio->ctrl |= (mask << PIO_CTRL_SM_RESTART_LSB) & PIO_CTRL_SM_RESTART_BITS;
|
pio->ctrl |= (mask << PIO_CTRL_SM_RESTART_LSB) & PIO_CTRL_SM_RESTART_BITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -583,6 +595,8 @@ static inline void pio_restart_sm_mask(PIO pio, uint32_t mask) {
|
|||||||
* \param sm State machine index (0..3)
|
* \param sm State machine index (0..3)
|
||||||
*/
|
*/
|
||||||
static inline void pio_sm_clkdiv_restart(PIO pio, uint sm) {
|
static inline void pio_sm_clkdiv_restart(PIO pio, uint sm) {
|
||||||
|
check_pio_param(pio);
|
||||||
|
check_sm_param(sm);
|
||||||
pio->ctrl |= 1u << (PIO_CTRL_CLKDIV_RESTART_LSB + sm);
|
pio->ctrl |= 1u << (PIO_CTRL_CLKDIV_RESTART_LSB + sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -616,6 +630,7 @@ static inline void pio_sm_clkdiv_restart(PIO pio, uint sm) {
|
|||||||
* \param mask bit mask of state machine indexes to modify the enabled state of
|
* \param mask bit mask of state machine indexes to modify the enabled state of
|
||||||
*/
|
*/
|
||||||
static inline void pio_clkdiv_restart_sm_mask(PIO pio, uint32_t mask) {
|
static inline void pio_clkdiv_restart_sm_mask(PIO pio, uint32_t mask) {
|
||||||
|
check_pio_param(pio);
|
||||||
pio->ctrl |= (mask << PIO_CTRL_CLKDIV_RESTART_LSB) & PIO_CTRL_CLKDIV_RESTART_BITS;
|
pio->ctrl |= (mask << PIO_CTRL_CLKDIV_RESTART_LSB) & PIO_CTRL_CLKDIV_RESTART_BITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -631,6 +646,7 @@ static inline void pio_clkdiv_restart_sm_mask(PIO pio, uint32_t mask) {
|
|||||||
* \param mask bit mask of state machine indexes to modify the enabled state of
|
* \param mask bit mask of state machine indexes to modify the enabled state of
|
||||||
*/
|
*/
|
||||||
static inline void pio_enable_sm_mask_in_sync(PIO pio, uint32_t mask) {
|
static inline void pio_enable_sm_mask_in_sync(PIO pio, uint32_t mask) {
|
||||||
|
check_pio_param(pio);
|
||||||
pio->ctrl |= ((mask << PIO_CTRL_CLKDIV_RESTART_LSB) & PIO_CTRL_CLKDIV_RESTART_BITS) |
|
pio->ctrl |= ((mask << PIO_CTRL_CLKDIV_RESTART_LSB) & PIO_CTRL_CLKDIV_RESTART_BITS) |
|
||||||
((mask << PIO_CTRL_SM_ENABLE_LSB) & PIO_CTRL_SM_ENABLE_BITS);
|
((mask << PIO_CTRL_SM_ENABLE_LSB) & PIO_CTRL_SM_ENABLE_BITS);
|
||||||
}
|
}
|
||||||
@ -643,6 +659,7 @@ static inline void pio_enable_sm_mask_in_sync(PIO pio, uint32_t mask) {
|
|||||||
* \return the program counter
|
* \return the program counter
|
||||||
*/
|
*/
|
||||||
static inline uint8_t pio_sm_get_pc(PIO pio, uint sm) {
|
static inline uint8_t pio_sm_get_pc(PIO pio, uint sm) {
|
||||||
|
check_pio_param(pio);
|
||||||
check_sm_param(sm);
|
check_sm_param(sm);
|
||||||
return (uint8_t) pio->sm[sm].addr;
|
return (uint8_t) pio->sm[sm].addr;
|
||||||
}
|
}
|
||||||
@ -660,6 +677,7 @@ static inline uint8_t pio_sm_get_pc(PIO pio, uint sm) {
|
|||||||
* \param instr the encoded PIO instruction
|
* \param instr the encoded PIO instruction
|
||||||
*/
|
*/
|
||||||
inline static void pio_sm_exec(PIO pio, uint sm, uint instr) {
|
inline static void pio_sm_exec(PIO pio, uint sm, uint instr) {
|
||||||
|
check_pio_param(pio);
|
||||||
check_sm_param(sm);
|
check_sm_param(sm);
|
||||||
pio->sm[sm].instr = instr;
|
pio->sm[sm].instr = instr;
|
||||||
}
|
}
|
||||||
@ -672,6 +690,7 @@ inline static void pio_sm_exec(PIO pio, uint sm, uint instr) {
|
|||||||
* \return true if the executed instruction is still running (stalled)
|
* \return true if the executed instruction is still running (stalled)
|
||||||
*/
|
*/
|
||||||
static inline bool pio_sm_is_exec_stalled(PIO pio, uint sm) {
|
static inline bool pio_sm_is_exec_stalled(PIO pio, uint sm) {
|
||||||
|
check_pio_param(pio);
|
||||||
check_sm_param(sm);
|
check_sm_param(sm);
|
||||||
return !!(pio->sm[sm].execctrl & PIO_SM0_EXECCTRL_EXEC_STALLED_BITS);
|
return !!(pio->sm[sm].execctrl & PIO_SM0_EXECCTRL_EXEC_STALLED_BITS);
|
||||||
}
|
}
|
||||||
@ -689,6 +708,8 @@ static inline bool pio_sm_is_exec_stalled(PIO pio, uint sm) {
|
|||||||
* \param instr the encoded PIO instruction
|
* \param instr the encoded PIO instruction
|
||||||
*/
|
*/
|
||||||
static inline void pio_sm_exec_wait_blocking(PIO pio, uint sm, uint instr) {
|
static inline void pio_sm_exec_wait_blocking(PIO pio, uint sm, uint instr) {
|
||||||
|
check_pio_param(pio);
|
||||||
|
check_sm_param(sm);
|
||||||
pio_sm_exec(pio, sm, instr);
|
pio_sm_exec(pio, sm, instr);
|
||||||
while (pio_sm_is_exec_stalled(pio, sm)) tight_loop_contents();
|
while (pio_sm_is_exec_stalled(pio, sm)) tight_loop_contents();
|
||||||
}
|
}
|
||||||
@ -703,7 +724,10 @@ static inline void pio_sm_exec_wait_blocking(PIO pio, uint sm, uint instr) {
|
|||||||
* if the instruction does not itself update the program_counter
|
* if the instruction does not itself update the program_counter
|
||||||
*/
|
*/
|
||||||
static inline void pio_sm_set_wrap(PIO pio, uint sm, uint wrap_target, uint wrap) {
|
static inline void pio_sm_set_wrap(PIO pio, uint sm, uint wrap_target, uint wrap) {
|
||||||
|
check_pio_param(pio);
|
||||||
check_sm_param(sm);
|
check_sm_param(sm);
|
||||||
|
valid_params_if(PIO, wrap < PIO_INSTRUCTION_COUNT);
|
||||||
|
valid_params_if(PIO, wrap_target < PIO_INSTRUCTION_COUNT);
|
||||||
pio->sm[sm].execctrl =
|
pio->sm[sm].execctrl =
|
||||||
(pio->sm[sm].execctrl & ~(PIO_SM0_EXECCTRL_WRAP_TOP_BITS | PIO_SM0_EXECCTRL_WRAP_BOTTOM_BITS)) |
|
(pio->sm[sm].execctrl & ~(PIO_SM0_EXECCTRL_WRAP_TOP_BITS | PIO_SM0_EXECCTRL_WRAP_BOTTOM_BITS)) |
|
||||||
(wrap_target << PIO_SM0_EXECCTRL_WRAP_BOTTOM_LSB) |
|
(wrap_target << PIO_SM0_EXECCTRL_WRAP_BOTTOM_LSB) |
|
||||||
@ -721,9 +745,10 @@ static inline void pio_sm_set_wrap(PIO pio, uint sm, uint wrap_target, uint wrap
|
|||||||
* \param out_count 0-32 Number of pins to set.
|
* \param out_count 0-32 Number of pins to set.
|
||||||
*/
|
*/
|
||||||
static inline void pio_sm_set_out_pins(PIO pio, uint sm, uint out_base, uint out_count) {
|
static inline void pio_sm_set_out_pins(PIO pio, uint sm, uint out_base, uint out_count) {
|
||||||
|
check_pio_param(pio);
|
||||||
check_sm_param(sm);
|
check_sm_param(sm);
|
||||||
assert(out_base < 32);
|
valid_params_if(PIO, out_base < 32);
|
||||||
assert(out_count <= 32);
|
valid_params_if(PIO, out_count <= 32);
|
||||||
pio->sm[sm].pinctrl = (pio->sm[sm].pinctrl & ~(PIO_SM0_PINCTRL_OUT_BASE_BITS | PIO_SM0_PINCTRL_OUT_COUNT_BITS)) |
|
pio->sm[sm].pinctrl = (pio->sm[sm].pinctrl & ~(PIO_SM0_PINCTRL_OUT_BASE_BITS | PIO_SM0_PINCTRL_OUT_COUNT_BITS)) |
|
||||||
(out_base << PIO_SM0_PINCTRL_OUT_BASE_LSB) |
|
(out_base << PIO_SM0_PINCTRL_OUT_BASE_LSB) |
|
||||||
(out_count << PIO_SM0_PINCTRL_OUT_COUNT_LSB);
|
(out_count << PIO_SM0_PINCTRL_OUT_COUNT_LSB);
|
||||||
@ -741,9 +766,10 @@ static inline void pio_sm_set_out_pins(PIO pio, uint sm, uint out_base, uint out
|
|||||||
* \param set_count 0-5 Number of pins to set.
|
* \param set_count 0-5 Number of pins to set.
|
||||||
*/
|
*/
|
||||||
static inline void pio_sm_set_set_pins(PIO pio, uint sm, uint set_base, uint set_count) {
|
static inline void pio_sm_set_set_pins(PIO pio, uint sm, uint set_base, uint set_count) {
|
||||||
|
check_pio_param(pio);
|
||||||
check_sm_param(sm);
|
check_sm_param(sm);
|
||||||
assert(set_base < 32);
|
valid_params_if(PIO, set_base < 32);
|
||||||
assert(set_count <= 5);
|
valid_params_if(PIO, set_count <= 5);
|
||||||
pio->sm[sm].pinctrl = (pio->sm[sm].pinctrl & ~(PIO_SM0_PINCTRL_SET_BASE_BITS | PIO_SM0_PINCTRL_SET_COUNT_BITS)) |
|
pio->sm[sm].pinctrl = (pio->sm[sm].pinctrl & ~(PIO_SM0_PINCTRL_SET_BASE_BITS | PIO_SM0_PINCTRL_SET_COUNT_BITS)) |
|
||||||
(set_base << PIO_SM0_PINCTRL_SET_BASE_LSB) |
|
(set_base << PIO_SM0_PINCTRL_SET_BASE_LSB) |
|
||||||
(set_count << PIO_SM0_PINCTRL_SET_COUNT_LSB);
|
(set_count << PIO_SM0_PINCTRL_SET_COUNT_LSB);
|
||||||
@ -759,8 +785,9 @@ static inline void pio_sm_set_set_pins(PIO pio, uint sm, uint set_base, uint set
|
|||||||
* \param in_base 0-31 First pin to use as input
|
* \param in_base 0-31 First pin to use as input
|
||||||
*/
|
*/
|
||||||
static inline void pio_sm_set_in_pins(PIO pio, uint sm, uint in_base) {
|
static inline void pio_sm_set_in_pins(PIO pio, uint sm, uint in_base) {
|
||||||
|
check_pio_param(pio);
|
||||||
check_sm_param(sm);
|
check_sm_param(sm);
|
||||||
assert(in_base < 32);
|
valid_params_if(PIO, in_base < 32);
|
||||||
pio->sm[sm].pinctrl = (pio->sm[sm].pinctrl & ~PIO_SM0_PINCTRL_IN_BASE_BITS) |
|
pio->sm[sm].pinctrl = (pio->sm[sm].pinctrl & ~PIO_SM0_PINCTRL_IN_BASE_BITS) |
|
||||||
(in_base << PIO_SM0_PINCTRL_IN_BASE_LSB);
|
(in_base << PIO_SM0_PINCTRL_IN_BASE_LSB);
|
||||||
}
|
}
|
||||||
@ -775,8 +802,9 @@ static inline void pio_sm_set_in_pins(PIO pio, uint sm, uint in_base) {
|
|||||||
* \param sideset_base 0-31 base pin for 'side set'
|
* \param sideset_base 0-31 base pin for 'side set'
|
||||||
*/
|
*/
|
||||||
static inline void pio_sm_set_sideset_pins(PIO pio, uint sm, uint sideset_base) {
|
static inline void pio_sm_set_sideset_pins(PIO pio, uint sm, uint sideset_base) {
|
||||||
|
check_pio_param(pio);
|
||||||
check_sm_param(sm);
|
check_sm_param(sm);
|
||||||
assert(sideset_base < 32);
|
valid_params_if(PIO, sideset_base < 32);
|
||||||
pio->sm[sm].pinctrl = (pio->sm[sm].pinctrl & ~PIO_SM0_PINCTRL_SIDESET_BASE_BITS) |
|
pio->sm[sm].pinctrl = (pio->sm[sm].pinctrl & ~PIO_SM0_PINCTRL_SIDESET_BASE_BITS) |
|
||||||
(sideset_base << PIO_SM0_PINCTRL_SIDESET_BASE_LSB);
|
(sideset_base << PIO_SM0_PINCTRL_SIDESET_BASE_LSB);
|
||||||
}
|
}
|
||||||
@ -796,6 +824,7 @@ static inline void pio_sm_set_sideset_pins(PIO pio, uint sm, uint sideset_base)
|
|||||||
* \sa pio_sm_put_blocking
|
* \sa pio_sm_put_blocking
|
||||||
*/
|
*/
|
||||||
static inline void pio_sm_put(PIO pio, uint sm, uint32_t data) {
|
static inline void pio_sm_put(PIO pio, uint sm, uint32_t data) {
|
||||||
|
check_pio_param(pio);
|
||||||
check_sm_param(sm);
|
check_sm_param(sm);
|
||||||
pio->txf[sm] = data;
|
pio->txf[sm] = data;
|
||||||
}
|
}
|
||||||
@ -816,6 +845,7 @@ static inline void pio_sm_put(PIO pio, uint sm, uint32_t data) {
|
|||||||
* \sa pio_sm_get_blocking
|
* \sa pio_sm_get_blocking
|
||||||
*/
|
*/
|
||||||
static inline uint32_t pio_sm_get(PIO pio, uint sm) {
|
static inline uint32_t pio_sm_get(PIO pio, uint sm) {
|
||||||
|
check_pio_param(pio);
|
||||||
check_sm_param(sm);
|
check_sm_param(sm);
|
||||||
return pio->rxf[sm];
|
return pio->rxf[sm];
|
||||||
}
|
}
|
||||||
@ -828,6 +858,7 @@ static inline uint32_t pio_sm_get(PIO pio, uint sm) {
|
|||||||
* \return true if the RX FIFO is full
|
* \return true if the RX FIFO is full
|
||||||
*/
|
*/
|
||||||
static inline bool pio_sm_is_rx_fifo_full(PIO pio, uint sm) {
|
static inline bool pio_sm_is_rx_fifo_full(PIO pio, uint sm) {
|
||||||
|
check_pio_param(pio);
|
||||||
check_sm_param(sm);
|
check_sm_param(sm);
|
||||||
return (pio->fstat & (1u << (PIO_FSTAT_RXFULL_LSB + sm))) != 0;
|
return (pio->fstat & (1u << (PIO_FSTAT_RXFULL_LSB + sm))) != 0;
|
||||||
}
|
}
|
||||||
@ -840,6 +871,7 @@ static inline bool pio_sm_is_rx_fifo_full(PIO pio, uint sm) {
|
|||||||
* \return true if the RX FIFO is empty
|
* \return true if the RX FIFO is empty
|
||||||
*/
|
*/
|
||||||
static inline bool pio_sm_is_rx_fifo_empty(PIO pio, uint sm) {
|
static inline bool pio_sm_is_rx_fifo_empty(PIO pio, uint sm) {
|
||||||
|
check_pio_param(pio);
|
||||||
check_sm_param(sm);
|
check_sm_param(sm);
|
||||||
return (pio->fstat & (1u << (PIO_FSTAT_RXEMPTY_LSB + sm))) != 0;
|
return (pio->fstat & (1u << (PIO_FSTAT_RXEMPTY_LSB + sm))) != 0;
|
||||||
}
|
}
|
||||||
@ -852,6 +884,7 @@ static inline bool pio_sm_is_rx_fifo_empty(PIO pio, uint sm) {
|
|||||||
* \return the number of elements in the RX FIFO
|
* \return the number of elements in the RX FIFO
|
||||||
*/
|
*/
|
||||||
static inline uint pio_sm_get_rx_fifo_level(PIO pio, uint sm) {
|
static inline uint pio_sm_get_rx_fifo_level(PIO pio, uint sm) {
|
||||||
|
check_pio_param(pio);
|
||||||
check_sm_param(sm);
|
check_sm_param(sm);
|
||||||
uint bitoffs = PIO_FLEVEL_RX0_LSB + sm * (PIO_FLEVEL_RX1_LSB - PIO_FLEVEL_RX0_LSB);
|
uint bitoffs = PIO_FLEVEL_RX0_LSB + sm * (PIO_FLEVEL_RX1_LSB - PIO_FLEVEL_RX0_LSB);
|
||||||
const uint32_t mask = PIO_FLEVEL_RX0_BITS >> PIO_FLEVEL_RX0_LSB;
|
const uint32_t mask = PIO_FLEVEL_RX0_BITS >> PIO_FLEVEL_RX0_LSB;
|
||||||
@ -866,6 +899,7 @@ static inline uint pio_sm_get_rx_fifo_level(PIO pio, uint sm) {
|
|||||||
* \return true if the TX FIFO is full
|
* \return true if the TX FIFO is full
|
||||||
*/
|
*/
|
||||||
static inline bool pio_sm_is_tx_fifo_full(PIO pio, uint sm) {
|
static inline bool pio_sm_is_tx_fifo_full(PIO pio, uint sm) {
|
||||||
|
check_pio_param(pio);
|
||||||
check_sm_param(sm);
|
check_sm_param(sm);
|
||||||
return (pio->fstat & (1u << (PIO_FSTAT_TXFULL_LSB + sm))) != 0;
|
return (pio->fstat & (1u << (PIO_FSTAT_TXFULL_LSB + sm))) != 0;
|
||||||
}
|
}
|
||||||
@ -878,6 +912,7 @@ static inline bool pio_sm_is_tx_fifo_full(PIO pio, uint sm) {
|
|||||||
* \return true if the TX FIFO is empty
|
* \return true if the TX FIFO is empty
|
||||||
*/
|
*/
|
||||||
static inline bool pio_sm_is_tx_fifo_empty(PIO pio, uint sm) {
|
static inline bool pio_sm_is_tx_fifo_empty(PIO pio, uint sm) {
|
||||||
|
check_pio_param(pio);
|
||||||
check_sm_param(sm);
|
check_sm_param(sm);
|
||||||
return (pio->fstat & (1u << (PIO_FSTAT_TXEMPTY_LSB + sm))) != 0;
|
return (pio->fstat & (1u << (PIO_FSTAT_TXEMPTY_LSB + sm))) != 0;
|
||||||
}
|
}
|
||||||
@ -890,6 +925,7 @@ static inline bool pio_sm_is_tx_fifo_empty(PIO pio, uint sm) {
|
|||||||
* \return the number of elements in the TX FIFO
|
* \return the number of elements in the TX FIFO
|
||||||
*/
|
*/
|
||||||
static inline uint pio_sm_get_tx_fifo_level(PIO pio, uint sm) {
|
static inline uint pio_sm_get_tx_fifo_level(PIO pio, uint sm) {
|
||||||
|
check_pio_param(pio);
|
||||||
check_sm_param(sm);
|
check_sm_param(sm);
|
||||||
unsigned int bitoffs = PIO_FLEVEL_TX0_LSB + sm * (PIO_FLEVEL_TX1_LSB - PIO_FLEVEL_TX0_LSB);
|
unsigned int bitoffs = PIO_FLEVEL_TX0_LSB + sm * (PIO_FLEVEL_TX1_LSB - PIO_FLEVEL_TX0_LSB);
|
||||||
const uint32_t mask = PIO_FLEVEL_TX0_BITS >> PIO_FLEVEL_TX0_LSB;
|
const uint32_t mask = PIO_FLEVEL_TX0_BITS >> PIO_FLEVEL_TX0_LSB;
|
||||||
@ -904,6 +940,7 @@ static inline uint pio_sm_get_tx_fifo_level(PIO pio, uint sm) {
|
|||||||
* \param data the 32 bit data value
|
* \param data the 32 bit data value
|
||||||
*/
|
*/
|
||||||
static inline void pio_sm_put_blocking(PIO pio, uint sm, uint32_t data) {
|
static inline void pio_sm_put_blocking(PIO pio, uint sm, uint32_t data) {
|
||||||
|
check_pio_param(pio);
|
||||||
check_sm_param(sm);
|
check_sm_param(sm);
|
||||||
while (pio_sm_is_tx_fifo_full(pio, sm)) tight_loop_contents();
|
while (pio_sm_is_tx_fifo_full(pio, sm)) tight_loop_contents();
|
||||||
pio_sm_put(pio, sm, data);
|
pio_sm_put(pio, sm, data);
|
||||||
@ -916,6 +953,7 @@ static inline void pio_sm_put_blocking(PIO pio, uint sm, uint32_t data) {
|
|||||||
* \param sm State machine index (0..3)
|
* \param sm State machine index (0..3)
|
||||||
*/
|
*/
|
||||||
static inline uint32_t pio_sm_get_blocking(PIO pio, uint sm) {
|
static inline uint32_t pio_sm_get_blocking(PIO pio, uint sm) {
|
||||||
|
check_pio_param(pio);
|
||||||
check_sm_param(sm);
|
check_sm_param(sm);
|
||||||
while (pio_sm_is_rx_fifo_empty(pio, sm)) tight_loop_contents();
|
while (pio_sm_is_rx_fifo_empty(pio, sm)) tight_loop_contents();
|
||||||
return pio_sm_get(pio, sm);
|
return pio_sm_get(pio, sm);
|
||||||
@ -944,6 +982,7 @@ void pio_sm_drain_tx_fifo(PIO pio, uint sm);
|
|||||||
* \param div the floating point clock divider
|
* \param div the floating point clock divider
|
||||||
*/
|
*/
|
||||||
static inline void pio_sm_set_clkdiv(PIO pio, uint sm, float div) {
|
static inline void pio_sm_set_clkdiv(PIO pio, uint sm, float div) {
|
||||||
|
check_pio_param(pio);
|
||||||
check_sm_param(sm);
|
check_sm_param(sm);
|
||||||
uint div_int = (uint16_t) div;
|
uint div_int = (uint16_t) div;
|
||||||
uint div_frac = (uint8_t) ((div - (float)div_int) * (1u << 8u));
|
uint div_frac = (uint8_t) ((div - (float)div_int) * (1u << 8u));
|
||||||
@ -961,6 +1000,7 @@ static inline void pio_sm_set_clkdiv(PIO pio, uint sm, float div) {
|
|||||||
* \param div_frac the fractional part of the clock divider in 1/256s
|
* \param div_frac the fractional part of the clock divider in 1/256s
|
||||||
*/
|
*/
|
||||||
static inline void pio_sm_set_clkdiv_int_frac(PIO pio, uint sm, uint16_t div_int, uint8_t div_frac) {
|
static inline void pio_sm_set_clkdiv_int_frac(PIO pio, uint sm, uint16_t div_int, uint8_t div_frac) {
|
||||||
|
check_pio_param(pio);
|
||||||
check_sm_param(sm);
|
check_sm_param(sm);
|
||||||
pio->sm[sm].clkdiv =
|
pio->sm[sm].clkdiv =
|
||||||
(((uint)div_frac) << PIO_SM0_CLKDIV_FRAC_LSB) |
|
(((uint)div_frac) << PIO_SM0_CLKDIV_FRAC_LSB) |
|
||||||
@ -975,6 +1015,7 @@ static inline void pio_sm_set_clkdiv_int_frac(PIO pio, uint sm, uint16_t div_int
|
|||||||
*/
|
*/
|
||||||
static inline void pio_sm_clear_fifos(PIO pio, uint sm) {
|
static inline void pio_sm_clear_fifos(PIO pio, uint sm) {
|
||||||
// changing the FIFO join state clears the fifo
|
// changing the FIFO join state clears the fifo
|
||||||
|
check_pio_param(pio);
|
||||||
check_sm_param(sm);
|
check_sm_param(sm);
|
||||||
hw_xor_bits(&pio->sm[sm].shiftctrl, PIO_SM0_SHIFTCTRL_FJOIN_RX_BITS);
|
hw_xor_bits(&pio->sm[sm].shiftctrl, PIO_SM0_SHIFTCTRL_FJOIN_RX_BITS);
|
||||||
hw_xor_bits(&pio->sm[sm].shiftctrl, PIO_SM0_SHIFTCTRL_FJOIN_RX_BITS);
|
hw_xor_bits(&pio->sm[sm].shiftctrl, PIO_SM0_SHIFTCTRL_FJOIN_RX_BITS);
|
||||||
|
@ -79,8 +79,8 @@ bool pio_can_add_program(PIO pio, const pio_program_t *program) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool _pio_can_add_program_at_offset(PIO pio, const pio_program_t *program, uint offset) {
|
static bool _pio_can_add_program_at_offset(PIO pio, const pio_program_t *program, uint offset) {
|
||||||
assert(offset < PIO_INSTRUCTION_COUNT);
|
valid_params_if(PIO, offset < PIO_INSTRUCTION_COUNT);
|
||||||
assert(offset + program->length <= PIO_INSTRUCTION_COUNT);
|
valid_params_if(PIO, offset + program->length <= PIO_INSTRUCTION_COUNT);
|
||||||
if (program->origin >= 0 && (uint)program->origin != offset) return false;
|
if (program->origin >= 0 && (uint)program->origin != offset) return false;
|
||||||
uint32_t used_mask = _used_instruction_space[pio_get_index(pio)];
|
uint32_t used_mask = _used_instruction_space[pio_get_index(pio)];
|
||||||
uint32_t program_mask = (1u << program->length) - 1;
|
uint32_t program_mask = (1u << program->length) - 1;
|
||||||
@ -147,6 +147,8 @@ void pio_clear_instruction_memory(PIO pio) {
|
|||||||
// which is not currently running a program. This is intended for one-time
|
// which is not currently running a program. This is intended for one-time
|
||||||
// setup of initial pin states.
|
// setup of initial pin states.
|
||||||
void pio_sm_set_pins(PIO pio, uint sm, uint32_t pins) {
|
void pio_sm_set_pins(PIO pio, uint sm, uint32_t pins) {
|
||||||
|
check_pio_param(pio);
|
||||||
|
check_sm_param(sm);
|
||||||
uint32_t pinctrl_saved = pio->sm[sm].pinctrl;
|
uint32_t pinctrl_saved = pio->sm[sm].pinctrl;
|
||||||
uint remaining = 32;
|
uint remaining = 32;
|
||||||
uint base = 0;
|
uint base = 0;
|
||||||
@ -164,6 +166,8 @@ void pio_sm_set_pins(PIO pio, uint sm, uint32_t pins) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void pio_sm_set_pins_with_mask(PIO pio, uint sm, uint32_t pinvals, uint32_t pin_mask) {
|
void pio_sm_set_pins_with_mask(PIO pio, uint sm, uint32_t pinvals, uint32_t pin_mask) {
|
||||||
|
check_pio_param(pio);
|
||||||
|
check_sm_param(sm);
|
||||||
uint32_t pinctrl_saved = pio->sm[sm].pinctrl;
|
uint32_t pinctrl_saved = pio->sm[sm].pinctrl;
|
||||||
while (pin_mask) {
|
while (pin_mask) {
|
||||||
uint base = (uint)__builtin_ctz(pin_mask);
|
uint base = (uint)__builtin_ctz(pin_mask);
|
||||||
@ -177,6 +181,8 @@ void pio_sm_set_pins_with_mask(PIO pio, uint sm, uint32_t pinvals, uint32_t pin_
|
|||||||
}
|
}
|
||||||
|
|
||||||
void pio_sm_set_pindirs_with_mask(PIO pio, uint sm, uint32_t pindirs, uint32_t pin_mask) {
|
void pio_sm_set_pindirs_with_mask(PIO pio, uint sm, uint32_t pindirs, uint32_t pin_mask) {
|
||||||
|
check_pio_param(pio);
|
||||||
|
check_sm_param(sm);
|
||||||
uint32_t pinctrl_saved = pio->sm[sm].pinctrl;
|
uint32_t pinctrl_saved = pio->sm[sm].pinctrl;
|
||||||
while (pin_mask) {
|
while (pin_mask) {
|
||||||
uint base = (uint)__builtin_ctz(pin_mask);
|
uint base = (uint)__builtin_ctz(pin_mask);
|
||||||
@ -190,7 +196,9 @@ void pio_sm_set_pindirs_with_mask(PIO pio, uint sm, uint32_t pindirs, uint32_t p
|
|||||||
}
|
}
|
||||||
|
|
||||||
void pio_sm_set_consecutive_pindirs(PIO pio, uint sm, uint pin, uint count, bool is_out) {
|
void pio_sm_set_consecutive_pindirs(PIO pio, uint sm, uint pin, uint count, bool is_out) {
|
||||||
assert(pin < 32u);
|
check_pio_param(pio);
|
||||||
|
check_sm_param(sm);
|
||||||
|
valid_params_if(PIO, pin < 32u);
|
||||||
uint32_t pinctrl_saved = pio->sm[sm].pinctrl;
|
uint32_t pinctrl_saved = pio->sm[sm].pinctrl;
|
||||||
uint pindir_val = is_out ? 0x1f : 0;
|
uint pindir_val = is_out ? 0x1f : 0;
|
||||||
while (count > 5) {
|
while (count > 5) {
|
||||||
@ -205,6 +213,7 @@ void pio_sm_set_consecutive_pindirs(PIO pio, uint sm, uint pin, uint count, bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
void pio_sm_init(PIO pio, uint sm, uint initial_pc, const pio_sm_config *config) {
|
void pio_sm_init(PIO pio, uint sm, uint initial_pc, const pio_sm_config *config) {
|
||||||
|
valid_params_if(PIO, initial_pc < PIO_INSTRUCTION_COUNT);
|
||||||
// Halt the machine, set some sensible defaults
|
// Halt the machine, set some sensible defaults
|
||||||
pio_sm_set_enabled(pio, sm, false);
|
pio_sm_set_enabled(pio, sm, false);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user