]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - rpp/src/rpp/din.c
Change license to MIT
[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  * Permission is hereby granted, free of charge, to any person
7  * obtaining a copy of this software and associated documentation
8  * files (the "Software"), to deal in the Software without
9  * restriction, including without limitation the rights to use,
10  * copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following
13  * conditions:
14  *
15  * The above copyright notice and this permission notice shall be
16  * included in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25  * OTHER DEALINGS IN THE SOFTWARE.
26  *
27  * File : din.c
28  * Abstract:
29  *     Digital Input RPP API implementation file.
30  *
31  * References:
32  *     din.h
33  *     RPP API documentation.
34  */
35
36
37 #include "rpp/rpp.h"
38 #include "rpp/mutex.h"
39
40 #ifndef FREERTOS_POSIX
41 #include "drv/din.h"
42 #include "drv/spi_def.h"
43 #endif
44
45 RPP_MUTEX_DEFINE(mutex_din);
46
47 static boolean_t initialized = FALSE;
48
49 int8_t rpp_din_init()
50 {
51         if (initialized)
52                 return FAILURE;
53         if (!RPP_MUTEX_INIT(mutex_din))
54                 return FAILURE;
55         initialized = TRUE;
56 #ifndef FREERTOS_POSIX
57         dmmInit();
58         gioInit();
59         hetInit();
60         spi_init();
61 #endif
62
63         return SUCCESS;
64 }
65
66 int8_t rpp_din_ref(uint16_t ref_a, uint16_t ref_b)
67 {
68         if ((ref_a > 4095) || (ref_b > 4095))
69                 return -1;
70
71 #ifndef FREERTOS_POSIX
72         RPP_MUTEX_LOCK(mutex_din);
73         drv_din_ref(ref_a, ref_b);
74         RPP_MUTEX_UNLOCK(mutex_din);
75 #endif
76         return SUCCESS;
77 }
78
79
80 // Check for configuration changes to avoid SPI overhead
81 static boolean_t config_changed = FALSE;
82
83 // All cached values are 16 bits in the form [SG7,...,SG0][SP7,...,SP0]
84 static uint16_t pull_cache     = 0x0; /* 0 - pull-down, 1 - pull-up */
85 static uint16_t active_cache   = 0x0; /* 0 - tri-state, 1 - active */
86 static uint16_t can_wake_cache = 0x0;
87
88 static boolean_t check_pin_busy(uint8_t pin)
89 {
90         if (rpp_irc_status(RPP_IRC_1) == 1 && (pin == 10 || pin == 11))
91                 return TRUE;
92         if (rpp_irc_status(RPP_IRC_2) == 1 && (pin == 14 || pin == 15))
93                 return TRUE;
94         return FALSE;
95 }
96
97 int8_t rpp_din_setup(uint8_t pin, boolean_t pull_up,
98                                          boolean_t active, boolean_t can_wake)
99 {
100         // Check range
101         if (pin > 15)
102                 return -1;
103
104         // Check programmable feature
105         if (!pull_up && (pin > 7))
106                 return -2;
107
108         RPP_MUTEX_LOCK(mutex_din);
109         // Check blockade of specific pins
110         if (check_pin_busy(pin)) {
111                 RPP_MUTEX_UNLOCK(mutex_din);
112                 return -RPP_EBUSY;
113         }
114
115         // Set bits
116         if (pull_up)
117                 bit_set(pull_cache, pin);
118         else
119                 bit_clear(pull_cache, pin);
120
121         if (active)
122                 bit_set(active_cache, pin);
123         else
124                 bit_clear(active_cache, pin);
125
126         if (can_wake)
127                 bit_set(can_wake_cache, pin);
128         else
129                 bit_clear(can_wake_cache, pin);
130
131         config_changed = TRUE;
132         RPP_MUTEX_UNLOCK(mutex_din);
133         return SUCCESS;
134 }
135
136
137 static uint16_t in_cache = 0x0;
138
139 int8_t rpp_din_get(uint8_t pin)
140 {
141         // Check range
142         if (pin > 15)
143                 return -1;
144
145         // Check blockade of specific pins
146         if (check_pin_busy(pin))
147                 return -RPP_EBUSY;
148
149         return is_bit_set(in_cache, pin) ? RPP_CLOSED : RPP_OPEN;
150 }
151
152 int8_t rpp_din_get_tr(uint8_t pin)
153 {
154         // Check range
155         if (pin < 8 || pin > 15)
156                 return -1;
157
158         // Check blockade of specific pins
159         if (check_pin_busy(pin))
160                 return -RPP_EBUSY;
161
162 #ifndef FREERTOS_POSIX
163         if (drv_din_get_varthr(pin) == 1)
164                 return HIGH;
165 #endif
166         return LOW;
167 }
168
169
170
171 static uint16_t diag_cache = 0x0;
172
173 int8_t rpp_din_diag(uint8_t pin)
174 {
175         // Check range
176         if (pin > 15)
177                 return -1;
178
179         // Check blockade of specific pins
180         if (check_pin_busy(pin))
181                 return -RPP_EBUSY;
182
183         return is_bit_set(diag_cache, pin) ? HIGH : LOW;
184 }
185
186 /*
187  * pouzivat din_mod s pouzivanim enumu
188  */
189 int8_t rpp_din_update()
190 {
191         RPP_MUTEX_LOCK(mutex_din);
192 #ifndef FREERTOS_POSIX
193         /// Setup pins
194         if (config_changed) {
195                 uint16_t sp = 0x0;
196                 uint16_t sg = 0x0;
197
198                 // Reset chip
199                 din_set_reg(DIN_RESET_CMD, 0, 0);
200                 //rpp_sci_printf("din_reset()\r\n");
201
202                 // Set pull-type.
203                 // In DRV logic is inverted:
204                 // DRV: 1 - set pin as switch-to-battery. RPP: 0 - pull-down.
205                 // DRV: 0 - set pin as switch-to-ground.  RPP: 1 - pull-up.
206                 sp = (~pull_cache) & 0xFF;
207                 din_set_reg(DIN_SETTINGS_CMD, 0xffff, sp);
208                 //rpp_sci_printf("din_set_pr(%X)\r\n", sp);
209
210                 // Set state type, active or tri-stated.
211                 // In DRV logic is inverted:
212                 // DRV: 1 - tri-state. RPP: 0 - tri-state.
213                 // DRV: 0 - active.    RPP: 1 - active.
214                 sp = ((~active_cache)     ) & 0xFF;
215                 sg = ((~active_cache) >> 8) & 0xFF;
216                 din_set_reg(DIN_TRI_STATE_CMD_YES, 0xffff, sp);
217                 din_set_reg(DIN_TRI_STATE_CMD_NO, 0xffff, sg);
218                 //rpp_sci_printf("din_set_stat(%X, %X)\r\n", sp, sg);
219
220                 // Set wake / interrupt.
221                 // IN DRV logic is not inverted.
222                 // DRV: 1 - can wake.           RPP: 1 - can wake.
223                 // DRV: 0 - interrupt disabled. RPP: 0 - interrupt disabled.
224                 sp = (can_wake_cache     ) & 0xFF;
225                 sg = (can_wake_cache >> 8) & 0xFF;
226
227                 din_set_reg(DIN_WAKE_UP_CMD_ENB, 0xffff, sp);
228                 din_set_reg(DIN_WAKE_UP_CMD_DIS, 0xffff, sg);
229                 //rpp_sci_printf("din_set_int(%X, %X)\r\n", sp, sg);
230
231                 // Mark configuration as commited
232                 config_changed = FALSE;
233         }
234
235         // Update cached values
236         din_set_reg(DIN_SWITCH_STATUS_CMD, 0, 0);
237         in_cache = din_get_val_word();
238
239         // FIXME: Implement. Dummy assign for now.
240         diag_cache = in_cache;
241
242         if (diag_cache != in_cache) {
243                 RPP_MUTEX_UNLOCK(mutex_din);
244                 return FAILURE;
245         }
246
247         #else /* ifndef FREERTOS_POSIX */
248         UNUSED(config_changed);
249         #endif /* ifndef FREERTOS_POSIX */
250
251         RPP_MUTEX_UNLOCK(mutex_din);
252         return SUCCESS;
253 }