Firmware SDK
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
bc_cy8cmbr3102.c
1 #include <bc_cy8cmbr3102.h>
2 
3 #define _BC_CY8CMBR3102_START_INTERVAL 1500
4 #define _BC_CY8CMBR3102_SCAN_INTERVAL 100
5 #define _BC_CY8CMBR3102_SCAN_INTERVAL_IS_TOUCH 1000
6 
7 static const uint8_t _bc_cy8cmbr3102_default_setting[] = {
8  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9  0x00, 0x00, 0x00, 0x00, 0x32, 0x7F, 0x00, 0x00,
10  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11  0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
12  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80,
13  0x05, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00,
14  0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00,
15  0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
16  0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17  0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x54,
18  0x00, 0x37, 0x01, 0x00, 0x00, 0x0A, 0x00, 0x00,
19  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
20  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
21  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
22  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
23  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x0E
24 };
25 
26 static void _bc_cy8cmbr3102_task(void *param);
27 
28 bool bc_cy8cmbr3102_init(bc_cy8cmbr3102_t *self, bc_i2c_channel_t i2c_channel, uint8_t i2c_address)
29 {
30  memset(self, 0, sizeof(*self));
31 
32  self->_i2c_channel = i2c_channel;
33  self->_i2c_address = i2c_address;
34 
35  bc_i2c_init(self->_i2c_channel, BC_I2C_SPEED_400_KHZ);
36 
37  self->_scan_interval = _BC_CY8CMBR3102_SCAN_INTERVAL;
38 
39  self->_task_id_task = bc_scheduler_register(_bc_cy8cmbr3102_task, self, _BC_CY8CMBR3102_START_INTERVAL);
40 
41  return true;
42 }
43 
44 void bc_cy8cmbr3102_set_event_handler(bc_cy8cmbr3102_t *self, void (*event_handler)(bc_cy8cmbr3102_t *, bc_cy8cmbr3102_event_t, void *), void *event_param)
45 {
46  self->_event_handler = event_handler;
47  self->_event_param = event_param;
48 }
49 
51 {
52  self->_scan_interval = scan_interval;
53 
54  bc_scheduler_plan_absolute(self->_task_id_task, _BC_CY8CMBR3102_START_INTERVAL < bc_tick_get() ? _BC_CY8CMBR3102_START_INTERVAL: 0);
55 }
56 
58 {
59  return bc_i2c_memory_read_16b(self->_i2c_channel, self->_i2c_address, 0xba, &value);
60 }
61 
62 bool bc_cy8cmbr3102_is_touch(bc_cy8cmbr3102_t *self, bool *is_touch)
63 {
64  uint8_t prox_stat = 0;
65 
66  if (!bc_i2c_memory_read_8b(self->_i2c_channel, self->_i2c_address, 0xae, &prox_stat))
67  {
68  return false;
69  }
70 
71  *is_touch = (prox_stat & 0x01) != 0;
72 
73  return true;
74 }
75 
76 
77 static void _bc_cy8cmbr3102_task(void *param)
78 {
79  bc_cy8cmbr3102_t *self = param;
80 
81  start:
82 
83  switch (self->_state)
84  {
85  case BC_CY8CMBR3102_STATE_ERROR:
86  {
87  if (self->_event_handler != NULL)
88  {
89  self->_event_handler(self, BC_CY8CMBR3102_EVENT_ERROR, self->_event_param);
90  }
91 
92  self->_state = BC_CY8CMBR3102_STATE_INITIALIZE;
93 
94  bc_scheduler_plan_current_from_now(self->_scan_interval);
95 
96  return;
97  }
98  case BC_CY8CMBR3102_STATE_INITIALIZE:
99  {
100  bc_i2c_memory_transfer_t transfer;
101  transfer.device_address = self->_i2c_address;
102  transfer.memory_address = 0x00;
103  transfer.buffer = (uint8_t *)_bc_cy8cmbr3102_default_setting;
104  transfer.length = sizeof(_bc_cy8cmbr3102_default_setting);
105 
106  if (!bc_i2c_memory_write(self->_i2c_channel, &transfer))
107  {
108  if (self->_error_cnt++ < 2)
109  {
111 
112  return;
113  }
114 
115  self->_error_cnt = 0;
116 
117  self->_state = BC_CY8CMBR3102_STATE_ERROR;
118 
119  goto start;
120  }
121 
122  self->_state = BC_CY8CMBR3102_STATE_CALC_CONFIG_CRC;
123 
125 
126  return;
127  }
128  case BC_CY8CMBR3102_STATE_CALC_CONFIG_CRC:
129  {
130  if (!bc_i2c_memory_write_8b(self->_i2c_channel, self->_i2c_address, 0x86, 0x02))
131  {
132  self->_state = BC_CY8CMBR3102_STATE_ERROR;
133 
134  goto start;
135  }
136 
137  self->_state = BC_CY8CMBR3102_STATE_SELF_RESET;
138 
140 
141  return;
142  }
143  case BC_CY8CMBR3102_STATE_SELF_RESET:
144  {
145  if (!bc_i2c_memory_write_8b(self->_i2c_channel, self->_i2c_address, 0x86, 0xff))
146  {
147  self->_state = BC_CY8CMBR3102_STATE_ERROR;
148  goto start;
149  }
150 
151  self->_state = BC_CY8CMBR3102_STATE_READ;
152 
154 
155  return;
156  }
157  case BC_CY8CMBR3102_STATE_READ:
158  {
159  bool is_touch;
160 
161  if (!bc_cy8cmbr3102_is_touch(self, &is_touch))
162  {
163  if (self->_error_cnt++ < 2)
164  {
166 
167  return;
168  }
169 
170  self->_error_cnt = 0;
171 
172  self->_state = BC_CY8CMBR3102_STATE_ERROR;
173 
174  goto start;
175  }
176 
177  if (is_touch)
178  {
179  if (self->_event_handler != NULL)
180  {
181  self->_event_handler(self, BC_CY8CMBR3102_EVENT_TOUCH, self->_event_param);
182  }
183 
184  bc_scheduler_plan_current_from_now(_BC_CY8CMBR3102_SCAN_INTERVAL_IS_TOUCH);
185 
186  return;
187  }
188 
189  bc_scheduler_plan_current_from_now(self->_scan_interval);
190 
191  return;
192  }
193  default:
194  {
195  self->_state = BC_CY8CMBR3102_STATE_ERROR;
196 
197  goto start;
198  }
199  }
200 }
201 
void * buffer
Pointer to buffer which is being written or read.
Definition: bc_i2c.h:66
uint64_t bc_tick_t
Timestamp data type.
Definition: bc_tick.h:16
I2C communication speed is 400 kHz.
Definition: bc_i2c.h:36
bool bc_cy8cmbr3102_init(bc_cy8cmbr3102_t *self, bc_i2c_channel_t i2c_channel, uint8_t i2c_address)
Initialize CY8CMBR3102.
void bc_scheduler_plan_absolute(bc_scheduler_task_id_t task_id, bc_tick_t tick)
Schedule specified task to absolute tick.
Definition: bc_scheduler.c:124
void bc_cy8cmbr3102_set_event_handler(bc_cy8cmbr3102_t *self, void(*event_handler)(bc_cy8cmbr3102_t *, bc_cy8cmbr3102_event_t, void *), void *event_param)
Set callback function.
bc_scheduler_task_id_t bc_scheduler_register(void(*task)(void *), void *param, bc_tick_t tick)
Register task in scheduler.
Definition: bc_scheduler.c:56
bool bc_i2c_memory_read_8b(bc_i2c_channel_t channel, uint8_t device_address, uint32_t memory_address, uint8_t *data)
Memory read 1 byte from I2C channel.
Definition: bc_i2c.c:431
void bc_i2c_init(bc_i2c_channel_t channel, bc_i2c_speed_t speed)
Initialize I2C channel.
Definition: bc_i2c.c:54
bc_tick_t bc_tick_get(void)
Get absolute timestamp since start of program.
Definition: bc_tick.c:7
void bc_cy8cmbr3102_set_scan_interval(bc_cy8cmbr3102_t *self, bc_tick_t scan_interval)
Set scan interval.
uint32_t memory_address
8-bit I2C memory address (it can be extended to 16-bit format if OR-ed with BC_I2C_MEMORY_ADDRESS_16_...
Definition: bc_i2c.h:63
uint8_t device_address
7-bit I2C device address
Definition: bc_i2c.h:60
I2C memory transfer parameters.
Definition: bc_i2c.h:57
bool bc_cy8cmbr3102_is_touch(bc_cy8cmbr3102_t *self, bool *is_touch)
Is touch.
struct bc_cy8cmbr3102_t bc_cy8cmbr3102_t
TCA9534A instance.
bc_i2c_channel_t
I2C channels.
Definition: bc_i2c.h:15
void bc_scheduler_plan_current_from_now(bc_tick_t tick)
Schedule current task to tick relative from now.
Definition: bc_scheduler.c:154
size_t length
Length of buffer which is being written or read.
Definition: bc_i2c.h:69
bool bc_i2c_memory_write(bc_i2c_channel_t channel, const bc_i2c_memory_transfer_t *transfer)
Memory write to I2C channel.
Definition: bc_i2c.c:327
bc_cy8cmbr3102_event_t
Callback events.
bool bc_i2c_memory_read_16b(bc_i2c_channel_t channel, uint8_t device_address, uint32_t memory_address, uint16_t *data)
Memory read 2 bytes from I2C channel.
Definition: bc_i2c.c:443
bool bc_cy8cmbr3102_get_proximity(bc_cy8cmbr3102_t *self, uint16_t value)
Get proximity (Capacitive sensor difference count signal.)
bool bc_i2c_memory_write_8b(bc_i2c_channel_t channel, uint8_t device_address, uint32_t memory_address, uint8_t data)
Memory write 1 byte to I2C channel.
Definition: bc_i2c.c:402