diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2020-11-22 01:06:30 -0700 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2020-11-22 01:06:30 -0700 |
commit | 9f28e53c71d28d04e2775c59944d2887a99f1e86 (patch) | |
tree | c0ecb2872c6d27acf08aa73919d709f949200de5 /02-usart/src/arch/stm32l4xxx/peripherals/gpio.c | |
parent | ebb9123c00d1e9629376b6f0a2f1f4e7e550c2af (diff) | |
download | stm32l4-9f28e53c71d28d04e2775c59944d2887a99f1e86.tar.gz stm32l4-9f28e53c71d28d04e2775c59944d2887a99f1e86.tar.bz2 stm32l4-9f28e53c71d28d04e2775c59944d2887a99f1e86.zip |
Large reorganization.
What was in core/ is now moved to arch/stm34l4xxx/peripherals. This new
directory is *supposed to* to contain raw header files defining just the
pertinent register structures for the various peripherals. Peripheral
management belongs somewhere in the new `kern/..` directories. This is
not completely the case at the moment, so more refactoring needs to be
done.
What was sitting in the root has now been moved into the kern/
directory. The kern/ directory is to contain everything else
other than raw device register definitions. The root of the kern/
tree is reserved for standard library-esque headers.
The kern/<peripheral> directory contains management systems for that
peripheral. (At the moment DMA is the only peripheral with a decent
management system.) Preferably these peripheral systems should only
include their correlating header in arch/stm34l4xxx/peripherals, and
use other management systems for handling other peripherals rather
than manipulating their raw registers directly. (Though this ideal
will require much more critical mass of management systems.)
Diffstat (limited to '02-usart/src/arch/stm32l4xxx/peripherals/gpio.c')
-rw-r--r-- | 02-usart/src/arch/stm32l4xxx/peripherals/gpio.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/02-usart/src/arch/stm32l4xxx/peripherals/gpio.c b/02-usart/src/arch/stm32l4xxx/peripherals/gpio.c new file mode 100644 index 0000000..a1e82c7 --- /dev/null +++ b/02-usart/src/arch/stm32l4xxx/peripherals/gpio.c @@ -0,0 +1,52 @@ +#include "arch/stm32l4xxx/peripherals/gpio.h" +#include "arch/stm32l4xxx/peripherals/rcc.h" + +/* + * Sets the mode of a pin on a gpio por. + */ +void set_gpio_pin_mode( + __IO gpio_port_t* gpio_port, gpio_pin_t pin, gpio_pin_mode_t mode) +{ + /* Each pin has a 2-bit mode provided at bits pin#*2 and pin#*2+1 */ + gpio_port->mode_r &= ~(0x03 << pin * 2); + gpio_port->mode_r |= mode << pin * 2; +} + +gpio_output_pin_t set_gpio_pin_output( + __IO gpio_port_t* gpio_port, gpio_pin_t pin) +{ + set_gpio_pin_mode(gpio_port, pin, MODE_OUTPUT); + + return (gpio_output_pin_t){.gpio_port = gpio_port, .pin = pin}; +} + +void set_gpio_output_pin(gpio_output_pin_t pin, bool onoff) +{ + if (onoff) { + pin.gpio_port->output_r |= 1 << pin.pin; + } else { + pin.gpio_port->output_r &= ~(1 << pin.pin); + } +} + +void set_gpio_alternate_function( + __IO gpio_port_t* port, gpio_pin_t gpio_pin, alternate_function_t afn) +{ + __IO uint32_t* reg; + if (gpio_pin < 8) { + reg = &(port->af_rl); + } else { + reg = &(port->af_rh); + gpio_pin -= 8; + } + + uint32_t tmp = *reg & (~0x0f << gpio_pin * 4); + *reg = tmp | (afn << gpio_pin * 4); +} + +#define GPIO_PORTS_BASE_ADDR ((uint8_t*)0x48000000) +__IO gpio_port_t* enable_gpio(gpio_port_number_t gpio_port_number) +{ + RCC.ahb2en_r |= 1 << gpio_port_number; /* Enable the GPIO port. */ + return (__IO gpio_port_t*)(GPIO_PORTS_BASE_ADDR + (gpio_port_number * 0x400)); +} |