#include <stdlib.h>
#include <assert.h>
Go to the source code of this file.
Classes | |
struct | XFER_VAR |
Defines | |
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 |
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 | au8_xferVarWriteable [NUM_XFER_VARS/8+((NUM_XFER_VARS%8) > 0)] |
Receive state machine | |
#define | CHAR_RECEIVED_INDEX 0xFF |
#define | NUM_ERROR_CODES (ERR_PIC_VAR_SPEC + 1) |
Number of error codes in the RECEIVE_ERROR enum. | |
enum | RECEIVE_STATE { STATE_RECV_START, STATE_RECV_CMD_WAIT, STATE_RECV_READ_BYTES, STATE_RECV_LONG_INDEX, STATE_RECV_LONG_LENGTH, STATE_RECV_SPEC_INDEX } |
enum | RECEIVE_ERROR { ERR_NONE = 0, ERR_REPEATED_CMD, ERR_TIMEOUT, ERR_INTERRUPTED_CMD, ERR_UNSPECIFIED_INDEX, ERR_INDEX_TOO_HIGH, ERR_VAR_SIZE_MISMATCH, ERR_READ_ONLY_VAR, ERR_PIC_VAR_SPEC } |
RECEIVE_STATE | getReceiveMachineState () |
char | getReceiveMachineOutChar () |
uint | getReceiveMachineIndex () |
RECEIVE_ERROR | getReceiveMachineError () |
BOOL | getReceiveMachineIsSpec () |
void | resetReceiveMachine () |
void | clearReceiveMachineError () |
void | clearReceiveStruct () |
BOOL | isReceiveMachineChar (char *c_receivedChar) |
BOOL | isReceiveMachineData (uint *u_receivedIndex) |
BOOL | isReceiveMachineSpec (uint *u_receivedIndex) |
uint | getVarIndex (char c_cmd) |
uint | getVarLength (char c_cmd) |
void | assignBit (uint u_index, BOOL b_bitVal) |
BOOL | isVarWriteable (uint u_index) |
RECEIVE_ERROR | stepReceiveMachine (char c_inChar, BOOL b_isTimeout) |
const char * | getReceiveErrorString () |
Returns an error string matching the last error code. |
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.
On receive: implement as a state machine (see sketch below).
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 !PIC 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
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 320 of file dataXferImpl.h.
#define CMD_LONG_VAR ((char) 0xFD) |
After a command token, this value specifies that the command is a long variable.
Definition at line 215 of file dataXferImpl.h.
#define CMD_SEND_ONLY ((char) 0xFE) |
After a command token, this value specifies that the command is a send-only var.
Definition at line 219 of file dataXferImpl.h.
#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 223 of file dataXferImpl.h.
#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 207 of file dataXferImpl.h.
#define ESCAPED_CMD ((char) 0xFC) |
After a command token, this value specifies that the character CMD_TOKEN was sent.
Definition at line 211 of file dataXferImpl.h.
#define NUM_XFER_VARS 62 |
Number of transfer variables supported. Must be less than the MAX_NUM_XFER_VARS.
Definition at line 297 of file dataXferImpl.h.
#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 234 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 227 of file dataXferImpl.h.
enum CMD_OUTPUT |
The output of the command-finding state machine. See stepCommandFindMachine for more information.
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 249 of file dataXferImpl.h.
enum CMD_STATE |
State of the command-finding state machine. See stepCommandFindMachine for more information.
Definition at line 238 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.
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_PIC_VAR_SPEC | The PIC is sent a variable specification. |
Definition at line 343 of file dataXferImpl.h.
enum RECEIVE_STATE |
States of the receive state machine. See stepReceiveMachine for more information.
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 324 of file dataXferImpl.h.
void assignBit | ( | uint | u_index, | |
BOOL | b_bitVal | |||
) |
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 356 of file dataXferImpl.c.
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 236 of file dataXferImpl.c.
void clearReceiveStruct | ( | ) |
Clear the received data structure, so that no variables are specified.
Definition at line 243 of file dataXferImpl.c.
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 202 of file dataXferImpl.c.
uint getReceiveMachineIndex | ( | ) |
Return the index output by the receive state machine. See stepReceiveMachine for more information.
Definition at line 193 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 214 of file dataXferImpl.c.
char getReceiveMachineOutChar | ( | ) |
Return the character last output by the receive state machine. See stepReceiveMachine for more information.
Definition at line 186 of file dataXferImpl.c.
RECEIVE_STATE getReceiveMachineState | ( | ) |
Return the current receive machine state. See stepReceiveMachine for more information.
Definition at line 179 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 299 of file dataXferImpl.c.
uint getVarLength | ( | char | c_cmd | ) |
Return the number of bytes of a variable in a command byte.
c_cmd | Command byte. |
Definition at line 308 of file dataXferImpl.c.
BOOL isReceiveMachineChar | ( | char * | c_receivedChar | ) |
Determines if the receive state machine just received a character; also returns that character.
c_receivedChar | The character received is placed here. If the return value if false, this variable is overwritten with an undefined value. |
Definition at line 255 of file dataXferImpl.c.
BOOL isReceiveMachineData | ( | uint * | u_receivedIndex | ) |
Determines if the receive state machine just received some data; also returns the index of the data.
u_receivedIndex | The index to the data received is placed here. If the return value if false, this variable is overwritten with an undefined value. |
Definition at line 270 of file dataXferImpl.c.
BOOL isReceiveMachineSpec | ( | uint * | u_receivedIndex | ) |
Determines if the receive state machine just received an updated specification; also returns the index of the updated spec. PC only.
u_receivedIndex | The index to the spec received is placed here. If the return value if false, this variable is overwritten with an undefined value. |
Definition at line 286 of file dataXferImpl.c.
BOOL isVarWriteable | ( | uint | u_index | ) |
Read a bit in the au8_xferVarWriteable bit field.
u_index | The index of the variable to set. |
Definition at line 375 of file dataXferImpl.c.
void resetCommandFindMachine | ( | ) |
Resets the command-finding state machine; see stepCommandFindMachine for more information.
Definition at line 19 of file dataXferImpl.c.
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 224 of file dataXferImpl.c.
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 62 of file dataXferImpl.c.
RECEIVE_ERROR stepReceiveMachine | ( | char | c_inChar, | |
BOOL | b_isTimeout | |||
) |
This state machine receives data from the PIC. 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. | |
b_isTimeout | True if a timeout occurred between reception of the previous character and this character. |
Definition at line 475 of file dataXferImpl.c.
uint8 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 PIC to read-only access to this variable.
Definition at line 143 of file dataXferImpl.c.