diff --git a/TF_Config.example.h b/TF_Config.example.h index 4ace3bd..eeb964e 100644 --- a/TF_Config.example.h +++ b/TF_Config.example.h @@ -1,4 +1,6 @@ // +// TinyFrame configuration file. +// // Rename to TF_Config.h // @@ -19,7 +21,7 @@ // | 1 | ? | ? | ? | ? | ... | ? | <- size (bytes) // '-----+----+-----+------+------------+- - - -+------------' -// !!! BOTH SIDES MUST USE THE SAME SETTINGS !!! +// !!! BOTH PEERS MUST USE THE SAME SETTINGS !!! // Adjust sizes as desired (1,2,4) #define TF_ID_BYTES 1 @@ -52,7 +54,7 @@ typedef uint8_t TF_COUNT; #define TF_MAX_PAYLOAD_RX 1024 // Size of the sending buffer. Larger payloads will be split to pieces and sent // in multiple calls to the write function. This can be lowered to reduce RAM usage. -#define TF_SENDBUF_LEN 1024 +#define TF_SENDBUF_LEN 128 // --- Listener counts - determine sizes of the static slot tables --- diff --git a/TF_Integration.example.c b/TF_Integration.example.c new file mode 100644 index 0000000..4ca8e59 --- /dev/null +++ b/TF_Integration.example.c @@ -0,0 +1,28 @@ +#include "TinyFrame.h" + +/** + * This is an example of integrating TinyFrame into the application. + * + * TF_WriteImpl() is required, the mutex functions are weak and can + * be removed if not used. They are called from all TF_Send/Respond functions. + * + * Also remember to periodically call TF_Tick() if you wish to use the + * listener timeout feature. + */ + +void TF_WriteImpl(const uint8_t *buff, size_t len) +{ + // send to UART +} + +/** Claim the TX interface before composing and sending a frame */ +void TF_ClaimTx(void) +{ + // take mutex +} + +/** Free the TX interface after composing and sending a frame */ +void TF_ReleaseTx(void) +{ + // release mutex +} diff --git a/TinyFrame.c b/TinyFrame.c index b6f6016..f165743 100644 --- a/TinyFrame.c +++ b/TinyFrame.c @@ -1,7 +1,6 @@ //--------------------------------------------------------------------------- #include "TinyFrame.h" #include -//#include "demo/utils.h" //--------------------------------------------------------------------------- // Compatibility with ESP8266 SDK @@ -31,6 +30,7 @@ typedef struct _IdListener_struct_ { TF_TICKS timeout; // nr of ticks remaining to disable this listener TF_TICKS timeout_max; // the original timeout is stored here void *userdata; + void *userdata2; } IdListener; typedef struct _TypeListener_struct_ { @@ -233,6 +233,7 @@ static void _TF_FN cleanup_id_listener(TF_COUNT i, IdListener *lst) // Make user clean up their data - only if not NULL if (lst->userdata != NULL) { msg.userdata = lst->userdata; + msg.userdata2 = lst->userdata2; msg.data = NULL; // this is a signal that the listener should clean up lst->fn(&msg); // return value is ignored here - use TF_STAY or TF_CLOSE } @@ -281,6 +282,7 @@ bool _TF_FN TF_AddIdListener(TF_Msg *msg, TF_Listener cb, TF_TICKS timeout) lst->fn = cb; lst->id = msg->frame_id; lst->userdata = msg->userdata; + lst->userdata2 = msg->userdata2; lst->timeout_max = lst->timeout = timeout; if (i >= tf.count_id_lst) { tf.count_id_lst = (TF_COUNT) (i + 1); @@ -403,8 +405,10 @@ static void _TF_FN TF_HandleReceivedMessage(void) ilst = &tf.id_listeners[i]; if (ilst->fn && ilst->id == msg.frame_id) { msg.userdata = ilst->userdata; // pass userdata pointer to the callback + msg.userdata2 = ilst->userdata2; res = ilst->fn(&msg); ilst->userdata = msg.userdata; // put it back (may have changed the pointer or set to NULL) + ilst->userdata2 = msg.userdata2; // put it back (may have changed the pointer or set to NULL) if (res != TF_NEXT) { if (res == TF_CLOSE) { @@ -418,6 +422,7 @@ static void _TF_FN TF_HandleReceivedMessage(void) } } msg.userdata = NULL; + msg.userdata2 = NULL; // clean up for the following listeners that don't use userdata // Type listeners @@ -734,6 +739,8 @@ static bool _TF_FN TF_SendFrame(TF_Msg *msg, TF_Listener listener, TF_TICKS time size_t sent = 0; TF_CKSUM cksum = 0; + TF_ClaimTx(); + len = TF_ComposeHead(tf.sendbuf, &msg->frame_id, msg->type, @@ -769,6 +776,8 @@ static bool _TF_FN TF_SendFrame(TF_Msg *msg, TF_Listener listener, TF_TICKS time len += TF_ComposeTail(tf.sendbuf+len, &cksum); TF_WriteImpl((const uint8_t *) tf.sendbuf, len); + TF_ReleaseTx(); + return true; } @@ -852,3 +861,12 @@ void _TF_FN TF_Tick(void) } } +void __attribute__((weak)) TF_ClaimTx(void) +{ + // do nothing +} + +void __attribute__((weak)) TF_ReleaseTx(void) +{ + // do nothing +} diff --git a/TinyFrame.h b/TinyFrame.h index 0ba0c77..2422edd 100644 --- a/TinyFrame.h +++ b/TinyFrame.h @@ -1,6 +1,17 @@ #ifndef TinyFrameH #define TinyFrameH +/** + * TinyFrame protocol library + * + * version: 1.2.0 + * + * (c) Ondřej Hruška 2017, MIT License + * no liability/warranty, free for any use, must retain this notice & license + * + * Upstream URL: https://github.com/MightyPork/TinyFrame + */ + //--------------------------------------------------------------------------- #include // for uint8_t etc #include // for bool @@ -105,6 +116,7 @@ typedef struct _TF_MSG_STRUCT_ { const uint8_t *data; //!< buffer of received data or data to send. NULL = listener timed out, free userdata! TF_LEN len; //!< length of the buffer void *userdata; //!< here's a place for custom data; this data will be stored with the listener + void *userdata2; } TF_Msg; /** @@ -118,6 +130,7 @@ static inline void TF_ClearMsg(TF_Msg *msg) msg->data = NULL; msg->len = 0; msg->userdata = NULL; + msg->userdata2 = NULL; } /** @@ -269,4 +282,10 @@ extern void TF_WriteImpl(const uint8_t *buff, size_t len); */ void TF_Tick(void); +/** Claim the TX interface before composing and sending a frame */ +extern void TF_ClaimTx(void); + +/** Free the TX interface after composing and sending a frame */ +extern void TF_ReleaseTx(void); + #endif