Skip to content

Commit c305807

Browse files
committed
Modifications to support the SAMD21
- Added necessary guard macros to prevent `SoftwareSerial` inclusion - Removed scans for uint8_t's in sscanf. SAMD21 was locking up trying to store 32-bit numbers in 8-bit locations. (Even with `%hhu` :\). - Added `const`s to char parameters where they should have been in the first place - Fixed an ugly bug where address 0 was being written to in `readAvailable`
1 parent 57cb5cb commit c305807

File tree

3 files changed

+70
-30
lines changed

3 files changed

+70
-30
lines changed

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=SparkFun LTE Shield Arduino Library
2-
version=1.0.0
2+
version=1.1.0
33
author=SparkFun Electronics <techsupport@sparkfun.com>
44
maintainer=SparkFun Electronics <sparkfun.com>
55
sentence=Library for the SparkFun LTE Shield -- based on the u-blox SARA-R410M-02B

src/SparkFun_LTE_Shield_Arduino_Library.cpp

Lines changed: 64 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ const char LTE_SHIELD_GPS_GPRMC[] = "+UGRMC";
7676
const char LTE_SHIELD_RESPONSE_OK[] = "OK\r\n";
7777

7878
// CTRL+Z and ESC ASCII codes for SMS message sends
79-
#define ASCII_CTRL_Z 0x1A
80-
#define ASCII_ESC 0x1B
79+
const char ASCII_CTRL_Z = 0x1A;
80+
const char ASCII_ESC = 0x1B;
8181

8282
#define NOT_AT_COMMAND false
8383
#define AT_COMMAND true
@@ -102,7 +102,9 @@ static boolean parseGPRMCString(char * rmcString, PositionData * pos, ClockData
102102

103103
LTE_Shield::LTE_Shield(uint8_t powerPin, uint8_t resetPin)
104104
{
105+
#ifdef LTE_SHIELD_SOFTWARE_SERIAL_ENABLED
105106
_softSerial = NULL;
107+
#endif
106108
_hardSerial = NULL;
107109
_baud = 0;
108110
_resetPin = resetPin;
@@ -115,6 +117,7 @@ LTE_Shield::LTE_Shield(uint8_t powerPin, uint8_t resetPin)
115117
memset(lteShieldRXBuffer, 0, 128);
116118
}
117119

120+
#ifdef LTE_SHIELD_SOFTWARE_SERIAL_ENABLED
118121
boolean LTE_Shield::begin(SoftwareSerial & softSerial, unsigned long baud)
119122
{
120123
LTE_Shield_error_t err;
@@ -128,6 +131,7 @@ boolean LTE_Shield::begin(SoftwareSerial & softSerial, unsigned long baud)
128131
}
129132
return false;
130133
}
134+
#endif
131135

132136
boolean LTE_Shield::begin(HardwareSerial &hardSerial, unsigned long baud)
133137
{
@@ -337,10 +341,11 @@ LTE_Shield_error_t LTE_Shield::enableEcho(boolean enable)
337341
{
338342
sprintf(command, "%s0", LTE_SHIELD_COMMAND_ECHO);
339343
}
340-
341344
err = sendCommandWithResponse(command, LTE_SHIELD_RESPONSE_OK,
342345
NULL, LTE_SHIELD_STANDARD_RESPONSE_TIMEOUT);
343346

347+
free(command);
348+
344349
return err;
345350
}
346351

@@ -473,6 +478,8 @@ LTE_Shield_error_t LTE_Shield::clock(uint8_t * y, uint8_t * mo, uint8_t * d,
473478
char * clockBegin;
474479
char * clockEnd;
475480

481+
int iy, imo, id, ih, imin, is, itz;
482+
476483
command = lte_calloc_char(strlen(LTE_SHIELD_COMMAND_CLOCK) + 2);
477484
if (command == NULL) return LTE_SHIELD_ERROR_OUT_OF_MEMORY;
478485
sprintf(command, "%s?", LTE_SHIELD_COMMAND_CLOCK);
@@ -486,10 +493,16 @@ LTE_Shield_error_t LTE_Shield::clock(uint8_t * y, uint8_t * mo, uint8_t * d,
486493
// Response format: \r\n+CCLK: "YY/MM/DD,HH:MM:SS-TZ"\r\n\r\nOK\r\n
487494
if (err == LTE_SHIELD_ERROR_SUCCESS)
488495
{
489-
if (sscanf(response, "\r\n+CCLK: \"%hhu/%hhu/%hhu,%hhu:%hhu:%hhu-%hhu\"\r\n",
490-
y, mo, d, h, min, s, tz) == 7)
496+
if (sscanf(response, "\r\n+CCLK: \"%d/%d/%d,%d:%d:%d-%d\"\r\n",
497+
&iy, &imo, &id, &ih, &imin, &is, &itz) == 7)
491498
{
492-
// Do nothing?
499+
*y = iy;
500+
*mo = imo;
501+
*d = id;
502+
*h = ih;
503+
*min = imin;
504+
*s = is;
505+
*tz = itz;
493506
}
494507
}
495508

@@ -661,7 +674,7 @@ LTE_Shield_error_t LTE_Shield::getAPN(String * apn, IPAddress * ip)
661674
char * command;
662675
char * response;
663676
char * searchPtr;
664-
uint8_t ipOctets[4];
677+
int ipOctets[4];
665678

666679
command = lte_calloc_char(strlen(LTE_SHIELD_MESSAGE_PDP_DEF) + 3);
667680
if (command == NULL) return LTE_SHIELD_ERROR_OUT_OF_MEMORY;
@@ -700,13 +713,13 @@ LTE_Shield_error_t LTE_Shield::getAPN(String * apn, IPAddress * ip)
700713
// Now get the IP:
701714
if (searchPtr != NULL)
702715
{
703-
int scanned = sscanf(searchPtr, "\",\"%hhu.%hhu.%hhu.%hhu\"",
716+
int scanned = sscanf(searchPtr, "\",\"%d.%d.%d.%d\"",
704717
&ipOctets[0], &ipOctets[1], &ipOctets[2], &ipOctets[3]);
705718
if (scanned == 4)
706719
{
707720
for (int octet = 0; octet < 4; octet++)
708721
{
709-
(*ip)[octet] = ipOctets[octet];
722+
(*ip)[octet] = (uint8_t)ipOctets[octet];
710723
}
711724
}
712725
}
@@ -799,7 +812,7 @@ uint8_t LTE_Shield::getOperators(struct operator_stats * opRet, int maxOps)
799812
int stat;
800813
char longOp[26];
801814
char shortOp[11];
802-
uint8_t act;
815+
int act;
803816
unsigned long numOp;
804817

805818
opBegin = response;
@@ -972,7 +985,7 @@ LTE_Shield_error_t LTE_Shield::sendSMS(String number, String message)
972985
messageCStr = lte_calloc_char(message.length() + 1);
973986
if (messageCStr == NULL)
974987
{
975-
hwPrint(ASCII_ESC);
988+
hwWrite(ASCII_CTRL_Z);
976989
return LTE_SHIELD_ERROR_OUT_OF_MEMORY;
977990
}
978991
message.toCharArray(messageCStr, message.length() + 1);
@@ -1110,7 +1123,7 @@ LTE_Shield_error_t LTE_Shield::socketClose(int socket, int timeout)
11101123
char * command;
11111124

11121125
command = lte_calloc_char(strlen(LTE_SHIELD_CLOSE_SOCKET) + 10);
1113-
if (command == NULL) return -1;
1126+
if (command == NULL) return LTE_SHIELD_ERROR_OUT_OF_MEMORY;
11141127
sprintf(command, "%s=%d", LTE_SHIELD_CLOSE_SOCKET, socket);
11151128

11161129
return sendCommandWithResponse(command, LTE_SHIELD_RESPONSE_OK,
@@ -1123,7 +1136,7 @@ LTE_Shield_error_t LTE_Shield::socketConnect(int socket, const char * address,
11231136
char * command;
11241137

11251138
command = lte_calloc_char(strlen(LTE_SHIELD_CONNECT_SOCKET) + strlen(address) + 11);
1126-
if (command == NULL) return -1;
1139+
if (command == NULL) return LTE_SHIELD_ERROR_OUT_OF_MEMORY;
11271140
sprintf(command, "%s=%d,\"%s\",%d", LTE_SHIELD_CONNECT_SOCKET, socket, address, port);
11281141

11291142
return sendCommandWithResponse(command, LTE_SHIELD_RESPONSE_OK,
@@ -1522,7 +1535,7 @@ LTE_Shield_error_t LTE_Shield::getMno(mobile_network_operator_t * mno)
15221535
*mno = MNO_INVALID;
15231536
return LTE_SHIELD_ERROR_UNEXPECTED_RESPONSE;
15241537
}
1525-
*mno = *(response + i) - 0x30; // Convert to integer
1538+
*mno = (mobile_network_operator_t)(*(response + i) - 0x30); // Convert to integer
15261539

15271540
free(command);
15281541
free(response);
@@ -1561,7 +1574,7 @@ LTE_Shield_error_t LTE_Shield::getMno(mobile_network_operator_t * mno)
15611574
return LTE_SHIELD_ERROR_UNEXPECTED_RESPONSE;
15621575
}*/
15631576

1564-
LTE_Shield_error_t LTE_Shield::waitForResponse(char * expectedResponse, uint16_t timeout)
1577+
LTE_Shield_error_t LTE_Shield::waitForResponse(const char * expectedResponse, uint16_t timeout)
15651578
{
15661579
unsigned long timeIn;
15671580
boolean found = false;
@@ -1591,7 +1604,7 @@ LTE_Shield_error_t LTE_Shield::waitForResponse(char * expectedResponse, uint16_t
15911604
}
15921605

15931606
LTE_Shield_error_t LTE_Shield::sendCommandWithResponse(
1594-
const char * command, char * expectedResponse, char * responseDest,
1607+
const char * command, const char * expectedResponse, char * responseDest,
15951608
unsigned long commandTimeout, boolean at)
15961609
{
15971610
unsigned long timeIn;
@@ -1647,17 +1660,13 @@ LTE_Shield_error_t LTE_Shield::sendCommandWithResponse(
16471660

16481661
boolean LTE_Shield::sendCommand(const char * command, boolean at)
16491662
{
1650-
char * commandToSend;
1651-
16521663
readAvailable(NULL); // Clear out receive buffer before sending a new command
16531664

16541665
if (at)
16551666
{
1656-
commandToSend = lte_calloc_char(strlen(LTE_SHIELD_COMMAND_AT) + strlen(command) + 2);
1657-
if (commandToSend == NULL) return false;
1658-
sprintf(commandToSend, "%s%s\r", LTE_SHIELD_COMMAND_AT, command);
1659-
hwPrint(commandToSend);
1660-
free(commandToSend);
1667+
hwPrint(LTE_SHIELD_COMMAND_AT);
1668+
hwPrint(command);
1669+
hwPrint("\r");
16611670
}
16621671
else
16631672
{
@@ -1733,6 +1742,22 @@ size_t LTE_Shield::hwPrint(const char * s)
17331742
return (size_t) 0;
17341743
}
17351744

1745+
size_t LTE_Shield::hwWrite(const char c)
1746+
{
1747+
if (_hardSerial != NULL)
1748+
{
1749+
return _hardSerial->write(c);
1750+
}
1751+
#ifdef LTE_SHIELD_SOFTWARE_SERIAL_ENABLED
1752+
else if (_softSerial != NULL)
1753+
{
1754+
return _softSerial->write(c);
1755+
}
1756+
#endif
1757+
1758+
return (size_t) 0;
1759+
}
1760+
17361761
int LTE_Shield::readAvailable(char * inString)
17371762
{
17381763
int len = 0;
@@ -1742,19 +1767,31 @@ int LTE_Shield::readAvailable(char * inString)
17421767
while (_hardSerial->available())
17431768
{
17441769
char c = (char)_hardSerial->read();
1745-
inString[len++] = c;
1770+
if (inString != NULL)
1771+
{
1772+
inString[len++] = c;
1773+
}
1774+
}
1775+
if (inString != NULL)
1776+
{
1777+
inString[len] = 0;
17461778
}
1747-
inString[len] = 0;
17481779
}
17491780
#ifdef LTE_SHIELD_SOFTWARE_SERIAL_ENABLED
17501781
if (_softSerial != NULL)
17511782
{
17521783
while (_softSerial->available())
17531784
{
17541785
char c = (char)_softSerial->read();
1755-
inString[len++] = c;
1786+
if (inString != NULL)
1787+
{
1788+
inString[len++] = c;
1789+
}
1790+
}
1791+
if (inString != NULL)
1792+
{
1793+
inString[len] = 0;
17561794
}
1757-
inString[len] = 0;
17581795
}
17591796
#endif
17601797

src/SparkFun_LTE_Shield_Arduino_Library.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,9 @@ class LTE_Shield : public Print {
154154
LTE_Shield(uint8_t powerPin = LTE_SHIELD_POWER_PIN, uint8_t resetPin = LTE_SHIELD_RESET_PIN);
155155

156156
// Begin -- initialize BT module and ensure it's connected
157+
#ifdef LTE_SHIELD_SOFTWARE_SERIAL_ENABLED
157158
boolean begin(SoftwareSerial & softSerial, unsigned long baud = 9600);
159+
#endif
158160
boolean begin(HardwareSerial & hardSerial, unsigned long baud = 9600);
159161

160162
// Loop polling and polling setup
@@ -339,10 +341,10 @@ class LTE_Shield : public Print {
339341
LTE_Shield_error_t getMno(mobile_network_operator_t * mno);
340342

341343
// Wait for an expected response (don't send a command)
342-
LTE_Shield_error_t waitForResponse(char * expectedResponse, uint16_t timeout);
344+
LTE_Shield_error_t waitForResponse(const char * expectedResponse, uint16_t timeout);
343345

344346
// Send command with an expected (potentially partial) response, store entire response
345-
LTE_Shield_error_t sendCommandWithResponse(const char * command, char * expectedResponse,
347+
LTE_Shield_error_t sendCommandWithResponse(const char * command, const char * expectedResponse,
346348
char * responseDest, unsigned long commandTimeout, boolean at = true);
347349

348350
// Send a command -- prepend AT if at is true
@@ -354,6 +356,7 @@ class LTE_Shield : public Print {
354356

355357
// UART Functions
356358
size_t hwPrint(const char * s);
359+
size_t hwWrite(const char c);
357360
int readAvailable(char * inString);
358361
char readChar(void);
359362
int hwAvailable(void);

0 commit comments

Comments
 (0)