]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - rpp/src/rpp/din.c
spi: Rework the SPI interface
[pes-rpp/rpp-lib.git] / rpp / src / rpp / din.c
1 /* Copyright (C) 2013, 2015 Czech Technical University in Prague
2  *
3  * Authors:
4  *     - Carlos Jenkins <carlos@jenkins.co.cr>
5  *
6  * This document contains proprietary information belonging to Czech
7  * Technical University in Prague. Passing on and copying of this
8  * document, and communication of its contents is not permitted
9  * without prior written authorization.
10  *
11  * File : din.c
12  * Abstract:
13  *     Digital Input RPP API implementation file.
14  *
15  * References:
16  *     din.h
17  *     RPP API documentation.
18  */
19
20
21 #include "rpp/rpp.h"
22 #include "rpp/mutex.h"
23
24 #ifndef FREERTOS_POSIX
25 #include "drv/din.h"
26 #include "drv/spi_def.h"
27 #endif
28
29 RPP_MUTEX_DEFINE(mutex_din);
30
31 static boolean_t initialized = FALSE;
32
33 int8_t rpp_din_init()
34 {
35         if (initialized)
36                 return FAILURE;
37         if (!RPP_MUTEX_INIT(mutex_din))
38                 return FAILURE;
39         initialized = TRUE;
40 #ifndef FREERTOS_POSIX
41         dmmInit();
42         gioInit();
43         hetInit();
44         spi_init();
45 #endif
46
47         return SUCCESS;
48 }
49
50 int8_t rpp_din_ref(uint16_t ref_a, uint16_t ref_b)
51 {
52         if ((ref_a > 4095) || (ref_b > 4095))
53                 return -1;
54
55 #ifndef FREERTOS_POSIX
56         RPP_MUTEX_LOCK(mutex_din);
57         drv_din_ref(ref_a, ref_b);
58         RPP_MUTEX_UNLOCK(mutex_din);
59 #endif
60         return SUCCESS;
61 }
62
63
64 // Check for configuration changes to avoid SPI overhead
65 static boolean_t config_changed = FALSE;
66
67 // All cached values are 16 bits in the form [SG7,...,SG0][SP7,...,SP0]
68 static uint16_t pull_cache     = 0x0; /* 0 - pull-down, 1 - pull-up */
69 static uint16_t active_cache   = 0x0; /* 0 - tri-state, 1 - active */
70 static uint16_t can_wake_cache = 0x0;
71
72 static boolean_t check_pin_busy(uint8_t pin)
73 {
74         if (rpp_irc_status(RPP_IRC_1) == 1 && (pin == 10 || pin == 11))
75                 return TRUE;
76         if (rpp_irc_status(RPP_IRC_2) == 1 && (pin == 14 || pin == 15))
77                 return TRUE;
78         return FALSE;
79 }
80
81 int8_t rpp_din_setup(uint8_t pin, boolean_t pull_up,
82                                          boolean_t active, boolean_t can_wake)
83 {
84         // Check range
85         if (pin > 15)
86                 return -1;
87
88         // Check programmable feature
89         if (!pull_up && (pin > 7))
90                 return -2;
91
92         RPP_MUTEX_LOCK(mutex_din);
93         // Check blockade of specific pins
94         if (check_pin_busy(pin)) {
95                 RPP_MUTEX_UNLOCK(mutex_din);
96                 return -RPP_EBUSY;
97         }
98
99         // Set bits
100         if (pull_up)
101                 bit_set(pull_cache, pin);
102         else
103                 bit_clear(pull_cache, pin);
104
105         if (active)
106                 bit_set(active_cache, pin);
107         else
108                 bit_clear(active_cache, pin);
109
110         if (can_wake)
111                 bit_set(can_wake_cache, pin);
112         else
113                 bit_clear(can_wake_cache, pin);
114
115         config_changed = TRUE;
116         RPP_MUTEX_UNLOCK(mutex_din);
117         return SUCCESS;
118 }
119
120
121 static uint16_t in_cache = 0x0;
122
123 int8_t rpp_din_get(uint8_t pin)
124 {
125         // Check range
126         if (pin > 15)
127                 return -1;
128
129         // Check blockade of specific pins
130         if (check_pin_busy(pin))
131                 return -RPP_EBUSY;
132
133         return is_bit_set(in_cache, pin) ? RPP_CLOSED : RPP_OPEN;
134 }
135
136 int8_t rpp_din_get_tr(uint8_t pin)
137 {
138         // Check range
139         if (pin < 8 || pin > 15)
140                 return -1;
141
142         // Check blockade of specific pins
143         if (check_pin_busy(pin))
144                 return -RPP_EBUSY;
145
146 #ifndef FREERTOS_POSIX
147         if (drv_din_get_varthr(pin) == 1)
148                 return HIGH;
149 #endif
150         return LOW;
151 }
152
153
154
155 static uint16_t diag_cache = 0x0;
156
157 int8_t rpp_din_diag(uint8_t pin)
158 {
159         // Check range
160         if (pin > 15)
161                 return -1;
162
163         // Check blockade of specific pins
164         if (check_pin_busy(pin))
165                 return -RPP_EBUSY;
166
167         return is_bit_set(diag_cache, pin) ? HIGH : LOW;
168 }
169
170 /*
171  * pouzivat din_mod s pouzivanim enumu
172  */
173 int8_t rpp_din_update()
174 {
175         RPP_MUTEX_LOCK(mutex_din);
176 #ifndef FREERTOS_POSIX
177         /// Setup pins
178         if (config_changed) {
179                 uint16_t sp = 0x0;
180                 uint16_t sg = 0x0;
181
182                 // Reset chip
183                 din_set_reg(DIN_RESET_CMD, 0, 0);
184                 //rpp_sci_printf("din_reset()\r\n");
185
186                 // Set pull-type.
187                 // In DRV logic is inverted:
188                 // DRV: 1 - set pin as switch-to-battery. RPP: 0 - pull-down.
189                 // DRV: 0 - set pin as switch-to-ground.  RPP: 1 - pull-up.
190                 sp = (~pull_cache) & 0xFF;
191                 din_set_reg(DIN_SETTINGS_CMD, 0xffff, sp);
192                 //rpp_sci_printf("din_set_pr(%X)\r\n", sp);
193
194                 // Set state type, active or tri-stated.
195                 // In DRV logic is inverted:
196                 // DRV: 1 - tri-state. RPP: 0 - tri-state.
197                 // DRV: 0 - active.    RPP: 1 - active.
198                 sp = ((~active_cache)     ) & 0xFF;
199                 sg = ((~active_cache) >> 8) & 0xFF;
200                 din_set_reg(DIN_TRI_STATE_CMD_YES, 0xffff, sp);
201                 din_set_reg(DIN_TRI_STATE_CMD_NO, 0xffff, sg);
202                 //rpp_sci_printf("din_set_stat(%X, %X)\r\n", sp, sg);
203
204                 // Set wake / interrupt.
205                 // IN DRV logic is not inverted.
206                 // DRV: 1 - can wake.           RPP: 1 - can wake.
207                 // DRV: 0 - interrupt disabled. RPP: 0 - interrupt disabled.
208                 sp = (can_wake_cache     ) & 0xFF;
209                 sg = (can_wake_cache >> 8) & 0xFF;
210
211                 din_set_reg(DIN_WAKE_UP_CMD_ENB, 0xffff, sp);
212                 din_set_reg(DIN_WAKE_UP_CMD_DIS, 0xffff, sg);
213                 //rpp_sci_printf("din_set_int(%X, %X)\r\n", sp, sg);
214
215                 // Mark configuration as commited
216                 config_changed = FALSE;
217         }
218
219         // Update cached values
220         din_set_reg(DIN_SWITCH_STATUS_CMD, 0, 0);
221         in_cache = din_get_val_word();
222
223         // FIXME: Implement. Dummy assign for now.
224         diag_cache = in_cache;
225
226         if (diag_cache != in_cache) {
227                 RPP_MUTEX_UNLOCK(mutex_din);
228                 return FAILURE;
229         }
230
231         #else /* ifndef FREERTOS_POSIX */
232         UNUSED(config_changed);
233         #endif /* ifndef FREERTOS_POSIX */
234
235         RPP_MUTEX_UNLOCK(mutex_din);
236         return SUCCESS;
237 }