]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - rpp/src/drv/digital_io.c
Merge port and gpio definitions into one file in the DRV layer
[pes-rpp/rpp-lib.git] / rpp / src / drv / digital_io.c
1 /*
2  * digital_io.c
3  *
4  *  Created on: 17.7.2015
5  *      Author: michal
6  */
7
8 #include "drv/digital_io.h"
9 #include "drv/spi.h"
10
11 extern gioPORT_t *dio_port_id_map[DIO_MAX_PORT_CNT];
12 extern dio_pin_map_element_t dio_pin_map[DIO_MAX_PIN_CNT];
13 extern dio_port_def_t dio_port_definition[DIO_PORT_CNT];
14
15 #define SPI_PORT_BUF_LEN 4
16 /** Buffer for spi command to be sent */
17 uint8_t spi_port_buf_tx[SPI_PORT_BUF_LEN];
18 /** Buffer for spi response */
19 uint8_t spi_port_buf_rx[SPI_PORT_BUF_LEN];
20
21 uint8_t dio_gpio_get_pin_cnt() {
22         return DIO_MAX_PIN_CNT;
23 }
24
25 dio_pin_map_element_t* dio_gpio_get_pin_map() {
26         return dio_pin_map;
27 }
28
29 gioPORT_t *dio_gpio_get_port_base(uint32_t port_num)
30 {
31         return dio_port_id_map[port_num];
32 }
33
34 uint32_t dio_gpio_pin_get_port_num(uint32_t pin_dsc)
35 {
36
37         return (pin_dsc & ~DIO_PORT_CONF_MASK) >> DIO_PORT_SHIFT;
38 }
39
40 gioPORT_t *dio_gpio_pin_get_port_base(uint32_t pin_dsc)
41 {
42         return dio_gpio_get_port_base(dio_gpio_pin_get_port_num(pin_dsc));
43 }
44
45
46 uint32_t *dio_gpio_pin_get_dsc(const char *pin_name, int len)
47 {
48         uint32_t i;
49         const char *pin_name_ptr;
50         char pin_name_term[32];
51
52         if (len != -1) {    // pin name not terminated by '\0'
53                 strncpy(pin_name_term, pin_name, len);
54                 pin_name_term[len] = '\0';
55                 pin_name_ptr = pin_name_term;
56         }
57         else pin_name_ptr = pin_name;
58
59         for (i = 0; i < DIO_MAX_PIN_CNT; i++) {
60                 if (strcmp(pin_name_ptr, dio_pin_map[i].pin_name) == 0)
61                         return &dio_pin_map[i].pin_desc;
62         }
63         return NULL;
64 }
65
66
67 uint32_t dio_gpio_pin_get_value(uint32_t pin_dsc)
68 {
69         return ((dio_gpio_pin_get_port_base(pin_dsc)->DIN) >> (pin_dsc & 0x1f)) & 1;
70 }
71
72
73 void dio_gpio_pin_set_value(uint32_t pin_dsc, uint32_t value)
74 {
75         if (value)
76                 dio_gpio_pin_get_port_base(pin_dsc)->DSET = 1 << (pin_dsc & 0x1f);
77         else
78                 dio_gpio_pin_get_port_base(pin_dsc)->DCLR = 1 << (pin_dsc & 0x1f);
79 }
80
81
82 int dio_gpio_pin_set_dir_in(uint32_t pin_dsc)
83 {
84         dio_gpio_pin_get_port_base(pin_dsc)->DIR &= ~(1 << (pin_dsc & 0x1f));
85         return 0;
86 }
87
88 int dio_gpio_pin_set_dir_out(uint32_t pin_dsc, uint32_t value)
89 {
90         dio_gpio_pin_set_value(pin_dsc, value);
91         dio_gpio_pin_get_port_base(pin_dsc)->DIR |= (1 << (pin_dsc & 0x1f));
92         return 0;
93 }
94
95 int dio_gpio_pin_get_dir(uint32_t pin_dsc)
96 {
97         return (dio_gpio_pin_get_port_base(pin_dsc)->DIR >> (pin_dsc & 0x1f)) & 1;
98 }
99
100
101 uint32_t dio_gpio_pin_set_mode(uint32_t pin_dsc, uint32_t mode)
102 {
103         gioPORT_t *gioPort = dio_gpio_pin_get_port_base(pin_dsc);
104
105         if (mode & DIO_PORT_CONF_MODE_PTYPE_MASK)
106                 gioPort->PSL |= (1 << (pin_dsc & 0x1f));
107         else
108                 gioPort->PSL &= ~(1 << (pin_dsc & 0x1f));
109         if (mode & DIO_PORT_CONF_MODE_PEN_MASK)
110                 gioPort->PULDIS |= (1 << (pin_dsc & 0x1f));
111         else
112                 gioPort->PULDIS &= ~(1 << (pin_dsc & 0x1f));
113         return 0;
114 }
115
116
117 uint32_t dio_gpio_pin_set_od(uint32_t pin_dsc, uint32_t od)
118 {
119         gioPORT_t *gioPort = dio_gpio_pin_get_port_base(pin_dsc);
120
121         if (od & DIO_PORT_CONF_OD_ON)
122                 gioPort->PDR |= (1 << (pin_dsc & 0x1f));
123         else
124                 gioPort->PDR &= ~(1 << (pin_dsc & 0x1f));
125         return 0;
126 }
127
128
129 uint32_t dio_gpio_pin_set_config(uint32_t pin_dsc, uint32_t conf)
130 {
131         pin_dsc &= ~DIO_PORT_CONF_MASK;
132         dio_gpio_pin_set_mode(pin_dsc, conf & DIO_PORT_CONF_MODE_MASK);
133         dio_gpio_pin_set_od(pin_dsc, conf & DIO_PORT_CONF_OD_MASK);
134         if (conf & DIO_PORT_CONF_SET_DIR) {
135                 if ((conf & DIO_PORT_CONF_DIR_MASK) == (DIO_PORT_CONF_DIR_IN & DIO_PORT_CONF_DIR_MASK))
136                         dio_gpio_pin_set_dir_in(pin_dsc);
137                 else
138                         dio_gpio_pin_set_dir_out(pin_dsc, conf & DIO_PORT_CONF_INIT_HIGH);
139         }
140
141         return 0;
142 }
143
144 uint32_t dio_gpio_pin_configure(uint32_t pin_dsc)
145 {
146         return dio_gpio_pin_set_config(pin_dsc, pin_dsc);
147 }
148
149
150 uint32_t dio_gpio_port_get_val(uint32_t *config, uint32_t num_val, uint32_t *values)
151 {
152         uint32_t i;
153
154         for (i = 0; i < num_val; i++) {
155                 values[i] = dio_gpio_pin_get_value(config[i]);
156         }
157         return 0;
158 }
159
160 uint32_t dio_gpio_port_set_val(uint32_t *config, uint32_t num_val, const uint32_t *values)
161 {
162         uint32_t i;
163
164         for (i = 0; i < num_val; i++) {
165                 dio_gpio_pin_set_value(config[i], (values[i/8] >> i%8) & 0x1);
166         }
167         return 0;
168 }
169
170 const dio_port_def_t *dio_port_get_map()
171 {
172         return (const dio_port_def_t *)dio_port_definition;
173 }
174
175 dio_port_desc_t *dio_port_get_dsc(const char *port_name, int len)
176 {
177         uint32_t i;
178         const char *port_name_ptr;
179         char port_name_term[32];
180
181         if (len != -1) {    // port name not terminated by '\0'
182                 strncpy(port_name_term, port_name, len);
183                 port_name_term[len] = '\0';
184                 port_name_ptr = port_name_term;
185         }
186         else port_name_ptr = port_name;
187
188         for (i = 0; i < DIO_PORT_CNT; i++) {
189                 if (strcmp(port_name_ptr, dio_port_definition[i].name) == 0)
190                         return dio_port_definition[i].desc;
191         }
192         return NULL;
193 }
194
195 uint32_t dio_port_get_val_cnt(const dio_port_desc_t* port_desc) {
196         if (port_desc != NULL) {
197                 return port_desc->numValues;
198         }
199         else {
200                 return 0;
201         }
202 }
203
204 uint32_t dio_spi_port_transfer_command(uint32_t *config, uint32_t num_bytes, const uint32_t *commands)
205 {
206         spi_drv_t *ifc;
207         int i;
208         uint32_t ret;
209
210         for (i = 0; i < num_bytes; i++)
211                 spi_port_buf_tx[i] = commands[i];
212
213         ifc = spi_find_drv(NULL, config[0]);
214         if (ifc == NULL)
215                 return 0;
216
217         if (!(ifc->flags & SPI_IFC_ON))
218                 return 0;
219
220         spi_transfer(ifc, config[1], num_bytes, spi_port_buf_tx, spi_port_buf_rx);
221         ret = 0;
222         for (i = 0; i < num_bytes; i++)
223                 ret |= spi_port_buf_rx[i] << i*8;
224         return ret;
225 }