Skip to content

Commit

Permalink
update note-c and bump version (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
bsatrom authored Dec 7, 2020
1 parent 8f36330 commit 477fdef
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 29 deletions.
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=Blues Wireless Notecard
version=1.2.7
version=1.2.8
author=Blues Wireless
maintainer=Blues Wireless <[email protected]>
sentence=An easy to use Notecard Library for Arduino.
Expand Down
1 change: 1 addition & 0 deletions src/note-c/n_const.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ const char *c_mem = "mem";
const char *c_timeout = "timeout";
const char *c_err = "err";
const char *c_req = "req";
const char *c_cmd = "cmd";
const char *c_bad = "bad";
5 changes: 3 additions & 2 deletions src/note-c/n_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -789,9 +789,10 @@ bool NoteGetStatusST(char *statusBuf, int statusBufLen, JTIME *bootTime, bool *r
bool NoteSleep(char *stateb64, uint32_t seconds, const char *modes) {
bool success = false;

// Put ourselves to sleep
// Use a Command rather than a Request so that the Notecard doesn't try to send
// a response back to us, which would cause a communications error on that end.
_Debug("requesting sleep\n");
J *req = NoteNewRequest("card.attn");
J *req = NoteNewCommand("card.attn");
if (req != NULL) {
// Add the base64 item in a wonderful way that doesn't strdup the huge string
J *stringReferenceItem = JCreateStringReference(stateb64);
Expand Down
6 changes: 3 additions & 3 deletions src/note-c/n_hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -503,9 +503,9 @@ char NoteSerialReceive() {
@returns A boolean indicating whether the I2C bus was reset.
*/
/**************************************************************************/
bool NoteI2CReset() {
bool NoteI2CReset(uint16_t DevAddress) {
if (hookActiveInterface == interfaceI2C && hookI2CReset != NULL) {
return hookI2CReset();
return hookI2CReset(DevAddress);
}
return false;
}
Expand Down Expand Up @@ -552,7 +552,7 @@ const char *NoteI2CReceive(uint16_t DevAddress, uint8_t* pBuffer, uint16_t Size,
*/
/**************************************************************************/
uint32_t NoteI2CAddress() {
if (i2cAddress == NOTE_I2C_MAX_DEFAULT)
if (i2cAddress == NOTE_I2C_ADDR_DEFAULT)
return 0x17;
return i2cAddress;
}
Expand Down
10 changes: 7 additions & 3 deletions src/note-c/n_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const char *i2cNoteTransaction(char *json, char **jsonResponse) {
estr = _I2CTransmit(_I2CAddress(), chunk, chunklen);
if (estr != NULL) {
_Free(transmitBuf);
_I2CReset();
_I2CReset(_I2CAddress());
_UnlockI2C();
#ifdef ERRDBG
_Debug("i2c transmit: ");
Expand All @@ -80,6 +80,10 @@ const char *i2cNoteTransaction(char *json, char **jsonResponse) {
// Free the transmit buffer
_Free(transmitBuf);

// If no reply expected, we're done
if (jsonResponse == NULL)
return NULL;

// Dynamically grow the buffer as we read. Note that we always put the +1 in the alloc
// so we can be assured that it can be null-terminated, which must be the case because
// our json parser requires a null-terminated string.
Expand Down Expand Up @@ -187,7 +191,7 @@ bool i2cNoteReset() {

// Reset the I2C subsystem and exit if failure
_LockI2C();
bool success = _I2CReset();
bool success = _I2CReset(_I2CAddress());
_UnlockI2C();
if (!success)
return false;
Expand Down Expand Up @@ -235,7 +239,7 @@ bool i2cNoteReset() {

// Reinitialize i2c if there's no response
_LockI2C();
_I2CReset();
_I2CReset(_I2CAddress());
_UnlockI2C();
_Debug(ERRSTR("notecard not responding\n", "no notecard\n"));
_DelayMs(2000);
Expand Down
25 changes: 14 additions & 11 deletions src/note-c/n_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ bool NoteSerialReset(void);
void NoteSerialTransmit(uint8_t *, size_t, bool);
bool NoteSerialAvailable(void);
char NoteSerialReceive(void);
bool NoteI2CReset(void);
bool NoteI2CReset(uint16_t DevAddress);
const char *NoteI2CTransmit(uint16_t DevAddress, uint8_t* pBuffer, uint16_t Size);
const char *NoteI2CReceive(uint16_t DevAddress, uint8_t* pBuffer, uint16_t Size, uint32_t *avail);
bool NoteHardReset(void);
Expand All @@ -96,36 +96,39 @@ bool NoteIsDebugOutputActive(void);

// Constants, a global optimization to save static string memory
extern const char *c_null;

#define c_null_len 4
extern const char *c_false;

extern const char *c_false;
#define c_false_len 5
extern const char *c_true;

extern const char *c_true;
#define c_true_len 4
extern const char *c_nullstring;

extern const char *c_nullstring;
#define c_nullstring_len 0
extern const char *c_newline;

extern const char *c_newline;
#define c_newline_len 2
extern const char *c_mem;

extern const char *c_mem;
#define c_mem_len 3
extern const char *c_timeout;

extern const char *c_timeout;
#define c_timeout_len 7
extern const char *c_err;

extern const char *c_err;
#define c_err_len 3
extern const char *c_req;

extern const char *c_req;
#define c_req_len 3
extern const char *c_bad;

extern const char *c_cmd;
#define c_cmd_len 3

extern const char *c_bad;
#define c_bad_len 3


// Readability wrappers. Anything starting with _ is simply calling the wrapper
// function.
#define _LockNote NoteLockNote
Expand Down
36 changes: 35 additions & 1 deletion src/note-c/n_request.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,23 @@ J *NoteNewRequest(const char *request) {
return reqdoc;
}

/**************************************************************************/
/*!
@brief Create a new command object to populate before sending to the Notecard.
Lock for mutual exclusion, not only because access to the card must be serialized, but also because
both C++ and ArduinoJSON call malloc() which is not a thread-safe operation.
@param request
The name of the command, for example `hub.set`.
@returns a `J` cJSON object with the request name pre-populated.
*/
/**************************************************************************/
J *NoteNewCommand(const char *request) {
J *reqdoc = JCreateObject();
if (reqdoc != NULL)
JAddStringToObject(reqdoc, c_cmd, request);
return reqdoc;
}

/**************************************************************************/
/*!
@brief Send a request to the Notecard.
Expand Down Expand Up @@ -174,6 +191,13 @@ char *NoteRequestResponseJSON(char *reqJSON) {
/**************************************************************************/
J *NoteTransaction(J *req) {

// Validate in case of memory failure of the requestor
if (req == NULL)
return NULL;

// Determine whether or not a response will be expected, by virtue of "cmd" being present
bool noResponseExpected = (JGetString(req, "req")[0] == '\0' && JGetString(req, "cmd")[0] != '\0');

// If a reset of the module is required for any reason, do it now.
// We must do this before acquiring lock.
if (resetRequired) {
Expand All @@ -198,7 +222,11 @@ J *NoteTransaction(J *req) {

// Pertform the transaction
char *responseJSON;
const char *errStr = _Transaction(json, &responseJSON);
const char *errStr;
if (noResponseExpected)
errStr = _Transaction(json, NULL);
else
errStr = _Transaction(json, &responseJSON);

// Free the json
JFree(json);
Expand All @@ -211,6 +239,12 @@ J *NoteTransaction(J *req) {
return rsp;
}

// Exit with a blank object (with no err field) if no response expected
if (noResponseExpected) {
_UnlockNote();
return JCreateObject();
}

// Parse the reply from the card on the input stream
J *rspdoc = JParse(responseJSON);
if (rspdoc == NULL) {
Expand Down
4 changes: 4 additions & 0 deletions src/note-c/n_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ const char *serialNoteTransaction(char *json, char **jsonResponse) {
_DelayMs(CARD_REQUEST_SERIAL_SEGMENT_DELAY_MS);
}

// If no reply expected, we're done
if (jsonResponse == NULL)
return NULL;

// Wait for something to become available, processing timeout errors up-front
// because the json parse operation immediately following is subject to the
// serial port timeout. We'd like more flexibility in max timeout and ultimately
Expand Down
26 changes: 18 additions & 8 deletions src/note-c/note.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,25 +38,34 @@
#pragma once

// In case they're not yet defined
#include <float.h>
#include <stdbool.h>
#include <stdint.h>

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

// If using a short float, we must be on a VERY small MCU. In this case, define additional
// symbols that will save quite a bit of memory in the runtime image.
#ifdef NOTE_FLOAT
#define JNUMBER float
#define ERRSTR(x,y) (y)
#define NOTE_LOWMEM
#else
#define JNUMBER double
#define ERRSTR(x,y) (x)
#define ERRDBG
#endif

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

Expand All @@ -92,6 +101,7 @@ bool NoteReset(void);
void NoteResetRequired(void);
#define NoteNewBody JCreateObject
J *NoteNewRequest(const char *request);
J *NoteNewCommand(const char *request);
J *NoteRequestResponse(J *req);
char *NoteRequestResponseJSON(char *reqJSON);
void NoteSuspendTransactionDebug(void);
Expand Down

0 comments on commit 477fdef

Please sign in to comment.