StateMachine: Add pull up/down for inputs

This commit is contained in:
Jeff Epler 2021-03-04 10:03:31 -06:00
parent 68ac14b309
commit ff62b0d2c0
7 changed files with 39 additions and 2 deletions

View File

@ -69,6 +69,8 @@
//| initial_out_pin_direction: int = 0xffffffff,
//| first_in_pin: Optional[microcontroller.Pin] = None,
//| in_pin_count: int = 1,
//| pull_in_pin_up: int = 0,
//| pull_in_pin_down: int = 0,
//| first_set_pin: Optional[microcontroller.Pin] = None,
//| set_pin_count: int = 1,
//| initial_set_pin_state: int = 0,
@ -99,6 +101,8 @@
//| :param int initial_out_pin_direction: the initial output direction for out pins starting at first_out_pin
//| :param ~microcontroller.Pin first_in_pin: the first pin to use with the IN instruction
//| :param int in_pin_count: the count of consecutive pins to use with IN starting at first_in_pin
//| :param int pull_in_pin_up: a 1-bit in this mask sets pull up on the corresponding in pin
//| :param int pull_in_pin_down: a 1-bit in this mask sets pull up on the corresponding in pin. Setting both pulls enables a "bus keep" function, i.e. a weak pull to whatever is current high/low state of GPIO.
//| :param ~microcontroller.Pin first_set_pin: the first pin to use with the SET instruction
//| :param int set_pin_count: the count of consecutive pins to use with SET starting at first_set_pin
//| :param int initial_set_pin_state: the initial output value for set pins starting at first_set_pin
@ -133,6 +137,7 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n
enum { ARG_program, ARG_frequency, ARG_init,
ARG_first_out_pin, ARG_out_pin_count, ARG_initial_out_pin_state, ARG_initial_out_pin_direction,
ARG_first_in_pin, ARG_in_pin_count,
ARG_pull_in_pin_up, ARG_pull_in_pin_down,
ARG_first_set_pin, ARG_set_pin_count, ARG_initial_set_pin_state, ARG_initial_set_pin_direction,
ARG_first_sideset_pin, ARG_sideset_pin_count, ARG_initial_sideset_pin_state, ARG_initial_sideset_pin_direction,
ARG_exclusive_pin_use,
@ -151,6 +156,8 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n
{ MP_QSTR_first_in_pin, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_in_pin_count, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
{ MP_QSTR_pull_in_pin_up, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_pull_in_pin_down, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_first_set_pin, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_set_pin_count, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
@ -233,7 +240,7 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n
args[ARG_frequency].u_int,
init_bufinfo.buf, init_bufinfo.len / 2,
first_out_pin, args[ARG_out_pin_count].u_int, args[ARG_initial_out_pin_state].u_int, args[ARG_initial_out_pin_direction].u_int,
first_in_pin, args[ARG_in_pin_count].u_int,
first_in_pin, args[ARG_in_pin_count].u_int, args[ARG_pull_in_pin_up].u_int, args[ARG_pull_in_pin_down].u_int,
first_set_pin, args[ARG_set_pin_count].u_int, args[ARG_initial_set_pin_state].u_int, args[ARG_initial_set_pin_direction].u_int,
first_sideset_pin, args[ARG_sideset_pin_count].u_int, args[ARG_initial_sideset_pin_state].u_int, args[ARG_initial_sideset_pin_direction].u_int,
args[ARG_exclusive_pin_use].u_bool,

View File

@ -41,7 +41,7 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
size_t frequency,
const uint16_t* init, size_t init_len,
const mcu_pin_obj_t * first_out_pin, uint8_t out_pin_count, uint32_t initial_out_pin_state, uint32_t initial_out_pin_direction,
const mcu_pin_obj_t * first_in_pin, uint8_t in_pin_count,
const mcu_pin_obj_t * first_in_pin, uint8_t in_pin_count, uint32_t pull_pin_up, uint32_t pull_pin_down,
const mcu_pin_obj_t * first_set_pin, uint8_t set_pin_count, uint32_t initial_set_pin_state, uint32_t initial_set_pin_direction,
const mcu_pin_obj_t * first_sideset_pin, uint8_t sideset_pin_count, uint32_t initial_sideset_pin_state, uint32_t initial_sideset_pin_direction,
bool exclusive_pin_use,

View File

@ -122,6 +122,7 @@ void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t* self,
NULL, 0,
data, 1, 0, 0xffffffff, // out pin
NULL, 0, // in pins
0, 0, // in pulls
NULL, 0, 0, 0x1f, // set pins
bit_clock, 2, 0, 0x1f, // sideset pins
true, // exclusive pin use

View File

@ -68,6 +68,7 @@ void common_hal_audiobusio_pdmin_construct(audiobusio_pdmin_obj_t* self,
NULL, 0,
NULL, 1, 0, 0xffffffff, // out pin
data_pin, 1, // in pins
0, 0, // in pulls
NULL, 0, 0, 0x1f, // set pins
clock_pin, 1, 0, 0x1f, // sideset pins
true, // exclusive pin use

View File

@ -67,6 +67,7 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t* digitalinout,
NULL, 0, // init program
NULL, 1, // out
NULL, 1, // in
0, 0, // in pulls
NULL, 1, // set
digitalinout->pin, 1, // sideset
0, pins_we_use, // initial pin state

View File

@ -53,6 +53,17 @@ STATIC uint32_t _current_sm_pins[NUM_PIOS][NUM_PIO_STATE_MACHINES];
STATIC PIO pio_instances[2] = {pio0, pio1};
static void rp2pio_statemachine_set_pull(uint32_t pull_pin_up, uint32_t pull_pin_down, uint32_t pins_we_use) {
for (int i=0; i<TOTAL_GPIO_COUNT; i++) {
bool used = pins_we_use & (1 << i);
if(used) {
bool pull_up = pull_pin_up & (1 << i);
bool pull_down = pull_pin_down & (1 << i);
gpio_set_pulls(i, pull_up, pull_down);
}
}
}
void _reset_statemachine(PIO pio, uint8_t sm, bool leave_pins) {
uint8_t pio_index = pio_get_index(pio);
uint32_t program_id = _current_program_id[pio_index][sm];
@ -136,6 +147,7 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
const uint16_t* init, size_t init_len,
const mcu_pin_obj_t * first_out_pin, uint8_t out_pin_count,
const mcu_pin_obj_t * first_in_pin, uint8_t in_pin_count,
uint32_t pull_pin_up, uint32_t pull_pin_down,
const mcu_pin_obj_t * first_set_pin, uint8_t set_pin_count,
const mcu_pin_obj_t * first_sideset_pin, uint8_t sideset_pin_count,
uint32_t initial_pin_state, uint32_t initial_pin_direction,
@ -211,8 +223,11 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
pio_sm_set_pins_with_mask(self->pio, state_machine, initial_pin_state, pins_we_use);
pio_sm_set_pindirs_with_mask(self->pio, state_machine, initial_pin_direction, pins_we_use);
rp2pio_statemachine_set_pull(pull_pin_up, pull_pin_down, pins_we_use);
self->initial_pin_state = initial_pin_state;
self->initial_pin_direction = initial_pin_direction;
self->pull_pin_up = pull_pin_up;
self->pull_pin_down = pull_pin_down;
for (size_t pin_number = 0; pin_number < TOTAL_GPIO_COUNT; pin_number++) {
if ((pins_we_use & (1 << pin_number)) == 0) {
@ -302,6 +317,7 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
const uint16_t* init, size_t init_len,
const mcu_pin_obj_t * first_out_pin, uint8_t out_pin_count, uint32_t initial_out_pin_state, uint32_t initial_out_pin_direction,
const mcu_pin_obj_t * first_in_pin, uint8_t in_pin_count,
uint32_t pull_pin_up, uint32_t pull_pin_down,
const mcu_pin_obj_t * first_set_pin, uint8_t set_pin_count, uint32_t initial_set_pin_state, uint32_t initial_set_pin_direction,
const mcu_pin_obj_t * first_sideset_pin, uint8_t sideset_pin_count, uint32_t initial_sideset_pin_state, uint32_t initial_sideset_pin_direction,
bool exclusive_pin_use,
@ -444,12 +460,19 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
initial_pin_state = (initial_pin_state & ~sideset_mask) | mask_and_rotate(first_sideset_pin, sideset_pin_count, initial_sideset_pin_state);
initial_pin_direction = (initial_pin_direction & ~sideset_mask) | mask_and_rotate(first_sideset_pin, sideset_pin_count, initial_sideset_pin_direction);
// Deal with pull up/downs
uint32_t pull_up = mask_and_rotate(first_in_pin, in_pin_count, pull_pin_up);
uint32_t pull_down = mask_and_rotate(first_in_pin, in_pin_count, pull_pin_down);
if (initial_pin_direction & (pull_up | pull_down)) {
mp_raise_ValueError(translate("pull masks conflict with direction masks"));
}
bool ok = rp2pio_statemachine_construct(self,
program, program_len,
frequency,
init, init_len,
first_out_pin, out_pin_count,
first_in_pin, in_pin_count,
pull_up, pull_down,
first_set_pin, set_pin_count,
first_sideset_pin, sideset_pin_count,
initial_pin_state, initial_pin_direction,
@ -470,6 +493,7 @@ void common_hal_rp2pio_statemachine_restart(rp2pio_statemachine_obj_t *self) {
uint32_t pins_we_use = _current_sm_pins[pio_index][self->state_machine];
pio_sm_set_pins_with_mask(self->pio, self->state_machine, self->initial_pin_state, pins_we_use);
pio_sm_set_pindirs_with_mask(self->pio, self->state_machine, self->initial_pin_direction, pins_we_use);
rp2pio_statemachine_set_pull(self->pull_pin_up, self->pull_pin_down, pins_we_use);
common_hal_rp2pio_statemachine_run(self, self->init, self->init_len);
pio_sm_set_enabled(self->pio, self->state_machine, true);
}

View File

@ -40,6 +40,8 @@ typedef struct {
size_t init_len;
uint32_t initial_pin_state;
uint32_t initial_pin_direction;
uint32_t pull_pin_up;
uint32_t pull_pin_down;
bool in;
bool out;
bool wait_for_txstall;
@ -59,6 +61,7 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
const uint16_t* init, size_t init_len,
const mcu_pin_obj_t * first_out_pin, uint8_t out_pin_count,
const mcu_pin_obj_t * first_in_pin, uint8_t in_pin_count,
uint32_t pull_pin_up, uint32_t pull_pin_down,
const mcu_pin_obj_t * first_set_pin, uint8_t set_pin_count,
const mcu_pin_obj_t * first_sideset_pin, uint8_t sideset_pin_count,
uint32_t initial_pin_state, uint32_t initial_pin_direction,