Firmware SDK
twr_module_sensor.c
1 #include <twr_module_sensor.h>
2 #include <twr_tca9534a.h>
3 #include <twr_onewire_gpio.h>
4 
5 #define _TWR_MODULE_SENSOR_INITIALIZED_STATE 0xff
6 #define _TWR_MODULE_SENSOR_INITIALIZED_DIRECTION 0x00
7 #define _TWR_MODULE_SENSOR_VDD (1 << 3)
8 #define _TWR_MODULE_SENSOR_CH_A_56R (1 << 4)
9 #define _TWR_MODULE_SENSOR_CH_A_4K7 (1 << 5)
10 #define _TWR_MODULE_SENSOR_CH_B_4K7 (1 << 6)
11 #define _TWR_MODULE_SENSOR_CH_B_56R (1 << 7)
12 
13 static struct
14 {
15  bool initialized;
16  twr_tca9534a_t tca9534a;
18  int onewire_power_semaphore;
19  bool onewire_initialized;
20  twr_onewire_t onewire;
21 
22 } _twr_module_sensor = {
23  .initialized = false,
24  .onewire_initialized = false
25 };
26 
27 static const twr_gpio_channel_t _twr_module_sensor_channel_gpio_lut[3] =
28 {
32 };
33 
35 {
36  if (!_twr_module_sensor.initialized)
37  {
38  if (!twr_tca9534a_init(&_twr_module_sensor.tca9534a, TWR_I2C_I2C0, 0x3e))
39  {
40  return false;
41  }
42 
43  if (!twr_tca9534a_write_port(&_twr_module_sensor.tca9534a, _TWR_MODULE_SENSOR_INITIALIZED_STATE))
44  {
45  return false;
46  }
47 
48  if (!twr_tca9534a_set_port_direction(&_twr_module_sensor.tca9534a, _TWR_MODULE_SENSOR_INITIALIZED_DIRECTION))
49  {
50  return false;
51  }
52 
53  twr_gpio_init(_twr_module_sensor_channel_gpio_lut[TWR_MODULE_SENSOR_CHANNEL_A]);
54  twr_gpio_init(_twr_module_sensor_channel_gpio_lut[TWR_MODULE_SENSOR_CHANNEL_B]);
55  twr_gpio_init(_twr_module_sensor_channel_gpio_lut[TWR_MODULE_SENSOR_CHANNEL_C]);
56 
57  _twr_module_sensor.initialized = true;
58  }
59 
60  return true;
61 }
62 
64 {
65  _twr_module_sensor.initialized = false;
66 }
67 
69 {
70  uint8_t port_actual;
71  uint8_t port_new;
72 
73  port_actual = _twr_module_sensor.tca9534a._output_port;
74 // twr_tca9534a_read_port(&_twr_module_sensor.tca9534a, &port_actual);
75 
76  port_new = port_actual;
77 
78  switch (channel)
79  {
81  {
82  port_new |= _TWR_MODULE_SENSOR_CH_A_4K7 | _TWR_MODULE_SENSOR_CH_A_56R;
83  break;
84  }
86  {
87  port_new |= _TWR_MODULE_SENSOR_CH_B_4K7 | _TWR_MODULE_SENSOR_CH_B_56R;
88  break;
89  }
91  default:
92  {
93  break;
94  }
95  }
96 
97  switch (pull)
98  {
100  {
101  // Done by OR mask above
102 
103  twr_gpio_set_pull(_twr_module_sensor_channel_gpio_lut[channel], TWR_GPIO_PULL_NONE);
104 
105  break;
106  }
108  {
109  switch (channel)
110  {
112  {
113  port_new &= ~_TWR_MODULE_SENSOR_CH_A_4K7;
114  break;
115  }
117  {
118  port_new &= ~_TWR_MODULE_SENSOR_CH_B_4K7;
119  break;
120  }
122  default:
123  {
124  return false;
125  }
126  }
127  break;
128  }
130  {
131  switch (channel)
132  {
134  {
135  port_new &= ~_TWR_MODULE_SENSOR_CH_A_56R;
136  break;
137  }
139  {
140  port_new &= ~_TWR_MODULE_SENSOR_CH_B_56R;
141  break;
142  }
144  default:
145  {
146  return false;
147  }
148  }
149  break;
150  }
152  {
153  twr_gpio_set_pull(_twr_module_sensor_channel_gpio_lut[channel], TWR_GPIO_PULL_UP);
154  break;
155  }
157  {
158  twr_gpio_set_pull(_twr_module_sensor_channel_gpio_lut[channel], TWR_GPIO_PULL_DOWN);
159  break;
160  }
161  default:
162  {
163  return false;
164  }
165  }
166 
167  if (port_actual != port_new)
168  {
169  twr_gpio_set_pull(_twr_module_sensor_channel_gpio_lut[channel], TWR_GPIO_PULL_NONE);
170  return twr_tca9534a_write_port(&_twr_module_sensor.tca9534a, port_new);
171  }
172 
173  return true;
174 }
175 
177 {
178  if (channel == TWR_MODULE_SENSOR_CHANNEL_A)
179  {
180  uint8_t port_actual = _twr_module_sensor.tca9534a._output_port;
181 
182  if ((port_actual & _TWR_MODULE_SENSOR_CH_A_4K7) == 0)
183  {
185  }
186 
187  if ((port_actual & _TWR_MODULE_SENSOR_CH_A_56R) == 0)
188  {
190  }
191  }
192  if (channel == TWR_MODULE_SENSOR_CHANNEL_B)
193  {
194  uint8_t port_actual = _twr_module_sensor.tca9534a._output_port;
195 
196  if ((port_actual & _TWR_MODULE_SENSOR_CH_B_4K7) == 0)
197  {
199  }
200 
201  if ((port_actual & _TWR_MODULE_SENSOR_CH_B_56R) == 0)
202  {
204  }
205  }
206 
207  return twr_gpio_get_pull(_twr_module_sensor_channel_gpio_lut[channel]);
208 }
209 
211 {
212  twr_gpio_set_mode(_twr_module_sensor_channel_gpio_lut[channel], mode);
213 }
214 
216 {
217  return twr_gpio_get_input(_twr_module_sensor_channel_gpio_lut[channel]);
218 }
219 
221 {
222  twr_gpio_set_output(_twr_module_sensor_channel_gpio_lut[channel], state);
223 }
224 
226 {
227  return twr_gpio_get_output(_twr_module_sensor_channel_gpio_lut[channel]);
228 }
229 
231 {
232  twr_gpio_toggle_output(_twr_module_sensor_channel_gpio_lut[channel]);
233 }
234 
236 {
237  uint8_t port_actual;
238  uint8_t port_new;
239 
241  {
242  return false;
243  }
244 
245  port_actual = _twr_module_sensor.tca9534a._output_port;
246 
247  if (on)
248  {
249  port_new = port_actual & ~_TWR_MODULE_SENSOR_VDD;
250  }
251  else
252  {
253  port_new = port_actual | _TWR_MODULE_SENSOR_VDD;
254  }
255 
256  if (port_actual != port_new)
257  {
258  return twr_tca9534a_write_port(&_twr_module_sensor.tca9534a, port_new);
259  }
260 
261  return true;
262 }
263 
265 {
266  if (!_twr_module_sensor.initialized)
267  {
269  }
270 
271  if (_twr_module_sensor.revision == TWR_MODULE_SENSOR_REVISION_UNKNOWN)
272  {
273  if (!twr_tca9534a_set_pin_direction(&_twr_module_sensor.tca9534a, TWR_TCA9534A_PIN_P1, TWR_TCA9534A_PIN_DIRECTION_INPUT))
274  {
276  }
277 
278  uint8_t test_vector = 0x86;
279  int value_input;
280  int value_output;
281 
282  for (size_t i = 0; i < sizeof(test_vector); i++)
283  {
284  value_output = (test_vector >> i) & 0x01;
285 
286  if (!twr_tca9534a_write_pin(&_twr_module_sensor.tca9534a, TWR_TCA9534A_PIN_P0, value_output))
287  {
289  }
290 
291  if (!twr_tca9534a_read_pin(&_twr_module_sensor.tca9534a, TWR_TCA9534A_PIN_P1, &value_input))
292  {
294  }
295 
296  if (value_output != value_input)
297  {
298  _twr_module_sensor.revision = TWR_MODULE_SENSOR_REVISION_R1_0;
299 
300  return _twr_module_sensor.revision;
301  }
302  }
303 
304  _twr_module_sensor.revision = TWR_MODULE_SENSOR_REVISION_R1_1;
305  }
306 
307  return _twr_module_sensor.revision;
308 }
309 
311 {
312  if (!_twr_module_sensor.onewire_initialized)
313  {
314  twr_onewire_gpio_init(&_twr_module_sensor.onewire, TWR_GPIO_P5);
315 
316  _twr_module_sensor.onewire_initialized = true;
317  }
318 
319  return &_twr_module_sensor.onewire;
320 }
321 
323 {
324  if (_twr_module_sensor.onewire_power_semaphore == 0)
325  {
327  {
329  {
330  return false;
331  }
332  }
333  else
334  {
336  {
337  return false;
338  }
339  }
340 
342  {
343  return false;
344  }
345  }
346 
347  _twr_module_sensor.onewire_power_semaphore++;
348 
349  return true;
350 }
351 
353 {
354  _twr_module_sensor.onewire_power_semaphore--;
355 
356  if (_twr_module_sensor.onewire_power_semaphore == 0)
357  {
359  {
361  {
362  return false;
363  }
364  }
365  else
366  {
368  {
369  return false;
370  }
371  }
372 
374  {
375  return false;
376  }
377  }
378 
379  return true;
380 }
void twr_module_sensor_toggle_output(twr_module_sensor_channel_t channel)
Toggle output state for Sensor Module channel.
void twr_gpio_set_mode(twr_gpio_channel_t channel, twr_gpio_mode_t mode)
Set mode of operation for GPIO channel.
Definition: twr_gpio.c:367
Channel has pull-up 4k7.
int twr_gpio_get_output(twr_gpio_channel_t channel)
Get output state for GPIO channel.
Definition: twr_gpio.c:477
bool twr_module_sensor_onewire_power_down(void)
Semaphore for 1Wire Power down: for R1.1 set VDD Off, for R1.0 pull none on channel A...
void twr_module_sensor_set_output(twr_module_sensor_channel_t channel, int state)
Set output state of Sensor Module channel.
twr_module_sensor_mode_t
Sensor Module mode of operation.
bool twr_tca9534a_write_port(twr_tca9534a_t *self, uint8_t state)
Write state to all pins.
Definition: twr_tca9534a.c:35
int twr_gpio_get_input(twr_gpio_channel_t channel)
Get input state for GPIO channel.
Definition: twr_gpio.c:465
twr_module_sensor_pull_t
Sensor module pull.
bool twr_module_sensor_init(void)
Initialize Sensor Module.
GPIO channel P7, A6.
Definition: twr_gpio.h:36
void twr_gpio_set_pull(twr_gpio_channel_t channel, twr_gpio_pull_t pull)
Set pull-up/pull-down configuration for GPIO channel.
Definition: twr_gpio.c:340
twr_module_sensor_revision_t twr_module_sensor_get_revision(void)
Get Sensor Module revision.
bool twr_tca9534a_read_pin(twr_tca9534a_t *self, twr_tca9534a_pin_t pin, int *state)
Read pin state.
Definition: twr_tca9534a.c:47
GPIO channel has no pull-up/pull-down.
Definition: twr_gpio.h:90
bool twr_tca9534a_init(twr_tca9534a_t *self, twr_i2c_channel_t i2c_channel, uint8_t i2c_address)
Initialize TCA9534A.
Definition: twr_tca9534a.c:8
twr_module_sensor_pull_t twr_module_sensor_get_pull(twr_module_sensor_channel_t channel)
Get pull-up/pull-down configuration for Sensor Module channel.
bool twr_tca9534a_write_pin(twr_tca9534a_t *self, twr_tca9534a_pin_t pin, int state)
Write pin state.
Definition: twr_tca9534a.c:61
void twr_module_sensor_set_mode(twr_module_sensor_channel_t channel, twr_module_sensor_mode_t mode)
Set output mode of Sensor Module channel.
void twr_gpio_toggle_output(twr_gpio_channel_t channel)
Toggle output state for GPIO channel.
Definition: twr_gpio.c:483
GPIO channel has pull-up.
Definition: twr_gpio.h:93
bool twr_module_sensor_set_pull(twr_module_sensor_channel_t channel, twr_module_sensor_pull_t pull)
Set pull of Sensor Module channel.
int twr_module_sensor_get_input(twr_module_sensor_channel_t channel)
Get input of Sensor Module channel.
Channel has internal pull-down.
void twr_gpio_init(twr_gpio_channel_t channel)
Initialize GPIO channel.
Definition: twr_gpio.c:325
twr_module_sensor_channel_t
Sensor Module channels.
twr_gpio_channel_t
GPIO channels.
Definition: twr_gpio.h:12
bool twr_module_sensor_onewire_power_up(void)
Semaphore for 1Wire Power up: for R1.1 set VDD On, for R1.0 pull up 56R on channel A...
struct twr_onewire_t twr_onewire_t
1-Wire instance
Definition: twr_onewire.h:14
Channel has pull-up 56R.
Hardware revision unknown.
GPIO channel P4, A4, DAC0.
Definition: twr_gpio.h:27
Hardware revision R1.1.
bool twr_tca9534a_set_pin_direction(twr_tca9534a_t *self, twr_tca9534a_pin_t pin, twr_tca9534a_pin_direction_t direction)
Set pin direction.
Definition: twr_tca9534a.c:113
Pin state.
Definition: twr_tca9534a.h:42
bool twr_module_sensor_set_vdd(bool on)
Set VDD On / Off.
Channel has no pull.
void twr_gpio_set_output(twr_gpio_channel_t channel, int state)
Set output state for GPIO channel.
Definition: twr_gpio.c:471
void twr_module_sensor_deinit(void)
Deinitialize Sensor Module.
void twr_onewire_gpio_init(twr_onewire_t *onewire, twr_gpio_channel_t channel)
Initialize 1-Wire.
twr_gpio_pull_t twr_gpio_get_pull(twr_gpio_channel_t channel)
Get pull-up/pull-down configuration for GPIO channel.
Definition: twr_gpio.c:361
Hardware revision R1.0.
I2C channel I2C0.
Definition: twr_i2c.h:18
bool twr_tca9534a_set_port_direction(twr_tca9534a_t *self, uint8_t direction)
Set direction of all pins.
Definition: twr_tca9534a.c:87
GPIO channel has pull-down.
Definition: twr_gpio.h:96
twr_module_sensor_revision_t
Sensor Module hardware revision.
int twr_module_sensor_get_output(twr_module_sensor_channel_t channel)
Get output state for Sensor Module channel.
GPIO channel P5, A5, DAC1.
Definition: twr_gpio.h:30
twr_onewire_t * twr_module_sensor_get_onewire(void)
Initialize and get Instance 1-Wire for channel B.
Channel has internal pull-up.