PIC24 Support Libraries
|
Routines which implement the uC comm protocol. More...
#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
Go to the source code of this file.
Data Structures | |
struct | XFER_VAR |
Macros | |
Constants | |
These values are #defined as necessary so that the work under:
| |
#define | FALSE 0 |
#define | TRUE 1 |
#define | ASSERT(x) assert(x) |
#define | ASSERTM(msg, expr) ASSERT(expr) |
An assert with message macro; the msg isn't used in C. | |
#define | BOOL unsigned char |
Typedefs | |
typedef unsigned int | uint |
An abbreviation for an unsigned integer. | |
typedef unsigned char | uint8_t |
An abbreviation for an 8-bit unsigned integer. | |
Command-finding state machine | |
#define | CMD_TOKEN ((char) 0xAA) |
#define | ESCAPED_CMD ((char) 0xFC) |
#define | CMD_LONG_VAR ((char) 0xFD) |
#define | CMD_SEND_ONLY ((char) 0xFE) |
#define | CMD_SEND_RECEIVE_VAR ((char) 0xFF) |
#define | VAR_SIZE_BITS 2 |
#define | VAR_SIZE_MASK ((1 << VAR_SIZE_BITS) - 1) |
A mask which removes all but the variable size bits in the varBits field. | |
#define | SHORT_VAR_MAX_LEN (1 << VAR_SIZE_BITS) |
enum | CMD_STATE { STATE_CMD_START, STATE_CMD_WAIT1, STATE_CMD_WAIT2 } |
enum | CMD_OUTPUT { OUTPUT_CMD_NONE, OUTPUT_CMD_CHAR, OUTPUT_CMD_CMD, OUTPUT_CMD_REPEATED_CMD, OUTPUT_CMD_REPEATED_WAIT } |
void | resetCommandFindMachine () |
CMD_OUTPUT | stepCommandFindMachine (char c_inChar, char *c_outChar) |
Data structures to store received variables | |
#define | MAX_NUM_XFER_VARS ((1 << (8 - VAR_SIZE_BITS)) - 1) |
Maximum number of transfer variables supported. | |
#define | NUM_XFER_VARS 62 |
XFER_VAR | xferVar [NUM_XFER_VARS] |
A table to hold the state of transfer variables. | |
uint8_t | au8_xferVarWriteable [NUM_XFER_VARS/8+((NUM_XFER_VARS % 8) > 0)] |
Routines which implement the uC comm protocol.
This implements code which receives data from a uC sent either as individual characters or as data packets. For a complete specification, see the uC comm protocol.
Two state machines implement this spec. The receive state machine uses the command-finding state machine in its operation, so that a user of this code will not normally need access to the command-finding machine.
Both machines can be reset (resetCommandFindMachine(), resetReceiveMachine()) and advanced by one state (stepCommandFindMachine(), stepReceiveMachine()).
Two mechanisms provide read access to the receive state machine. Low-level calls (getReceiveMachineOutChar(), getReceiveMachineIndex(), getReceiveMachineError(), getReceiveMachineIsSpec()) report machine state, while high-level calls (isReceiveMachineChar(), isReceiveMachineData(), isReceiveMachineSpec()) aggreate that state into more meaningful information.
Note: this is implemented in C (not C++), so that similar code can be re-used on a uC.
The uC keeps state in xferVar; a NULL address indicates nothing is present.
On receive: implement as a state machine (see sketch below).
For simplicity, "getch" really means one invocation of the receive state machine, which is runs until the next getch. Timeouts are not shown: if too much time passes, the state machine is reset to the top. Likewise, receiving a command at any unexpected point causes a state machine reset.
varBits = getch if !command: c = varBits // This was just a normal char; return it return index = 0 restart // varBits is a command, not a char if isLongVar(varBits): varNum, len = getch else assign varNum, len from varBits if isVarSpec and !MICROCONTROLLER getch len times to buf parse to var spec report any errors, restart else if isValid(varNum, len) getch len times to var return varIndex else getch len times and discard report error, restart
\author Bryan A. Jones, bjones AT ece DOT msstate DOT edu.
Definition in file dataXferImpl.h.
#define CHAR_RECEIVED_INDEX 0xFF |
This value retured for the index from the receive state machine (see, e.g., isReceiveMachineData) indicates that a character, not a command, was received.
Definition at line 358 of file dataXferImpl.h.
Referenced by isReceiveMachineChar(), isReceiveMachineData(), isReceiveMachineSpec(), and stepReceiveMachine().
#define CMD_LONG_VAR ((char) 0xFD) |
After a command token, this value specifies that the command is a long variable.
Definition at line 213 of file dataXferImpl.h.
Referenced by stepReceiveMachine().
#define CMD_SEND_ONLY ((char) 0xFE) |
After a command token, this value specifies that the command is a send-only var.
Definition at line 217 of file dataXferImpl.h.
Referenced by stepReceiveMachine().
#define CMD_SEND_RECEIVE_VAR ((char) 0xFF) |
After a command token, this value specifies that the command is a send/receive var.
Definition at line 221 of file dataXferImpl.h.
Referenced by stepReceiveMachine().
#define CMD_TOKEN ((char) 0xAA) |
The character used to begin a command. If this is not a command, then use the two-character sequence CMD_TOKEN ESCAPED_CMD; a CMD_TOKEN followed by any other value is a command.
Definition at line 205 of file dataXferImpl.h.
Referenced by stepCommandFindMachine(), and stepReceiveMachine().
#define ESCAPED_CMD ((char) 0xFC) |
After a command token, this value specifies that the character CMD_TOKEN was sent.
Definition at line 209 of file dataXferImpl.h.
Referenced by stepCommandFindMachine(), and stepReceiveMachine().
#define NUM_XFER_VARS 62 |
Number of transfer variables supported. Must be less than the MAX_NUM_XFER_VARS.
Definition at line 335 of file dataXferImpl.h.
Referenced by clearReceiveStruct(), formatVar(), sendVar(), specifyVar(), and validateIndex().
#define SHORT_VAR_MAX_LEN (1 << VAR_SIZE_BITS) |
The maximum size of a short variable (which must fit in VAR_SIZE_BITS number of bits).
Definition at line 232 of file dataXferImpl.h.
#define VAR_SIZE_BITS 2 |
The number of bits in the variable size field of the varBits field, following a command token.
Definition at line 225 of file dataXferImpl.h.
Referenced by getVarIndex().
enum CMD_OUTPUT |
The output of the command-finding state machine. See stepCommandFindMachine for more information.
Enumerator | |
---|---|
OUTPUT_CMD_NONE | The state machine produced no output, but is waiting for additional input. |
OUTPUT_CMD_CHAR | A character was received; c_outChar contains the character. |
OUTPUT_CMD_CMD | A command was received; c_outChar contains the command. |
OUTPUT_CMD_REPEATED_CMD | A repeated command was received; c_outChar contains the command. |
OUTPUT_CMD_REPEATED_WAIT | The machine received a CMD_TOKEN CMD_TOKEN CMD_TOKEN, so report a repeated command and wait for the next character to finish decoding. |
Definition at line 247 of file dataXferImpl.h.
enum CMD_STATE |
State of the command-finding state machine. See stepCommandFindMachine for more information.
Definition at line 236 of file dataXferImpl.h.
enum RECEIVE_ERROR |
Protocol errors produced by the receive state machine. Internal errors (invalid state transitions, etc.) are detected via ASSERTs.
Enumerator | |
---|---|
ERR_NONE | No error; all state machine outputs are valid when the state is STATE_RECV_START after execution of stepReceiveMachine. |
ERR_REPEATED_CMD | A repeated command (the sequence CMD_TOKEN CMD_TOKEN c, where c != ESCAPED_CMD), was received. |
ERR_TIMEOUT | A timeout occurred in the middle of receiving a command. |
ERR_INTERRUPTED_CMD | A command occurred in the middle of receiving data belonging to an earlier command. |
ERR_UNSPECIFIED_INDEX | Data was sent to a variable that has not been specified: the pointer to its data is NULL. |
ERR_INDEX_TOO_HIGH | Data was sent to a variable which exceeds the NUM_XFER_VARS. |
ERR_VAR_SIZE_MISMATCH | The size of data sent to a variable does not match the size specified earlier. |
ERR_READ_ONLY_VAR | The destination variable is read-only. |
ERR_MICROCONTROLLER_VAR_SPEC | The microcontroller is sent a variable specification. |
Definition at line 381 of file dataXferImpl.h.
enum RECEIVE_STATE |
States of the receive state machine. See stepReceiveMachine for more information.
Enumerator | |
---|---|
STATE_RECV_START | At the start of the machine. |
STATE_RECV_CMD_WAIT | Waiting for a command or escaped CMD_TOKEN. |
STATE_RECV_READ_BYTES | Reading data bytes in from a command. |
STATE_RECV_LONG_INDEX | Reading the variable index for a long var command. |
STATE_RECV_LONG_LENGTH | Reading the variable length for a long/specification command. |
STATE_RECV_SPEC_INDEX | Reading the variable index for a specification command. |
Definition at line 362 of file dataXferImpl.h.
Assign a bit in the au8_xferVarWriteable bit field.
u_index | The index of the variable to set. |
b_bitVal | Bit value to set at this index. |
Definition at line 267 of file dataXferImpl.c.
Referenced by specifyVar(), and stepReceiveMachine().
void clearReceiveMachineError | ( | ) |
Clear the current receive machine error status; the caller should therefore handle or report this error to a higher level of the program.
Definition at line 169 of file dataXferImpl.c.
void clearReceiveStruct | ( | ) |
Clear the received data structure, so that no variables are specified.
Definition at line 188 of file dataXferImpl.c.
Referenced by initDataXfer().
RECEIVE_ERROR getReceiveMachineError | ( | ) |
Return the error last encountered by the receive state machine. See stepReceiveMachine for more information. This also clears the error status.
Definition at line 146 of file dataXferImpl.c.
uint getReceiveMachineIndex | ( | ) |
Return the index output by the receive state machine. See stepReceiveMachine for more information.
Definition at line 141 of file dataXferImpl.c.
BOOL getReceiveMachineIsSpec | ( | ) |
Determine if the last data found by the receive state machine was a specification; if not, it was data. See stepReceiveMachine for more information. PC only.
Definition at line 154 of file dataXferImpl.c.
char getReceiveMachineOutChar | ( | ) |
Return the character output by the receive state machine. See stepReceiveMachine for more information.
Definition at line 137 of file dataXferImpl.c.
RECEIVE_STATE getReceiveMachineState | ( | ) |
Return the current receive machine state. See stepReceiveMachine for more information.
Definition at line 133 of file dataXferImpl.c.
uint getVarIndex | ( | char | c_cmd | ) |
Return the index of a variable in a command byte.
c_cmd | Command byte. |
Definition at line 220 of file dataXferImpl.c.
Referenced by stepReceiveMachine().
uint getVarLength | ( | char | c_cmd | ) |
Return the number of bytes of a variable in a command byte.
c_cmd | Command byte. |
Definition at line 224 of file dataXferImpl.c.
Referenced by stepReceiveMachine().
BOOL isReceiveMachineChar | ( | ) |
Determines if the receive state machine just received a character.
Definition at line 200 of file dataXferImpl.c.
BOOL isReceiveMachineData | ( | ) |
Determines if the receive state machine just received some data.
Definition at line 206 of file dataXferImpl.c.
BOOL isReceiveMachineSpec | ( | ) |
Determines if the receive state machine just received an updated specification. PC only.
Definition at line 213 of file dataXferImpl.c.
Read a bit in the au8_xferVarWriteable bit field.
u_index | The index of the variable to set. |
Definition at line 279 of file dataXferImpl.c.
Referenced by sendVar(), and validateIndex().
RECEIVE_ERROR notifyOfTimeout | ( | ) |
Notify the state machine that a timeout occurred between receiving the previous and next character. A timeout may not lead to an error; for example, between two received data packets or two received characters, timeout are allowed.
Definition at line 361 of file dataXferImpl.c.
void resetCommandFindMachine | ( | ) |
Resets the command-finding state machine; see stepCommandFindMachine for more information.
Definition at line 17 of file dataXferImpl.c.
Referenced by resetReceiveMachine().
void resetReceiveMachine | ( | ) |
Reset the receive state machine to its initial state and clear the error status. The outputs are not reset, because they will not be valid until after an invocation of the state machine.
Definition at line 160 of file dataXferImpl.c.
Referenced by initDataXfer(), and notifyOfTimeout().
CMD_OUTPUT stepCommandFindMachine | ( | char | c_inChar, |
char * | c_outChar | ||
) |
The command-finding state machine looks for commands in the data passed to it. Sequences it recognizes:
case START : if (c == CMD_TOKEN) state = WAIT1 else output c as a character case WAIT1 : if (c == CMD_TOKEN) state = WAIT2 if (c == ESCAPED_CMD) state = START, output CMD_TOKEN as a character else output c as a command case WAIT2 : if (c == ESCAPED_CMD) state = START, output command CMD_TOKEN if (c == CMD_TOKEN) output repeated command, remain in this state else output repeated command c
c_inChar | A character input to the machine. |
c_outChar | The character/command output by the machine when the returned state is not CMD_WAIT. |
Definition at line 22 of file dataXferImpl.c.
Referenced by stepReceiveMachine().
RECEIVE_ERROR stepReceiveMachine | ( | char | c_inChar | ) |
This state machine receives data from the microcontroller. It takes a character received plus an indication if a timeout occurred since the last invocation of this function and advances the machine. The machine produces outputs when the returned state is STATE_RECV_START. Outputs:
c_inChar | A character for the state machine to process. |
Definition at line 374 of file dataXferImpl.c.
uint8_t au8_xferVarWriteable[NUM_XFER_VARS/8+((NUM_XFER_VARS % 8) > 0)] |
An array of isWriteable bits for each var. Each bit is true if the PC is allowed to change this variable; false otherwise. This does NOT restrict the microcontroller to read-only access to this variable.
Definition at line 101 of file dataXferImpl.c.
Referenced by assignBit(), clearReceiveStruct(), and isVarWriteable().