Skip to content

Commit 477fdef

Browse files
authored
update note-c and bump version (#28)
1 parent 8f36330 commit 477fdef

File tree

9 files changed

+86
-29
lines changed

9 files changed

+86
-29
lines changed

library.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=Blues Wireless Notecard
2-
version=1.2.7
2+
version=1.2.8
33
author=Blues Wireless
44
maintainer=Blues Wireless <[email protected]>
55
sentence=An easy to use Notecard Library for Arduino.

src/note-c/n_const.c

+1
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ const char *c_mem = "mem";
2222
const char *c_timeout = "timeout";
2323
const char *c_err = "err";
2424
const char *c_req = "req";
25+
const char *c_cmd = "cmd";
2526
const char *c_bad = "bad";

src/note-c/n_helpers.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -789,9 +789,10 @@ bool NoteGetStatusST(char *statusBuf, int statusBufLen, JTIME *bootTime, bool *r
789789
bool NoteSleep(char *stateb64, uint32_t seconds, const char *modes) {
790790
bool success = false;
791791

792-
// Put ourselves to sleep
792+
// Use a Command rather than a Request so that the Notecard doesn't try to send
793+
// a response back to us, which would cause a communications error on that end.
793794
_Debug("requesting sleep\n");
794-
J *req = NoteNewRequest("card.attn");
795+
J *req = NoteNewCommand("card.attn");
795796
if (req != NULL) {
796797
// Add the base64 item in a wonderful way that doesn't strdup the huge string
797798
J *stringReferenceItem = JCreateStringReference(stateb64);

src/note-c/n_hooks.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -503,9 +503,9 @@ char NoteSerialReceive() {
503503
@returns A boolean indicating whether the I2C bus was reset.
504504
*/
505505
/**************************************************************************/
506-
bool NoteI2CReset() {
506+
bool NoteI2CReset(uint16_t DevAddress) {
507507
if (hookActiveInterface == interfaceI2C && hookI2CReset != NULL) {
508-
return hookI2CReset();
508+
return hookI2CReset(DevAddress);
509509
}
510510
return false;
511511
}
@@ -552,7 +552,7 @@ const char *NoteI2CReceive(uint16_t DevAddress, uint8_t* pBuffer, uint16_t Size,
552552
*/
553553
/**************************************************************************/
554554
uint32_t NoteI2CAddress() {
555-
if (i2cAddress == NOTE_I2C_MAX_DEFAULT)
555+
if (i2cAddress == NOTE_I2C_ADDR_DEFAULT)
556556
return 0x17;
557557
return i2cAddress;
558558
}

src/note-c/n_i2c.c

+7-3
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ const char *i2cNoteTransaction(char *json, char **jsonResponse) {
5757
estr = _I2CTransmit(_I2CAddress(), chunk, chunklen);
5858
if (estr != NULL) {
5959
_Free(transmitBuf);
60-
_I2CReset();
60+
_I2CReset(_I2CAddress());
6161
_UnlockI2C();
6262
#ifdef ERRDBG
6363
_Debug("i2c transmit: ");
@@ -80,6 +80,10 @@ const char *i2cNoteTransaction(char *json, char **jsonResponse) {
8080
// Free the transmit buffer
8181
_Free(transmitBuf);
8282

83+
// If no reply expected, we're done
84+
if (jsonResponse == NULL)
85+
return NULL;
86+
8387
// Dynamically grow the buffer as we read. Note that we always put the +1 in the alloc
8488
// so we can be assured that it can be null-terminated, which must be the case because
8589
// our json parser requires a null-terminated string.
@@ -187,7 +191,7 @@ bool i2cNoteReset() {
187191

188192
// Reset the I2C subsystem and exit if failure
189193
_LockI2C();
190-
bool success = _I2CReset();
194+
bool success = _I2CReset(_I2CAddress());
191195
_UnlockI2C();
192196
if (!success)
193197
return false;
@@ -235,7 +239,7 @@ bool i2cNoteReset() {
235239

236240
// Reinitialize i2c if there's no response
237241
_LockI2C();
238-
_I2CReset();
242+
_I2CReset(_I2CAddress());
239243
_UnlockI2C();
240244
_Debug(ERRSTR("notecard not responding\n", "no notecard\n"));
241245
_DelayMs(2000);

src/note-c/n_lib.h

+14-11
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ bool NoteSerialReset(void);
8787
void NoteSerialTransmit(uint8_t *, size_t, bool);
8888
bool NoteSerialAvailable(void);
8989
char NoteSerialReceive(void);
90-
bool NoteI2CReset(void);
90+
bool NoteI2CReset(uint16_t DevAddress);
9191
const char *NoteI2CTransmit(uint16_t DevAddress, uint8_t* pBuffer, uint16_t Size);
9292
const char *NoteI2CReceive(uint16_t DevAddress, uint8_t* pBuffer, uint16_t Size, uint32_t *avail);
9393
bool NoteHardReset(void);
@@ -96,36 +96,39 @@ bool NoteIsDebugOutputActive(void);
9696

9797
// Constants, a global optimization to save static string memory
9898
extern const char *c_null;
99-
10099
#define c_null_len 4
101-
extern const char *c_false;
102100

101+
extern const char *c_false;
103102
#define c_false_len 5
104-
extern const char *c_true;
105103

104+
extern const char *c_true;
106105
#define c_true_len 4
107-
extern const char *c_nullstring;
108106

107+
extern const char *c_nullstring;
109108
#define c_nullstring_len 0
110-
extern const char *c_newline;
111109

110+
extern const char *c_newline;
112111
#define c_newline_len 2
113-
extern const char *c_mem;
114112

113+
extern const char *c_mem;
115114
#define c_mem_len 3
116-
extern const char *c_timeout;
117115

116+
extern const char *c_timeout;
118117
#define c_timeout_len 7
119-
extern const char *c_err;
120118

119+
extern const char *c_err;
121120
#define c_err_len 3
122-
extern const char *c_req;
123121

122+
extern const char *c_req;
124123
#define c_req_len 3
125-
extern const char *c_bad;
126124

125+
extern const char *c_cmd;
126+
#define c_cmd_len 3
127+
128+
extern const char *c_bad;
127129
#define c_bad_len 3
128130

131+
129132
// Readability wrappers. Anything starting with _ is simply calling the wrapper
130133
// function.
131134
#define _LockNote NoteLockNote

src/note-c/n_request.c

+35-1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,23 @@ J *NoteNewRequest(const char *request) {
7575
return reqdoc;
7676
}
7777

78+
/**************************************************************************/
79+
/*!
80+
@brief Create a new command object to populate before sending to the Notecard.
81+
Lock for mutual exclusion, not only because access to the card must be serialized, but also because
82+
both C++ and ArduinoJSON call malloc() which is not a thread-safe operation.
83+
@param request
84+
The name of the command, for example `hub.set`.
85+
@returns a `J` cJSON object with the request name pre-populated.
86+
*/
87+
/**************************************************************************/
88+
J *NoteNewCommand(const char *request) {
89+
J *reqdoc = JCreateObject();
90+
if (reqdoc != NULL)
91+
JAddStringToObject(reqdoc, c_cmd, request);
92+
return reqdoc;
93+
}
94+
7895
/**************************************************************************/
7996
/*!
8097
@brief Send a request to the Notecard.
@@ -174,6 +191,13 @@ char *NoteRequestResponseJSON(char *reqJSON) {
174191
/**************************************************************************/
175192
J *NoteTransaction(J *req) {
176193

194+
// Validate in case of memory failure of the requestor
195+
if (req == NULL)
196+
return NULL;
197+
198+
// Determine whether or not a response will be expected, by virtue of "cmd" being present
199+
bool noResponseExpected = (JGetString(req, "req")[0] == '\0' && JGetString(req, "cmd")[0] != '\0');
200+
177201
// If a reset of the module is required for any reason, do it now.
178202
// We must do this before acquiring lock.
179203
if (resetRequired) {
@@ -198,7 +222,11 @@ J *NoteTransaction(J *req) {
198222

199223
// Pertform the transaction
200224
char *responseJSON;
201-
const char *errStr = _Transaction(json, &responseJSON);
225+
const char *errStr;
226+
if (noResponseExpected)
227+
errStr = _Transaction(json, NULL);
228+
else
229+
errStr = _Transaction(json, &responseJSON);
202230

203231
// Free the json
204232
JFree(json);
@@ -211,6 +239,12 @@ J *NoteTransaction(J *req) {
211239
return rsp;
212240
}
213241

242+
// Exit with a blank object (with no err field) if no response expected
243+
if (noResponseExpected) {
244+
_UnlockNote();
245+
return JCreateObject();
246+
}
247+
214248
// Parse the reply from the card on the input stream
215249
J *rspdoc = JParse(responseJSON);
216250
if (rspdoc == NULL) {

src/note-c/n_serial.c

+4
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ const char *serialNoteTransaction(char *json, char **jsonResponse) {
4343
_DelayMs(CARD_REQUEST_SERIAL_SEGMENT_DELAY_MS);
4444
}
4545

46+
// If no reply expected, we're done
47+
if (jsonResponse == NULL)
48+
return NULL;
49+
4650
// Wait for something to become available, processing timeout errors up-front
4751
// because the json parse operation immediately following is subject to the
4852
// serial port timeout. We'd like more flexibility in max timeout and ultimately

src/note-c/note.h

+18-8
Original file line numberDiff line numberDiff line change
@@ -38,25 +38,34 @@
3838
#pragma once
3939

4040
// In case they're not yet defined
41+
#include <float.h>
4142
#include <stdbool.h>
4243
#include <stdint.h>
4344

44-
// Define our basic floating data type. In most cases "double" is the right answer, however for
45-
// very small microcontrollers these libraries are simply too large. This ensures that we
46-
// use FLOATs when both are the same, and we don't define constants that are too large.
45+
// Determine our basic floating data type. In most cases "double" is the right answer, however for
46+
// very small microcontrollers we must use single-precision.
47+
#if defined(FLT_MAX_EXP) && defined(DBL_MAX_EXP)
48+
#if (FLT_MAX_EXP == DBL_MAX_EXP)
49+
#define NOTE_FLOAT
50+
#endif
51+
#elif defined(__FLT_MAX_EXP__) && defined(__DBL_MAX_EXP__)
4752
#if (__FLT_MAX_EXP__ == __DBL_MAX_EXP__)
4853
#define NOTE_FLOAT
49-
#define ERRSTR(x,y) (y)
50-
#define NOTE_LOWMEM
54+
#endif
5155
#else
52-
#define ERRSTR(x,y) (x)
53-
#define ERRDBG
56+
#error What are floating point exponent length symbols for this compiler?
5457
#endif
5558

59+
// If using a short float, we must be on a VERY small MCU. In this case, define additional
60+
// symbols that will save quite a bit of memory in the runtime image.
5661
#ifdef NOTE_FLOAT
5762
#define JNUMBER float
63+
#define ERRSTR(x,y) (y)
64+
#define NOTE_LOWMEM
5865
#else
5966
#define JNUMBER double
67+
#define ERRSTR(x,y) (x)
68+
#define ERRDBG
6069
#endif
6170

6271
// UNIX Epoch time (also known as POSIX time) is the number of seconds that have elapsed since
@@ -83,7 +92,7 @@ typedef bool (*serialResetFn) (void);
8392
typedef void (*serialTransmitFn) (uint8_t *data, size_t len, bool flush);
8493
typedef bool (*serialAvailableFn) (void);
8594
typedef char (*serialReceiveFn) (void);
86-
typedef bool (*i2cResetFn) (void);
95+
typedef bool (*i2cResetFn) (uint16_t DevAddress);
8796
typedef const char * (*i2cTransmitFn) (uint16_t DevAddress, uint8_t* pBuffer, uint16_t Size);
8897
typedef const char * (*i2cReceiveFn) (uint16_t DevAddress, uint8_t* pBuffer, uint16_t Size, uint32_t *avail);
8998

@@ -92,6 +101,7 @@ bool NoteReset(void);
92101
void NoteResetRequired(void);
93102
#define NoteNewBody JCreateObject
94103
J *NoteNewRequest(const char *request);
104+
J *NoteNewCommand(const char *request);
95105
J *NoteRequestResponse(J *req);
96106
char *NoteRequestResponseJSON(char *reqJSON);
97107
void NoteSuspendTransactionDebug(void);

0 commit comments

Comments
 (0)