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 <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2022-12-15 15:14:29 -05:00 committed by Eric Callahan
parent d30ad28f03
commit da7cc967d0
6 changed files with 100 additions and 12 deletions

View File

@ -18,6 +18,10 @@
DECL_CTR_INT("DECL_ENUMERATION_RANGE " ENUM " " NAME, \ DECL_CTR_INT("DECL_ENUMERATION_RANGE " ENUM " " NAME, \
2, CTR_INT(VALUE), CTR_INT(COUNT)) 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 PROTO_VERSION 0x00010000 // Version 1.0.0
#define CMD_CONNECT 0x11 #define CMD_CONNECT 0x11
#define CMD_RX_BLOCK 0x12 #define CMD_RX_BLOCK 0x12

View File

@ -64,10 +64,14 @@ regs_to_pin(LPC_GPIO_TypeDef *regs, uint32_t bit)
struct gpio_out struct gpio_out
gpio_out_setup(uint8_t pin, uint8_t val) 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)]; LPC_GPIO_TypeDef *regs = digital_regs[GPIO2PORT(pin)];
struct gpio_out g = { .regs=regs, .bit=GPIO2BIT(pin) }; struct gpio_out g = { .regs=regs, .bit=GPIO2BIT(pin) };
gpio_out_reset(g, val); gpio_out_reset(g, val);
return g; return g;
fail:
shutdown("Not an output pin");
} }
void void
@ -111,10 +115,14 @@ gpio_out_write(struct gpio_out g, uint8_t val)
struct gpio_in struct gpio_in
gpio_in_setup(uint8_t pin, int8_t pull_up) 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)]; LPC_GPIO_TypeDef *regs = digital_regs[GPIO2PORT(pin)];
struct gpio_in g = { .regs=regs, .bit=GPIO2BIT(pin) }; struct gpio_in g = { .regs=regs, .bit=GPIO2BIT(pin) };
gpio_in_reset(g, pull_up); gpio_in_reset(g, pull_up);
return g; return g;
fail:
shutdown("Not an input pin");
} }
void void

View File

@ -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); void gpio_in_reset(struct gpio_in g, int8_t pull_up);
uint8_t gpio_in_read(struct gpio_in g); 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 #endif // gpio.h

View File

@ -48,9 +48,13 @@ mask_to_pin(uint32_t mask)
struct gpio_out struct gpio_out
gpio_out_setup(uint8_t pin, uint8_t val) gpio_out_setup(uint8_t pin, uint8_t val)
{ {
if (pin >= 30)
goto fail;
struct gpio_out g = { .bit=1<<pin }; struct gpio_out g = { .bit=1<<pin };
gpio_out_reset(g, val); gpio_out_reset(g, val);
return g; return g;
fail:
shutdown("Not an output pin");
} }
void void
@ -89,9 +93,13 @@ gpio_out_write(struct gpio_out g, uint8_t val)
struct gpio_in struct gpio_in
gpio_in_setup(uint8_t pin, int8_t pull_up) gpio_in_setup(uint8_t pin, int8_t pull_up)
{ {
if (pin >= 30)
goto fail;
struct gpio_in g = { .bit=1<<pin }; struct gpio_in g = { .bit=1<<pin };
gpio_in_reset(g, pull_up); gpio_in_reset(g, pull_up);
return g; return g;
fail:
shutdown("Not an input pin");
} }
void void

View File

@ -6,10 +6,10 @@
#include <string.h> // ffs #include <string.h> // ffs
#include "board/irq.h" // irq_save #include "board/irq.h" // irq_save
#include "command.h" // DECL_ENUMERATION_RANGE
#include "gpio.h" // gpio_out_setup #include "gpio.h" // gpio_out_setup
#include "internal.h" // gpio_peripheral #include "internal.h" // gpio_peripheral
#include "compiler.h" // ARRAY_SIZE #include "sched.h" // sched_shutdown
#include "command.h" // DECL_ENUMERATION_RANGE
DECL_ENUMERATION_RANGE("pin", "PA0", GPIO('A', 0), 16); DECL_ENUMERATION_RANGE("pin", "PA0", GPIO('A', 0), 16);
DECL_ENUMERATION_RANGE("pin", "PB0", GPIO('B', 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; return 0;
} }
uint8_t // Verify that a gpio is a valid pin
check_gpio_valid(uint32_t pin) static int
gpio_valid(uint32_t pin)
{ {
if (GPIO2PORT(pin) >= ARRAY_SIZE(digital_regs)) uint32_t port = GPIO2PORT(pin);
return 0; return port < ARRAY_SIZE(digital_regs) && digital_regs[port];
GPIO_TypeDef *regs = digital_regs[GPIO2PORT(pin)];
if (! regs)
return 0;
return 1;
} }
struct gpio_out struct gpio_out
gpio_out_setup(uint32_t pin, uint32_t val) 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_TypeDef *regs = digital_regs[GPIO2PORT(pin)];
gpio_clock_enable(regs); gpio_clock_enable(regs);
struct gpio_out g = { .regs=regs, .bit=GPIO2BIT(pin) }; 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; regs->BSRR = g.bit << 16;
} }
struct gpio_in struct gpio_in
gpio_in_setup(uint32_t pin, int32_t pull_up) 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)]; GPIO_TypeDef *regs = digital_regs[GPIO2PORT(pin)];
struct gpio_in g = { .regs=regs, .bit=GPIO2BIT(pin) }; struct gpio_in g = { .regs=regs, .bit=GPIO2BIT(pin) };
gpio_in_reset(g, pull_up); gpio_in_reset(g, pull_up);

View File

@ -3,8 +3,6 @@
#include <stdint.h> // uint32_t #include <stdint.h> // uint32_t
uint8_t check_gpio_valid(uint32_t pin);
struct gpio_out { struct gpio_out {
void *regs; void *regs;
uint32_t bit; 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); void gpio_in_reset(struct gpio_in g, int32_t pull_up);
uint8_t gpio_in_read(struct gpio_in g); 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 #endif // gpio.h