embox

Форк
0
/
stm32_gpio_vl.c 
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  0x40021010
21
#define RCC_APB1PWR   0x10000000
22
#define RCC_APB2ENR   0x40021018
23
#define RCC_APB2GPIOC 0x00000010
24

25
#define RCC_APB2GPIOx 0x000001fc
26
#define RCC_APB2AFIO  0x00000001
27

28

29
#define STM32_GPIO_CHIP_ID OPTION_GET(NUMBER,gpio_chip_id)
30

31
EMBOX_UNIT_INIT(stm32_gpio_init);
32

33
static struct gpio_chip stm32_gpio_chip;
34

35
static int stm32_gpio_init(void) {
36
	REG_ORIN(RCC_APB1RSTR,RCC_APB1PWR);
37
	REG_ORIN(RCC_APB2ENR,RCC_APB2GPIOx);
38
	REG_ORIN(RCC_APB2ENR,RCC_APB2AFIO);
39
	return gpio_register_chip(&stm32_gpio_chip, STM32_GPIO_CHIP_ID);
40
}
41

42
static void set_state(struct stm32_gpio *gpio, gpio_mask_t mask, int new_state) {
43
	gpio_mask_t tmask = mask;
44
	assert(gpio);
45
	assert((new_state & ~(0xf)) == 0);
46
	for (int lo = 0; lo < 2; lo++) {
47
		uint32_t gpio_state = REG32_LOAD(&(gpio->crl));
48
		for (int i = 0; i < 8; i++) {
49
			if (tmask & 0x01) {
50
				gpio_state = (gpio_state & ~(0xf<< (i * 4))) | (new_state << (4 * i));
51
			}
52
			tmask >>= 1;
53
		}
54
		REG32_STORE(&(gpio->crl), gpio_state);
55
	}
56

57
}
58

59
static int stm32_gpio_setup_mode(unsigned char port, gpio_mask_t mask,
60
		int mode) {
61
	int mode_val = 0;
62
	struct stm32_gpio *gpio = STM32_GPIO(port);
63

64
	assert(gpio);
65

66
	if ((mode & GPIO_MODE_OUT_SECTION) &&
67
		(mode & GPIO_MODE_IN_SECTION)) { /* mode is incorrect */
68
		return -1;
69
	}
70

71
	if (mode & GPIO_MODE_IN) {
72

73
		mode_val = 4;
74
		/* mask inputs flag only without GPIO_MODE_INPUT */
75
		if ((mode & GPIO_MODE_IN_SECTION) & ~GPIO_MODE_IN) {
76
			mode_val = 8;
77

78
			if (mode & GPIO_MODE_IN_PULL_UP) {
79
				REG32_STORE(&(gpio->bsrr), mask);
80
			}
81

82
			if (mode & GPIO_MODE_IN_PULL_DOWN) {
83
				REG32_STORE(&(gpio->brr), mask);
84
			}
85
		}
86
	} else if (mode & GPIO_MODE_OUT) {
87

88
		mode_val = 3;
89

90
		if (mode & GPIO_MODE_OUT_ALTERNATE) {
91
			mode_val |= 8;
92
		}
93

94
		if (mode & GPIO_MODE_OUT_OPEN_DRAIN) {
95
			mode_val |= 4;
96
		}
97
	}
98

99
	set_state(gpio, mask, mode_val);
100

101
	return 0;
102
}
103

104
static void stm32_gpio_set(unsigned char port, gpio_mask_t mask, char level) {
105
	struct stm32_gpio *gpio = STM32_GPIO(port);
106

107
	assert(gpio);
108
	assert((mask & ~((1 << 16) - 1)) == 0);
109

110
	if(level) {
111
		REG32_STORE(&(gpio->bsrr), mask);
112
	} else {
113
		REG32_STORE(&(gpio->brr), mask);
114
	}
115
}
116

117
static gpio_mask_t stm32_gpio_get(unsigned char port, gpio_mask_t mask){
118
	struct stm32_gpio *gpio = STM32_GPIO(port);
119
	assert(gpio);
120
	return mask & REG32_LOAD(&(gpio->idr));
121
}
122

123
static 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_NUM
128
};
129

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.