/**************************************************************************** * apps/logging/nxscope/nxscope_pser.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. The * ASF licenses this file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. * ****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include #include #include #include #include #include #include #include /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ #define NXSCOPE_HDR_LEN (sizeof(struct nxscope_hdr_s)) #define NXSCOPE_DATA_START (NXSCOPE_HDR_LEN) #define NXSCOPE_BASEFRAME_LEN (NXSCOPE_HDR_LEN + NXSCOPE_CRC_LEN) #define NXSCOPE_HDR_SOF (0x55) #define NXSCOPE_CRC_LEN (sizeof(uint16_t)) /**************************************************************************** * Private Type Definition ****************************************************************************/ /* Nxscope serial protocol frame: * +--------------------+------------+-------------+ * | HDR [4B] | frame data | footer [2B] | * +-----+---------+----+------------+-------------+ * | SOF | len [1] | id | frame data | crc16 [2] | * +-----+----+----+----+------------+------+------+ * | 0 | 1 | 2 | 3 | ... | n+1 | n+2 | * +-----+----+----+----+------------+------+------+ * * [1] - always little-endian * [2] - always big-endian */ /* Nxscope header */ begin_packed_struct struct nxscope_hdr_s { uint8_t sof; /* SOF */ uint16_t len; /* Frame length */ uint8_t id; /* Frame ID */ } end_packed_struct; /* Nxscope footer */ begin_packed_struct struct nxscope_footer_s { uint16_t crc16; /* check sum (see nxscope_frame_final()) */ } end_packed_struct; /**************************************************************************** * Private Function Protototypes ****************************************************************************/ static int nxscope_frame_get(FAR struct nxscope_proto_s *p, FAR uint8_t *buff, size_t len, FAR struct nxscope_frame_s *frame); static int nxscope_frame_final(FAR struct nxscope_proto_s *p, uint8_t id, FAR uint8_t *buff, FAR size_t *len); /**************************************************************************** * Public Data ****************************************************************************/ static struct nxscope_proto_ops_s g_nxscope_proto_ser_ops = { nxscope_frame_get, nxscope_frame_final, }; static struct nxscope_proto_s g_nxscope_proto_ser = { false, NULL, &g_nxscope_proto_ser_ops, (size_t)NXSCOPE_HDR_LEN, (size_t)NXSCOPE_CRC_LEN }; /**************************************************************************** * Private Functions ****************************************************************************/ /**************************************************************************** * Name: nxscope_hdr_fill ****************************************************************************/ static void nxscope_hdr_fill(FAR uint8_t *buff, uint8_t id, uint16_t len) { FAR struct nxscope_hdr_s *hdr = NULL; DEBUGASSERT(buff); hdr = (FAR struct nxscope_hdr_s *)buff; hdr->sof = NXSCOPE_HDR_SOF; /* Length always as little endian */ hdr->len = htole16(len); hdr->id = id; } /**************************************************************************** * Name: nxscope_frame_get ****************************************************************************/ static int nxscope_frame_get(FAR struct nxscope_proto_s *p, FAR uint8_t *buff, size_t len, FAR struct nxscope_frame_s *frame) { FAR struct nxscope_hdr_s *hdr = NULL; uint16_t crc = 0; int ret = OK; int i = 0; DEBUGASSERT(p); DEBUGASSERT(buff); DEBUGASSERT(frame); UNUSED(p); /* Find SOF */ for (i = 0; i < len - NXSCOPE_HDR_LEN; i++) { hdr = (FAR struct nxscope_hdr_s *)&buff[i]; /* Verify SOF */ if (hdr->sof == NXSCOPE_HDR_SOF) { break; } } if (hdr->sof != NXSCOPE_HDR_SOF) { ret = -EINVAL; goto errout; } /* Verify len - always little-endian */ hdr->len = htole16(hdr->len); if ((len - i) < hdr->len) { ret = -EINVAL; goto errout; } /* Verify crc16 for the whole frame */ crc = crc16(&buff[i], hdr->len); if (crc != 0) { _err("ERROR: invalid crc16 %d\n", crc); ret = -EINVAL; goto errout; } /* Return the frame data */ frame->id = hdr->id; frame->data = &buff[i + NXSCOPE_DATA_START]; frame->drop = hdr->len + i; frame->dlen = hdr->len - NXSCOPE_BASEFRAME_LEN; errout: return ret; } /**************************************************************************** * Name: nxscope_frame_final ****************************************************************************/ static int nxscope_frame_final(FAR struct nxscope_proto_s *p, uint8_t id, FAR uint8_t *buff, FAR size_t *len) { uint16_t crc = 0; int ret = OK; DEBUGASSERT(p); DEBUGASSERT(buff); DEBUGASSERT(len); if (*len <= NXSCOPE_HDR_LEN) { /* No data */ ret = -ENODATA; goto errout; } /* Fill hdr */ nxscope_hdr_fill(buff, id, *len + NXSCOPE_CRC_LEN); /* Add crc16 - always as big-endian. * * crc16 xmodem: * polynominal = 0x1021 * initial value = 0x0000 * final xor value = 0x0000 */ crc = crc16(buff, *len); #ifdef CONFIG_ENDIAN_BIG buff[(*len)++] = (crc >> 0) & 0xff; buff[(*len)++] = (crc >> 8) & 0xff; #else buff[(*len)++] = (crc >> 8) & 0xff; buff[(*len)++] = (crc >> 0) & 0xff; #endif errout: return ret; } /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** * Name: nxscope_proto_ser_init ****************************************************************************/ int nxscope_proto_ser_init(FAR struct nxscope_proto_s *proto, FAR void *cfg) { DEBUGASSERT(proto); /* cfg argument not used, but keept here for compatibility with * future protocol implementations. */ UNUSED(cfg); /* Just copy protocol data */ memcpy(proto, &g_nxscope_proto_ser, sizeof(struct nxscope_proto_s)); /* Initialized */ proto->initialized = true; return OK; } /**************************************************************************** * Name: nxscope_proto_ser_deinit ****************************************************************************/ void nxscope_proto_ser_deinit(FAR struct nxscope_proto_s *proto) { DEBUGASSERT(proto); /* Nothings here */ UNUSED(proto); }