Firmware SDK
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
bc_wssfm10r1at.c
1 #include <bc_wssfm10r1at.h>
2 
3 #define BC_WSSFM10R1AT_DELAY_RUN 100
4 #define BC_WSSFM10R1AT_DELAY_INITIALIZATION_RESET_H 100
5 #define BC_WSSFM10R1AT_DELAY_INITIALIZATION_AT_COMMAND 100
6 #define BC_WSSFM10R1AT_DELAY_INITIALIZATION_AT_RESPONSE 100
7 #define BC_WSSFM10R1AT_DELAY_SET_POWER_RESPONSE 100
8 #define BC_WSSFM10R1AT_DELAY_SEND_RF_FRAME_RESPONSE 12000
9 #define BC_WSSFM10R1AT_DELAY_READ_ID_RESPONSE 100
10 #define BC_WSSFM10R1AT_DELAY_READ_PAC_RESPONSE 100
11 #define BC_WSSFM10R1AT_DELAY_CONTINUOUS_WAVE_RESPONSE 2000
12 #define BC_WSSFM10R1AT_DELAY_DEEP_SLEEP_RESPONSE 100
13 
14 static void _bc_wssfm10r1at_task(void *param);
15 
16 static void _bc_wssfm10r1at_set_state(bc_wssfm10r1at_t *self, bc_wssfm10r1at_state_t state);
17 
18 static bool _bc_wssfm10r1at_read_response(bc_wssfm10r1at_t *self);
19 
21 {
22  memset(self, 0, sizeof(*self));
23 
24  self->_reset_signal = reset_signal;
25  self->_uart_channel = uart_channel;
26 
27  bc_gpio_init(self->_reset_signal);
28  bc_gpio_set_output(self->_reset_signal, 0);
29  bc_gpio_set_mode(self->_reset_signal, BC_GPIO_MODE_OUTPUT);
30 
31  bc_fifo_init(&self->_tx_fifo, self->_tx_fifo_buffer, sizeof(self->_tx_fifo_buffer));
32  bc_fifo_init(&self->_rx_fifo, self->_rx_fifo_buffer, sizeof(self->_rx_fifo_buffer));
33 
35  bc_uart_set_async_fifo(self->_uart_channel, &self->_tx_fifo, &self->_rx_fifo);
36  bc_uart_async_read_start(self->_uart_channel, BC_TICK_INFINITY);
37 
38  self->_task_id = bc_scheduler_register(_bc_wssfm10r1at_task, self, BC_WSSFM10R1AT_DELAY_RUN);
39 
40  self->_state = BC_WSSFM10R1AT_STATE_INITIALIZE;
41 }
42 
43 void bc_wssfm10r1at_set_event_handler(bc_wssfm10r1at_t *self, void (*event_handler)(bc_wssfm10r1at_t *, bc_wssfm10r1at_event_t, void *), void *event_param)
44 {
45  self->_event_handler = event_handler;
46  self->_event_param = event_param;
47 }
48 
50 {
51  if (self->_state == BC_WSSFM10R1AT_STATE_READY)
52  {
53  return true;
54  }
55 
56  if (self->_state == BC_WSSFM10R1AT_STATE_DEEP_SLEEP)
57  {
58  return true;
59  }
60 
61  return false;
62 }
63 
64 bool bc_wssfm10r1at_send_rf_frame(bc_wssfm10r1at_t *self, const void *buffer, size_t length)
65 {
66  if (!bc_wssfm10r1at_is_ready(self) || length == 0 || length > 12)
67  {
68  return false;
69  }
70 
71  self->_message_length = length;
72 
73  memcpy(self->_message_buffer, buffer, self->_message_length);
74 
75  _bc_wssfm10r1at_set_state(self, BC_WSSFM10R1AT_STATE_SEND_RF_FRAME_COMMAND);
76 
77  return true;
78 }
79 
81 {
82  if (!bc_wssfm10r1at_is_ready(self))
83  {
84  return false;
85  }
86 
87  _bc_wssfm10r1at_set_state(self, BC_WSSFM10R1AT_STATE_READ_DEVICE_ID_COMMAND);
88 
89  return true;
90 }
91 
92 bool bc_wssfm10r1at_get_device_id(bc_wssfm10r1at_t *self, char *buffer, size_t buffer_size)
93 {
94  if (buffer_size < 8 + 1)
95  {
96  return false;
97  }
98 
99  if (self->_state != BC_WSSFM10R1AT_STATE_READ_DEVICE_ID_RESPONSE)
100  {
101  return false;
102  }
103 
104  if (strlen(self->_response) != 9 || self->_response[8] != '\r')
105  {
106  return false;
107  }
108 
109  strncpy(buffer, self->_response, 8);
110 
111  buffer[8] = '\0';
112 
113  return true;
114 }
115 
117 {
118  if (!bc_wssfm10r1at_is_ready(self))
119  {
120  return false;
121  }
122 
123  _bc_wssfm10r1at_set_state(self, BC_WSSFM10R1AT_STATE_READ_DEVICE_PAC_COMMAND);
124 
125  return true;
126 }
127 
128 bool bc_wssfm10r1at_get_device_pac(bc_wssfm10r1at_t *self, char *buffer, size_t buffer_size)
129 {
130  if (buffer_size < 16 + 1)
131  {
132  return false;
133  }
134 
135  if (self->_state != BC_WSSFM10R1AT_STATE_READ_DEVICE_PAC_RESPONSE)
136  {
137  return false;
138  }
139 
140  if (strlen(self->_response) != 17 || self->_response[16] != '\r')
141  {
142  return false;
143  }
144 
145  strncpy(buffer, self->_response, 16);
146 
147  buffer[16] = '\0';
148 
149  return true;
150 }
151 
153 {
154  if (!bc_wssfm10r1at_is_ready(self))
155  {
156  return false;
157  }
158 
159  _bc_wssfm10r1at_set_state(self, BC_WSSFM10R1AT_STATE_CONTINUOUS_WAVE_COMMAND);
160 
161  return true;
162 }
163 
164 static void _bc_wssfm10r1at_task(void *param)
165 {
166  bc_wssfm10r1at_t *self = param;
167 
168  while (true)
169  {
170  switch (self->_state)
171  {
172  case BC_WSSFM10R1AT_STATE_READY:
173  {
174  if (self->_deep_sleep)
175  {
176  self->_deep_sleep = false;
177 
178  self->_state = self->_state_after_sleep;
179 
180  continue;
181  }
182 
183  if (self->_event_handler != NULL)
184  {
185  self->_event_handler(self, BC_WSSFM10R1AT_EVENT_READY, self->_event_param);
186  }
187 
188  if (self->_state == BC_WSSFM10R1AT_STATE_READY)
189  {
190  self->_state = BC_WSSFM10R1AT_STATE_DEEP_SLEEP_COMMAND;
191  }
192 
193  continue;
194  }
195  case BC_WSSFM10R1AT_STATE_ERROR:
196  {
197  self->_deep_sleep = false;
198 
199  if (self->_event_handler != NULL)
200  {
201  self->_event_handler(self, BC_WSSFM10R1AT_EVENT_ERROR, self->_event_param);
202  }
203 
204  self->_state = BC_WSSFM10R1AT_STATE_INITIALIZE;
205 
206  continue;
207  }
208  case BC_WSSFM10R1AT_STATE_INITIALIZE:
209  {
210  self->_state = BC_WSSFM10R1AT_STATE_INITIALIZE_RESET_L;
211 
212  continue;
213  }
214  case BC_WSSFM10R1AT_STATE_INITIALIZE_RESET_L:
215  {
216  bc_gpio_set_output(self->_reset_signal, 0);
217 
218  self->_state = BC_WSSFM10R1AT_STATE_INITIALIZE_RESET_H;
219 
220  bc_scheduler_plan_current_from_now(BC_WSSFM10R1AT_DELAY_INITIALIZATION_RESET_H);
221 
222  return;
223  }
224  case BC_WSSFM10R1AT_STATE_INITIALIZE_RESET_H:
225  {
226  bc_gpio_set_output(self->_reset_signal, 1);
227 
228  self->_state = BC_WSSFM10R1AT_STATE_INITIALIZE_AT_COMMAND;
229 
230  bc_scheduler_plan_current_from_now(BC_WSSFM10R1AT_DELAY_INITIALIZATION_AT_COMMAND);
231 
232  return;
233  }
234  case BC_WSSFM10R1AT_STATE_INITIALIZE_AT_COMMAND:
235  {
236  self->_state = BC_WSSFM10R1AT_STATE_ERROR;
237 
238  // TODO Purge RX FIFO
239 
240  strcpy(self->_command, "\rAT\r");
241 
242  size_t length = strlen(self->_command);
243 
244  if (bc_uart_async_write(self->_uart_channel, self->_command, length) != length)
245  {
246  continue;
247  }
248 
249  bc_gpio_set_output(self->_reset_signal, 1);
250 
251  self->_state = BC_WSSFM10R1AT_STATE_INITIALIZE_AT_RESPONSE;
252 
253  bc_scheduler_plan_current_from_now(BC_WSSFM10R1AT_DELAY_INITIALIZATION_AT_RESPONSE);
254 
255  return;
256  }
257  case BC_WSSFM10R1AT_STATE_INITIALIZE_AT_RESPONSE:
258  {
259  self->_state = BC_WSSFM10R1AT_STATE_ERROR;
260 
261  if (!_bc_wssfm10r1at_read_response(self))
262  {
263  continue;
264  }
265 
266  if (strcmp(self->_response, "OK\r") != 0)
267  {
268  continue;
269  }
270 
271  self->_state = BC_WSSFM10R1AT_STATE_SET_POWER_COMMAND;
272 
273  continue;
274  }
275  case BC_WSSFM10R1AT_STATE_SET_POWER_COMMAND:
276  {
277  self->_state = BC_WSSFM10R1AT_STATE_ERROR;
278 
279  strcpy(self->_command, "ATS302=15\r");
280 
281  size_t length = strlen(self->_command);
282 
283  if (bc_uart_async_write(self->_uart_channel, self->_command, length) != length)
284  {
285  continue;
286  }
287 
288  self->_state = BC_WSSFM10R1AT_STATE_SET_POWER_RESPONSE;
289 
290  bc_scheduler_plan_current_from_now(BC_WSSFM10R1AT_DELAY_SET_POWER_RESPONSE);
291 
292  return;
293  }
294  case BC_WSSFM10R1AT_STATE_SET_POWER_RESPONSE:
295  {
296  self->_state = BC_WSSFM10R1AT_STATE_ERROR;
297 
298  if (!_bc_wssfm10r1at_read_response(self))
299  {
300  continue;
301  }
302 
303  if (strcmp(self->_response, "OK\r") != 0)
304  {
305  continue;
306  }
307 
308  self->_state = BC_WSSFM10R1AT_STATE_READY;
309 
310  continue;
311  }
312  case BC_WSSFM10R1AT_STATE_SEND_RF_FRAME_COMMAND:
313  {
314  self->_state = BC_WSSFM10R1AT_STATE_ERROR;
315 
316  static const char *hex_lookup_table[] =
317  {
318  "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F",
319  "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F",
320  "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F",
321  "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C", "3D", "3E", "3F",
322  "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4A", "4B", "4C", "4D", "4E", "4F",
323  "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", "5E", "5F",
324  "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6A", "6B", "6C", "6D", "6E", "6F",
325  "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7A", "7B", "7C", "7D", "7E", "7F",
326  "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8A", "8B", "8C", "8D", "8E", "8F",
327  "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9A", "9B", "9C", "9D", "9E", "9F",
328  "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF",
329  "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF",
330  "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB", "CC", "CD", "CE", "CF",
331  "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF",
332  "E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF",
333  "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF"
334  };
335 
336  strcpy(self->_command, "AT$SF=");
337 
338  for (size_t i = 0; i < self->_message_length; i++)
339  {
340  strcat(self->_command, hex_lookup_table[*((uint8_t *) self->_message_buffer + i)]);
341  }
342 
343  strcat(self->_command, "\r");
344 
345  size_t length = strlen(self->_command);
346 
347  if (bc_uart_async_write(self->_uart_channel, self->_command, length) != length)
348  {
349  continue;
350  }
351 
352  self->_state = BC_WSSFM10R1AT_STATE_SEND_RF_FRAME_RESPONSE;
353 
354  if (self->_event_handler != NULL)
355  {
356  self->_event_handler(self, BC_WSSFM10R1AT_EVENT_SEND_RF_FRAME_START, self->_event_param);
357  }
358 
359  bc_scheduler_plan_current_from_now(BC_WSSFM10R1AT_DELAY_SEND_RF_FRAME_RESPONSE);
360 
361  return;
362  }
363  case BC_WSSFM10R1AT_STATE_SEND_RF_FRAME_RESPONSE:
364  {
365  self->_state = BC_WSSFM10R1AT_STATE_ERROR;
366 
367  if (!_bc_wssfm10r1at_read_response(self))
368  {
369  continue;
370  }
371 
372  if (strcmp(self->_response, "OK\r") != 0)
373  {
374  continue;
375  }
376 
377  self->_state = BC_WSSFM10R1AT_STATE_READY;
378 
379  if (self->_event_handler != NULL)
380  {
381  self->_event_handler(self, BC_WSSFM10R1AT_EVENT_SEND_RF_FRAME_DONE, self->_event_param);
382  }
383 
384  continue;
385  }
386  case BC_WSSFM10R1AT_STATE_READ_DEVICE_ID_COMMAND:
387  {
388  self->_state = BC_WSSFM10R1AT_STATE_ERROR;
389 
390  strcpy(self->_command, "AT$I=10\r");
391 
392  size_t length = strlen(self->_command);
393 
394  if (bc_uart_async_write(self->_uart_channel, self->_command, length) != length)
395  {
396  continue;
397  }
398 
399  self->_state = BC_WSSFM10R1AT_STATE_READ_DEVICE_ID_RESPONSE;
400 
401  bc_scheduler_plan_current_from_now(BC_WSSFM10R1AT_DELAY_READ_PAC_RESPONSE);
402 
403  return;
404  }
405  case BC_WSSFM10R1AT_STATE_READ_DEVICE_ID_RESPONSE:
406  {
407  if (!_bc_wssfm10r1at_read_response(self))
408  {
409  self->_state = BC_WSSFM10R1AT_STATE_ERROR;
410 
411  continue;
412  }
413 
414  if (self->_event_handler != NULL)
415  {
416  self->_event_handler(self, BC_WSSFM10R1AT_EVENT_READ_DEVICE_ID, self->_event_param);
417  }
418 
419  self->_state = BC_WSSFM10R1AT_STATE_READY;
420 
421  continue;
422  }
423  case BC_WSSFM10R1AT_STATE_READ_DEVICE_PAC_COMMAND:
424  {
425  self->_state = BC_WSSFM10R1AT_STATE_ERROR;
426 
427  strcpy(self->_command, "AT$I=11\r");
428 
429  size_t length = strlen(self->_command);
430 
431  if (bc_uart_async_write(self->_uart_channel, self->_command, length) != length)
432  {
433  continue;
434  }
435 
436  self->_state = BC_WSSFM10R1AT_STATE_READ_DEVICE_PAC_RESPONSE;
437 
438  bc_scheduler_plan_current_from_now(BC_WSSFM10R1AT_DELAY_READ_PAC_RESPONSE);
439 
440  return;
441  }
442  case BC_WSSFM10R1AT_STATE_READ_DEVICE_PAC_RESPONSE:
443  {
444  if (!_bc_wssfm10r1at_read_response(self))
445  {
446  self->_state = BC_WSSFM10R1AT_STATE_ERROR;
447 
448  continue;
449  }
450 
451  if (self->_event_handler != NULL)
452  {
453  self->_event_handler(self, BC_WSSFM10R1AT_EVENT_READ_DEVICE_PAC, self->_event_param);
454  }
455 
456  self->_state = BC_WSSFM10R1AT_STATE_READY;
457 
458  continue;
459  }
460  case BC_WSSFM10R1AT_STATE_CONTINUOUS_WAVE_COMMAND:
461  {
462  self->_state = BC_WSSFM10R1AT_STATE_ERROR;
463 
464  strcpy(self->_command, "AT$CW=868130000,1,15\r");
465 
466  size_t length = strlen(self->_command);
467 
468  if (bc_uart_async_write(self->_uart_channel, self->_command, length) != length)
469  {
470  continue;
471  }
472 
473  self->_state = BC_WSSFM10R1AT_STATE_CONTINUOUS_WAVE_RESPONSE;
474 
475  bc_scheduler_plan_current_from_now(BC_WSSFM10R1AT_DELAY_CONTINUOUS_WAVE_RESPONSE);
476 
477  return;
478  }
479  case BC_WSSFM10R1AT_STATE_CONTINUOUS_WAVE_RESPONSE:
480  {
481  self->_state = BC_WSSFM10R1AT_STATE_ERROR;
482 
483  if (!_bc_wssfm10r1at_read_response(self))
484  {
485  continue;
486  }
487 
488  if (strcmp(self->_response, "OK\r") != 0)
489  {
490  continue;
491  }
492 
493  self->_state = BC_WSSFM10R1AT_STATE_CONTINUOUS_WAVE;
494 
495  continue;
496  }
497  case BC_WSSFM10R1AT_STATE_CONTINUOUS_WAVE:
498  {
499  return;
500  }
501  case BC_WSSFM10R1AT_STATE_DEEP_SLEEP_COMMAND:
502  {
503  self->_state = BC_WSSFM10R1AT_STATE_ERROR;
504 
505  strcpy(self->_command, "AT$P=2\r");
506 
507  size_t length = strlen(self->_command);
508 
509  if (bc_uart_async_write(self->_uart_channel, self->_command, length) != length)
510  {
511  continue;
512  }
513 
514  self->_state = BC_WSSFM10R1AT_STATE_DEEP_SLEEP_RESPONSE;
515 
516  bc_scheduler_plan_current_from_now(BC_WSSFM10R1AT_DELAY_DEEP_SLEEP_RESPONSE);
517 
518  return;
519  }
520  case BC_WSSFM10R1AT_STATE_DEEP_SLEEP_RESPONSE:
521  {
522  self->_state = BC_WSSFM10R1AT_STATE_ERROR;
523 
524  if (!_bc_wssfm10r1at_read_response(self))
525  {
526  continue;
527  }
528 
529  if (strcmp(self->_response, "OK\r") != 0)
530  {
531  continue;
532  }
533 
534  self->_state = BC_WSSFM10R1AT_STATE_DEEP_SLEEP;
535 
536  continue;
537  }
538  case BC_WSSFM10R1AT_STATE_DEEP_SLEEP:
539  {
540  self->_deep_sleep = true;
541 
542  return;
543  }
544  default:
545  {
546  break;
547  }
548  }
549  }
550 }
551 
552 static void _bc_wssfm10r1at_set_state(bc_wssfm10r1at_t *self, bc_wssfm10r1at_state_t state)
553 {
554  if (self->_deep_sleep)
555  {
556  self->_state = BC_WSSFM10R1AT_STATE_INITIALIZE;
557 
558  self->_state_after_sleep = state;
559  }
560  else
561  {
562  self->_state = state;
563  }
564 
565  bc_scheduler_plan_now(self->_task_id);
566 }
567 
568 static bool _bc_wssfm10r1at_read_response(bc_wssfm10r1at_t *self)
569 {
570  size_t length = 0;
571 
572  while (true)
573  {
574  char rx_character;
575 
576  if (bc_uart_async_read(self->_uart_channel, &rx_character, 1) == 0)
577  {
578  return false;
579  }
580 
581  if (rx_character == '\n')
582  {
583  continue;
584  }
585 
586  self->_response[length++] = rx_character;
587 
588  if (rx_character == '\r')
589  {
590  if (length == 1)
591  {
592  length = 0;
593 
594  continue;
595  }
596 
597  self->_response[length] = '\0';
598 
599  break;
600  }
601 
602  if (length == sizeof(self->_response) - 1)
603  {
604  return false;
605  }
606  }
607 
608  return true;
609 }
bc_uart_channel_t
UART channels.
Definition: bc_uart.h:13
Device PAC has been read event.
struct bc_wssfm10r1at_t bc_wssfm10r1at_t
WSSFM10R1AT instance.
bc_wssfm10r1at_event_t
Callback events.
bool bc_uart_async_read_start(bc_uart_channel_t channel, bc_tick_t timeout)
Start async reading.
Definition: bc_uart.c:475
void bc_wssfm10r1at_init(bc_wssfm10r1at_t *self, bc_gpio_channel_t reset_signal, bc_uart_channel_t uart_channel)
Initialize WSSFM10R1AT.
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
8N1: 8 data bits, none parity bit, 1 stop bit
Definition: bc_uart.h:70
void bc_scheduler_plan_now(bc_scheduler_task_id_t task_id)
Schedule specified task for immediate execution.
Definition: bc_scheduler.c:119
void bc_gpio_set_output(bc_gpio_channel_t channel, int state)
Set output state for GPIO channel.
Definition: bc_gpio.c:442
bool bc_wssfm10r1at_read_device_pac(bc_wssfm10r1at_t *self)
Read device PAC command.
void bc_gpio_set_mode(bc_gpio_channel_t channel, bc_gpio_mode_t mode)
Set mode of operation for GPIO channel.
Definition: bc_gpio.c:340
bool bc_wssfm10r1at_is_ready(bc_wssfm10r1at_t *self)
Check if modem is ready for commands.
void bc_uart_init(bc_uart_channel_t channel, bc_uart_baudrate_t baudrate, bc_uart_setting_t setting)
Initialize UART channel.
Definition: bc_uart.c:53
RF frame transmission finished event.
void bc_fifo_init(bc_fifo_t *fifo, void *buffer, size_t size)
Initialize FIFO buffer.
Definition: bc_fifo.c:4
bool bc_wssfm10r1at_get_device_pac(bc_wssfm10r1at_t *self, char *buffer, size_t buffer_size)
Get device PAC (can be called only in BC_WSSFM10R1AT_EVENT_READ_DEVICE_PAC event) ...
bool bc_wssfm10r1at_continuous_wave(bc_wssfm10r1at_t *self)
Generate continuous wave command.
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 bc_uart_async_write(bc_uart_channel_t channel, const void *buffer, size_t length)
Add data to be transmited in async mode.
Definition: bc_uart.c:428
bool bc_wssfm10r1at_read_device_id(bc_wssfm10r1at_t *self)
Read device ID command.
void bc_uart_set_async_fifo(bc_uart_channel_t channel, bc_fifo_t *write_fifo, bc_fifo_t *read_fifo)
Set buffers for async transfers.
Definition: bc_uart.c:422
RF frame transmission started event.
#define BC_TICK_INFINITY
Maximum timestamp value.
Definition: bc_tick.h:12
bc_gpio_channel_t
GPIO channels.
Definition: bc_gpio.h:12
UART baudrat 9600 bps.
Definition: bc_uart.h:31
void bc_wssfm10r1at_set_event_handler(bc_wssfm10r1at_t *self, void(*event_handler)(bc_wssfm10r1at_t *, bc_wssfm10r1at_event_t, void *), void *event_param)
Set callback function.
size_t bc_uart_async_read(bc_uart_channel_t channel, void *buffer, size_t length)
Get data that has been received in async mode.
Definition: bc_uart.c:571
bool bc_wssfm10r1at_get_device_id(bc_wssfm10r1at_t *self, char *buffer, size_t buffer_size)
Get device ID (can be called only in BC_WSSFM10R1AT_EVENT_READ_DEVICE_ID event)
Device ID has been read event.
void bc_gpio_init(bc_gpio_channel_t channel)
Initialize GPIO channel.
Definition: bc_gpio.c:301
bool bc_wssfm10r1at_send_rf_frame(bc_wssfm10r1at_t *self, const void *buffer, size_t length)
Send RF frame command.
GPIO channel operates as output.
Definition: bc_gpio.h:102