Add a function to get low level register access

The port is free to return NULL for any/all of these, and the caller has
to check.

This will be used in the floppy code, because aside from getting the
registers, it looks like all is independent of MCU.
This commit is contained in:
Jeff Epler 2022-01-04 14:15:20 -06:00
parent ae58858036
commit db5f99c63e
No known key found for this signature in database
GPG Key ID: D5BF15AB975AB4DE
3 changed files with 63 additions and 0 deletions

View File

@ -187,3 +187,30 @@ digitalio_pull_t common_hal_digitalio_digitalinout_get_pull(
}
}
}
bool common_hal_digitalio_has_reg_op(digitalinout_reg_op_t op) {
return true;
}
volatile uint32_t *common_hal_digitalio_digitalinout_get_reg(digitalio_digitalinout_obj_t *self, digitalinout_reg_op_t op, uint32_t *mask) {
const uint8_t pin = self->pin->number;
int port = GPIO_PORT(pin);
*mask = 1u << GPIO_PIN(pin);
switch (op) {
case DIGITALINOUT_REG_READ:
return (volatile uint32_t *)&PORT->Group[port].IN.reg;
case DIGITALINOUT_REG_WRITE:
return &PORT->Group[port].OUT.reg;
case DIGITALINOUT_REG_SET:
return &PORT->Group[port].OUTSET.reg;
case DIGITALINOUT_REG_RESET:
return &PORT->Group[port].OUTCLR.reg;
case DIGITALINOUT_REG_TOGGLE:
return &PORT->Group[port].OUTTGL.reg;
default:
return NULL;
}
}

View File

@ -164,3 +164,28 @@ digitalio_pull_t common_hal_digitalio_digitalinout_get_pull(
}
return PULL_NONE;
}
bool common_hal_digitalio_has_reg_op(digitalinout_reg_op_t op) {
return true;
}
volatile uint32_t *common_hal_digitalio_digitalinout_get_reg(digitalio_digitalinout_obj_t *self, digitalinout_reg_op_t op, uint32_t *mask) {
const uint8_t pin = self->pin->number;
*mask = 1u << pin;
switch (op) {
case DIGITALINOUT_REG_READ:
return (volatile uint32_t *)&sio_hw->gpio_in;
case DIGITALINOUT_REG_WRITE:
return &sio_hw->gpio_out;
case DIGITALINOUT_REG_SET:
return &sio_hw->gpio_set;
case DIGITALINOUT_REG_RESET:
return &sio_hw->gpio_clr;
case DIGITALINOUT_REG_TOGGLE:
return &sio_hw->gpio_togl;
default:
return NULL;
}
}

View File

@ -41,6 +41,14 @@ typedef enum {
DIGITALINOUT_INPUT_ONLY
} digitalinout_result_t;
typedef enum {
DIGITALINOUT_REG_READ,
DIGITALINOUT_REG_WRITE,
DIGITALINOUT_REG_SET,
DIGITALINOUT_REG_RESET,
DIGITALINOUT_REG_TOGGLE,
} digitalinout_reg_op_t;
digitalinout_result_t common_hal_digitalio_digitalinout_construct(digitalio_digitalinout_obj_t *self, const mcu_pin_obj_t *pin);
void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t *self);
bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t *self);
@ -56,4 +64,7 @@ digitalio_pull_t common_hal_digitalio_digitalinout_get_pull(digitalio_digitalino
void common_hal_digitalio_digitalinout_never_reset(digitalio_digitalinout_obj_t *self);
digitalio_digitalinout_obj_t *assert_digitalinout(mp_obj_t obj);
volatile uint32_t *common_hal_digitalio_digitalinout_get_reg(digitalio_digitalinout_obj_t *self, digitalinout_reg_op_t op, uint32_t *mask);
bool common_hal_digitalio_has_reg_op(digitalinout_reg_op_t op);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DIGITALIO_DIGITALINOUT_H