From da7cc967d0d1d547142912795565fd141ce0fc79 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Thu, 15 Dec 2022 15:14:29 -0500 Subject: [PATCH] gpio: Resync gpio code with upstream Klipper code Add a shutdown() compatibility macro so that the upstream Klipper gpio code can be used unmodified. Sync the rp2040, lpc176x, and stm32 gpio.c code with Klipper's code. Signed-off-by: Kevin O'Connor --- src/command.h | 4 ++++ src/lpc176x/gpio.c | 8 ++++++++ src/lpc176x/gpio.h | 34 ++++++++++++++++++++++++++++++++++ src/rp2040/gpio.c | 8 ++++++++ src/stm32/gpio.c | 22 ++++++++++++---------- src/stm32/gpio.h | 36 ++++++++++++++++++++++++++++++++++-- 6 files changed, 100 insertions(+), 12 deletions(-) diff --git a/src/command.h b/src/command.h index d0b5821..0ff9960 100644 --- a/src/command.h +++ b/src/command.h @@ -18,6 +18,10 @@ DECL_CTR_INT("DECL_ENUMERATION_RANGE " ENUM " " NAME, \ 2, CTR_INT(VALUE), CTR_INT(COUNT)) +// Shutdown wrappers for Klipper compatibility +#define shutdown(msg) do { } while (1) +#define try_shutdown(msg) do { } while (0) + #define PROTO_VERSION 0x00010000 // Version 1.0.0 #define CMD_CONNECT 0x11 #define CMD_RX_BLOCK 0x12 diff --git a/src/lpc176x/gpio.c b/src/lpc176x/gpio.c index 270480f..0b6d034 100644 --- a/src/lpc176x/gpio.c +++ b/src/lpc176x/gpio.c @@ -64,10 +64,14 @@ regs_to_pin(LPC_GPIO_TypeDef *regs, uint32_t bit) struct gpio_out gpio_out_setup(uint8_t pin, uint8_t val) { + if (GPIO2PORT(pin) >= ARRAY_SIZE(digital_regs)) + goto fail; LPC_GPIO_TypeDef *regs = digital_regs[GPIO2PORT(pin)]; struct gpio_out g = { .regs=regs, .bit=GPIO2BIT(pin) }; gpio_out_reset(g, val); return g; +fail: + shutdown("Not an output pin"); } void @@ -111,10 +115,14 @@ gpio_out_write(struct gpio_out g, uint8_t val) struct gpio_in gpio_in_setup(uint8_t pin, int8_t pull_up) { + if (GPIO2PORT(pin) >= ARRAY_SIZE(digital_regs)) + goto fail; LPC_GPIO_TypeDef *regs = digital_regs[GPIO2PORT(pin)]; struct gpio_in g = { .regs=regs, .bit=GPIO2BIT(pin) }; gpio_in_reset(g, pull_up); return g; +fail: + shutdown("Not an input pin"); } void diff --git a/src/lpc176x/gpio.h b/src/lpc176x/gpio.h index b0e5e64..e03afbb 100644 --- a/src/lpc176x/gpio.h +++ b/src/lpc176x/gpio.h @@ -21,4 +21,38 @@ struct gpio_in gpio_in_setup(uint8_t pin, int8_t pull_up); void gpio_in_reset(struct gpio_in g, int8_t pull_up); uint8_t gpio_in_read(struct gpio_in g); +struct gpio_pwm { + void *reg; + uint8_t channel; +}; +struct gpio_pwm gpio_pwm_setup(uint8_t pin, uint32_t cycle_time, uint8_t val); +void gpio_pwm_write(struct gpio_pwm g, uint32_t val); + +struct gpio_adc { + uint32_t chan; +}; +struct gpio_adc gpio_adc_setup(uint8_t pin); +uint32_t gpio_adc_sample(struct gpio_adc g); +uint16_t gpio_adc_read(struct gpio_adc g); +void gpio_adc_cancel_sample(struct gpio_adc g); + +struct spi_config { + void *spi; + uint32_t cr0, cpsr; +}; +struct spi_config spi_setup(uint32_t bus, uint8_t mode, uint32_t rate); +void spi_prepare(struct spi_config config); +void spi_transfer(struct spi_config config, uint8_t receive_data + , uint8_t len, uint8_t *data); + +struct i2c_config { + void *i2c; + uint8_t addr; +}; + +struct i2c_config i2c_setup(uint32_t bus, uint32_t rate, uint8_t addr); +void i2c_write(struct i2c_config config, uint8_t write_len, uint8_t *write); +void i2c_read(struct i2c_config config, uint8_t reg_len, uint8_t *reg + , uint8_t read_len, uint8_t *read); + #endif // gpio.h diff --git a/src/rp2040/gpio.c b/src/rp2040/gpio.c index 36d191e..98e0778 100644 --- a/src/rp2040/gpio.c +++ b/src/rp2040/gpio.c @@ -48,9 +48,13 @@ mask_to_pin(uint32_t mask) struct gpio_out gpio_out_setup(uint8_t pin, uint8_t val) { + if (pin >= 30) + goto fail; struct gpio_out g = { .bit=1<= 30) + goto fail; struct gpio_in g = { .bit=1< // ffs #include "board/irq.h" // irq_save +#include "command.h" // DECL_ENUMERATION_RANGE #include "gpio.h" // gpio_out_setup #include "internal.h" // gpio_peripheral -#include "compiler.h" // ARRAY_SIZE -#include "command.h" // DECL_ENUMERATION_RANGE +#include "sched.h" // sched_shutdown DECL_ENUMERATION_RANGE("pin", "PA0", GPIO('A', 0), 16); DECL_ENUMERATION_RANGE("pin", "PB0", GPIO('B', 0), 16); @@ -66,20 +66,19 @@ regs_to_pin(GPIO_TypeDef *regs, uint32_t bit) return 0; } -uint8_t -check_gpio_valid(uint32_t pin) +// Verify that a gpio is a valid pin +static int +gpio_valid(uint32_t pin) { - if (GPIO2PORT(pin) >= ARRAY_SIZE(digital_regs)) - return 0; - GPIO_TypeDef *regs = digital_regs[GPIO2PORT(pin)]; - if (! regs) - return 0; - return 1; + uint32_t port = GPIO2PORT(pin); + return port < ARRAY_SIZE(digital_regs) && digital_regs[port]; } struct gpio_out gpio_out_setup(uint32_t pin, uint32_t val) { + if (!gpio_valid(pin)) + shutdown("Not an output pin"); GPIO_TypeDef *regs = digital_regs[GPIO2PORT(pin)]; gpio_clock_enable(regs); struct gpio_out g = { .regs=regs, .bit=GPIO2BIT(pin) }; @@ -126,9 +125,12 @@ gpio_out_write(struct gpio_out g, uint32_t val) regs->BSRR = g.bit << 16; } + struct gpio_in gpio_in_setup(uint32_t pin, int32_t pull_up) { + if (!gpio_valid(pin)) + shutdown("Not a valid input pin"); GPIO_TypeDef *regs = digital_regs[GPIO2PORT(pin)]; struct gpio_in g = { .regs=regs, .bit=GPIO2BIT(pin) }; gpio_in_reset(g, pull_up); diff --git a/src/stm32/gpio.h b/src/stm32/gpio.h index bf1a612..281e3a8 100644 --- a/src/stm32/gpio.h +++ b/src/stm32/gpio.h @@ -3,8 +3,6 @@ #include // uint32_t -uint8_t check_gpio_valid(uint32_t pin); - struct gpio_out { void *regs; uint32_t bit; @@ -23,4 +21,38 @@ struct gpio_in gpio_in_setup(uint32_t pin, int32_t pull_up); void gpio_in_reset(struct gpio_in g, int32_t pull_up); uint8_t gpio_in_read(struct gpio_in g); +struct gpio_pwm { + void *reg; +}; +struct gpio_pwm gpio_pwm_setup(uint8_t pin, uint32_t cycle_time, uint8_t val); +void gpio_pwm_write(struct gpio_pwm g, uint32_t val); + +struct gpio_adc { + void *adc; + uint32_t chan; +}; +struct gpio_adc gpio_adc_setup(uint32_t pin); +uint32_t gpio_adc_sample(struct gpio_adc g); +uint16_t gpio_adc_read(struct gpio_adc g); +void gpio_adc_cancel_sample(struct gpio_adc g); + +struct spi_config { + void *spi; + uint32_t spi_cr1; +}; +struct spi_config spi_setup(uint32_t bus, uint8_t mode, uint32_t rate); +void spi_prepare(struct spi_config config); +void spi_transfer(struct spi_config config, uint8_t receive_data + , uint8_t len, uint8_t *data); + +struct i2c_config { + void *i2c; + uint8_t addr; +}; + +struct i2c_config i2c_setup(uint32_t bus, uint32_t rate, uint8_t addr); +void i2c_write(struct i2c_config config, uint8_t write_len, uint8_t *write); +void i2c_read(struct i2c_config config, uint8_t reg_len, uint8_t *reg + , uint8_t read_len, uint8_t *read); + #endif // gpio.h