Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
MLX_BaseSPI.c
00001 // ***** *********************************************************************** 00002 /*! 00003 Module: Melexis Base SPI 00004 00005 Platform: Win32 - Win64 - embedded 00006 00007 \file MLX_BaseSPI.h 00008 00009 \brief Base control module the ASIC SPI, Melexis protocol. 00010 00011 \author Jean-F. Bernier 00012 00013 \since 2015-04-23 00014 */ 00015 // *************************************************************************** 00016 00017 //***************************************************************************** 00018 //*************** Header includes ********************************************* 00019 //***************************************************************************** 00020 //#include "Tools.h" 00021 #include <string.h> 00022 #include "MLX_BaseSPI.h" 00023 00024 00025 // Bit field widths in a packet 00026 #define WID_TYPE 4 /// Packet type 00027 #define WID_SIZE 8 /// Size 00028 #define WID_SEQ 4 /// Sequence number 00029 #define WID_DATA 16 /// Additional data 00030 #define WID_ADDR 16 /// Address 00031 #define WID_RES_DATA 32 /// Response data 00032 #define WID_ISERR 1 /// Is error or not 00033 #define WID_ERROR 15 /// Error qualifier 00034 00035 // Bit position offsets in a short packet 00036 #ifdef RIGHT_TO_LEFT 00037 #define OFF_TYPE (MLX_SHORT_SZ - WID_TYPE) 00038 #define OFF_SIZE (OFF_TYPE - WID_SIZE) 00039 #define OFF_SEQ (OFF_SIZE - WID_SEQ) 00040 #define OFF_ADDR (OFF_SEQ - WID_ADDR) 00041 #define OFF_DATA (OFF_ADDR - WID_DATA) 00042 #define OFF_RES_DATA (OFF_SEQ - WID_RES_DATA) 00043 #define OFF_ISERR (MLX_SHORT_SZ - 16 - WID_ISERR) 00044 #define OFF_ERROR (OFF_ISERR - WID_ERROR) 00045 00046 #define BIT_ORDER 0 00047 #else 00048 #define OFF_TYPE (WID_TYPE - 1) 00049 #define OFF_SIZE (OFF_TYPE + WID_SIZE) 00050 #define OFF_SEQ (OFF_SIZE + WID_SEQ) 00051 #define OFF_ADDR (OFF_SEQ + WID_ADDR) 00052 #define OFF_DATA (OFF_ADDR + WID_DATA) 00053 #define OFF_RES_DATA (OFF_SEQ + WID_RES_DATA) 00054 #define OFF_ISERR 16 00055 #define OFF_ERROR (OFF_ISERR+ WID_ERROR) 00056 00057 #define BIT_ORDER 1 00058 #endif 00059 00060 //***************************************************************************** 00061 //*************** Private Function Declarations ******************************* 00062 //***************************************************************************** 00063 static uint16 CRC16_Compute ( const uint8 *data, uint16 n); 00064 static BOOL CRC16_IsValid ( const uint8 *data, uint n, uint nbCrc); 00065 static void FillCRC_short ( PACK_SHORT *pack); 00066 static void FillCRC_long1 ( PACK_LONG1 *pack); 00067 static void FillCRC_long2 ( PACK_LONG2 *pack); 00068 00069 00070 static BOOL ValidCRC_short( const PACK_SHORT *pack); 00071 static BOOL ValidCRC_long1 ( const PACK_LONG1 *pack); 00072 static BOOL ValidCRC_long2 ( const PACK_LONG2 *pack); 00073 00074 00075 static int EncodeS ( PACK_SHORT *pack, const MLX_PackNfo *nfo); 00076 static int DecodeS ( const PACK_SHORT *pack, MLX_PackNfo *nfo); 00077 00078 static int EncodeL1(PACK_LONG1 *pack, const MLX_PackNfo *nfo); 00079 static int DecodeL1(const PACK_LONG1 *pack, MLX_PackNfo *nfo); 00080 00081 static int EncodeL2(PACK_LONG2 *pack, const MLX_PackNfo *nfo); 00082 static int DecodeL2(const PACK_LONG2 *pack, MLX_PackNfo *nfo); 00083 00084 //***************************************************************************** 00085 //*************** Function Definitions **************************************** 00086 //***************************************************************************** 00087 00088 // ******************************** 00089 // ***** MASTER SIDE FUNCTIONS **** 00090 // ******************************** 00091 00092 /// **************************************************************************** 00093 /// \fn MLX_ReqReadReg 00094 /// 00095 /// \brief Creates a read register request. 00096 /// 00097 /// \param[out] *pack: Packet to encode as a read register 00098 /// \param[in] reg: Register address to read 00099 /// 00100 /// \return Error code: 0 on success or negative on error. 00101 /// 00102 /// \authors Jean-Fran�ois Bernier 00103 /// \since 2015-04-01 00104 /// **************************************************************************** 00105 int MLX_ReqReadReg( PACK_SHORT *pack, uint16 reg) 00106 { 00107 int res; 00108 MLX_PackNfo nfo; 00109 00110 // Reset packet! 00111 memset( pack, 0, sizeof(*pack)); 00112 00113 nfo.pktype = PACK_RREG; 00114 nfo.size = 1; 00115 nfo.seq = 0; 00116 nfo.addr = reg; 00117 00118 res = EncodeS( pack, &nfo); 00119 if (res < 0) 00120 return -1; 00121 00122 return 0; 00123 } 00124 00125 00126 /// **************************************************************************** 00127 /// \fn MLX_ReqWriteReg 00128 /// 00129 /// \brief Creates a write register request. 00130 /// 00131 /// \param[out] *pack: Packet to encode as a write register 00132 /// \param[in] reg: Register address to write 00133 /// \param[in] val: Value to write 00134 /// 00135 /// \return Error code: 0 on success or negative on error. 00136 /// 00137 /// \authors Jean-Fran�ois Bernier 00138 /// \since 2015-04-07 00139 /// **************************************************************************** 00140 int MLX_ReqWriteReg( PACK_SHORT *pack, uint16 reg, uint16 val) 00141 { 00142 int res; 00143 MLX_PackNfo nfo; 00144 00145 // Reset packet! 00146 memset( pack, 0, sizeof(*pack)); 00147 00148 nfo.pktype = PACK_WREG; 00149 nfo.size = 1; 00150 nfo.seq = 0; 00151 nfo.addr = reg; 00152 nfo.data = val; 00153 00154 res = EncodeS( pack, &nfo); 00155 if (res < 0) 00156 return -1; 00157 00158 return 0; 00159 } 00160 00161 00162 /// **************************************************************************** 00163 /// \fn MLX_ReqReadTrc 00164 /// 00165 /// \brief Creates a read raw data request. 00166 /// 00167 /// \param[out] *pack: Packet to encode 00168 /// 00169 /// \return Error code: 0 on success or negative on error. 00170 /// 00171 /// \authors Jean-Fran�ois Bernier 00172 /// \since 2015-05-07 00173 /// **************************************************************************** 00174 int MLX_ReqReadTrc( PACK_SHORT *pack) 00175 { 00176 int res; 00177 MLX_PackNfo nfo; 00178 00179 nfo.pktype = PACK_RFIRM; 00180 nfo.size = 0; 00181 nfo.seq = 0; 00182 nfo.fwtype = FW_RAW; 00183 00184 res = EncodeS( pack, &nfo); 00185 if (res < 0) 00186 return -1; 00187 00188 return 0; 00189 } 00190 00191 00192 /// **************************************************************************** 00193 /// \fn MLX_ReqReadEch 00194 /// 00195 /// \brief Creates a read echoes request. 00196 /// 00197 /// \param[out] *pack: Packet to encode 00198 /// 00199 /// \return Error code: 0 on success or negative on error. 00200 /// 00201 /// \authors Jean-Fran�ois Bernier 00202 /// \since 2015-05-28 00203 /// **************************************************************************** 00204 int MLX_ReqReadEch( PACK_SHORT *pack) 00205 { 00206 int res; 00207 MLX_PackNfo nfo; 00208 00209 nfo.pktype = PACK_RFIRM; 00210 nfo.size = 0; 00211 nfo.seq = 0; 00212 nfo.fwtype = FW_PROCESSED; 00213 00214 res = EncodeS( pack, &nfo); 00215 if (res < 0) 00216 return -1; 00217 00218 return 0; 00219 } 00220 00221 00222 /// **************************************************************************** 00223 /// \fn MLX_ReqWriteFW 00224 /// 00225 /// \brief Creates a write firmware request. 00226 /// 00227 /// \param[out] *pack: Packet to encode 00228 /// \param[in] type: Firmware type to write 00229 /// \param[in] size: Words (2 bytes) to write. 0 means 256. If more than 1, the 00230 /// data will be located in following long packets. The size field 00231 /// of these long packets will be the size for this long pack only. 00232 /// \param[in] data: Data to be written, used only if size == 1 00233 /// 00234 /// \return Error code: 0 on success or negative on error. 00235 /// 00236 /// \authors Jean-Fran�ois Bernier 00237 /// \since 2015-05-07 00238 /// **************************************************************************** 00239 int MLX_ReqWriteFW( PACK_SHORT *pack, uint size, uint16 data) 00240 { 00241 int res; 00242 MLX_PackNfo nfo; 00243 00244 nfo.pktype = PACK_WFIRM; 00245 nfo.fwtype = FW_PATCH; 00246 nfo.size = size; 00247 nfo.seq = 0; 00248 nfo.data = data; 00249 00250 res = EncodeS( pack, &nfo); 00251 if (res < 0) 00252 return -1; 00253 00254 return 0; 00255 } 00256 00257 00258 /// **************************************************************************** 00259 /// \fn MLX_WriteDataL 00260 /// 00261 /// \brief Creates a long write packet. 00262 /// 00263 /// \param[out] *pack: Packet to encode 00264 /// \param[in] size: Words (2 bytes) to take from data. Max = MLX_LONG_DATA_SZ 00265 /// \param[in] seq: Serial sequence number stamping the packets 00266 /// \param[in] data: Data to be written 00267 /// 00268 /// \return Error code: 0 on success or negative on error. 00269 /// 00270 /// \authors Jean-Fran�ois Bernier 00271 /// \since 2015-05-07 00272 /// **************************************************************************** 00273 int MLX_WriteDataL2( PACK_LONG2 *pack, uint size, uint seq, const uint8 *data) 00274 { 00275 int res; 00276 MLX_PackNfo nfo; 00277 00278 if (size > MLX_LONG2_DATA_SZ) 00279 return -1; 00280 00281 nfo.pktype = PACK_WDATA_L; 00282 nfo.size = size; 00283 nfo.seq = seq; 00284 nfo.dataP = data; 00285 00286 res = EncodeL2( pack, &nfo); 00287 if (res < 0) 00288 return -1; 00289 00290 return 0; 00291 } 00292 00293 00294 /// **************************************************************************** 00295 /// \fn MLX_DecodeResS / L 00296 /// 00297 /// \brief Decodes a read or write response from slave. 00298 /// 00299 /// \param[in] *pack: Packet to decode 00300 /// \param[out] *val: Data value extracted from response 00301 /// 00302 /// \return 0 on success, negative on error. 00303 /// 00304 /// \authors Jean-Fran�ois Bernier 00305 /// \since 2015-04-24 00306 /// **************************************************************************** 00307 int MLX_DecodeResS( const PACK_SHORT *pack, uint32 *val) 00308 { 00309 int res; 00310 MLX_PackNfo nfo; 00311 00312 if (!ValidCRC_short(pack)){ 00313 return -5; 00314 } 00315 00316 //SWAP( rx+off, 1); 00317 00318 res = DecodeS( pack, &nfo); 00319 if (res < 0 || nfo.pktype != PACK_RDATA_RESP_S) 00320 if (nfo.pktype == PACK_STATUS_S) return -6; 00321 else return -20; 00322 00323 *val = nfo.data; 00324 return 0; 00325 } 00326 00327 int MLX_DecodeResL1(const PACK_LONG1 *pack) 00328 { 00329 int res; 00330 MLX_PackNfo nfo; 00331 00332 if (!ValidCRC_long1(pack)){ 00333 return -9; 00334 } 00335 00336 res = DecodeL1(pack, &nfo); 00337 if (res < 0 || nfo.pktype != PACK_RDATA_RESP_L) 00338 return -10; 00339 00340 return 0; 00341 } 00342 00343 int MLX_DecodeResL2(const PACK_LONG2 *pack) 00344 { 00345 int res; 00346 MLX_PackNfo nfo; 00347 00348 if (!ValidCRC_long2(pack)){ 00349 return -9; 00350 } 00351 00352 res = DecodeL2(pack, &nfo); 00353 if (res < 0 || ((nfo.pktype != PACK_RDATA_RESP_L) && (nfo.pktype != PACK_STATUS_L))) 00354 return -10; 00355 00356 return 0; 00357 } 00358 00359 00360 // ******************************** 00361 // ***** SLAVE SIDE FUNCTIONS ***** 00362 // ******************************** 00363 00364 /// **************************************************************************** 00365 /// \fn MLX_ResReadReg 00366 /// 00367 /// \brief Creates a read register response. 00368 /// 00369 /// \param[out] *pack: Packet to encode as a response 00370 /// \param[in] val: Register value 00371 /// 00372 /// \return Error code: 0 on success or negative on error. 00373 /// 00374 /// \authors Jean-Fran�ois Bernier 00375 /// \since 2015-04-01 00376 /// **************************************************************************** 00377 int MLX_ResReadReg( PACK_SHORT *pack, uint16 val) 00378 { 00379 int res; 00380 MLX_PackNfo nfo; 00381 00382 // Reset packet! 00383 memset( pack, 0, sizeof(*pack)); 00384 00385 nfo.pktype = PACK_RDATA_RESP_S; 00386 nfo.size = 1; 00387 nfo.seq = 0; 00388 nfo.data = val; 00389 00390 res = EncodeS( pack, &nfo); 00391 if (res < 0) 00392 return -1; 00393 00394 return 0; 00395 } 00396 00397 /// **************************************************************************** 00398 /// \fn MLX_DecodeReqS 00399 /// 00400 /// \brief Decodes a request from master. 00401 /// 00402 /// \param[in] *pack: Packet to decode 00403 /// \param[out] *nfo: Filled info struct 00404 /// 00405 /// \return Error code: 0 on success or negative on error. 00406 /// 00407 /// \authors Jean-Fran�ois Bernier 00408 /// \since 2015-04-28 00409 /// **************************************************************************** 00410 int MLX_DecodeReqS( const PACK_SHORT *pack, MLX_PackNfo *nfo) 00411 { 00412 int res; 00413 00414 if (!ValidCRC_short(pack)){ 00415 return -1; 00416 } 00417 00418 res = DecodeS( pack, nfo); 00419 if (res < 0) 00420 return -1; 00421 00422 return 0; 00423 } 00424 00425 00426 /// **************************************************************************** 00427 /// \fn MLX_ResReadData 00428 /// 00429 /// \brief Encodes a long read response. 00430 /// 00431 /// \param[in] *pack: Packet to decode 00432 /// \param[out] *nfo: Filled info struct 00433 /// 00434 /// \return Error code: 0 on success or negative on error. 00435 /// 00436 /// \authors Jean-Fran�ois Bernier 00437 /// \since 2015-05-07 00438 /// **************************************************************************** 00439 int MLX_ResReadData( PACK_LONG1 *pack, uint size, uint seq, const uint8 *data) 00440 { 00441 int res; 00442 MLX_PackNfo nfo; 00443 00444 if (size > MLX_LONG1_DATA_SZ) 00445 return -1; 00446 00447 nfo.pktype = PACK_RDATA_RESP_L; 00448 nfo.size = size; 00449 nfo.seq = seq; 00450 nfo.dataP = data; 00451 00452 res = EncodeL1( pack, &nfo); 00453 if (res < 0) 00454 return -1; 00455 00456 return 0; 00457 } 00458 00459 /// **************************************************************************** 00460 /// \fn MLX_ResReadDataE 00461 /// 00462 /// \brief Encodes an echo read response. 00463 /// 00464 /// \param[in] *pack: Packet to decode 00465 /// \param[out] *nfo: Filled info struct 00466 /// 00467 /// \return Error code: 0 on success or negative on error. 00468 /// 00469 /// \authors Jean-Fran�ois Bernier 00470 /// \since 2015-05-07 00471 /// **************************************************************************** 00472 int MLX_ResReadDataL2(PACK_LONG2 *pack, uint size, uint seq, const uint8 *data) 00473 { 00474 int res; 00475 MLX_PackNfo nfo; 00476 00477 if (size > MLX_LONG2_DATA_SZ) 00478 return -1; 00479 00480 nfo.pktype = PACK_RDATA_RESP_L; 00481 nfo.size = size; 00482 nfo.seq = seq; 00483 nfo.dataP = data; 00484 00485 res = EncodeL2(pack, &nfo); 00486 if (res < 0) 00487 return -1; 00488 00489 return 0; 00490 } 00491 00492 00493 // ******************************** 00494 // ****** COMMON FUNCTIONS ******** 00495 // ******************************** 00496 00497 /// **************************************************************************** 00498 /// \fn FillCRC_short / long 00499 /// 00500 /// \brief Computes and sets the CRC field in a packet. 00501 /// 00502 /// \param[in/out] *pack: Packet on which to set the CRC 00503 /// 00504 /// \return Nothing. 00505 /// 00506 /// \authors Jean-Fran�ois Bernier 00507 /// \since 2015-04-24 00508 /// **************************************************************************** 00509 void FillCRC_short( PACK_SHORT *pack) 00510 { 00511 pack->crc = CRC16_Compute( (uint8*)pack, sizeof(*pack)-MLX_CRC_SZ); 00512 //SWAP(&pack->crc,2); 00513 } 00514 00515 void FillCRC_long1(PACK_LONG1 *pack) 00516 { 00517 pack->crc = CRC16_Compute((uint8*)pack, sizeof(*pack) - MLX_CRC_SZ); 00518 //SWAP(&pack->crc,2); 00519 } 00520 00521 void FillCRC_long2(PACK_LONG2 *pack) 00522 { 00523 pack->crc = CRC16_Compute((uint8*)pack, sizeof(*pack) - MLX_CRC_SZ); 00524 //SWAP(&pack->crc,2); 00525 } 00526 00527 /// **************************************************************************** 00528 /// \fn ValidCRC_short / long 00529 /// 00530 /// \brief Validates the CRC of a packet. 00531 /// 00532 /// \param[in/out] pack: Packet on which to validate the CRC 00533 /// 00534 /// \return Validation status. TRUE if valid, FALSE if invalid. 00535 /// 00536 /// \authors Jean-Fran�ois Bernier 00537 /// \since 2015-04-24 00538 /// **************************************************************************** 00539 BOOL ValidCRC_short( const PACK_SHORT *pack) 00540 { 00541 return CRC16_IsValid( (uint8*)pack, sizeof(*pack), MLX_CRC_SZ); 00542 } 00543 00544 BOOL ValidCRC_long1( const PACK_LONG1 *pack) 00545 { 00546 return CRC16_IsValid( (uint8*)pack, sizeof(*pack), MLX_CRC_SZ); 00547 } 00548 00549 BOOL ValidCRC_long2(const PACK_LONG2 *pack) 00550 { 00551 return CRC16_IsValid((uint8*)pack, sizeof(*pack), MLX_CRC_SZ); 00552 } 00553 00554 /// **************************************************************************** 00555 /// \fn CRC16_Compute 00556 /// 00557 /// \brief Computes the CRC16 of a data vector. 00558 /// This is the CCITT CRC 16 polynomial X^16 + X^12 + X^5 + 1. 00559 /// This works out to be 0x1021, but the way the algorithm works 00560 /// lets us use 0x8408 (the reverse of the bit pattern). The high 00561 /// bit is always assumed to be set, thus we only use 16 bits to 00562 /// represent the 17 bit value. 00563 /// 00564 /// Reference: stjarnhimlen.se/snippets/crc-16.c 00565 /// 00566 /// \param[in] *data: Data vector for which to compute the CRC 00567 /// \param[in] n: Number of bytes in data 00568 /// 00569 /// \return The CRC 00570 /// 00571 /// \authors Jean-F. Bernier 00572 /// \since 2015-03-31 00573 /// **************************************************************************** 00574 /* uint16 CRC16_Compute( const uint8 *data, uint16 n) 00575 { 00576 uint8 a; 00577 uint tmp; 00578 uint crc = 0x0000; 00579 00580 const uint POLY = 0x8408; 00581 00582 if (n == 0) 00583 return (~crc); 00584 00585 do 00586 { 00587 tmp = (uint)0xFF & *data++; 00588 00589 for (a = 0 ; a < 8; ++a) 00590 { 00591 tmp >>= 1; 00592 if ((crc & 0x0001) ^ (tmp & 0x0001)) 00593 crc = (crc >> 1) ^ POLY; 00594 else 00595 crc >>= 1; 00596 } 00597 } while (--n); 00598 00599 crc = ~crc; 00600 tmp = crc; 00601 crc = (crc << 8) | (tmp >> 8 & 0xFF); 00602 00603 return crc; 00604 } 00605 */ 00606 00607 /* 00608 * Copyright 2001-2010 Georges Menie (www.menie.org) 00609 * All rights reserved. 00610 * Redistribution and use in source and binary forms, with or without 00611 * modification, are permitted provided that the following conditions are met: 00612 * 00613 * * Redistributions of source code must retain the above copyright 00614 * notice, this list of conditions and the following disclaimer. 00615 * * Redistributions in binary form must reproduce the above copyright 00616 * notice, this list of conditions and the following disclaimer in the 00617 * documentation and/or other materials provided with the distribution. 00618 * * Neither the name of the University of California, Berkeley nor the 00619 * names of its contributors may be used to endorse or promote products 00620 * derived from this software without specific prior written permission. 00621 * 00622 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY 00623 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00624 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00625 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 00626 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00627 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00628 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00629 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00630 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00631 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00632 */ 00633 00634 /* CRC16 implementation acording to CCITT standards */ 00635 00636 static const uint16 crc16tab[256] = { 00637 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 00638 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 00639 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 00640 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 00641 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 00642 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 00643 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 00644 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 00645 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 00646 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 00647 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 00648 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 00649 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 00650 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 00651 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 00652 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 00653 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 00654 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 00655 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 00656 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 00657 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 00658 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 00659 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 00660 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 00661 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 00662 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 00663 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 00664 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 00665 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 00666 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 00667 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 00668 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 00669 }; 00670 00671 uint16 CRC16_Compute(const uint8 *buf, uint16 len) 00672 { 00673 uint16 tmp; 00674 int counter; 00675 uint16 crc = 0; 00676 for (counter = 0; counter < len; counter++) 00677 crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ *(char *)buf++) & 0x00FF]; 00678 00679 tmp = crc; 00680 crc = (crc << 8) | (tmp >> 8 & 0xFF); 00681 00682 return crc; 00683 } 00684 00685 00686 /// **************************************************************************** 00687 /// \fn CRC16_IsValid 00688 /// 00689 /// \brief Validates the CRC in a byte vector. Computes CRC on all bytes except 00690 /// the X lasts CRC bytes and compares it to the one found in these X lasts. 00691 /// 00692 /// \param[in] *data: Data vector for which to validate the CRC 00693 /// \param[in] n: Total bytes in data 00694 /// \param[in] nbCrc: Nb of bytes at the end of data for the CRC 00695 /// 00696 /// \return TRUE if valid, FALSE otherwise. 00697 /// 00698 /// \authors Jean-F. Bernier 00699 /// \since 2014-10-21 00700 /// **************************************************************************** 00701 BOOL CRC16_IsValid( const uint8 *data, uint n, uint nbCrc) 00702 { 00703 if (n <= 1){ 00704 return FALSE; 00705 } 00706 00707 uint16 test = *(uint16*)(data+n-nbCrc); 00708 //SWAP( &test, 1); 00709 uint16 crc = CRC16_Compute( data, n-nbCrc); 00710 return (crc == test); 00711 } 00712 00713 00714 00715 /// **************************************************************************** 00716 /// \fn SetBitVector 00717 /// 00718 /// \brief Sets a value in a vector of bits at chosen offset and bit width. 00719 /// Input bits all pre-supposed at zero in buffer. 00720 /// 00721 /// \param[in] *buf: Target vector of bits to be modified. The first byte will contain 00722 /// the lowest bits (at lowest offset). 00723 /// \param[in] off: Position offset in bits where to put val, 0-based 00724 /// \param[in] wid: Number of bits to take from val [0 32] 00725 /// \param[in] val: Value to set in buf. Its low bit is always set first at chosen offset. 00726 /// \param[in] inv: Inverse bit ordering inside a byte. Usually, bit#0 is the least significant to the right. 00727 /// With this, bit#0 becomes the most significant to the left. 00728 /// 00729 /// \return Error code: 0 on success, negative otherwise. 00730 /// 00731 /// \authors Jean-F. Bernier 00732 /// \since 2015-04-01 00733 /// **************************************************************************** 00734 int SetBitVector( uint8 *buf, uint32 off, uchar wid, uint32 val, uchar inv) 00735 { 00736 if (wid <= 0 || wid > 32 || buf == NULL) 00737 return -1; 00738 00739 if (inv && wid > off+1) 00740 return -2; 00741 00742 buf += (off >> 3); // Byte count to move 00743 uint8 rem = off % 8; // Remaining bits to move 00744 00745 // While there is a remaining bit to set... 00746 while (wid >= 1) 00747 { 00748 // Check the bit value. If zero, nothing to do. 00749 if (val & 1) 00750 { 00751 if (!inv) 00752 BIT_SET( *buf, rem); 00753 else 00754 BIT_SET( *buf, 7-rem); 00755 } 00756 00757 if (!inv) 00758 { 00759 // Wrap around. Goto next byte when setting bit index > 7 00760 ++rem; 00761 if (rem >= 8) 00762 { 00763 rem = 0; 00764 ++buf; 00765 } 00766 } 00767 else 00768 { 00769 // Wrap around. Goto previous byte when setting "negative" bit index 00770 --rem; 00771 if (rem >= 8) 00772 { 00773 rem = 7; 00774 --buf; 00775 } 00776 } 00777 00778 // Activate the next bit 00779 val >>= 1; 00780 --wid; 00781 } 00782 00783 return 0; 00784 } 00785 00786 00787 /// **************************************************************************** 00788 /// \fn GetBitVector 00789 /// 00790 /// \brief Gets a sub-array of bits inside a bigger one. 00791 /// Selects the bits to obtain using offset and bit width. 00792 /// 00793 /// \param[in] *buf: Target vector of bits to be read. The first byte will contain 00794 /// the lowest bits (at lowest offset). 00795 /// \param[in] off: Position offset in bits where to start reading the low bit, 0-based 00796 /// \param[in] wid: Number of bits to read into val [0 32] 00797 /// \param[out] *val: Value obtained from buf. 00798 /// \param[in] inv: Inverse bit ordering inside a byte. Usually, bit#0 is the least significant to the right. 00799 /// With this, bit#0 becomes the most significant to the left. 00800 /// 00801 /// \return Error code: 0 on success, negative otherwise. 00802 /// 00803 /// \authors Jean-F. Bernier 00804 /// \since 2015-04-28 00805 /// **************************************************************************** 00806 int GetBitVector( const uint8 *buf, uint32 off, uchar wid, uint32 *val, uchar inv) 00807 { 00808 if (wid <= 0 || wid > 32 || buf == NULL) 00809 return -1; 00810 00811 if (inv && wid > off+1) 00812 return -2; 00813 00814 buf += (off >> 3); // Byte count to move 00815 uint8 rem = off % 8; // Remaining bits to move 00816 uchar bit, b = 0; 00817 *val = 0; 00818 00819 // While there is a remaining bit to set... 00820 while (wid >= 1) 00821 { 00822 if (!inv) 00823 bit = BIT_GET( *buf, rem); 00824 else 00825 bit = BIT_GET( *buf, 7-rem); 00826 00827 if (bit) 00828 BIT_SET( *val, b); 00829 00830 if (!inv) 00831 { 00832 // Wrap around. Goto next byte when setting bit index > 7 00833 ++rem; 00834 if (rem >= 8) 00835 { 00836 rem = 0; 00837 ++buf; 00838 } 00839 } 00840 else 00841 { 00842 // Wrap around. Goto previous byte when setting "negative" bit index 00843 --rem; 00844 if (rem >= 8) 00845 { 00846 rem = 7; 00847 --buf; 00848 } 00849 } 00850 00851 // Activate the next bit 00852 --wid; 00853 ++b; 00854 } 00855 00856 return 0; 00857 } 00858 00859 /// **************************************************************************** 00860 /// \fn ReverseBits 00861 /// 00862 /// \brief Reverses a bit pattern like a mirror. First bits becomes last. 00863 /// Ex.: 011001 <-> 100110 (v = 25, n = 6) 00864 /// 00865 /// \param[in] bits: Value to use as bit pattern 00866 /// \param[in] nb: Number of bits to take from v. Starts at low bits. 00867 /// 00868 /// \return The value with a reversed bit pattern. 00869 /// 00870 /// \authors Jean-Fran�ois Bernier 00871 /// \since 2015-04-30 00872 /// **************************************************************************** 00873 /*uint32 ReverseBits( uint32 bits, char nb) 00874 { 00875 // If n == 0, no bits to use. So result will be zero. 00876 uint32 res = 0; 00877 00878 while ((signed char)--nb >= 0) 00879 { 00880 res <<= 1; // Shift current result by 1 00881 res += (bits & 1); // Take the current bit into result 00882 bits >>= 1; // Prepare for next bit 00883 } 00884 00885 return res; 00886 } 00887 */ 00888 /// **************************************************************************** 00889 /// \fn EncodeS 00890 /// 00891 /// \brief Generic short packet encoder. 00892 /// 00893 /// \param[out] *pack: Resulting packet encoded with nfo 00894 /// \param[in] *nfo: Info used to encode packet 00895 /// 00896 /// \return Error code: 0 on success or negative on error. 00897 /// 00898 /// \authors Jean-Fran�ois Bernier 00899 /// \since 2015-04-27 00900 /// **************************************************************************** 00901 int EncodeS( PACK_SHORT *pack, const MLX_PackNfo *nfo) 00902 { 00903 int res; 00904 00905 // Reject long packets 00906 if (nfo->pktype == PACK_STATUS_L || nfo->pktype == PACK_RDATA_RESP_L || nfo->pktype == PACK_WDATA_L) 00907 { 00908 return -1; 00909 } 00910 00911 if (nfo->pktype == PACK_STATUS_S) 00912 { 00913 res = SetBitVector( pack->buf, OFF_TYPE, WID_TYPE, nfo->pktype, BIT_ORDER); 00914 if (res < 0) 00915 return -1; 00916 00917 // Is error field 00918 res = SetBitVector( pack->buf, OFF_ISERR, WID_ISERR, nfo->iserr, BIT_ORDER); 00919 if (res < 0) 00920 return -1; 00921 00922 // Error qualifier field 00923 res = SetBitVector( pack->buf, OFF_ERROR, WID_ERROR, nfo->error, BIT_ORDER); 00924 if (res < 0) 00925 return -1; 00926 00927 goto END; 00928 } 00929 00930 // Packet type field 00931 res = SetBitVector( pack->buf, OFF_TYPE, WID_TYPE, nfo->pktype, BIT_ORDER); 00932 if (res < 0) 00933 return -1; 00934 00935 // Size field 00936 res = SetBitVector( pack->buf, OFF_SIZE, WID_SIZE, nfo->size, BIT_ORDER); 00937 if (res < 0) 00938 return -1; 00939 00940 // Sequence field 00941 res = SetBitVector( pack->buf, OFF_SEQ, WID_SEQ, nfo->seq, BIT_ORDER); 00942 if (res < 0) 00943 return -1; 00944 00945 // Address field 00946 if (nfo->pktype == PACK_RREG || nfo->pktype == PACK_WREG) 00947 { 00948 res = SetBitVector( pack->buf, OFF_ADDR, WID_ADDR, nfo->addr, BIT_ORDER); 00949 } 00950 else if (nfo->pktype == PACK_RFIRM) 00951 { 00952 res = SetBitVector( pack->buf, OFF_ADDR, WID_ADDR, nfo->fwtype, BIT_ORDER); 00953 } 00954 else if (nfo->pktype == PACK_WFIRM) 00955 { 00956 res = SetBitVector(pack->buf, OFF_ADDR, WID_ADDR, nfo->fwtype, BIT_ORDER); 00957 } 00958 00959 if (res < 0) 00960 return -1; 00961 00962 // Data field 00963 if (nfo->pktype == PACK_RDATA_RESP_S) 00964 { 00965 res = SetBitVector( pack->buf, OFF_RES_DATA, WID_RES_DATA, nfo->data, BIT_ORDER); 00966 } 00967 else if (nfo->pktype == PACK_WREG) 00968 { 00969 res = SetBitVector( pack->buf, OFF_DATA, WID_DATA, nfo->data, BIT_ORDER); 00970 } 00971 else if (nfo->pktype == PACK_WFIRM) 00972 { 00973 res = SetBitVector(pack->buf, OFF_DATA, WID_DATA, nfo->data, BIT_ORDER); 00974 } 00975 00976 if (res < 0) 00977 return -1; 00978 00979 //SWAP(&pack,sizeof(*pack)); 00980 00981 END: 00982 FillCRC_short(pack); 00983 //SWAP( &pack->crc, 1); 00984 00985 return 0; 00986 } 00987 00988 /// **************************************************************************** 00989 /// \fn DecodeS 00990 /// 00991 /// \brief Generic short packet decoder. 00992 /// 00993 /// \param[in] *pack: Packet to be decoded into info 00994 /// \param[out] *nfo: Filled packet info from pack data 00995 /// 00996 /// \return Error code: 0 on success or negative on error. 00997 /// 00998 /// \authors Jean-Fran�ois Bernier 00999 /// \since 2015-04-27 01000 /// **************************************************************************** 01001 int DecodeS( const PACK_SHORT *pack, MLX_PackNfo *nfo) 01002 { 01003 uint32 v; 01004 int res; 01005 01006 //SWAP(&pack, sizeof(*pack)); 01007 01008 res = GetBitVector( pack->buf, OFF_TYPE, WID_TYPE, &v, BIT_ORDER); 01009 if (res < 0) 01010 return -1; 01011 nfo->pktype = (PackType)v; 01012 01013 res = GetBitVector( pack->buf, OFF_SIZE, WID_SIZE, &v, BIT_ORDER); 01014 if (res < 0) 01015 return -1; 01016 nfo->size = v; 01017 01018 res = GetBitVector( pack->buf, OFF_SEQ, WID_SEQ, &v, BIT_ORDER); 01019 if (res < 0) 01020 return -1; 01021 nfo->seq = v; 01022 01023 if (nfo->pktype == PACK_STATUS_S) 01024 { 01025 res = GetBitVector( pack->buf, OFF_ISERR, WID_ISERR, &v, BIT_ORDER); 01026 if (res < 0) 01027 return -1; 01028 01029 nfo->iserr = v; 01030 01031 res = GetBitVector( pack->buf, OFF_ERROR, WID_ERROR, &v, BIT_ORDER); 01032 if (res < 0) 01033 return -1; 01034 01035 nfo->error = v; 01036 return 0; 01037 } 01038 01039 01040 if (nfo->pktype == PACK_RREG || nfo->pktype == PACK_WREG) 01041 { 01042 res = GetBitVector( pack->buf, OFF_ADDR, WID_ADDR, &v, BIT_ORDER); 01043 if (res < 0) 01044 return -1; 01045 01046 nfo->addr = v; 01047 } 01048 01049 01050 v = 0; 01051 if (nfo->pktype == PACK_RDATA_RESP_S) 01052 { 01053 res = GetBitVector( pack->buf, OFF_RES_DATA, WID_RES_DATA, &v, BIT_ORDER); 01054 } 01055 else if (nfo->pktype == PACK_WREG || nfo->pktype == PACK_WFIRM) 01056 { 01057 res = GetBitVector( pack->buf, OFF_DATA, WID_DATA, &v, BIT_ORDER); 01058 } 01059 01060 if (res < 0) 01061 return -1; 01062 01063 nfo->data = v; 01064 01065 return 0; 01066 } 01067 01068 /// **************************************************************************** 01069 /// \fn EncodeL 01070 /// 01071 /// \brief Generic long packet encoder. 01072 /// 01073 /// \param[out] *pack: Resulting packet encoded with nfo 01074 /// \param[in] *nfo: Info used to encode packet 01075 /// 01076 /// \return Error code: 0 on success or negative on error. 01077 /// 01078 /// \authors Jean-Fran�ois Bernier 01079 /// \since 2015-04-27 01080 /// **************************************************************************** 01081 int EncodeL1( PACK_LONG1 *pack, const MLX_PackNfo *nfo) 01082 { 01083 int res; 01084 01085 // Reset packet! 01086 memset( pack, 0, sizeof(*pack)); 01087 01088 // Reject short packets 01089 if (nfo->pktype != PACK_STATUS_L && nfo->pktype != PACK_RDATA_RESP_L && nfo->pktype != PACK_WDATA_L) 01090 { 01091 return -1; 01092 } 01093 01094 if (nfo->pktype == PACK_STATUS_L) 01095 { 01096 res = SetBitVector( pack->buf, OFF_TYPE, WID_TYPE, nfo->pktype, BIT_ORDER); 01097 if (res < 0) 01098 return -1; 01099 01100 // Is error field 01101 res = SetBitVector( pack->buf, OFF_ISERR, WID_ISERR, nfo->iserr, BIT_ORDER); 01102 if (res < 0) 01103 return -1; 01104 01105 // Error qualifier field 01106 res = SetBitVector( pack->buf, OFF_ERROR, WID_ERROR, nfo->error, BIT_ORDER); 01107 if (res < 0) 01108 return -1; 01109 01110 goto END; 01111 } 01112 01113 // Packet type field 01114 res = SetBitVector( pack->buf, OFF_TYPE, WID_TYPE, nfo->pktype, BIT_ORDER); 01115 if (res < 0) 01116 return -1; 01117 01118 // Size field 01119 res = SetBitVector( pack->buf, OFF_SIZE, WID_SIZE, nfo->size, BIT_ORDER); 01120 if (res < 0) 01121 return -1; 01122 01123 // Sequence field 01124 res = SetBitVector( pack->buf, OFF_SEQ, WID_SEQ, nfo->seq, BIT_ORDER); 01125 if (res < 0) 01126 return -1; 01127 01128 // Data field 01129 memcpy( pack->data, nfo->dataP, nfo->size); 01130 if (res < 0) 01131 return -1; 01132 01133 //SWAP(&pack,sizeof(*pack)); 01134 01135 END: 01136 FillCRC_long1(pack); 01137 //SWAP( &pack->crc, 1); 01138 01139 return 0; 01140 } 01141 01142 01143 01144 /// **************************************************************************** 01145 /// \fn DecodeL 01146 /// 01147 /// \brief Generic long packet decoder. 01148 /// 01149 /// \param[in] *pack: Packet to be decoded into info 01150 /// \param[out] *nfo: Filled packet info from pack data 01151 /// 01152 /// \return Error code: 0 on success or negative on error. 01153 /// 01154 /// \authors Jean-Fran�ois Bernier 01155 /// \since 2015-04-27 01156 /// **************************************************************************** 01157 int DecodeL1( const PACK_LONG1 *pack, MLX_PackNfo *nfo) 01158 { 01159 uint32 v; 01160 int res; 01161 01162 //SWAP(&pack,sizeof(*pack)); 01163 01164 res = GetBitVector( pack->buf, OFF_TYPE, WID_TYPE, &v, BIT_ORDER); 01165 if (res < 0) 01166 return -1; 01167 nfo->pktype = (PackType)v; 01168 01169 res = GetBitVector( pack->buf, OFF_SIZE, WID_SIZE, &v, BIT_ORDER); 01170 if (res < 0) 01171 return -1; 01172 nfo->size = v; 01173 01174 res = GetBitVector( pack->buf, OFF_SEQ, WID_SEQ, &v, BIT_ORDER); 01175 if (res < 0) 01176 return -1; 01177 nfo->seq = v; 01178 01179 if (nfo->pktype == PACK_STATUS_L) 01180 { 01181 res = GetBitVector( pack->buf, OFF_ISERR, WID_ISERR, &v, BIT_ORDER); 01182 if (res < 0) 01183 return -1; 01184 01185 nfo->iserr = v; 01186 01187 res = GetBitVector( pack->buf, OFF_ERROR, WID_ERROR, &v, BIT_ORDER); 01188 if (res < 0) 01189 return -1; 01190 01191 nfo->error = v; 01192 return 0; 01193 } 01194 01195 return 0; 01196 } 01197 01198 /// **************************************************************************** 01199 /// \fn EncodeL2 01200 /// 01201 /// \brief Generic long packet encoder. 01202 /// 01203 /// \param[out] *pack: Resulting packet encoded with nfo 01204 /// \param[in] *nfo: Info used to encode packet 01205 /// 01206 /// \return Error code: 0 on success or negative on error. 01207 /// 01208 /// \authors Jean-Fran�ois Bernier 01209 /// \since 2015-04-27 01210 /// **************************************************************************** 01211 int EncodeL2(PACK_LONG2 *pack, const MLX_PackNfo *nfo) 01212 { 01213 int res; 01214 01215 // Reset packet! 01216 memset(pack, 0, sizeof(*pack)); 01217 01218 // Reject short packets 01219 if (nfo->pktype != PACK_STATUS_L && nfo->pktype != PACK_RDATA_RESP_L && nfo->pktype != PACK_WDATA_L) 01220 { 01221 return -1; 01222 } 01223 01224 if (nfo->pktype == PACK_STATUS_L) 01225 { 01226 res = SetBitVector(pack->buf, OFF_TYPE, WID_TYPE, nfo->pktype, BIT_ORDER); 01227 if (res < 0) 01228 return -1; 01229 01230 // Is error field 01231 res = SetBitVector(pack->buf, OFF_ISERR, WID_ISERR, nfo->iserr, BIT_ORDER); 01232 if (res < 0) 01233 return -1; 01234 01235 // Error qualifier field 01236 res = SetBitVector(pack->buf, OFF_ERROR, WID_ERROR, nfo->error, BIT_ORDER); 01237 if (res < 0) 01238 return -1; 01239 01240 goto END; 01241 } 01242 01243 // Packet type field 01244 res = SetBitVector(pack->buf, OFF_TYPE, WID_TYPE, nfo->pktype, BIT_ORDER); 01245 if (res < 0) 01246 return -1; 01247 01248 // Size field 01249 res = SetBitVector(pack->buf, OFF_SIZE, WID_SIZE, nfo->size, BIT_ORDER); 01250 if (res < 0) 01251 return -1; 01252 01253 // Sequence field 01254 res = SetBitVector(pack->buf, OFF_SEQ, WID_SEQ, nfo->seq, BIT_ORDER); 01255 if (res < 0) 01256 return -1; 01257 01258 // Data field 01259 memcpy(pack->data, nfo->dataP, nfo->size*2); 01260 01261 if (res < 0) 01262 return -1; 01263 01264 //SWAP(&pack,sizeof(*pack)); 01265 01266 END: 01267 FillCRC_long2(pack); 01268 //SWAP( &pack->crc, 1); 01269 01270 return 0; 01271 } 01272 01273 01274 01275 /// **************************************************************************** 01276 /// \fn DecodeE 01277 /// 01278 /// \brief Generic long packet decoder. 01279 /// 01280 /// \param[in] *pack: Packet to be decoded into info 01281 /// \param[out] *nfo: Filled packet info from pack data 01282 /// 01283 /// \return Error code: 0 on success or negative on error. 01284 /// 01285 /// \authors Jean-Fran�ois Bernier 01286 /// \since 2015-04-27 01287 /// **************************************************************************** 01288 int DecodeL2(const PACK_LONG2 *pack, MLX_PackNfo *nfo) 01289 { 01290 uint32 v; 01291 int res; 01292 01293 //SWAP(&pack,sizeof(*pack)); 01294 01295 res = GetBitVector(pack->buf, OFF_TYPE, WID_TYPE, &v, BIT_ORDER); 01296 if (res < 0) 01297 return -1; 01298 nfo->pktype = (PackType)v; 01299 01300 res = GetBitVector(pack->buf, OFF_SIZE, WID_SIZE, &v, BIT_ORDER); 01301 if (res < 0) 01302 return -1; 01303 nfo->size = v; 01304 01305 res = GetBitVector(pack->buf, OFF_SEQ, WID_SEQ, &v, BIT_ORDER); 01306 if (res < 0) 01307 return -1; 01308 nfo->seq = v; 01309 01310 if (nfo->pktype == PACK_STATUS_L) 01311 { 01312 res = GetBitVector(pack->buf, OFF_ISERR, WID_ISERR, &v, BIT_ORDER); 01313 if (res < 0) 01314 return -1; 01315 01316 nfo->iserr = v; 01317 01318 res = GetBitVector(pack->buf, OFF_ERROR, WID_ERROR, &v, BIT_ORDER); 01319 if (res < 0) 01320 return -1; 01321 01322 nfo->error = v; 01323 return 0; 01324 } 01325 01326 return 0; 01327 } 01328 01329 01330 01331 01332 /// **************************************************************************** 01333 /// \fn MLX_EncodeStatusS 01334 /// 01335 /// \brief Creates a short status packet. 01336 /// 01337 /// \param[out] *pack: Resulting encoded packet 01338 /// \param[in] iserr: Flag telling if it is an error or not 01339 /// \param[in] err: Error qualifier data 01340 /// 01341 /// \return Error code: 0 on success or negative on error. 01342 /// 01343 /// \authors Jean-Fran�ois Bernier 01344 /// \since 2015-04-28 01345 /// **************************************************************************** 01346 int MLX_EncodeStatusS( PACK_SHORT *pack, uint8 iserr, uint16 err) 01347 { 01348 int res; 01349 MLX_PackNfo nfo; 01350 01351 // Reset packet! 01352 memset( pack, 0, sizeof(*pack)); 01353 01354 nfo.pktype = PACK_STATUS_S; 01355 nfo.iserr = iserr; 01356 nfo.error = err; 01357 01358 res = EncodeS( pack, &nfo); 01359 if (res < 0) 01360 return -1; 01361 01362 return 0; 01363 } 01364 01365 /// **************************************************************************** 01366 /// \fn MLX_DecodeStatusS 01367 /// 01368 /// \brief Attempts to decode a packet as a status packet. 01369 /// 01370 /// \param[in] *pack: Packet to decode 01371 /// \param[out] *iserr: Flag telling if it is an error or not 01372 /// \param[out] *err: Error qualifier data 01373 /// 01374 /// \return Error code: 0 on success or negative on error. 01375 /// 01376 /// \authors Jean-Fran�ois Bernier 01377 /// \since 2015-05-01 01378 /// **************************************************************************** 01379 int MLX_DecodeStatusS( const PACK_SHORT *pack, uint8 *iserr, uint16 *err) 01380 { 01381 int res; 01382 MLX_PackNfo nfo; 01383 01384 if (!ValidCRC_short(pack)){ 01385 return -1; 01386 } 01387 01388 res = DecodeS( pack, &nfo); 01389 if (res < 0 || nfo.pktype != PACK_STATUS_S) 01390 return -1; 01391 01392 *iserr = nfo.iserr; 01393 *err = nfo.error; 01394 01395 return 0; 01396 } 01397 01398 01399 /// **************************************************************************** 01400 /// \fn MLX_EncodeStatusL 01401 /// 01402 /// \brief Creates a long status packet. 01403 /// 01404 /// \param[out] *pack: Resulting encoded packet 01405 /// \param[in] iserr: Flag telling if it is an error or not 01406 /// \param[in] err: Error qualifier data 01407 /// 01408 /// \return Error code: 0 on success or negative on error. 01409 /// 01410 /// \authors Jean-Fran�ois Bernier 01411 /// \since 2015-05-19 01412 /// **************************************************************************** 01413 int MLX_EncodeStatusL1( PACK_LONG1 *pack, uint8 iserr, uint16 err) 01414 { 01415 int res; 01416 MLX_PackNfo nfo; 01417 01418 // Reset packet! 01419 memset(pack, 0, sizeof(*pack)); 01420 01421 nfo.pktype = PACK_STATUS_L; 01422 nfo.iserr = iserr; 01423 nfo.error = err; 01424 01425 res = EncodeL1( pack, &nfo); 01426 if (res < 0) 01427 return -1; 01428 01429 return 0; 01430 } 01431 01432 /// **************************************************************************** 01433 /// \fn MLX_DecodeStatusL 01434 /// 01435 /// \brief Attempts to decode a packet as a status packet. 01436 /// 01437 /// \param[in] *pack: Packet to decode 01438 /// \param[out] *iserr: Flag telling if it is an error or not 01439 /// \param[out] *err: Error qualifier data 01440 /// 01441 /// \return Error code: 0 on success or negative on error. 01442 /// 01443 /// \authors Jean-Fran�ois Bernier 01444 /// \since 2015-05-19 01445 /// **************************************************************************** 01446 int MLX_DecodeStatusL1( const PACK_LONG1 *pack, uint8 *iserr, uint16 *err) 01447 { 01448 int res; 01449 MLX_PackNfo nfo; 01450 01451 if (!ValidCRC_long1(pack)) 01452 return -1; 01453 01454 res = DecodeL1( pack, &nfo); 01455 if (res < 0 || nfo.pktype != PACK_STATUS_L) 01456 return -1; 01457 01458 *iserr = nfo.iserr; 01459 *err = nfo.error; 01460 01461 return 0; 01462 } 01463 01464 /// **************************************************************************** 01465 /// \fn MLX_EncodeStatusL2 01466 /// 01467 /// \brief Creates a echo status packet. 01468 /// 01469 /// \param[out] *pack: Resulting encoded packet 01470 /// \param[in] iserr: Flag telling if it is an error or not 01471 /// \param[in] err: Error qualifier data 01472 /// 01473 /// \return Error code: 0 on success or negative on error. 01474 /// 01475 /// \authors Jean-Fran�ois Bernier 01476 /// \since 2015-05-19 01477 /// **************************************************************************** 01478 int MLX_EncodeStatusL2(PACK_LONG2 *pack, uint8 iserr, uint16 err) 01479 { 01480 int res; 01481 MLX_PackNfo nfo; 01482 01483 // Reset packet! 01484 memset(pack, 0, sizeof(*pack)); 01485 01486 nfo.pktype = PACK_STATUS_L; 01487 nfo.iserr = iserr; 01488 nfo.error = err; 01489 01490 res = EncodeL2(pack, &nfo); 01491 if (res < 0) 01492 return -1; 01493 01494 return 0; 01495 } 01496 01497 /// **************************************************************************** 01498 /// \fn MLX_DecodeStatusL2 01499 /// 01500 /// \brief Attempts to decode a packet as a status packet. 01501 /// 01502 /// \param[in] *pack: Packet to decode 01503 /// \param[out] *iserr: Flag telling if it is an error or not 01504 /// \param[out] *err: Error qualifier data 01505 /// 01506 /// \return Error code: 0 on success or negative on error. 01507 /// 01508 /// \authors Jean-Fran�ois Bernier 01509 /// \since 2015-05-19 01510 /// **************************************************************************** 01511 int MLX_DecodeStatusL2(const PACK_LONG2 *pack, uint8 *iserr, uint16 *err) 01512 { 01513 int res; 01514 MLX_PackNfo nfo; 01515 01516 if (!ValidCRC_long2(pack)) 01517 return -1; 01518 01519 res = DecodeL2(pack, &nfo); 01520 if (res < 0 || nfo.pktype != PACK_STATUS_L) 01521 return -1; 01522 01523 *iserr = nfo.iserr; 01524 *err = nfo.error; 01525 01526 return 0; 01527 } 01528 01529
Generated on Sun Jul 17 2022 06:16:31 by
1.7.2