31 #define SRXL_MIN_FRAMESPACE_US 8000U 32 #define SRXL_MAX_CHANNELS 20U 35 #define STATE_IDLE 0x00U 36 #define STATE_NEW 0x01U 37 #define STATE_COLLECT 0x02U 42 #define SRXL_FRAMELEN_V1 27U 43 #define SRXL_FRAMELEN_V2 35U 44 #define SRXL_FRAMELEN_V5 18U 45 #define SRXL_FRAMELEN_MAX 35U 48 #define SRXL_HEADER_V1 0xA1U 49 #define SRXL_HEADER_V2 0xA2U 50 #define SRXL_HEADER_V5 0xA5U 51 #define SRXL_HEADER_NOT_IMPL 0xFFU 86 static uint16_t
srxl_crc16 (uint16_t crc, uint8_t new_byte)
89 crc = crc ^ (uint16_t)new_byte << 8;
90 for(loop = 0; loop < 8; loop++) {
91 crc = (crc & 0x8000) ? (crc << 1) ^ 0x1021 : (crc << 1);
136 uint32_t channel_raw_value;
139 *failsafe_state = 0U;
142 for (loop=0U; loop < *num_values; loop++) {
143 channel_raw_value = ((((uint32_t)
buffer[loop*2U+1U])& 0x0000000FU) << 8U) | ((uint32_t)(
buffer[loop*2U+2U]));
144 channels[
loop] = (uint16_t)(((channel_raw_value * (uint32_t)1400U) >> 12U) + (uint32_t)800U);
148 if ( (uint16_t)*num_values > max_values) {
149 *num_values = (uint8_t)max_values;
151 memcpy(values,
channels, (*num_values)*2);
179 static int srxl_channels_get_v5(uint16_t max_values, uint8_t *num_values, uint16_t *values,
bool *failsafe_state)
184 for (uint8_t i=0; i<7; i++) {
186 uint16_t c = b >> 11;
187 int32_t
v = b & 0x7FF;
195 v = (b & 0x1FF) << 2;
196 c = 10 + ((b >> 9) & 0x7);
201 printf(
"b=0x%04x v=%u c=%u b[1]=0x%02x\n",
202 (
unsigned)b, (
unsigned)v, (
unsigned)c, (
unsigned)
buffer[1]);
214 v = (((v - 0x400) * 500) / 876) + 1500;
226 if (*num_values > max_values) {
227 *num_values = max_values;
229 memcpy(values,
channels, (*num_values)*2);
233 *failsafe_state = ((
buffer[1] & 2) == 0);
262 int srxl_decode(uint64_t timestamp_us, uint8_t
byte, uint8_t *num_values, uint16_t *values, uint16_t max_values,
bool *failsafe_state)
362 #ifdef TEST_MAIN_PROGRAM 366 #include <sys/types.h> 367 #include <sys/stat.h> 378 return 1.0e6*((ts.tv_sec + (ts.tv_nsec*1.0e-9)));
381 int main(
int argc,
const char *argv[])
383 int fd =
open(argv[1], O_RDONLY|O_CLOEXEC);
389 struct termios options;
391 tcgetattr(fd, &options);
393 cfsetispeed(&options, B115200);
394 cfsetospeed(&options, B115200);
396 options.c_cflag &= ~(PARENB|CSTOPB|CSIZE);
397 options.c_cflag |= CS8;
399 options.c_lflag &= ~(ICANON|ECHO|ECHOE|ISIG);
400 options.c_iflag &= ~(IXON|IXOFF|IXANY);
401 options.c_oflag &= ~OPOST;
403 if (tcsetattr(fd, TCSANOW, &options) != 0) {
407 tcflush(fd, TCIOFLUSH);
411 uint8_t num_values = 0;
424 if (select(fd+1, &fds,
NULL,
NULL, &tv) != 1) {
428 if (
read(fd, &b, 1) != 1) {
432 if (
srxl_decode(
micros64(), b, &num_values, values,
sizeof(values)/
sizeof(values[0]), &failsafe_state) == 0) {
434 printf(
"%u: ", num_values);
435 for (uint8_t i=0; i<num_values; i++) {
436 printf(
"%u:%4u ", i+1, values[i]);
438 printf(
"%s\n", failsafe_state?
"FAIL":
"OK");
446 #ifdef TEST_BIN_PROGRAM 450 #include <sys/types.h> 451 #include <sys/stat.h> 458 int main(
int argc,
const char *argv[])
460 FILE *
f =
fopen(argv[1],
"r");
469 uint8_t num_values = 0;
475 if (fread(&header, 1, 1, f) != 1) {
479 uint8_t frame_size = 0;
491 if (frame_size == 0) {
494 uint8_t u[frame_size];
496 if (fread(&u[1], 1,
sizeof(u)-1, f) !=
sizeof(u)-1) {
501 for (uint8_t i=0; i<
sizeof(u); i++) {
504 if (
srxl_decode(t, b, &num_values, values,
sizeof(values)/
sizeof(values[0]), &failsafe_state) == 0) {
505 printf(
"%u: ", num_values);
506 for (uint8_t i=0; i<num_values; i++) {
507 printf(
"%u:%4u ", i+1, values[i]);
509 printf(
"%s\n", failsafe_state?
"FAIL":
"OK");
int printf(const char *fmt,...)
void clock_gettime(uint32_t a1, void *a2)
int open(const char *pathname, int flags)
POSIX Open a file with integer mode flags.
static uint16_t max_channels
static uint8_t buffer[SRXL_FRAMELEN_MAX]
int srxl_decode(uint64_t timestamp_us, uint8_t byte, uint8_t *num_values, uint16_t *values, uint16_t max_values, bool *failsafe_state)
static uint16_t channels[SRXL_MAX_CHANNELS]
static uint8_t decode_state_next
static uint16_t srxl_crc16(uint16_t crc, uint8_t new_byte)
#define SRXL_FRAMELEN_MAX
void perror(const char *s)
POSIX perror() - convert POSIX errno to text with user message.
ssize_t read(int fd, void *buf, size_t count)
POSIX read count bytes from *buf to fileno fd.
static int srxl_channels_get_v5(uint16_t max_values, uint8_t *num_values, uint16_t *values, bool *failsafe_state)
static uint8_t frame_header
static int srxl_channels_get_v1v2(uint16_t max_values, uint8_t *num_values, uint16_t *values, bool *failsafe_state)
int main(int argc, char const **argv)
#define SRXL_HEADER_NOT_IMPL
static uint8_t decode_state
static uint64_t last_data_us
FILE * fopen(const char *path, const char *mode)
POSIX Open a file with path name and ascii file mode string.
static uint8_t frame_len_full
#define SRXL_MIN_FRAMESPACE_US
#define SRXL_MAX_CHANNELS
static uint16_t crc_receiver