Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion src/host/hardware_gpio/gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,31 @@ void gpio_set_oeover(uint gpio, uint value) {

}

void gpio_set_input_hysteresis_enabled(uint gpio, bool enabled){

}

bool gpio_is_input_hysteresis_enabled(uint gpio){
return true;
}

void gpio_set_slew_rate(uint gpio, enum gpio_slew_rate slew){

}

enum gpio_slew_rate gpio_get_slew_rate(uint gpio){
return GPIO_SLEW_RATE_FAST;
}

void gpio_set_drive_strength(uint gpio, enum gpio_drive_strength drive){

}

enum gpio_drive_strength gpio_get_drive_strength(uint gpio){
return GPIO_DRIVE_STRENGTH_4MA;
}


void gpio_set_irq_enabled(uint gpio, uint32_t events, bool enable) {

}
Expand Down Expand Up @@ -115,4 +140,4 @@ void gpio_set_input_enabled(uint gpio, bool enable) {

void gpio_init_mask(uint gpio_mask) {

}
}
23 changes: 23 additions & 0 deletions src/host/hardware_gpio/include/hardware/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@ enum gpio_function {
GPIO_FUNC_NULL = 0xf,
};

enum gpio_slew_rate {
GPIO_SLEW_RATE_SLOW = 0, ///< Slew rate limiting enabled
GPIO_SLEW_RATE_FAST = 1 ///< Slew rate limiting disabled
};

enum gpio_drive_strength {
GPIO_DRIVE_STRENGTH_2MA = 0, ///< 2 mA nominal drive strength
GPIO_DRIVE_STRENGTH_4MA = 1, ///< 4 mA nominal drive strength
GPIO_DRIVE_STRENGTH_8MA = 2, ///< 8 mA nominal drive strength
GPIO_DRIVE_STRENGTH_12MA = 3 ///< 12 mA nominal drive strength
};

#define GPIO_OUT 1
#define GPIO_IN 0
Expand Down Expand Up @@ -58,6 +69,18 @@ void gpio_set_oeover(uint gpio, uint value);

void gpio_set_input_enabled(uint gpio, bool enable);

void gpio_set_input_hysteresis_enabled(uint gpio, bool enabled);

bool gpio_is_input_hysteresis_enabled(uint gpio);

void gpio_set_slew_rate(uint gpio, enum gpio_slew_rate slew);

enum gpio_slew_rate gpio_get_slew_rate(uint gpio);

void gpio_set_drive_strength(uint gpio, enum gpio_drive_strength drive);

enum gpio_drive_strength gpio_get_drive_strength(uint gpio);

// Configure a GPIO for direct input/output from software
void gpio_init(uint gpio);

Expand Down
47 changes: 47 additions & 0 deletions src/rp2_common/hardware_gpio/gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,53 @@ void gpio_set_oeover(uint gpio, uint value) {
);
}

void gpio_set_input_hysteresis_enabled(uint gpio, bool enabled) {
invalid_params_if(GPIO, gpio >= NUM_BANK0_GPIOS);
if (enabled)
hw_set_bits(&padsbank0_hw->io[gpio], PADS_BANK0_GPIO0_SCHMITT_BITS);
else
hw_clear_bits(&padsbank0_hw->io[gpio], PADS_BANK0_GPIO0_SCHMITT_BITS);
}


bool gpio_is_input_hysteresis_enabled(uint gpio) {
invalid_params_if(GPIO, gpio >= NUM_BANK0_GPIOS);
return (padsbank0_hw->io[gpio] & PADS_BANK0_GPIO0_SCHMITT_BITS) != 0;
}

void gpio_set_slew_rate(uint gpio, enum gpio_slew_rate slew) {
invalid_params_if(GPIO, gpio >= NUM_BANK0_GPIOS);
hw_write_masked(&padsbank0_hw->io[gpio],
(uint)slew << PADS_BANK0_GPIO0_SLEWFAST_LSB,
PADS_BANK0_GPIO0_SLEWFAST_BITS
);
}

enum gpio_slew_rate gpio_get_slew_rate(uint gpio) {
invalid_params_if(GPIO, gpio >= NUM_BANK0_GPIOS);
return (enum gpio_slew_rate)((padsbank0_hw->io[gpio]
& PADS_BANK0_GPIO0_SLEWFAST_BITS)
>> PADS_BANK0_GPIO0_SLEWFAST_LSB);
}


// Enum encoding should match hardware encoding on RP2040
static_assert(PADS_BANK0_GPIO0_DRIVE_VALUE_8MA == GPIO_DRIVE_STRENGTH_8MA, "");
void gpio_set_drive_strength(uint gpio, enum gpio_drive_strength drive) {
invalid_params_if(GPIO, gpio >= NUM_BANK0_GPIOS);
hw_write_masked(&padsbank0_hw->io[gpio],
(uint)drive << PADS_BANK0_GPIO0_DRIVE_LSB,
PADS_BANK0_GPIO0_DRIVE_BITS
);
}

enum gpio_drive_strength gpio_get_drive_strength(uint gpio) {
invalid_params_if(GPIO, gpio >= NUM_BANK0_GPIOS);
return (enum gpio_drive_strength)((padsbank0_hw->io[gpio]
& PADS_BANK0_GPIO0_DRIVE_BITS)
>> PADS_BANK0_GPIO0_DRIVE_LSB);
}

static void gpio_irq_handler(void) {
io_irq_ctrl_hw_t *irq_ctrl_base = get_core_num() ?
&iobank0_hw->proc1_irq_ctrl : &iobank0_hw->proc0_irq_ctrl;
Expand Down
84 changes: 84 additions & 0 deletions src/rp2_common/hardware_gpio/include/hardware/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,31 @@ enum gpio_override {
GPIO_OVERRIDE_HIGH = 3, ///< drive high/enable output
};

/*! \brief Slew rate limiting levels for GPIO outputs
* \ingroup hardware_gpio
*
* Slew rate limiting increases the minimum rise/fall time when a GPIO output
* is lightly loaded, which can help to reduce electromagnetic emissions.
* \sa gpio_set_slew_rate
*/
enum gpio_slew_rate {
GPIO_SLEW_RATE_SLOW = 0, ///< Slew rate limiting enabled
GPIO_SLEW_RATE_FAST = 1 ///< Slew rate limiting disabled
};

/*! \brief Drive strength levels for GPIO outputs
* \ingroup hardware_gpio
*
* Drive strength levels for GPIO outputs.
* \sa gpio_set_drive_strength
*/
enum gpio_drive_strength {
GPIO_DRIVE_STRENGTH_2MA = 0, ///< 2 mA nominal drive strength
GPIO_DRIVE_STRENGTH_4MA = 1, ///< 4 mA nominal drive strength
GPIO_DRIVE_STRENGTH_8MA = 2, ///< 8 mA nominal drive strength
GPIO_DRIVE_STRENGTH_12MA = 3 ///< 12 mA nominal drive strength
};

// ----------------------------------------------------------------------------
// Pad Controls + IO Muxing
// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -246,6 +271,65 @@ void gpio_set_oeover(uint gpio, uint value);
*/
void gpio_set_input_enabled(uint gpio, bool enabled);

/*! \brief Enable/disable GPIO input hysteresis (Schmitt trigger)
* \ingroup hardware_gpio
*
* Enable or disable the Schmitt trigger hysteresis on a given GPIO. This is
* enabled on all GPIOs by default. Disabling input hysteresis can lead to
* inconsistent readings when the input signal has very long rise or fall
* times, but slightly reduces the GPIO's input delay.
*
* \sa gpio_is_input_hysteresis_enabled
* \param gpio GPIO number
* \param enabled true to enable input hysteresis on specified GPIO
*/
void gpio_set_input_hysteresis_enabled(uint gpio, bool enabled);

/*! \brief Determine whether input hysteresis is enabled on a specified GPIO
* \ingroup hardware_gpio
*
* \sa gpio_set_input_hysteresis_enabled
* \param gpio GPIO number
*/
bool gpio_is_input_hysteresis_enabled(uint gpio);


/*! \brief Set slew rate for a specified GPIO
* \ingroup hardware_gpio
*
* \sa gpio_get_slew_rate
* \param gpio GPIO number
* \param slew GPIO output slew rate
*/
void gpio_set_slew_rate(uint gpio, enum gpio_slew_rate slew);

/*! \brief Determine current slew rate for a specified GPIO
* \ingroup hardware_gpio
*
* \sa gpio_set_slew_rate
* \param gpio GPIO number
* \return Current slew rate of that GPIO
*/
enum gpio_slew_rate gpio_get_slew_rate(uint gpio);

/*! \brief Set drive strength for a specified GPIO
* \ingroup hardware_gpio
*
* \sa gpio_get_drive_strength
* \param gpio GPIO number
* \param drive GPIO output drive strength
*/
void gpio_set_drive_strength(uint gpio, enum gpio_drive_strength drive);

/*! \brief Determine current slew rate for a specified GPIO
* \ingroup hardware_gpio
*
* \sa gpio_set_drive_strength
* \param gpio GPIO number
* \return Current drive strength of that GPIO
*/
enum gpio_drive_strength gpio_get_drive_strength(uint gpio);

/*! \brief Enable or disable interrupts for specified GPIO
* \ingroup hardware_gpio
*
Expand Down