|
PIC24 Support Libraries
|
Routines which implement the uC comm protocol. More...
#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 \ref dataXfer "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 !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 361 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 216 of file dataXferImpl.h.
Referenced by sendLongData(), sendLongToHighIndex(), sendLongToUnspecifiedIndex(), sendLongWithWrongSize(), sendVar(), stepReceiveMachine(), and testSend256ByteVar().
| #define CMD_SEND_ONLY ((char) 0xFE) |
After a command token, this value specifies that the command is a send-only var.
Definition at line 220 of file dataXferImpl.h.
Referenced by specifyVar(), stepReceiveMachine(), testSpecifyLongDesc(), testSpecifyLongFormat(), and testSpecifyLongName().
| #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 224 of file dataXferImpl.h.
Referenced by specifyVar(), stepReceiveMachine(), and testSpecifyMinimalVar().
| #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 208 of file dataXferImpl.h.
Referenced by findCommand(), findEscapedCommand(), findEscapedCommandChar(), findRepeatedCommand(), findRepeatedWait(), outCharXfer(), sendCommandCmdToken(), sendEscapedCommand(), sendFourBytesCmdTokenData(), sendFourBytesData(), sendInterruptedCommand(), sendLongData(), sendLongToHighIndex(), sendLongToUnspecifiedIndex(), sendLongWithWrongSize(), sendOneByteData(), sendRepeatedCommand(), sendRepeatedCommandCmdToken(), sendToHighIndex(), sendToUnspecifiedIndex(), sendVar(), sendVarSpecAndData(), sendWithTimeout(), sendWithWrongSize(), specifyVar(), stepCommandFindMachine(), stepReceiveMachine(), testSend256ByteVar(), testSendFourByteVar(), testSendOneByteVar(), testSendOneEscapedByteVar(), testSpecifyLongDesc(), testSpecifyLongFormat(), testSpecifyLongName(), and testSpecifyMinimalVar().
| #define ESCAPED_CMD ((char) 0xFC) |
After a command token, this value specifies that the character CMD_TOKEN was sent.
Definition at line 212 of file dataXferImpl.h.
Referenced by findChar(), findCommand(), findEscapedCommand(), findEscapedCommandChar(), outCharXfer(), sendCommandCmdToken(), sendEscapedCommand(), sendFourBytesCmdTokenData(), sendLongData(), sendRepeatedCommandCmdToken(), stepCommandFindMachine(), stepReceiveMachine(), testSend256ByteVar(), and testSendOneEscapedByteVar().
| #define NUM_XFER_VARS 62 |
Number of transfer variables supported. Must be less than the MAX_NUM_XFER_VARS.
Definition at line 338 of file dataXferImpl.h.
Referenced by formatVar(), sendLongToHighIndex(), sendToHighIndex(), sendVar(), setupXferData(), specifyVar(), testFormatIndexTooHigh(), testSendIndexTooHigh(), testSpecifyIndexTooHigh(), 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 235 of file dataXferImpl.h.
Referenced by sendVar().
| #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 228 of file dataXferImpl.h.
Referenced by getVarIndex(), and sendVar().
| 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 250 of file dataXferImpl.h.
| enum CMD_STATE |
State of the command-finding state machine. See stepCommandFindMachine for more information.
Definition at line 239 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_PIC_VAR_SPEC |
The PIC is sent a variable specification. |
Definition at line 384 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 365 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 246 of file dataXferImpl.c.
Referenced by setupXferData(), specifyVar(), stepReceiveMachine(), and testSendToReadOnly().
| 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.
Referenced by sendInterruptedCommand().
| void clearReceiveStruct | ( | ) |
Clear the received data structure, so that no variables are specified.
Definition at line 174 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.
Referenced by sendRepeatedCommand(), and sendRepeatedCommandCmdToken().
| uint getReceiveMachineIndex | ( | ) |
Return the index output by the receive state machine. See stepReceiveMachine for more information.
Definition at line 141 of file dataXferImpl.c.
Referenced by sendCommandCmdToken(), sendFourBytesCmdTokenData(), sendFourBytesData(), sendInterruptedCommand(), sendOneByteData(), sendRepeatedCommand(), sendRepeatedCommandCmdToken(), and sendVarSpecAndData().
| 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.
Referenced by sendEscapedCommand(), and sendOneNormalChar().
| RECEIVE_STATE getReceiveMachineState | ( | ) |
Return the current receive machine state. See stepReceiveMachine for more information.
Definition at line 133 of file dataXferImpl.c.
Referenced by sendData().
| uint getVarIndex | ( | char | c_cmd) |
Return the index of a variable in a command byte.
| c_cmd | Command byte. |
Definition at line 199 of file dataXferImpl.c.
Referenced by sendCommandCmdToken(), sendRepeatedCommandCmdToken(), and 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 203 of file dataXferImpl.c.
Referenced by sendCommandCmdToken(), sendRepeatedCommandCmdToken(), and stepReceiveMachine().
| BOOL isReceiveMachineChar | ( | ) |
Determines if the receive state machine just received a character.
Definition at line 179 of file dataXferImpl.c.
Referenced by sendEscapedCommand(), and sendOneNormalChar().
| BOOL isReceiveMachineData | ( | ) |
Determines if the receive state machine just received some data.
Definition at line 185 of file dataXferImpl.c.
Referenced by sendCommandCmdToken(), sendFourBytesCmdTokenData(), sendFourBytesData(), sendInterruptedCommand(), sendOneByteData(), sendRepeatedCommand(), sendRepeatedCommandCmdToken(), and sendVarSpecAndData().
| BOOL isReceiveMachineSpec | ( | ) |
Determines if the receive state machine just received an updated specification. PC only.
Definition at line 192 of file dataXferImpl.c.
Referenced by resendVarSpec(), sendEmptyVarSpec(), sendFormatOnlyVarSpec(), sendNameOnlyVarSpec(), sendVarSpec(), and sendWriteableVarSpec().
Read a bit in the au8_xferVarWriteable bit field.
| u_index | The index of the variable to set. |
Definition at line 258 of file dataXferImpl.c.
Referenced by resendVarSpec(), sendEmptyVarSpec(), sendFormatOnlyVarSpec(), sendNameOnlyVarSpec(), sendVar(), sendVarSpec(), sendWriteableVarSpec(), testSpecifyLongDesc(), testSpecifyLongFormat(), testSpecifyLongName(), testSpecifyMinimalVar(), 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 345 of file dataXferImpl.c.
Referenced by sendWithTimeout().
| 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(), notifyOfTimeout(), and sendWithTimeout().
| 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 findChar(), findCommand(), findEscapedCommand(), findEscapedCommandChar(), findRepeatedCommand(), findRepeatedWait(), and stepReceiveMachine().
| RECEIVE_ERROR stepReceiveMachine | ( | char | c_inChar) |
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. |
Definition at line 358 of file dataXferImpl.c.
Referenced by sendData(), sendInterruptedCommand(), sendLongToHighIndex(), sendLongToUnspecifiedIndex(), sendLongWithWrongSize(), sendOneNormalChar(), sendRepeatedCommand(), sendRepeatedCommandCmdToken(), sendToHighIndex(), sendToUnspecifiedIndex(), sendWithTimeout(), and sendWithWrongSize().
| 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 PIC to read-only access to this variable.
Definition at line 101 of file dataXferImpl.c.
Referenced by assignBit(), clearReceiveStruct(), and isVarWriteable().
1.8.4