]> rtime.felk.cvut.cz Git - pes-rpp/rpp-test-sw.git/blob - rpp/lib/rpp/src/rpp/din.c
63fda55bd2e528de7cd6cbaee319b9c2ac3de747
[pes-rpp/rpp-test-sw.git] / rpp / lib / rpp / src / rpp / din.c
1 /* Copyright (C) 2013 Czech Technical University in Prague
2  *
3  * Authors:
4  *     - Carlos Jenkins <carlos@jenkins.co.cr>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  * File : din.c
20  * Abstract:
21  *     Digital Input RPP API implementation file.
22  *
23  * References:
24  *     din.h
25  *     RPP API documentation.
26  */
27
28
29 #include "rpp/rpp.h"
30
31 #if rppCONFIG_INCLUDE_DIN == 1
32
33 #if rppCONFIG_DRV == 1
34 #include "drv/din.h"
35 #endif
36
37 static boolean_t initialized = FALSE;
38
39 int8_t rpp_din_init()
40 {
41     if(initialized) {
42         return FAILURE;
43     }
44     initialized = TRUE;
45
46     return SUCCESS;
47 }
48
49 int8_t rpp_din_ref(uint16_t ref_a, uint16_t ref_b)
50 {
51     if((ref_a > 4095) || (ref_b > 4095)) {
52         return -1;
53     }
54
55     #if rppCONFIG_DRV == 1
56     drv_din_ref(ref_a, ref_b);
57     #endif
58     return SUCCESS;
59 }
60
61
62 // Check for configuration changes to avoid SPI overhead
63 static boolean_t config_changed = FALSE;
64
65 // All cached values are 16 bits in the form [SG7,...,SG0][SP7,...,SP0]
66 static uint16_t pull_cache     = 0x0;
67 static uint16_t active_cache   = 0x0;
68 static uint16_t can_wake_cache = 0x0;
69
70 int8_t rpp_din_setup(uint8_t pin, boolean_t pull_type,
71                       boolean_t active, boolean_t can_wake)
72 {
73     // Check range
74     if(pin > 15) {
75         return -1;
76     }
77
78     // Check programmable feature
79     if(pull_type && (pin > 7)) {
80         return -2;
81     }
82
83     // Set bits
84     uint8_t index = pin;
85     if(pull_type) {
86         bit_set(pull_cache, index);
87     } else {
88         bit_clear(pull_cache, index);
89     }
90
91     if(active) {
92         bit_set(active_cache, index);
93     } else {
94         bit_clear(active_cache, index);
95     }
96
97     if(can_wake) {
98         bit_set(can_wake_cache, index);
99     } else {
100         bit_clear(can_wake_cache, index);
101     }
102
103     config_changed = TRUE;
104     return SUCCESS;
105 }
106
107
108 static uint16_t in_cache = 0x0;
109
110 int8_t rpp_din_get(uint8_t pin, boolean_t var_thr)
111 {
112     // Check range
113     if(pin > 15) {
114         return -1;
115     }
116
117     // Check feature
118     if(var_thr && (pin < 8)) {
119         return -2;
120     }
121
122     // Use of variable threshold was requested
123     if(var_thr) {
124         #if rppCONFIG_DRV == 1
125         if(drv_din_get_varthr(pin) == 1) {
126             return HIGH;
127         }
128         #endif
129         return LOW;
130     }
131
132     if(is_bit_set(in_cache, pin)) {
133         return HIGH;
134     }
135     return LOW;
136 }
137
138
139 static uint16_t diag_cache = 0x0;
140
141 int8_t rpp_din_diag(uint8_t pin)
142 {
143     // Check range
144     if(pin > 15) {
145         return -1;
146     }
147
148     if(is_bit_set(diag_cache, pin)) {
149         return HIGH;
150     }
151     return LOW;
152 }
153
154
155 int8_t rpp_din_update()
156 {
157     #if rppCONFIG_DRV == 1
158     /// Setup pins
159     if(config_changed) {
160         uint16_t sp = 0x0;
161         uint16_t sg = 0x0;
162
163         // Reset chip
164         din_reset();
165         din_spi_transfer();
166         //rpp_sci_printf("din_reset()\r\n");
167
168         // Set pull-type.
169         // In DRV logic is inverted:
170         // DRV: 1 - set pin as switch-to-battery. RPP: 0 - pull-down.
171         // DRV: 0 - set pin as switch-to-ground.  RPP: 1 - pull-up.
172         sp = (~pull_cache) & 0xFF;
173         din_set_pr((uint8_t)sp);
174         din_spi_transfer();
175         //rpp_sci_printf("din_set_pr(%X)\r\n", sp);
176
177         // Set state type, active or tri-stated.
178         // In DRV logic is inverted:
179         // DRV: 1 - tri-state. RPP: 0 - tri-state.
180         // DRV: 0 - active.    RPP: 1 - active.
181         sp = ((~active_cache)     ) & 0xFF;
182         sg = ((~active_cache) >> 8) & 0xFF;
183         din_set_stat(sp, sg);
184         din_spi_transfer();
185         //rpp_sci_printf("din_set_stat(%X, %X)\r\n", sp, sg);
186
187         // Set wake / interrupt.
188         // IN DRV logic is not inverted.
189         // DRV: 1 - can wake.           RPP: 1 - can wake.
190         // DRV: 0 - interrupt disabled. RPP: 0 - interrupt disabled.
191         sp = (can_wake_cache     ) & 0xFF;
192         sg = (can_wake_cache >> 8) & 0xFF;
193         din_set_int(sp, sg);
194         din_spi_transfer();
195         //rpp_sci_printf("din_set_int(%X, %X)\r\n", sp, sg);
196
197         // Mark configuration as commited
198         config_changed = FALSE;
199     }
200
201     // Update cached values
202     din_switch_st();
203     din_spi_transfer();
204     in_cache = din_get_val_word();
205
206     // FIXME: Implement. Dummy assign for now.
207     diag_cache = in_cache;
208
209     if(diag_cache != in_cache) {
210         return FAILURE;
211     }
212     #else
213     UNUSED(config_changed);
214     #endif
215
216     return SUCCESS;
217 }
218
219
220 #endif /* rppCONFIG_INCLUDE_DIN */
221