embox

Форк
0
/
k210_gpio.c 
141 строка · 3.5 Кб
1
/**
2
 * @file k210_gpio.c
3
 * @brief
4
 * @author sksat <sksat@sksat.net>
5
 * @version 0.1
6
 * @date 2020-08-15
7
 */
8

9
#include <assert.h>
10
#include <util/log.h>
11

12
#include <embox/unit.h>
13
#include <lib/libds/bit.h>
14
#include <lib/libds/array.h>
15

16
#include <drivers/gpio/gpio_driver.h>
17
#include <drivers/gpio/k210.h>
18
#include <drivers/gpio/k210/fpioa.h>
19
#include <config/board_config.h>
20

21
EMBOX_UNIT_INIT(k210_gpio_init);
22

23
#define K210_GPIO_CHIP_ID OPTION_GET(NUMBER,gpio_chip_id)
24

25
volatile k210_gpio_t* const gpio = (volatile k210_gpio_t*) CONF_GPIO_PORT_REGION_BASE;
26

27
extern volatile sysctl_clock_enable_central* const clk_en_cent;
28
extern volatile sysctl_clock_enable_peripheral* const clk_en_peri;
29

30
static struct gpio_chip k210_gpio_chip = {
31
	.setup_mode = k210_gpio_setup_mode,
32
	.get = k210_gpio_get,
33
	.set = k210_gpio_set,
34
	.nports = CONF_GPIO_PORT_NUM
35
};
36

37
static int k210_gpio_setup_mode(unsigned char port, gpio_mask_t pins, int mode){
38
	assert(port < CONF_GPIO_PORT_NUM);
39

40
	if(mode & GPIO_MODE_OUT) {
41
		k210_gpio_set_dir(pins, 1);
42
	} else if (mode & GPIO_MODE_IN){
43
		log_error("GPIO input mode is not implemented");
44
		return -1;
45
	} else {
46
		log_error("GPIO mode %x is not implemented", mode);
47
		return -1;
48
	}
49

50
	return 0;
51
}
52

53
static void k210_gpio_set(unsigned char port, gpio_mask_t pins, char level){
54
	volatile uint32_t *reg_dir = gpio->dir.reg32;
55
	volatile uint32_t *reg = gpio->data_out.reg32;
56
	uint32_t input = ~(*reg_dir);
57

58
	assert(port < CONF_GPIO_PORT_NUM);
59
	// direction check
60
	input = (uint32_t)pins & input;
61
	if (input) {
62
		log_error("input pin cannot set level: pin mask=%x, level=%d", input, level);
63
	}
64

65
	if (level == GPIO_PIN_HIGH) {
66
		*reg &= ~(uint32_t)pins;
67
		log_debug("gpio_set high: %x", pins);
68
	} else if (level == GPIO_PIN_LOW){
69
		*reg |= ((uint32_t)pins);
70
		log_debug("gpio_set low: %x", pins);
71
	} else {
72
		log_error("unknown GPIO pin level");
73
	}
74
	log_debug("gpio_set result: %x", *reg);
75
}
76

77
static gpio_mask_t k210_gpio_get(unsigned char port, gpio_mask_t pins){
78
	volatile uint32_t *reg_dir = gpio->dir.reg32;
79
	gpio_mask_t res = 0;
80
	assert(port < CONF_GPIO_PORT_NUM);
81

82
	uint32_t dir = *reg_dir;
83
	int bit;
84
	bit_foreach(bit, (uint32_t)pins){
85
		uint32_t reg;
86

87
		reg = (dir & (1 << bit)) ? gpio->data_out.reg32[0] : gpio->data_in.reg32[0];
88
		log_debug("bit: %d dir: 0x%x reg: 0x%x", bit, dir, reg);
89
		if (!(reg & (1 << bit))) {
90
			res |= (1 << bit);
91
		}
92
	}
93
	log_debug("state: %x", res);
94
	return res;
95
}
96

97
static void maix_bit_gpio_config(void){
98
	// builtin RGB LEDs
99
	k210_fpioa_set_func(MAIXBIT_IO_LED_R, FN_GPIO0);
100
	k210_fpioa_set_pull(MAIXBIT_IO_LED_R, FPIOA_PULL_DOWN);
101
	k210_gpio_setup_mode(0, 1 << 0, GPIO_MODE_OUT);
102

103
	k210_fpioa_set_func(MAIXBIT_IO_LED_G, FN_GPIO1);
104
	k210_fpioa_set_pull(MAIXBIT_IO_LED_G, FPIOA_PULL_DOWN);
105
	k210_gpio_setup_mode(0, 1 << 1, GPIO_MODE_OUT);
106

107
	k210_fpioa_set_func(MAIXBIT_IO_LED_B, FN_GPIO2);
108
	k210_fpioa_set_pull(MAIXBIT_IO_LED_B, FPIOA_PULL_DOWN);
109
	k210_gpio_setup_mode(0, 1 << 2, GPIO_MODE_OUT);
110

111
	// IO24
112
	k210_fpioa_set_func(MAIXBIT_IO24, FN_GPIO3);
113
	k210_fpioa_set_pull(MAIXBIT_IO24, FPIOA_PULL_DOWN);
114
	k210_gpio_setup_mode(0, 1 << 3, GPIO_MODE_OUT);
115

116
	/* we set up GPIO 0..3 to low level */
117
	k210_gpio_set(0, 0x0F, GPIO_PIN_LOW);
118
}
119

120
static int k210_gpio_init(void){
121
	//k210_fpioa_set_func(24, FN_GPIO3);
122
	// enable bus clock
123
	clk_en_cent->apb0 = 1;
124

125
	// enable device clock
126
	clk_en_peri->gpio = 1;
127

128
	maix_bit_gpio_config();
129

130
	return gpio_register_chip(&k210_gpio_chip, K210_GPIO_CHIP_ID);
131
}
132

133
void k210_gpio_set_dir(gpio_mask_t pins, bool dir){
134
	volatile uint32_t *reg = gpio->dir.reg32;
135

136
	if(dir) {
137
		*reg |= (uint32_t)pins;
138
	} else{
139
		*reg &= ~((uint32_t)pins);
140
	}
141
}
142

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

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

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

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