embox
128 строк · 2.6 Кб
1/**
2* @file
3* @brief
4*
5* @author Anton Kozlov
6* @date 07.04.2012
7*/
8
9#include "stm32_gpio_vl.h"10
11#include <assert.h>12#include <stdint.h>13
14#include <drivers/gpio/gpio_driver.h>15
16#include <hal/reg.h>17
18#include <embox/unit.h>19
20#define RCC_APB1RSTR 0x4002101021#define RCC_APB1PWR 0x1000000022#define RCC_APB2ENR 0x4002101823#define RCC_APB2GPIOC 0x0000001024
25#define RCC_APB2GPIOx 0x000001fc26#define RCC_APB2AFIO 0x0000000127
28
29#define STM32_GPIO_CHIP_ID OPTION_GET(NUMBER,gpio_chip_id)30
31EMBOX_UNIT_INIT(stm32_gpio_init);32
33static struct gpio_chip stm32_gpio_chip;34
35static int stm32_gpio_init(void) {36REG_ORIN(RCC_APB1RSTR,RCC_APB1PWR);37REG_ORIN(RCC_APB2ENR,RCC_APB2GPIOx);38REG_ORIN(RCC_APB2ENR,RCC_APB2AFIO);39return gpio_register_chip(&stm32_gpio_chip, STM32_GPIO_CHIP_ID);40}
41
42static void set_state(struct stm32_gpio *gpio, gpio_mask_t mask, int new_state) {43gpio_mask_t tmask = mask;44assert(gpio);45assert((new_state & ~(0xf)) == 0);46for (int lo = 0; lo < 2; lo++) {47uint32_t gpio_state = REG32_LOAD(&(gpio->crl));48for (int i = 0; i < 8; i++) {49if (tmask & 0x01) {50gpio_state = (gpio_state & ~(0xf<< (i * 4))) | (new_state << (4 * i));51}52tmask >>= 1;53}54REG32_STORE(&(gpio->crl), gpio_state);55}56
57}
58
59static int stm32_gpio_setup_mode(unsigned char port, gpio_mask_t mask,60int mode) {61int mode_val = 0;62struct stm32_gpio *gpio = STM32_GPIO(port);63
64assert(gpio);65
66if ((mode & GPIO_MODE_OUT_SECTION) &&67(mode & GPIO_MODE_IN_SECTION)) { /* mode is incorrect */68return -1;69}70
71if (mode & GPIO_MODE_IN) {72
73mode_val = 4;74/* mask inputs flag only without GPIO_MODE_INPUT */75if ((mode & GPIO_MODE_IN_SECTION) & ~GPIO_MODE_IN) {76mode_val = 8;77
78if (mode & GPIO_MODE_IN_PULL_UP) {79REG32_STORE(&(gpio->bsrr), mask);80}81
82if (mode & GPIO_MODE_IN_PULL_DOWN) {83REG32_STORE(&(gpio->brr), mask);84}85}86} else if (mode & GPIO_MODE_OUT) {87
88mode_val = 3;89
90if (mode & GPIO_MODE_OUT_ALTERNATE) {91mode_val |= 8;92}93
94if (mode & GPIO_MODE_OUT_OPEN_DRAIN) {95mode_val |= 4;96}97}98
99set_state(gpio, mask, mode_val);100
101return 0;102}
103
104static void stm32_gpio_set(unsigned char port, gpio_mask_t mask, char level) {105struct stm32_gpio *gpio = STM32_GPIO(port);106
107assert(gpio);108assert((mask & ~((1 << 16) - 1)) == 0);109
110if(level) {111REG32_STORE(&(gpio->bsrr), mask);112} else {113REG32_STORE(&(gpio->brr), mask);114}115}
116
117static gpio_mask_t stm32_gpio_get(unsigned char port, gpio_mask_t mask){118struct stm32_gpio *gpio = STM32_GPIO(port);119assert(gpio);120return mask & REG32_LOAD(&(gpio->idr));121}
122
123static struct gpio_chip stm32_gpio_chip = {124.setup_mode = stm32_gpio_setup_mode,125.get = stm32_gpio_get,126.set = stm32_gpio_set,127.nports = GPIO_PORT_NUM128};129