Tom N / LidarSpi

Dependents:   MLX75320_API

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MLX_BaseSPI.c Source File

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