aboutsummaryrefslogtreecommitdiffstats
path: root/src/stm32f0/gpio.c
diff options
context:
space:
mode:
authorEugene Krashtan <Eugene.Krashtan@opensynergy.com>2019-03-11 12:47:58 +0200
committerKevin O'Connor <kevin@koconnor.net>2019-03-24 12:10:11 -0400
commitb822f389237981043a8033aa4232e8b084137b2c (patch)
treefec159e50a3314cabbe18352e26c10db39c6f621 /src/stm32f0/gpio.c
parent74c6a85cde9327b13a52b1d142b698e00e2d6122 (diff)
downloadkutter-b822f389237981043a8033aa4232e8b084137b2c.tar.gz
kutter-b822f389237981043a8033aa4232e8b084137b2c.tar.xz
kutter-b822f389237981043a8033aa4232e8b084137b2c.zip
stm32f0: New target STM32F0 added.
Signed-off-by: Eugene Krashtan <Eugene.Krashtan@opensynergy.com>
Diffstat (limited to 'src/stm32f0/gpio.c')
-rw-r--r--src/stm32f0/gpio.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/src/stm32f0/gpio.c b/src/stm32f0/gpio.c
new file mode 100644
index 00000000..74e2fb9e
--- /dev/null
+++ b/src/stm32f0/gpio.c
@@ -0,0 +1,141 @@
+/*
+ * GPIO functions on STM32F042 boards.
+ *
+ * Copyright (C) 2019 Eug Krashtan <eug.krashtan@gmail.com>
+ * This file may be distributed under the terms of the GNU GPLv3 license.
+ *
+ */
+
+#include "board/gpio.h" // gpio_out_setup
+#include "stm32f0xx_hal.h"
+#include "internal.h" // GPIO
+#include "board/irq.h" // irq_save
+#include "compiler.h" // ARRAY_SIZE
+#include "sched.h" // sched_shutdown
+#include "command.h" // shutdown
+
+DECL_ENUMERATION_RANGE("pin", "PA0", GPIO('A', 0), 11);
+DECL_ENUMERATION_RANGE("pin", "PB0", GPIO('B', 0), 9);
+DECL_ENUMERATION_RANGE("pin", "PF0", GPIO('F', 0), 2);
+
+GPIO_TypeDef *const digital_regs[] = {
+ GPIOA, GPIOB, GPIOC, GPIOF
+};
+
+// <port:4><pin:4>
+uint8_t const avail_pins[] = {
+ 0x0 + 0x0, //PA0
+ 0x0 + 0x1, //PA1
+#if !(CONFIG_SERIAL)
+ 0x0 + 0x2, //PA2 - USART pins
+ 0x0 + 0x3, //PA3
+#endif
+ 0x0 + 0x4, //PA4
+ 0x0 + 0x5, //PA5
+ 0x0 + 0x6, //PA6
+ 0x0 + 0x7, //PA7
+#if !(CONFIG_CANSERIAL)
+ 0x0 + 0x9, //PA9 - but remapped in CAN mode to PA11,PA12
+ 0x0 + 0xa, //PA10
+#endif
+ 0x10 + 0x1, //PB1
+ 0x10 + 0x8, //PB8
+ 0x50 + 0x0, //PF0
+ 0x50 + 0x1, //PF1
+};
+
+/****************************************************************
+ * General Purpose Input Output (GPIO) pins
+ ****************************************************************/
+
+static uint8_t
+gpio_check_pin(uint8_t pin)
+{
+ int i;
+ for(i=0; i<ARRAY_SIZE(avail_pins); i++) {
+ if (avail_pins[i] == pin)
+ return i;
+ }
+ return 0xFF;
+}
+
+struct gpio_out
+gpio_out_setup(uint8_t pin, uint8_t val)
+{
+ struct gpio_out g = { .pin=pin };
+ if (gpio_check_pin(pin) < 0xFF) {
+ gpio_out_reset(g, val);
+ } else {
+ shutdown("Not an output pin");
+ }
+ return g;
+}
+
+void
+gpio_out_reset(struct gpio_out g, uint8_t val)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ GPIO_InitStruct.Pin = 1 << (g.pin % 16);
+ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+ HAL_GPIO_Init(digital_regs[GPIO2PORT(g.pin)], &GPIO_InitStruct);
+ HAL_GPIO_WritePin(digital_regs[GPIO2PORT(g.pin)], 1 << (g.pin % 16), val);
+}
+
+void
+gpio_out_write(struct gpio_out g, uint8_t val)
+{
+ HAL_GPIO_WritePin(digital_regs[GPIO2PORT(g.pin)], 1 << (g.pin % 16), val);
+}
+
+struct gpio_in
+gpio_in_setup(uint8_t pin, int8_t pull_up)
+{
+ struct gpio_in g = { .pin=pin };
+ if (gpio_check_pin(pin) < 0xFF) {
+ gpio_in_reset(g, pull_up);
+ } else {
+ shutdown("Not an input pin");
+ }
+ return g;
+}
+
+void
+gpio_in_reset(struct gpio_in g, int8_t pull_up)
+{
+ irqstatus_t flag = irq_save();
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ GPIO_InitStruct.Pin = 1 << (g.pin % 16);
+ GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+ GPIO_InitStruct.Pull = (pull_up)?GPIO_PULLUP:GPIO_NOPULL;
+ HAL_GPIO_Init(digital_regs[GPIO2PORT(g.pin)], &GPIO_InitStruct);
+ irq_restore(flag);
+}
+
+uint8_t
+gpio_in_read(struct gpio_in g)
+{
+ return HAL_GPIO_ReadPin(digital_regs[GPIO2PORT(g.pin)], 1 << (g.pin % 16));
+}
+
+void
+gpio_out_toggle_noirq(struct gpio_out g)
+{
+ HAL_GPIO_TogglePin(digital_regs[GPIO2PORT(g.pin)], 1 << (g.pin % 16));
+}
+
+void
+gpio_out_toggle(struct gpio_out g)
+{
+ irqstatus_t flag = irq_save();
+ gpio_out_toggle_noirq(g);
+ irq_restore(flag);
+}
+
+void gpio_init(void)
+{
+ /* GPIO Ports Clock Enable */
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ __HAL_RCC_GPIOF_CLK_ENABLE();
+}