Firmware SDK
twr_chester_a.c
1 #include <twr_chester_a.h>
2 #include <twr_log.h>
3 
4 #define RELAY_1_MASK (1 << TWR_TCA9534A_PIN_P0)
5 #define RELAY_2_MASK (1 << TWR_TCA9534A_PIN_P1)
6 
7 static bool init_tca9534a(twr_chester_a_t *self)
8 {
9  if (self->is_tca9534a_initialized)
10  {
11  return true;
12  }
13 
14  if (!twr_tca9534a_write_port(&self->tca9534a, 0x00)) {
15  twr_log_error("CHESTER A: Expander write_port");
16  return false;
17  }
18 
19  if (!twr_tca9534a_set_port_direction(&self->tca9534a, 0x00)) {
20  twr_log_error("CHESTER A: Expander port_direction");
21  return false;
22  }
23 
24  self->is_tca9534a_initialized = true;
25 
26  return true;
27 }
28 
29 bool twr_chester_a_init(twr_chester_a_t *self, twr_i2c_channel_t i2c_channel)
30 {
31  self->is_tca9534a_initialized = false;
32 
33  twr_tca9534a_init(&self->tca9534a, i2c_channel, 0x3a);
34 
35  return init_tca9534a(self);
36 }
37 
38 bool twr_chester_a_relay_set_state(twr_chester_a_t *self, twr_chester_a_relay_t relay, bool state)
39 {
40  if (!init_tca9534a(self))
41  {
42  return false;
43  }
44 
45  uint8_t port = self->tca9534a._output_port;
46 
47  switch (relay)
48  {
49  case TWR_CHESTER_A_RELAY_1:
50  {
51  if (state) {
52  port |= RELAY_1_MASK;
53  } else {
54  port &= ~RELAY_1_MASK;
55  }
56  break;
57  }
58  case TWR_CHESTER_A_RELAY_2:
59  {
60  if (state) {
61  port |= RELAY_2_MASK;
62  } else {
63  port &= ~RELAY_2_MASK;
64  }
65  break;
66  }
67  case TWR_CHESTER_A_RELAY_BOTH:
68  {
69  if (state) {
70  port |= RELAY_1_MASK | RELAY_2_MASK;
71  } else {
72  port &= ~(RELAY_1_MASK | RELAY_2_MASK);
73  }
74  break;
75  }
76  default:
77  {
78  twr_log_error("CHESTER A: unknown relay");
79  return false;
80  }
81  }
82 
83  if (!twr_tca9534a_write_port(&self->tca9534a, port)) {
84  self->is_tca9534a_initialized = false;
85  twr_log_error("CHESTER A: Expander write_port");
86  return false;
87  }
88 
89  return true;
90 }
91 
92 bool twr_chester_a_relay_get_state(twr_chester_a_t *self, twr_chester_a_relay_t relay, bool *state)
93 {
94  if (!init_tca9534a(self))
95  {
96  return false;
97  }
98 
99  uint8_t port = self->tca9534a._output_port;
100 
101  switch (relay)
102  {
103  case TWR_CHESTER_A_RELAY_1:
104  {
105  *state = (port & RELAY_1_MASK) != 0;
106  break;
107  }
108  case TWR_CHESTER_A_RELAY_2:
109  {
110  *state = (port & RELAY_2_MASK) != 0;
111  break;
112  }
113  case TWR_CHESTER_A_RELAY_BOTH:
114  default:
115  {
116  twr_log_error("CHESTER A: unknown relay");
117  return false;
118  }
119  }
120 
121  return true;
122 }
123 
124 bool twr_chester_a_relay_toggle(twr_chester_a_t *self, twr_chester_a_relay_t relay)
125 {
126  bool state;
127  return twr_chester_a_relay_get_state(self, relay, &state) &&
128  twr_chester_a_relay_set_state(self, relay, !state);
129 }
130 
twr_chester_a_relay_t
Relay enum.
Definition: twr_chester_a.h:18
struct twr_chester_a_t twr_chester_a_t
HARDWARIO CHESTER A instance.
Definition: twr_chester_a.h:13
twr_i2c_channel_t
I2C channels.
Definition: twr_i2c.h:16
void void void void void twr_log_error(const char *format,...) __attribute__((format(printf
Log ERROR message (annotated in log as <E>)
bool twr_tca9534a_write_port(twr_tca9534a_t *self, uint8_t state)
Write state to all pins.
Definition: twr_tca9534a.c:35
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
bool twr_tca9534a_set_port_direction(twr_tca9534a_t *self, uint8_t direction)
Set direction of all pins.
Definition: twr_tca9534a.c:87