IoT-MBBR (masterthesis)
Masterthesis upgrading a Moving Bed BioReactor with extra sensors and cloud connectivity.
BG96_at_driver.c File Reference

BG96 AT-command driver functionality. More...

#include <stdint.h>
#include <stdbool.h>
#include "em_cmu.h"
#include "em_device.h"
#include "em_gpio.h"
#include "BG96_at_driver.h"
#include "debug_dbprint.h"
#include "delay.h"
#include "util_string.h"
#include "datatypes.h"
#include "credentials.h"
#include "pin_mapping.h"

Go to the source code of this file.

Macros

#define PRINT_ID_TOKEN   0 /* 0 = don't print ID & Token, 1 = print ID & Token */
 

Functions

static bool transmissionBegin (bool continueCode)
 Code for the start of a NB-IoT transmission. More...
 
static bool transmissionEnd (bool continueCode)
 Code for the end of a NB-IoT transmission. More...
 
void initBG96 (void)
 Initialize the GPIO pins and UART0 module necessary to communicate with the BG96 module. More...
 
void sendMeasurements (MeasurementData_t *data)
 Send measurements to the cloud using NB-IoT. More...
 
void sendStatus (int8_t status)
 Send status to the cloud using NB-IoT. More...
 
void sendPulse (uint8_t number, uint8_t pulse)
 Send current pulses to the cloud using NB-IoT. More...
 
void powerBG96 (void)
 Method to enable the power key for 100ms to enable/disable the module. More...
 
void disableEcho (void)
 Disable echo. More...
 
void sendCMD (char *message)
 Print a string (char array) to USARTx. More...
 
void readResponse (char *buf)
 Read a string (char array) from USARTx. More...
 
bool waitForResponse (char *response, uint8_t timeout)
 Wait for the correct response using sleep/timeout functionality. More...
 

Variables

char DEVICE_ID_hex [2 *(sizeof(DEVICE_ID) -1)+1]
 
char DEVICE_TOKEN_hex [2 *(sizeof(DEVICE_TOKEN) -1)+1]
 

Detailed Description

BG96 AT-command driver functionality.

Version
1.0
Author
Brecht Van Eeckhoudt

Versions

  • v1.0: Basic functionality to send measurements to the cloud using NB-IoT without timeout functionality.

License

Copyright (C) 2020 - Brecht Van Eeckhoudt

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

A copy of the GNU General Public License can be found in the LICENSE file along with this source code.


Some methods use code obtained from examples from Silicon Labs' GitHub. These sections are licensed under the Silabs License Agreement. See the file "Silabs_License_Agreement.txt" for details. Before using this software for any purpose, you must agree to the terms of that agreement.

Definition in file BG96_at_driver.c.

Macro Definition Documentation

◆ PRINT_ID_TOKEN

#define PRINT_ID_TOKEN   0 /* 0 = don't print ID & Token, 1 = print ID & Token */

Definition at line 59 of file BG96_at_driver.c.

Function Documentation

◆ disableEcho()

void disableEcho ( void  )

Disable echo.

Definition at line 592 of file BG96_at_driver.c.

593 {
594 
595 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
596  dbinfo("Sending Disable Echo command...");
597 #endif /* DEBUG_DBPRINT */
598 
599  bool continueCode = true;
600 
601  sendCMD("ATE0\r");
602 
603  while (!continueCode) // TODO: update this code with timeout functionality?
604  {
605  sleep(2);
606  sendCMD("ATE0\r");
607  continueCode = waitForResponse("OK", 5); /* Wait for the correct response */
608  }
609 }
void dbinfo(char *message)
Print an info string (char array) to USARTx and go to the next line.
Definition: dbprint.c:505
void sendCMD(char *message)
Print a string (char array) to USARTx.
bool waitForResponse(char *response, uint8_t timeout)
Wait for the correct response using sleep/timeout functionality.
void sleep(uint32_t sSleep)
Sleep for a certain amount of seconds in EM2/3.
Definition: delay.c:293

◆ initBG96()

void initBG96 ( void  )

Initialize the GPIO pins and UART0 module necessary to communicate with the BG96 module.

Definition at line 82 of file BG96_at_driver.c.

83 {
84  /* Convert ID & Token */
87 
88 #if PRINT_ID_TOKEN == 1 /* PRINT_ID_TOKEN */
89 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
90  dbprint("INFO: DEVICE_ID = ");
92  dbprint("INFO: DEVICE_ID_hex = ");
94  dbprintln("");
95  dbprint("INFO: DEVICE_TOKEN = ");
97  dbprint("INFO: DEVICE_TOKEN_hex = ");
99  dbprintln("");
100 #endif /* DEBUG_DBPRINT */
101 #endif /* PRINT_ID_TOKEN */
102 
103  /* Enable oscillator to GPIO*/
104  CMU_ClockEnable(cmuClock_GPIO, true);
105 
106  /* Initialize GPIO pin for PWR key */
107  /* In the case of gpioModePushPull, the last argument directly sets the pin state */
108  GPIO_PinModeSet(BG96_PWRKEY_PORT, BG96_PWRKEY_PIN, gpioModePushPull, 0);
109 
110  /*
111  * USART_INITASYNC_DEFAULT:
112  * config.enable = usartEnable // Specifies whether TX and/or RX is enabled when initialization is completed
113  * // (Enable RX/TX when initialization is complete).
114  * config.refFreq = 0 // USART/UART reference clock assumed when configuring baud rate setup
115  * // (0 = Use current configured reference clock for configuring baud rate).
116  * config.baudrate = 115200 // Desired baudrate (115200 bits/s).
117  * config.oversampling = usartOVS16 // Oversampling used (16x oversampling).
118  * config.databits = usartDatabits8 // Number of data bits in frame (8 data bits).
119  * config.parity = usartNoParity // Parity mode to use (no parity).
120  * config.stopbits = usartStopbits1 // Number of stop bits to use (1 stop bit).
121  * config.mvdis = false // Majority Vote Disable for 16x, 8x and 6x oversampling modes (Do not disable majority vote).
122  * config.prsRxEnable = false // Enable USART Rx via PRS (Not USART PRS input mode).
123  * config.prsRxCh = 0 // Select PRS channel for USART Rx. (Only valid if prsRxEnable is true - PRS channel 0).
124  * config.autoCsEnable = false // Auto CS enabling (Auto CS functionality enable/disable switch - disabled).
125  */
126 
127  USART_InitAsync_TypeDef config = USART_INITASYNC_DEFAULT;
128 
129  /* Enable oscillator to USARTx modules */
130  if (BG96_UART == USART0) CMU_ClockEnable(cmuClock_USART0, true);
131  else if (BG96_UART == USART1) CMU_ClockEnable(cmuClock_USART1, true);
132 
133  /* Set pin modes for UART TX and RX pins */
134  if (BG96_UART == USART0)
135  {
136  switch (BG96_UART_LOC)
137  {
138  case 0:
139  GPIO_PinModeSet(gpioPortE, 11, gpioModeInput, 0); /* RX */
140  GPIO_PinModeSet(gpioPortE, 10, gpioModePushPull, 1); /* TX */
141  break;
142  case 2:
143  GPIO_PinModeSet(gpioPortC, 10, gpioModeInput, 0); /* RX */
144  /* No TX pin in this mode */
145  break;
146  case 3:
147  GPIO_PinModeSet(gpioPortE, 12, gpioModeInput, 0); /* RX */
148  GPIO_PinModeSet(gpioPortE, 13, gpioModePushPull, 1); /* TX */
149  break;
150  case 4:
151  GPIO_PinModeSet(gpioPortB, 8, gpioModeInput, 0); /* RX */
152  GPIO_PinModeSet(gpioPortB, 7, gpioModePushPull, 1); /* TX */
153  break;
154  case 5:
155  case 6:
156  GPIO_PinModeSet(gpioPortC, 1, gpioModeInput, 0); /* RX */
157  GPIO_PinModeSet(gpioPortC, 0, gpioModePushPull, 1); /* TX */
158  break;
159  /* default: */
160  /* No default */
161  }
162  }
163  else if (BG96_UART == USART1)
164  {
165  switch (BG96_UART_LOC)
166  {
167  case 0:
168  GPIO_PinModeSet(gpioPortC, 1, gpioModeInput, 0); /* RX */
169  GPIO_PinModeSet(gpioPortC, 0, gpioModePushPull, 1); /* TX */
170  break;
171  case 2:
172  case 3:
173  GPIO_PinModeSet(gpioPortD, 6, gpioModeInput, 0); /* RX */
174  GPIO_PinModeSet(gpioPortD, 7, gpioModePushPull, 1); /* TX */
175  break;
176  case 4:
177  GPIO_PinModeSet(gpioPortA, 0, gpioModeInput, 0); /* RX */
178  GPIO_PinModeSet(gpioPortF, 2, gpioModePushPull, 1); /* TX */
179  break;
180  case 5:
181  GPIO_PinModeSet(gpioPortC, 2, gpioModeInput, 0); /* RX */
182  GPIO_PinModeSet(gpioPortC, 1, gpioModePushPull, 1); /* TX */
183  break;
184  /* default: */
185  /* No default */
186  }
187  }
188 
189  /* Initialize USART asynchronous mode */
190  USART_InitAsync(BG96_UART, &config);
191 
192  /* Route pins */
193  switch (BG96_UART_LOC)
194  {
195  case 0:
196  BG96_UART->ROUTE |= USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_LOCATION_LOC0;
197  break;
198  case 1:
199  BG96_UART->ROUTE |= USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_LOCATION_LOC1;
200  break;
201  case 2:
202  BG96_UART->ROUTE |= USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_LOCATION_LOC2;
203  break;
204  case 3:
205  BG96_UART->ROUTE |= USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_LOCATION_LOC3;
206  break;
207  case 4:
208  BG96_UART->ROUTE |= USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_LOCATION_LOC4;
209  break;
210  case 5:
211  BG96_UART->ROUTE |= USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_LOCATION_LOC5;
212  break;
213  case 6:
214  BG96_UART->ROUTE |= USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_LOCATION_LOC6;
215  break;
216  default:
217  BG96_UART->ROUTE |= USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_LOCATION_DEFAULT;
218  }
219 
220 }
void dbprint(char *message)
Print a string (char array) to USARTx.
Definition: dbprint.c:375
#define DEVICE_TOKEN
Definition: credentials.h:17
void dbprintln(char *message)
Print a string (char array) to USARTx and go to the next line.
Definition: dbprint.c:397
#define DEVICE_ID
Definition: credentials.h:16
#define BG96_UART_LOC
Definition: pin_mapping.h:72
#define BG96_PWRKEY_PIN
Definition: pin_mapping.h:78
void charASCII_to_charHex(char *inbuf, char *outbuf)
Convert an ASCII char array (string) to a hexadecimal char array.
Definition: util_string.c:63
#define BG96_UART
Definition: pin_mapping.h:71
char DEVICE_ID_hex[2 *(sizeof(DEVICE_ID) -1)+1]
#define BG96_PWRKEY_PORT
Definition: pin_mapping.h:77
char DEVICE_TOKEN_hex[2 *(sizeof(DEVICE_TOKEN) -1)+1]

◆ powerBG96()

void powerBG96 ( void  )

Method to enable the power key for 100ms to enable/disable the module.

Definition at line 579 of file BG96_at_driver.c.

580 {
581  /* Set PWK high for 100ms */
582  GPIO_PinOutSet(BG96_PWRKEY_PORT, BG96_PWRKEY_PIN);
583  delay(100);
584  GPIO_PinOutClear(BG96_PWRKEY_PORT, BG96_PWRKEY_PIN);
585 }
#define BG96_PWRKEY_PIN
Definition: pin_mapping.h:78
#define BG96_PWRKEY_PORT
Definition: pin_mapping.h:77
void delay(uint32_t msDelay)
Wait for a certain amount of milliseconds in EM2/3.
Definition: delay.c:124

◆ readResponse()

void readResponse ( char *  buf)

Read a string (char array) from USARTx.

Note
The reading stops when a "LF" (Line Feed) character is received or the maximum length (UART_BUFFER_SIZE) is reached.
Parameters
[in]bufThe buffer to put the resulting string in.
This needs to have a length of UART_BUFFER_SIZE for the function to work properly: char buf[UART_BUFFER_SIZE];!

Definition at line 647 of file BG96_at_driver.c.

648 {
649  for (uint32_t i = 0; i < UART_BUFFER_SIZE - 1 ; i++ )
650  {
651  char localBuffer = USART_Rx(BG96_UART);
652 
653  /* Check if a LF character is received */
654  if (localBuffer == '\n')
655  {
656  /* End with a null termination character */
657  buf[i] = '\0';
658  break;
659  }
660  else
661  {
662  buf[i] = localBuffer;
663  }
664  }
665 }
#define UART_BUFFER_SIZE
#define BG96_UART
Definition: pin_mapping.h:71
unsigned int uint32_t
Typedef defining 32 bit unsigned int type. The developer should modify this to suit the platform bein...
Definition: vl53l1_types.h:78

◆ sendCMD()

void sendCMD ( char *  message)

Print a string (char array) to USARTx.

Note
If the input is not a string (ex.: "Hello world!") but a char array, the input message (array) needs to end with NULL ("\0")!
Parameters
[in]messageThe string to print to USARTx.

Definition at line 623 of file BG96_at_driver.c.

624 {
625  /* "message[i] != 0" makes "uint32_t length = strlen(message)"
626  * not necessary (given string MUST be terminated by NULL for this to work) */
627  for (uint32_t i = 0; message[i] != 0; i++)
628  {
629  USART_Tx(BG96_UART, message[i]);
630  }
631 }
#define BG96_UART
Definition: pin_mapping.h:71
unsigned int uint32_t
Typedef defining 32 bit unsigned int type. The developer should modify this to suit the platform bein...
Definition: vl53l1_types.h:78

◆ sendMeasurements()

void sendMeasurements ( MeasurementData_t *  data)

Send measurements to the cloud using NB-IoT.

Parameters
[in]dataThe measurements to send

Definition at line 230 of file BG96_at_driver.c.

231 {
232  /* Begin transmission */
233  bool continueCode = transmissionBegin(true);
234 
235  if (continueCode)
236  {
237 
238 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
239  dbprintln("INFO: Sending the following values to the cloud:");
240  dbprint(" t1 = ");
241  dbprintInt(data->t1);
242  dbprint(", t2 = ");
243  dbprintInt(data->t2);
244  dbprint(", p = ");
245  dbprintInt(data->p);
246  dbprint(", n1 = ");
247  dbprintInt(data->n1);
248  dbprint(", n2 = ");
249  dbprintInt(data->n2);
250  dbprint(", r = ");
251  dbprintInt(data->r);
252  dbprint(", c = ");
253  dbprintlnInt(data->c);
254 #endif /* DEBUG_DBPRINT */
255 
256  /* Convert values */
257  char t1_hex[9]; // TODO: Use less chars here because we use uint16_t (check if values aren't bigger than 0xFFFF)
258  uint32_to_charHex(data->t1, t1_hex); // TODO: Make sure we can send negative values!
259  char t2_hex[9];
260  uint32_to_charHex(data->t2, t2_hex); // TODO: Make sure we can send negative values!
261  char p_hex[9];
262  uint32_to_charHex(data->p, p_hex);
263  char n1_hex[9];
264  uint32_to_charHex(data->n1, n1_hex);
265  char n2_hex[9];
266  uint32_to_charHex(data->n2, n2_hex);
267  char r_hex[9];
268  uint32_to_charHex(data->r, r_hex);
269  char c_hex[9];
270  uint32_to_charHex(data->c, c_hex);
271 
272  /*
273  * http://cbor.me/
274  *
275  * Diagnostic:
276  * {
277  * "t1": 2345,
278  * "t2": 2345,
279  * "p": 2345,
280  * "n1": 2345,
281  * "n2": 2345,
282  * "r": 2345,
283  * "c": 2345
284  * }
285  *
286  * CBOR:
287  * A7 # map(7)
288  * 62 # text(2)
289  * 7431 # "t1"
290  * 19 0929 # unsigned(2345) (19 ~ uint16_t)
291  * 62 # text(2)
292  * 7432 # "t2"
293  * 19 0929 # unsigned(2345)
294  * 61 # text(1)
295  * 70 # "p"
296  * 19 0929 # unsigned(2345)
297  * 62 # text(2)
298  * 6E31 # "n1"
299  * 19 0929 # unsigned(2345)
300  * 62 # text(2)
301  * 6E32 # "n2"
302  * 19 0929 # unsigned(2345)
303  * 61 # text(1)
304  * 72 # "r"
305  * 19 0929 # unsigned(2345)
306  * 61 # text(1)
307  * 63 # "c"
308  * 19 0929 # unsigned(2345)
309  */
310 
311  /* Send commands */
312  sendCMD("AT+QISENDEX=0,\"");
314  sendCMD("0a"); /* \n */
316  sendCMD("0a"); /* \n */
317  sendCMD("a762743119"); /* 0xa6 = map(7), 0x62 = text(2), 0x7431 = "t1", 0x19 = uint16_t */
318  sendCMD(t1_hex);
319  sendCMD("62743219"); /* 0x62 = text(2), 0x7432 = "t2", 0x19 = uint16_t */
320  sendCMD(t2_hex);
321  sendCMD("617019"); /* 0x61 = text(1), 0x70 = "p", 0x19 = uint16_t */
322  sendCMD(p_hex);
323  sendCMD("626e3119"); /* 0x62 = text(2), 0x6e31 = "n1", 0x19 = uint16_t */
324  sendCMD(n1_hex);
325  sendCMD("626e3219"); /* 0x62 = text(2), 0x6e32 = "n2", 0x19 = uint16_t */
326  sendCMD(n2_hex);
327  sendCMD("617219"); /* 0x61 = text(1), 0x72 = "r", 0x19 = uint16_t */
328  sendCMD(r_hex);
329  sendCMD("616319"); /* 0x61 = text(1), 0x63 = "c", 0x19 = uint16_t */
330  sendCMD(c_hex);
331  sendCMD("\"\n\r");
332 
333  /* Wait for the correct response */
334  continueCode = waitForResponse("SEND OK", 5);
335  }
336 
337  /* End transmission */
338  continueCode = transmissionEnd(continueCode);
339 }
void dbprint(char *message)
Print a string (char array) to USARTx.
Definition: dbprint.c:375
void dbprintlnInt(int32_t value)
Print a number in decimal notation to USARTx and go to the next line.
Definition: dbprint.c:776
static bool transmissionEnd(bool continueCode)
Code for the end of a NB-IoT transmission.
void dbprintln(char *message)
Print a string (char array) to USARTx and go to the next line.
Definition: dbprint.c:397
void sendCMD(char *message)
Print a string (char array) to USARTx.
char DEVICE_ID_hex[2 *(sizeof(DEVICE_ID) -1)+1]
bool waitForResponse(char *response, uint8_t timeout)
Wait for the correct response using sleep/timeout functionality.
static bool transmissionBegin(bool continueCode)
Code for the start of a NB-IoT transmission.
void dbprintInt(int32_t value)
Print a number in decimal notation to USARTx.
Definition: dbprint.c:740
char DEVICE_TOKEN_hex[2 *(sizeof(DEVICE_TOKEN) -1)+1]
static void uint32_to_charHex(char *buf, uint32_t value, bool spacing)
Convert a uint32_t value to a hexadecimal char array (string).
Definition: dbprint.c:1063

◆ sendPulse()

void sendPulse ( uint8_t  number,
uint8_t  pulse 
)

Send current pulses to the cloud using NB-IoT.

Parameters
[in]number
  • 0 - PULSE0 selected.
  • 1 - PULSE0 selected.
[in]pulseThe pulse value to send

Definition at line 412 of file BG96_at_driver.c.

413 {
414  /* Begin transmission */
415  bool continueCode = transmissionBegin(true);
416 
417  if (continueCode)
418  {
419 
420 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
421  dbprintln("INFO: Sending pulse(s) [");
422  dbprintInt(pulse);
423  dbprintln("] to the cloud.");
424 #endif /* DEBUG_DBPRINT */
425 
426  /* Convert values */
427  char pulse_hex[9]; // TODO: Use less chars here because we use uint16_t (check if values aren't bigger than 0xFFFF)
428  uint32_to_charHex(pulse, pulse_hex);
429 
430  /*
431  * http://cbor.me/
432  *
433  * Diagnostic:
434  * {
435  * "p1": 2345
436  * }
437  *
438  * CBOR:
439  * A1 # map(1)
440  * 62 # text(2)
441  * 7031 # "p1"
442  * 19 0929 # unsigned(2345) (19 ~ uint16_t)
443  */
444 
445  /* Send commands */
446  sendCMD("AT+QISENDEX=0,\"");
448  sendCMD("0a"); /* \n */
450  sendCMD("0a"); /* \n */
451  if (number == 0) sendCMD("a162703119"); /* 0xa1 = map(1), 0x62 = text(2), 0x7031 = "p1", 0x19 = uint16_t */
452  else if (number == 1) sendCMD("a162703219"); /* 0xa1 = map(1), 0x62 = text(2), 0x7032 = "p2", 0x19 = uint16_t */
453  sendCMD(pulse_hex);
454  sendCMD("\"\n\r");
455 
456  /* Wait for the correct response */
457  continueCode = waitForResponse("SEND OK", 5);
458  }
459 
460  /* End transmission */
461  continueCode = transmissionEnd(continueCode);
462 }
static bool transmissionEnd(bool continueCode)
Code for the end of a NB-IoT transmission.
void dbprintln(char *message)
Print a string (char array) to USARTx and go to the next line.
Definition: dbprint.c:397
void sendCMD(char *message)
Print a string (char array) to USARTx.
char DEVICE_ID_hex[2 *(sizeof(DEVICE_ID) -1)+1]
bool waitForResponse(char *response, uint8_t timeout)
Wait for the correct response using sleep/timeout functionality.
static bool transmissionBegin(bool continueCode)
Code for the start of a NB-IoT transmission.
void dbprintInt(int32_t value)
Print a number in decimal notation to USARTx.
Definition: dbprint.c:740
char DEVICE_TOKEN_hex[2 *(sizeof(DEVICE_TOKEN) -1)+1]
static void uint32_to_charHex(char *buf, uint32_t value, bool spacing)
Convert a uint32_t value to a hexadecimal char array (string).
Definition: dbprint.c:1063

◆ sendStatus()

void sendStatus ( int8_t  status)

Send status to the cloud using NB-IoT.

Parameters
[in]statusThe status value to send

Definition at line 349 of file BG96_at_driver.c.

350 {
351  /* Begin transmission */
352  bool continueCode = transmissionBegin(true);
353 
354  if (continueCode)
355  {
356 
357 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
358  dbprintln("INFO: Sending status ");
359  dbprintInt(status);
360  dbprintln(" to the cloud.");
361 #endif /* DEBUG_DBPRINT */
362 
363  /* Convert values */
364  char s_hex[9]; // TODO: Use less chars here because we use uint16_t (check if values aren't bigger than 0xFFFF)
365  uint32_to_charHex(status, s_hex); // TODO: Make sure we can send negative values!
366 
367  /*
368  * http://cbor.me/
369  *
370  * Diagnostic:
371  * {
372  * "s": 2345
373  * }
374  *
375  * CBOR:
376  * A1 # map(1)
377  * 61 # text(1)
378  * 73 # "s"
379  * 19 0929 # unsigned(2345) (19 ~ uint16_t)
380  */
381 
382  /* Send commands */
383  sendCMD("AT+QISENDEX=0,\"");
385  sendCMD("0a"); /* \n */
387  sendCMD("0a"); /* \n */
388  sendCMD("a1617319"); /* 0xa1 = map(1), 0x61 = text(1), 0x73 = "s", 0x19 = uint16_t */
389  sendCMD(s_hex);
390  sendCMD("\"\n\r");
391 
392  /* Wait for the correct response */
393  continueCode = waitForResponse("SEND OK", 5);
394  }
395 
396  /* End transmission */
397  continueCode = transmissionEnd(continueCode);
398 }
static bool transmissionEnd(bool continueCode)
Code for the end of a NB-IoT transmission.
void dbprintln(char *message)
Print a string (char array) to USARTx and go to the next line.
Definition: dbprint.c:397
void sendCMD(char *message)
Print a string (char array) to USARTx.
char DEVICE_ID_hex[2 *(sizeof(DEVICE_ID) -1)+1]
bool waitForResponse(char *response, uint8_t timeout)
Wait for the correct response using sleep/timeout functionality.
static bool transmissionBegin(bool continueCode)
Code for the start of a NB-IoT transmission.
void dbprintInt(int32_t value)
Print a number in decimal notation to USARTx.
Definition: dbprint.c:740
char DEVICE_TOKEN_hex[2 *(sizeof(DEVICE_TOKEN) -1)+1]
static void uint32_to_charHex(char *buf, uint32_t value, bool spacing)
Convert a uint32_t value to a hexadecimal char array (string).
Definition: dbprint.c:1063

◆ transmissionBegin()

static bool transmissionBegin ( bool  continueCode)
static

Code for the start of a NB-IoT transmission.

Note
This is a static method because it's only internally used in this file and called by other methods if necessary.
Parameters
[in]continueCodeFunctionality to skip code if previous code failed.
Returns
If the code finished okay/failed.

Definition at line 479 of file BG96_at_driver.c.

480 {
481 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
482  dbinfo("Powering on BG96");
483 #endif /* DEBUG_DBPRINT */
484 
485  powerBG96(); /* Power up BG96 */
486  continueCode = waitForResponse("APP RDY", 5); /* Wait for the correct response */
487 
488  sleep(8); // TODO: Wait some time before activating PDP?
489 
490  if (continueCode)
491  {
492 
493 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
494  dbinfo("Sending Activate PDP command...");
495 #endif /* DEBUG_DBPRINT */
496 
497  sendCMD("AT+QIACT=1\r");
498  continueCode = waitForResponse("OK", 5); /* Wait for the correct response */
499 
500  while (!continueCode) // TODO: update timeout functionality
501  {
502  sleep(2); /* Sleep for 2s */
503  sendCMD("AT+QIACT=1\r");
504  continueCode = waitForResponse("OK", 5); /* Wait for the correct response */
505  }
506  }
507 
508 
509  if (continueCode)
510  {
511 
512 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
513  dbinfo("Sending Create UDP command...");
514 #endif /* DEBUG_DBPRINT */
515 
516  sendCMD("AT+QIOPEN=1,0,\"UDP\",\"40.68.172.187\",8891\r"); // BEFORE: api.allthingstalk.io
517  continueCode = waitForResponse("OK", 5); /* Wait for the correct response */
518  continueCode = waitForResponse("+QIOPEN: 0,0", 5); /* Wait for the correct response */
519  }
520 
521  return (continueCode);
522 }
void powerBG96(void)
Method to enable the power key for 100ms to enable/disable the module.
void dbinfo(char *message)
Print an info string (char array) to USARTx and go to the next line.
Definition: dbprint.c:505
void sendCMD(char *message)
Print a string (char array) to USARTx.
bool waitForResponse(char *response, uint8_t timeout)
Wait for the correct response using sleep/timeout functionality.
void sleep(uint32_t sSleep)
Sleep for a certain amount of seconds in EM2/3.
Definition: delay.c:293

◆ transmissionEnd()

static bool transmissionEnd ( bool  continueCode)
static

Code for the end of a NB-IoT transmission.

Note
This is a static method because it's only internally used in this file and called by other methods if necessary.
Parameters
[in]continueCodeFunctionality to skip code if previous code failed.
Returns
If the code finished okay/failed.

Definition at line 539 of file BG96_at_driver.c.

540 {
541 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
542  dbinfo("Sending Deactivate PDP command...");
543 #endif /* DEBUG_DBPRINT */
544 
545  sendCMD("AT+QIDEACT=1\r");
546  continueCode = waitForResponse("OK", 5); /* Wait for the correct response */
547 
548  if (continueCode)
549  {
550 
551 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
552  dbinfo("Sending Power down command...");
553 #endif /* DEBUG_DBPRINT */
554 
555  sendCMD("AT+QPOWD\r");
556  continueCode = waitForResponse("OK", 5); /* Wait for the correct response */
557  continueCode = waitForResponse("POWERED DOWN", 5); /* Wait for the correct response */
558  }
559  else
560  {
561 
562 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
563  dbwarn("Powering down BG96 using hardware...");
564 #endif /* DEBUG_DBPRINT */
565 
566  powerBG96();
567  }
568 
569  sleep(2); // TODO: Wait less
570 
571  return (continueCode);
572 }
void powerBG96(void)
Method to enable the power key for 100ms to enable/disable the module.
void dbwarn(char *message)
Print a warning string (char array) in yellow to USARTx and go to the next line.
Definition: dbprint.c:523
void dbinfo(char *message)
Print an info string (char array) to USARTx and go to the next line.
Definition: dbprint.c:505
void sendCMD(char *message)
Print a string (char array) to USARTx.
bool waitForResponse(char *response, uint8_t timeout)
Wait for the correct response using sleep/timeout functionality.
void sleep(uint32_t sSleep)
Sleep for a certain amount of seconds in EM2/3.
Definition: delay.c:293

◆ waitForResponse()

bool waitForResponse ( char *  response,
uint8_t  timeout 
)

Wait for the correct response using sleep/timeout functionality.

Parameters
[in]responseThe correct response to look for.
[in]timeoutThe timeout value.
Returns
  • true - Module responded correctly before timeout.
  • false - The module timed out or gave only incorrect responses.

Definition at line 682 of file BG96_at_driver.c.

683 {
684  uint8_t i = 0;
685 
686  char rxBuf[UART_BUFFER_SIZE];
687 
688  while (i < timeout) // TODO: update timeout functionality
689  {
690  readResponse(rxBuf);
691 
692  if (stringStartsWith((char *)rxBuf, response))
693  {
694 
695  // Printing breaks timing!
696 //#if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
697 // dbprint("INFO: > ");
698 // dbprint(response);
699 // dbprintln("");
700 //#endif /* DEBUG_DBPRINT */
701 
702  return(true);
703  }
704  else if (stringStartsWith((char *)rxBuf, "ERROR"))
705  {
706 
707  // Printing breaks timing!
708 //#if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
709 // dbcrit(" > ERROR");
710 //#endif /* DEBUG_DBPRINT */
711 
712  return(false);
713  }
714 
715  i++;
716  }
717 
718 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
719  dbprint_color("CRIT: Timeout reached while waiting on ", RED);
720  dbprint(response);
721  dbprint_color(" command", RED);
722  dbprintln("");
723 #endif /* DEBUG_DBPRINT */
724 
725  return(false);
726 }
void dbprint(char *message)
Print a string (char array) to USARTx.
Definition: dbprint.c:375
Definition: dbprint.h:54
void dbprintln(char *message)
Print a string (char array) to USARTx and go to the next line.
Definition: dbprint.c:397
#define UART_BUFFER_SIZE
bool stringStartsWith(char *inbuf, char *sequence)
Check if a given char array (string) starts with a given sequence.
Definition: util_string.c:203
void readResponse(char *buf)
Read a string (char array) from USARTx.
void dbprint_color(char *message, dbprint_color_t color)
Print a string (char array) to USARTx in a given color.
Definition: dbprint.c:423
unsigned char uint8_t
Typedef defining 8 bit unsigned char type. The developer should modify this to suit the platform bein...
Definition: vl53l1_types.h:98

Variable Documentation

◆ DEVICE_ID_hex

char DEVICE_ID_hex[2 *(sizeof(DEVICE_ID) -1)+1]

Definition at line 68 of file BG96_at_driver.c.

◆ DEVICE_TOKEN_hex

char DEVICE_TOKEN_hex[2 *(sizeof(DEVICE_TOKEN) -1)+1]

Definition at line 69 of file BG96_at_driver.c.