-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgpio-driver.c
153 lines (133 loc) · 3.54 KB
/
gpio-driver.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include <stdint.h>
#include <stdbool.h>
#include "gpio-driver.h"
uint8_t pin_map[MAX_NUM]; /* Vetor para mapear os pinos e os números
de GPIO atribuídos. Os números vão de 0 a MAX_NUM-1*/
bool port_init[] = {0,0,0};
bool firstGPIOinit(void);
uint8_t gpio_config(uint8_t gpio_num, uint8_t pin, gpio_pin_mode dir)
{
uint8_t sucess=0;
if (gpio_num<MAX_NUM)
{
pin_map[gpio_num]=pin;
struct bit_and_port num_bit_porta= getPort(pin_map[gpio_num]);
if(firstGPIOinit() == 1)
{
afio_init();
afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY); /* Habilita os pinos do JTAG*/
afio_remap(AFIO_REMAP_USART3_PARTIAL); // remap Serial2(USART3)PB10/PB11
afio_remap(AFIO_REMAP_TIM2_FULL); // better PWM compatibility
afio_remap(AFIO_REMAP_TIM3_PARTIAL);// better PWM compatibility
}
if(port_init[num_bit_porta.indice_porta]!=1)
{ /* Inicializa porta apenas se ela ainda não foi inicializada */
gpio_init(num_bit_porta.dev_ptr);
port_init[num_bit_porta.indice_porta]=1;
}
if((num_bit_porta.dev_ptr!=GPIOC) || (dir!=GPIO_OUTPUT_PP))
{ /* Pinos da porta GPIOC só podem receber corrente (só open drain) */
gpio_set_mode(num_bit_porta.dev_ptr, num_bit_porta.bit, dir);
sucess=1;
}
else
{
/*"Prohibited output type for this port!"*/
}
}
else
{
/*"Pin out of bounds!"*/
}
return sucess;
}
uint8_t gpio_write(uint8_t gpio_num, uint8_t val) //Escrever sinal digital no pino
{
uint8_t sucess=0;
if (gpio_num<MAX_NUM)
{
struct bit_and_port num_bit_porta= getPort(pin_map[gpio_num]);
gpio_write_bit(num_bit_porta.dev_ptr, num_bit_porta.bit, val);
sucess=1;
}
else
{
/* "Pin out of bounds!"*/
}
return sucess;
}
uint8_t gpio_toggle(uint8_t gpio_num) //Alternar o sinal escrito no pino
{
uint8_t sucess=0;
if (gpio_num<MAX_NUM)
{
struct bit_and_port num_bit_porta= getPort(pin_map[gpio_num]);
gpio_toggle_bit(num_bit_porta.dev_ptr, num_bit_porta.bit);
}
else
{
/*"Pin out of bounds!"*/
}
return sucess;
}
gpio_pin_mode gpio_dir(uint8_t gpio_num) //Lê qual a função que o pino selecionado tem
{
gpio_pin_mode mode = GPIO_INPUT_ANALOG;
if (gpio_num<MAX_NUM)
{
struct bit_and_port num_bit_porta= getPort(pin_map[gpio_num]);
mode = gpio_get_mode(num_bit_porta.dev_ptr, num_bit_porta.bit);
}
else
{
/* "Pin out of bounds!"*/
}
return mode;
}
uint8_t gpio_read(uint8_t gpio_num, uint8_t *val) //Ler sinal digital no pino
{
uint8_t sucess=0;
if (gpio_num<MAX_NUM)
{
struct bit_and_port num_bit_porta= getPort(pin_map[gpio_num]);
*val = gpio_read_bit(num_bit_porta.dev_ptr, num_bit_porta.bit) ? 1 : 0;
}
else
{
/*"Pin out of bounds!"*/
}
return sucess;
}
/* Funções auxiliares da identificação da porta do microcontrolador */
bool firstGPIOinit(void)
{
bool saida = 0;
for (uint8_t portas; portas<sizeof(port_init)/sizeof(port_init[0]); portas++)
{
saida |= port_init[portas];
}
return !saida;
}
struct bit_and_port getPort(uint8_t pin)
{
struct bit_and_port num_bit_porta = {NULL, 0, 0};
if (pin>PB15)
{
num_bit_porta.dev_ptr = GPIOC;
num_bit_porta.bit = pin - 32;
num_bit_porta.indice_porta = 2;
}
else if(pin>PA15)
{
num_bit_porta.dev_ptr = GPIOB;
num_bit_porta.bit = pin - 16;
num_bit_porta.indice_porta=1;
}
else
{
num_bit_porta.dev_ptr = GPIOA;
num_bit_porta.bit = pin - 0;
num_bit_porta.indice_porta = 0;
}
return num_bit_porta;
}