Ash
Description
See ash-protocol.h for source code.
Use the Asynchronous Serial Host (ASH) Framework interfaces on a host microcontroller when it communicates with an Ember chip via EZSP-UART.
See ash-common.h for source code.
Functions |
|
uint8_t | ashEncodeByte (uint8_t len, uint8_t byte, uint8_t *offset) |
Builds an ASH frame.
|
|
EzspStatus | ashDecodeByte (uint8_t byte, uint8_t *out, uint8_t *outLen) |
Decodes and validates an ASH frame.
|
|
uint8_t | ashRandomizeArray (uint8_t seed, uint8_t *buf, uint8_t len) |
Randomizes array contents by XORing with an 8-bit pseudo random sequence.
|
|
void | ashStartAckTimer (void) |
Sets ashAckTimer to the specified period and starts it running.
|
|
bool | ashAckTimerHasExpired (void) |
Indicates whether or not ashAckTimer has expired.
|
|
void | ashAdjustAckPeriod (bool expired) |
Adapts the acknowledgement timer period to the observed ACK delay.
|
|
void | ashStartNrTimer (void) |
Starts the Not Ready timer.
|
|
bool | ashNrTimerHasExpired (void) |
Tests whether the Not Ready timer has expired or has stopped.
|
|
Macros |
|
#define | ashStopAckTimer (void) do { ashAckTimer = 0; } while (false) |
Stops and clears ashAckTimer.
|
|
#define | ASH_VERSION 2 |
#define | ASH_FLAG 0x7E |
frame delimiter
|
|
#define | ASH_ESC 0x7D |
byte stuffing escape byte
|
|
#define | ASH_XON 0x11 |
flow control byte - means resume transmission
|
|
#define | ASH_XOFF 0x13 |
flow control byte - means suspend transmission
|
|
#define | ASH_SUB 0x18 |
replaces bytes w framing, overrun or overflow errors
|
|
#define | ASH_CAN 0x1A |
frame cancel byte
|
|
#define | ASH_WAKE 0xFF |
wake signal byte (also means NCP data pending)
|
|
#define | ASH_FLIP 0x20 |
XOR mask used in byte stuffing.
|
|
#define | ASH_MIN_DATA_FIELD_LEN EZSP_MIN_FRAME_LENGTH |
#define | ASH_MAX_DATA_FIELD_LEN EZSP_MAX_FRAME_LENGTH |
#define | ASH_MIN_DATA_FRAME_LEN (ASH_MIN_DATA_FIELD_LEN + 1) |
#define | ASH_MIN_FRAME_LEN 1 |
#define | ASH_MAX_FRAME_LEN (ASH_MAX_DATA_FIELD_LEN + 1) |
#define | ASH_CRC_LEN 2 |
#define | ASH_MIN_FRAME_WITH_CRC_LEN (ASH_MIN_FRAME_LEN + ASH_CRC_LEN) |
#define | ASH_MAX_FRAME_WITH_CRC_LEN (ASH_MAX_FRAME_LEN + ASH_CRC_LEN) |
#define | ASH_NCP_SHFRAME_RX_LEN 2 |
longest non-data frame received
|
|
#define | ASH_NCP_SHFRAME_TX_LEN 3 |
longest non-data frame sent
|
|
#define | ASH_HOST_SHFRAME_RX_LEN 3 |
longest non-data frame received
|
|
#define | ASH_HOST_SHFRAME_TX_LEN 2 |
longest non-data frame sent
|
|
#define | ASH_DFRAME_MASK 0x80 |
#define | ASH_CONTROL_DATA 0x00 |
#define | ASH_SHFRAME_MASK 0xE0 |
#define | ASH_CONTROL_ACK 0x80 |
#define | ASH_CONTROL_NAK 0xA0 |
#define | ASH_CONTROL_RST 0xC0 |
#define | ASH_CONTROL_RSTACK 0xC1 |
#define | ASH_CONTROL_ERROR 0xC2 |
#define | ASH_ACKNUM_MASK 0x07 |
acknowledge frame number
|
|
#define | ASH_ACKNUM_BIT 0 |
#define | ASH_RFLAG_MASK 0x08 |
retransmitted frame flag
|
|
#define | ASH_RFLAG_BIT 3 |
#define | ASH_NFLAG_MASK 0x08 |
receiver not ready flag
|
|
#define | ASH_NFLAG_BIT 3 |
#define | ASH_PFLAG_MASK 0x10 |
flag reserved for future use
|
|
#define | ASH_PFLAG_BIT 4 |
#define | ASH_FRMNUM_MASK 0x70 |
DATA frame number.
|
|
#define | ASH_FRMNUM_BIT 4 |
#define | ASH_GET_RFLAG (ctl) ((ctl & ASH_RFLAG_MASK ) >> ASH_RFLAG_BIT) |
#define | ASH_GET_NFLAG (ctl) ((ctl & ASH_NFLAG_MASK ) >> ASH_NFLAG_BIT) |
#define | ASH_GET_FRMNUM (ctl) ((ctl & ASH_FRMNUM_MASK ) >> ASH_FRMNUM_BIT) |
#define | ASH_GET_ACKNUM (ctl) ((ctl & ASH_ACKNUM_MASK ) >> ASH_ACKNUM_BIT) |
#define | ASH_FRAME_LEN_DATA_MIN (ASH_MIN_DATA_FIELD_LEN + 1) |
#define | ASH_FRAME_LEN_ACK 1 |
#define | ASH_FRAME_LEN_NAK 1 |
#define | ASH_FRAME_LEN_RST 1 |
#define | ASH_FRAME_LEN_RSTACK 3 |
#define | ASH_FRAME_LEN_ERROR 3 |
#define | MOD8 (n) ((n) & 7) |
mask to frame number modulus
|
|
#define | INC8 (n) (n = ( MOD8 (n + 1))) |
increment in frame number modulus
|
|
#define | WITHIN_RANGE (lo, n, hi) ( MOD8 (n - lo) <= MOD8 (hi - lo)) |
#define | ashAckTimerIsRunning () (ashAckTimer != 0) |
Indicates whether or not ashAckTimer is currently running.
|
|
#define | ashAckTimerIsNotRunning () (ashAckTimer == 0) |
Indicates whether or not ashAckTimer is currently running.
|
|
#define | ashSetAckPeriod (msec) do { ashAckPeriod = msec; ashAckTimer = 0; } while (false) |
Sets the acknowledgement timer period (in msec) and stops the timer.
|
|
#define | ashGetAckPeriod () (ashAckPeriod) |
Returns the acknowledgement timer period (in msec).
|
|
#define | ashSetAndStartAckTimer (msec) do { ashSetAckPeriod (msec); ashStartAckTimer (); } while (false) |
Sets the acknowledgement timer period (in msec), and starts the timer running.
|
|
#define | ASH_NR_TIMER_BIT 4 |
#define | ashStopNrTimer () do { ashNrTimer = 0; } while (false) |
Stops the Not Ready timer.
|
|
#define | ashNrTimerIsNotRunning () (ashAckTimer == 0) |
Indicates whether or not ashNrTimer is currently running.
|
|
Variables |
|
bool | ashDecodeInProgress |
uint16_t | ashAckTimer |
uint16_t | ashAckPeriod |
uint8_t | ashNrTimer |
Function Documentation
◆ ashEncodeByte()
uint8_t ashEncodeByte | ( | uint8_t |
len,
|
uint8_t |
byte,
|
||
uint8_t * |
offset
|
||
) |
Builds an ASH frame.
Byte stuffs the control and data fields as required, computes and appends the CRC and adds the ending flag byte. Called with the next byte to encode, this function may return several output bytes before it's ready for the next byte.
- Parameters
-
len
new frame flag / length of the frame to be encoded. A non-zero value begins a new frame, so all subsequent calls must use zero. The length includes control byte and data field, but not the flag or crc. This function does not validate the length. byte
the next byte of data to add to the frame. Note that in general the same byte of data may have to be passed more than once as escape bytes, the CRC and the end flag byte are output. offset
pointer to the offset of the next input byte. (If the frame data is the array data[], the next byte would be data[offset].) Is set to 0 when starting a new frame (ie, len is non-zero). Is set to 0xFF when the last byte of the frame is returned.
- Returns
- next encoded output byte in frame.
◆ ashDecodeByte()
EzspStatus ashDecodeByte | ( | uint8_t |
byte,
|
uint8_t * |
out,
|
||
uint8_t * |
outLen
|
||
) |
Decodes and validates an ASH frame.
Data is passed to it one byte at a time. Decodes byte stuffing, checks crc, finds the end flag and (if enabled) terminates the frame early on CAN or SUB bytes. The number of bytes output will not exceed the max valid frame length, which does not include the flag or the crc.
- Parameters
-
byte
the next byte of data to add to the frame out
pointer to where to write an output byte outLen
number of bytes output so far
- Returns
-
status of frame decoding
- ::EZSP_SUCCESS
- ::EZSP_ASH_IN_PROGRESS
- ::EZSP_ASH_CANCELLED
- ::EZSP_ASH_BAD_CRC
- ::EZSP_ASH_COMM_ERROR
- ::EZSP_ASH_TOO_SHORT
- ::EZSP_ASH_TOO_LONG
◆ ashRandomizeArray()
uint8_t ashRandomizeArray | ( | uint8_t |
seed,
|
uint8_t * |
buf,
|
||
uint8_t |
len
|
||
) |
Randomizes array contents by XORing with an 8-bit pseudo random sequence.
This reduces the likelihood that byte-stuffing will greatly increase the size of the payload. (This could happen if a DATA frame contained repeated instances of the same reserved byte value.)
- Parameters
-
seed
zero initializes the random sequence a non-zero value continues from a previous invocation buf
pointer to the array whose contents will be randomized len
number of bytes in the array to modify
- Returns
- last value of the sequence. If a buffer is processed in two or more chunks, as with linked buffers, this value should be passed back as the value of the seed argument
◆ ashStartAckTimer()
void ashStartAckTimer | ( | void |
|
) |
Sets ashAckTimer to the specified period and starts it running.
◆ ashAckTimerHasExpired()
bool ashAckTimerHasExpired | ( | void |
|
) |
Indicates whether or not ashAckTimer has expired.
If the timer is stopped then it is not expired.
◆ ashAdjustAckPeriod()
void ashAdjustAckPeriod | ( | bool |
expired
|
) |
Adapts the acknowledgement timer period to the observed ACK delay.
If the timer is not running, it does nothing. If the timer has expired, the timeourt period is doubled. If the timer has not expired, the elapsed time is fed into simple IIR filter: T[n+1] = (7*T[n] + elapsedTime) / 8 The timeout period, ashAckPeriod, is limited such that: ASH_xxx_TIME_DATA_MIN <= ashAckPeriod <= ASH_xxx_TIME_DATA_MAX, where xxx is either HOST or NCP.
The acknowledgement timer is always stopped by this function.
- Parameters
-
expired
true if timer has expired
◆ ashStartNrTimer()
void ashStartNrTimer | ( | void |
|
) |
Starts the Not Ready timer.
On the host, this times nFlag refreshing when the host doesn't have room for callbacks for a prolonged period.
On the NCP, if this times out the NCP resumes sending callbacks.
◆ ashNrTimerHasExpired()
bool ashNrTimerHasExpired | ( | void |
|
) |
Tests whether the Not Ready timer has expired or has stopped.
If expired, it is stopped.
- Returns
- true if the Not Ready timer has expired or stopped
Macro Definition Documentation
◆ ashStopAckTimer
void ashStopAckTimer | ( |
|
) | do { ashAckTimer = 0; } while (false) |
Stops and clears ashAckTimer.
◆ ASH_FLAG
#define ASH_FLAG 0x7E |
frame delimiter
◆ ASH_ESC
#define ASH_ESC 0x7D |
byte stuffing escape byte
◆ ASH_XON
#define ASH_XON 0x11 |
flow control byte - means resume transmission
◆ ASH_XOFF
#define ASH_XOFF 0x13 |
flow control byte - means suspend transmission
◆ ASH_SUB
#define ASH_SUB 0x18 |
replaces bytes w framing, overrun or overflow errors
◆ ASH_CAN
#define ASH_CAN 0x1A |
frame cancel byte
◆ ASH_WAKE
#define ASH_WAKE 0xFF |
wake signal byte (also means NCP data pending)
◆ ASH_FLIP
#define ASH_FLIP 0x20 |
XOR mask used in byte stuffing.
◆ ASH_NCP_SHFRAME_RX_LEN
#define ASH_NCP_SHFRAME_RX_LEN 2 |
longest non-data frame received
◆ ASH_NCP_SHFRAME_TX_LEN
#define ASH_NCP_SHFRAME_TX_LEN 3 |
longest non-data frame sent
◆ ASH_HOST_SHFRAME_RX_LEN
#define ASH_HOST_SHFRAME_RX_LEN 3 |
longest non-data frame received
◆ ASH_HOST_SHFRAME_TX_LEN
#define ASH_HOST_SHFRAME_TX_LEN 2 |
longest non-data frame sent
◆ ASH_ACKNUM_MASK
#define ASH_ACKNUM_MASK 0x07 |
acknowledge frame number
◆ ASH_RFLAG_MASK
#define ASH_RFLAG_MASK 0x08 |
retransmitted frame flag
◆ ASH_NFLAG_MASK
#define ASH_NFLAG_MASK 0x08 |
receiver not ready flag
◆ ASH_PFLAG_MASK
#define ASH_PFLAG_MASK 0x10 |
flag reserved for future use
◆ ASH_FRMNUM_MASK
#define ASH_FRMNUM_MASK 0x70 |
DATA frame number.
◆ MOD8
#define MOD8 | ( |
n
|
) | ((n) & 7) |
mask to frame number modulus
◆ INC8
#define INC8 | ( |
n
|
) | (n = ( MOD8 (n + 1))) |
increment in frame number modulus
◆ ashAckTimerIsRunning
#define ashAckTimerIsRunning | ( |
|
) | (ashAckTimer != 0) |
Indicates whether or not ashAckTimer is currently running.
The timer may be running even if expired.
◆ ashAckTimerIsNotRunning
#define ashAckTimerIsNotRunning | ( |
|
) | (ashAckTimer == 0) |
Indicates whether or not ashAckTimer is currently running.
The timer may be running even if expired.
◆ ashSetAckPeriod
#define ashSetAckPeriod | ( |
msec
|
) | do { ashAckPeriod = msec; ashAckTimer = 0; } while (false) |
Sets the acknowledgement timer period (in msec) and stops the timer.
◆ ashGetAckPeriod
#define ashGetAckPeriod | ( |
|
) | (ashAckPeriod) |
Returns the acknowledgement timer period (in msec).
◆ ashSetAndStartAckTimer
#define ashSetAndStartAckTimer | ( |
msec
|
) | do { ashSetAckPeriod (msec); ashStartAckTimer (); } while (false) |
Sets the acknowledgement timer period (in msec), and starts the timer running.
◆ ashStopNrTimer
#define ashStopNrTimer | ( |
|
) | do { ashNrTimer = 0; } while (false) |
Stops the Not Ready timer.
◆ ashNrTimerIsNotRunning
#define ashNrTimerIsNotRunning | ( |
|
) | (ashAckTimer == 0) |
Indicates whether or not ashNrTimer is currently running.