Library for using the LSR SiFlex/ProFlex RF modules with mbed.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LsrModule.cpp Source File

LsrModule.cpp

Go to the documentation of this file.
00001 /**
00002  * @file LsrModule.cpp
00003  * @author LS Research LLC
00004  * @version 1.0
00005  *
00006  * @section LICENSE
00007  *
00008  * This program is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU General Public License as
00010  * published by the Free Software Foundation; either version 2 of
00011  * the License, or (at your option) any later version.
00012  * 
00013  * This program is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * General Public License for more details at
00017  * http://www.gnu.org/copyleft/gpl.html
00018  *
00019  * @section DESCRIPTION
00020  *
00021  * Implementation of contents in LsrModule.h.
00022  */
00023 
00024 /**
00025  * Modified by Mark Harris at SAIT.ca
00026  * Improved functionality for mbed
00027  */
00028 
00029 #include "LsrModule.h "
00030 #include "mbed.h"
00031 
00032 /**
00033 * C function pointer typedef.
00034 *
00035 */
00036 typedef void (*ptrRxMsgCallback)(void);
00037 
00038 /**
00039 * Table used for subscribing callback functions for
00040 * received UART messages.
00041 */
00042 ptrRxMsgCallback ptrRxMsgCallbackTable[69];
00043 
00044 
00045 /**
00046 * This table contains the min and max length for each message type.  The first array index
00047 * is the message type and the second index is the min value (0) or max value (1).
00048 */
00049 const uint8_t cau8RxMsgLengthAndTypeTable[69][2] = {
00050     {12, 39},   // 0x81 - Query Firmware Version Response
00051     {0, 0},     // 0x82 - Invalid message type
00052     {0, 0},     // 0x83 - Invalid message type
00053     {0, 0},     // 0x84 - Invalid message type
00054     {0, 0},     // 0x85 - Invalid message type
00055     {0, 0},     // 0x86 - Invalid message type
00056     {0, 0},     // 0x87 - Invalid message type
00057     {0, 0},     // 0x88 - Invalid message type
00058     {0, 0},     // 0x89 - Invalid message type
00059     {0, 0},     // 0x8A - Invalid message type
00060     {0, 0},     // 0x8B - Invalid message type
00061     {5, 5},     // 0x8C - Set Security Transmit Frame Counter Ack
00062     {11, 11},   // 0x8D - Query Security Transmit Frame Counter Response
00063     {0, 0},     // 0x8E - Invalid message type
00064     {0, 0},     // 0x8F - Invalid message type
00065     {5, 5},     // 0x90 - Set Basic RF Settings Ack
00066     {39, 39},   // 0x91 - Query Basic RF Settings Response
00067     {5, 5},     // 0x92 - Save Settings to NV Memory Ack
00068     {5, 5},     // 0x93 - Reset Request Ack
00069     {9, 9},     // 0x94 - Query Supply Voltage Response
00070     {21, 21},   // 0x95 - Query Statistics Response
00071     {5, 5},     // 0x96 - Clear Statistics Ack
00072     {0, 0},     // 0x97 - Invalid message type
00073     {5, 5},     // 0x98 - Set Host Data Rate Ack
00074     {0, 0},     // 0x99 - Invalid message type
00075     {0, 0},     // 0x9A - Invalid message type
00076     {0, 0},     // 0x9B - Invalid message type
00077     {0, 0},     // 0x9C - Invalid message type
00078     {0, 0},     // 0x9D - Invalid message type
00079     {0, 0},     // 0x9E - Invalid message type
00080     {0, 0},     // 0x9F - Invalid message type
00081     {7, 7},     // 0xA0 - Send Simple Short Address RF Data Packet Ack
00082     {17, 115},  // 0xA1 - Received Simple Short Address RF Data Packet
00083     {7, 7},     // 0xA2 - Send Advanced Short Address RF Data Packet Ack
00084     {21, 119},  // 0xA3 - Received Advanced Short Address RF Data Packet
00085     {7, 7},     // 0xA4 - Send Simple Long Address RF Data Packet Ack
00086     {29, 127},  // 0xA5 - Received Simple Long Address RF Data Packet
00087     {7, 7},     // 0xA6 - Send Advanced Long Address RF Data Packet Ack
00088     {33, 131},  // 0xA7 - Received Advanced Long Address RF Data Packet
00089     {0, 0},     // 0xA8 - Invalid message type
00090     {0, 0},     // 0xA9 - Invalid message type
00091     {0, 0},     // 0xAA - Invalid message type
00092     {0, 0},     // 0xAB - Invalid message type
00093     {0, 0},     // 0xAC - Invalid message type
00094     {0, 0},     // 0xAD - Invalid message type
00095     {13, 131},  // 0xAE - Received Promiscuous Mode Packet
00096     {0, 0},     // 0xAF - Invalid message type
00097     {0, 0},     // 0xB0 - Invalid message type
00098     {0, 0},     // 0xB1 - Invalid message type
00099     {0, 0},     // 0xB2 - Invalid message type
00100     {0, 0},     // 0xB3 - Invalid message type
00101     {0, 0},     // 0xB4 - Invalid message type
00102     {0, 0},     // 0xB5 - Invalid message type
00103     {0, 0},     // 0xB6 - Invalid message type
00104     {0, 0},     // 0xB7 - Invalid message type
00105     {0, 0},     // 0xB8 - Invalid message type
00106     {0, 0},     // 0xB9 - Invalid message type
00107     {0, 0},     // 0xBA - Invalid message type
00108     {0, 0},     // 0xBB - Invalid message type
00109     {0, 0},     // 0xBC - Invalid message type
00110     {0, 0},     // 0xBD - Invalid message type
00111     {0, 0},     // 0xBE - Invalid message type
00112     {0, 0},     // 0xBF - Invalid message type
00113     {0, 0},     // 0xC0 - Invalid message type
00114     {0, 0},     // 0xC1 - Invalid message type
00115     {0, 0},     // 0xC2 - Invalid message type
00116     {0 ,0},     // 0xC3 - Invalid message type
00117     {5, 5},     // 0xC4 - Channel Energy Scan Ack
00118     {23, 23}    // 0xC5 - Channel Energy Scan Results
00119 };
00120 
00121 /**
00122 * Construnctor.
00123 *
00124 * Example:
00125 *
00126 * LsrModule(false, 19200);
00127 *
00128 */
00129 LsrModule::LsrModule(PinName tx, PinName rx, int baudRate) : Serial(tx, rx)
00130 {
00131     baud(baudRate);
00132     
00133     ptrHostState = &LsrModule::HostRxWaitForMsgStartByteState;
00134     
00135     //attach(this, &LsrModule::RunHostRxStateMachine);
00136 }   /*** End LsrModule ***/
00137 
00138 
00139 /**
00140 * Destructor.  Called automatically, de-allocates resources.
00141 *
00142 */
00143 LsrModule::~LsrModule(void)
00144 {
00145     pu8RxBuffer = NULL;
00146     ptrHostState = NULL;
00147     ptrHostProcessCallbackState = NULL;
00148     
00149     for (u8ForLoopCounter = 0; u8ForLoopCounter < sizeof(ptrRxMsgCallbackTable); u8ForLoopCounter++)
00150     {
00151         ptrRxMsgCallbackTable[u8ForLoopCounter] = NULL;
00152     }
00153 }   /*** End ~LsrModule ***/
00154 
00155 
00156 /**
00157 * Creates a callback for specific received UART message.  Call this function from your main application in 
00158 * this manner: "SubscribeRxMsgCallback(0xA1, &simpleShortAddrCallback)", where simpleShortAddrCallback is 
00159 * defined like this: void simpleShortAddrCallback(void) in your main application.  
00160 * IMPORTANT: All user defined callback methods must return void and take no parameters (void).
00161 *
00162 * @return True: Subscribed callback.  False: Did not subscribe callback.
00163 *
00164 */
00165 bool LsrModule::SubscribeRxMsgCallback(uint8_t u8RxMsgType ///< The received message for which you want the callback to execute.
00166                     , void (*callback)(void) ///< C function pointer to the specified callback function.
00167                      )
00168 {
00169     if ((u8RxMsgType > LSR_MODULE_MIN_SERIAL_RX_MSG_TYPE) && (u8RxMsgType < LSR_MODULE_MAX_SERIAL_RX_MSG_TYPE))
00170     {
00171         ptrRxMsgCallbackTable[u8RxMsgType- LSR_MODULE_MIN_SERIAL_RX_MSG_TYPE] = callback;
00172         return true;
00173     }
00174 
00175     return false;
00176 }   /*** End SubscribeRxMsgCallback ***/
00177 
00178 
00179 /**
00180 * Removes a callback for specific received UART message.  See SubscribeRxMsgCallback's description for 
00181 * more information.
00182 *
00183 * @return True: Unsubscribed callback.  False: Did not unsubscribed callback.
00184 *
00185 */
00186 bool LsrModule::UnsubscribeRxMsgCallback(uint8_t u8RxMsgType ///< The received message for which you want the callback to be removed.
00187                        )
00188 {
00189     if ((u8RxMsgType > LSR_MODULE_MIN_SERIAL_RX_MSG_TYPE) && (u8RxMsgType < LSR_MODULE_MAX_SERIAL_RX_MSG_TYPE))
00190     {
00191         ptrRxMsgCallbackTable[u8RxMsgType - LSR_MODULE_MIN_SERIAL_RX_MSG_TYPE] = NULL;
00192         return true;
00193     }
00194 
00195     return false;
00196 }   /*** End UnsubscribeRxMsgCallback ***/
00197 
00198 
00199 /**
00200 * Executes host RX state machine.  This function must be executed continually from the loop function in your main
00201 * application.
00202 *
00203 */
00204 void LsrModule::RunHostRxStateMachine(void)
00205 {
00206     (this->*ptrHostState)();
00207 }   /*** End RunHostRxStateMachine ***/
00208 
00209 
00210 /**
00211 * Flushes appropriate serial port.
00212 *
00213 */
00214 void LsrModule::SerialFlush(void)
00215 {
00216     // Serial.flush(); 
00217     // i think this is meant to clean out the rx buffer
00218     /*** End SerialFlush ***/
00219 }
00220 
00221 /**
00222 * Adds header to the UART transmit buffer.
00223 *
00224 */
00225 void LsrModule::AddSerialMsgHeader(uint8_t u8MsgType, uint8_t u8MsgLength)
00226 {
00227     SerialFlush();
00228     u8UartTxBufferIndex = LSR_MODULE_MSG_START_BYTE_INDEX;
00229     au8UartTxBuffer[u8UartTxBufferIndex++] = LSR_MODULE_SERIAL_MSG_START_BYTE;
00230     au8UartTxBuffer[u8UartTxBufferIndex++] = u8MsgLength;
00231     au8UartTxBuffer[u8UartTxBufferIndex++] = u8MsgType;
00232     u8TxMsgChecksum = (LSR_MODULE_SERIAL_MSG_START_BYTE + u8MsgLength + u8MsgType);
00233 }   /*** End LsrModuleAddSerialMsgHeader ***/
00234 
00235 
00236 /**
00237 * Adds data bytes to the UART transmit buffer.
00238 *
00239 */
00240 void LsrModule::AddSerialByteToMsgBuffer(uint8_t u8Data ///< The data to add.
00241                                            )
00242 {
00243     au8UartTxBuffer[u8UartTxBufferIndex++] = u8Data;
00244     u8TxMsgChecksum += u8Data;
00245 }   /*** End LsrModuleAddSerialByteToMsgBuffer ***/
00246 
00247 
00248 /**
00249 * Adds message trailer to the UART transmit buffer.
00250 *
00251 */
00252 void LsrModule::AddSerialMsgTrailer(void)
00253 {
00254     au8UartTxBuffer[u8UartTxBufferIndex++] = u8TxMsgChecksum;
00255     au8UartTxBuffer[u8UartTxBufferIndex] = LSR_MODULE_SERIAL_MSG_END_BYTE;
00256     WriteSerialMsg();
00257 }   /*** End AddSerialMsgTrailer ***/
00258 
00259 
00260 /**
00261 * Writes the UART transmit buffer using the appropriate serial port.
00262 *
00263 */
00264 void LsrModule::WriteSerialMsg(void)
00265 {
00266     //write (const uint8_t *buffer, int length, const event_callback_t &callback, int event=SERIAL_EVENT_TX_COMPLETE)
00267     write(au8UartTxBuffer, au8UartTxBuffer[LSR_MODULE_MSG_LENGTH_BYTE_INDEX]);
00268     
00269 }   /*** End WriteSerialMsg ***/
00270 
00271 
00272 /**
00273 * Sends message type 0x01 (Query Version) to the module via UART communication.  This will spark
00274 * a response message from the module to the Arduino of type 0x81.  Subscribing to 0x81 in 
00275 * your main application will allow you to parse the response data.  See the description for 
00276 * SubscribeRxMsgCallback for more information.
00277 *
00278 */
00279 void LsrModule::QueryVersionMsg(void)
00280 {
00281     AddSerialMsgHeader(LSR_MODULE_QUERY_VERSION_MSG_TYPE, 5);
00282     AddSerialMsgTrailer();
00283 }   /*** End QueryVersionMsg ***/
00284 
00285 
00286 /**
00287 * Sends message type 0x0C (Sets Security Transmit Frame Counter) to the module via UART communication.  
00288 * This frame counter is used with RF messages transmitted with security to ensure sequential freshness. 
00289 * This sets the starting frame count and is automatically incremented on every secured packet sent.  
00290 * This will spark an ACK message from the module to the Arduino of type 0x8C.  Subscribing to 0x8C in 
00291 * your main application will allow you to parse the response data.  See the description for 
00292 * SubscribeRxMsgCallback for more information.
00293 *
00294 * Example:
00295 *
00296 * uint32_t u32FrameCounter = 0xAEDFEDFA;
00297 * SetSecurityTransmitFrameCounterMsg(&u32FrameCounter);
00298 *
00299 */
00300 void LsrModule::SetSecurityTransmitFrameCounterMsg(uint32_t* pu32FrameCounter ///< Pointer to 4 byte frame counter (LSB to MSB).
00301                              )
00302 {
00303     DWordu_t dwuFrameCounter;
00304 
00305     dwuFrameCounter.u32 = *pu32FrameCounter;
00306       
00307     AddSerialMsgHeader(LSR_MODULE_SET_SECURITY_TX_FRAME_COUNTER_MSG_TYPE, 11);
00308     AddSerialByteToMsgBuffer(dwuFrameCounter.dws.lb);
00309     AddSerialByteToMsgBuffer(dwuFrameCounter.dws.mlb);
00310     AddSerialByteToMsgBuffer(dwuFrameCounter.dws.mhb);
00311     AddSerialByteToMsgBuffer(dwuFrameCounter.dws.hb);
00312     AddSerialByteToMsgBuffer(0x00);        // Add filler byte.
00313     AddSerialByteToMsgBuffer(0x00);        // Add filler byte.
00314     AddSerialMsgTrailer();
00315 }   /*** End SetSecurityTransmitFrameCounterMsg ***/ 
00316 
00317 
00318 /**
00319 * Sends message type 0x0D (Query Security Transmit Frame Counter) to the module via UART communication.  This
00320 * will spark a response message from the module to the Arduino of type 0x8D.  Subscribing to 0x8D in your main 
00321 * application will allow you to parse the response data.  See the description for SubscribeRxMsgCallback
00322 * for more information.
00323 *
00324 */
00325 void LsrModule::QuerySecurityTransmitFrameCounterMsg(void)
00326 {
00327     AddSerialMsgHeader(LSR_MODULE_QUERY_SECURITY_TX_FRAME_COUNTER_MSG_TYPE, 5);
00328     AddSerialMsgTrailer();
00329 }   /*** End QuerySecurityTransmitFrameCounterMsg ***/ 
00330 
00331 
00332 /**
00333 * Sends message type 0x10 (Set Basic RF Settings) to the module via UART communication.
00334 * This will spark an ACK message from the module to the Arduino of type 0x90.  Subscribing to 0x90 in 
00335 * your main application will allow you to parse the response data.  See the description for 
00336 * SubscribeRxMsgCallback for more information.
00337 *
00338 */
00339 void LsrModule::SetBasicRfSettingsMsg(uint16_t u16PanId ///< Personal Area Network (PAN) ID assigned to module.
00340                                        , uint16_t u16AddrShort ///< 2 byte short address assigned to module.
00341                        , uint8_t* pu8AddrLong ///< Pointer to 8 byte long address assigned to module.  Do not assign a zero, even if using short addressing.
00342                        , uint8_t u8RfChannel ///< RF channel assigned to module.
00343                        , uint8_t u8TxPowerLevel ///< Transmit power assigned to module.
00344                        , uint8_t u8ReceiverConfig ///< 1 byte bitmask of receiver options.
00345                        , uint8_t* pu8SecurityKey ///< Pointer to 32 byte security key assigned to module.
00346                     )
00347 {
00348     Wordu_t wuPanId;
00349     Wordu_t wuShortAddr;
00350     
00351     wuPanId.u16 = u16PanId;
00352     wuShortAddr.u16 = u16AddrShort;
00353     
00354     if ((u8RfChannel >= LSR_MODULE_RF_CHANNEL_MIN) && (u8RfChannel <= LSR_MODULE_RF_CHANNEL_MAX) &&
00355         (u8TxPowerLevel <= LSR_MODULE_TX_POWER_LEVEL_MAX) &&
00356         (u8ReceiverConfig <= LSR_MODULE_RX_CONFIG_MAX))
00357     {
00358         AddSerialMsgHeader(LSR_MODULE_SET_BASIC_RF_SETTINGS_MSG_TYPE, 39);
00359         AddSerialByteToMsgBuffer(wuPanId.ws.lb);
00360         AddSerialByteToMsgBuffer(wuPanId.ws.hb);
00361         AddSerialByteToMsgBuffer(wuShortAddr.ws.lb);
00362         AddSerialByteToMsgBuffer(wuShortAddr.ws.hb);
00363 
00364         for (u8ForLoopCounter = 0; u8ForLoopCounter < 8; u8ForLoopCounter++)
00365         {
00366             AddSerialByteToMsgBuffer(*pu8AddrLong);
00367             pu8AddrLong++;
00368         }
00369     
00370         AddSerialByteToMsgBuffer(u8RfChannel);
00371         AddSerialByteToMsgBuffer(u8TxPowerLevel);
00372         AddSerialByteToMsgBuffer(u8ReceiverConfig);
00373 
00374         AddSerialByteToMsgBuffer(0x00);        // Add filler byte.
00375         AddSerialByteToMsgBuffer(0x00);        // Add filler byte.
00376         AddSerialByteToMsgBuffer(0x00);        // Add filler byte.
00377 
00378         for (u8ForLoopCounter = 0; u8ForLoopCounter < 16; u8ForLoopCounter++)
00379         {
00380             AddSerialByteToMsgBuffer(*pu8SecurityKey);
00381             pu8SecurityKey++;
00382         }
00383 
00384         AddSerialMsgTrailer();
00385     }
00386 }   /*** End SetBasicRfSettingsMsg ***/
00387 
00388 
00389 /**
00390 * Sends message type 0x11 (Query Basic RF Settings) to the module via UART communication.  This will spark
00391 * a response message from the module to the Arduino of type 0x91.  Subscribing to 0x91 in your main 
00392 * application will allow you to parse the response data.  See the description for SubscribeRxMsgCallback 
00393 * for more information.
00394 *
00395 */
00396 void LsrModule::QueryBasicRfSettingsMsg(void)
00397 {
00398     AddSerialMsgHeader(LSR_MODULE_QUERY_BASIC_RF_SETTINGS_MSG_TYPE, 5);
00399     AddSerialMsgTrailer();
00400 }   /*** End QueryBasicRfSettingsMsg ***/
00401 
00402 
00403 /**
00404 * Sends message type 0x12 (Save Settings to non-volatile Memory) to the module via UART communication.  Calling
00405 * this command will make your module retain all basic configuration settings on boot up.  This will spark an ACK 
00406 * message from the module to the Arduino of type 0x92.  Subscribing to 0x92 in your main application will allow 
00407 * you to parse the response data.  See the description for SubscribeRxMsgCallback for more information.
00408 *
00409 */
00410 void LsrModule::SaveSettingsToNVMemoryMsg(void)
00411 {
00412     AddSerialMsgHeader(LSR_MODULE_SAVE_SETTINGS_TO_NV_MEMORY_MSG_TYPE, 5);
00413     AddSerialMsgTrailer();
00414 }   /*** End SaveSettingsToNVMemoryMsg ***/
00415 
00416 
00417 /**
00418 * Sends message type 0x13 (Reset Request) to the module via UART communication.  This will make your module perform
00419 * a restart.  This will spark an ACK message from the module to the Arduino of type 0x93.  Subscribing to 0x93 in 
00420 * your main application will allow you to parse the response data.  See the description for SubscribeRxMsgCallback
00421 * for more information.
00422 *
00423 */
00424 void LsrModule::ResetRequestMsg(void)
00425 {
00426     AddSerialMsgHeader(LSR_MODULE_RESET_REQUEST_MSG_TYPE, 5);
00427     AddSerialMsgTrailer();
00428 }   /*** End ResetRequestMsg ***/
00429 
00430 
00431 /**
00432 * Sends message type 0x14 (Query Supply Voltage) to the module via UART communication.  This will spark a 
00433 * response message from the module to the Arduino of type 0x94.  Subscribing to 0x94 in your main application
00434 * will allow you to parse the response data.  See the description for SubscribeRxMsgCallback for more information.
00435 *
00436 */
00437 void LsrModule::QuerySupplyVoltageMsg(void)
00438 {
00439     AddSerialMsgHeader(LSR_MODULE_QUERY_SUPPLY_VOLTAGE_MSG_TYPE, 5);
00440     AddSerialMsgTrailer();
00441 }   /*** End QuerySupplyVoltageMsg ***/
00442 
00443 
00444 /**
00445 * Sends message type 0x15 (Query Statistics) to the module via UART communication.  Statistics include packets sent, 
00446 * acks received, packets received and broadcast packets received.  This will spark a response message from the module 
00447 * to the Arduino of type 0x95.  Subscribing to 0x94 in your main application will allow you to parse the response 
00448 * data.  See the description for SubscribeRxMsgCallback for more information.
00449 *
00450 */
00451 void LsrModule::QueryStatisticsMsg(void)
00452 {
00453     AddSerialMsgHeader(LSR_MODULE_QUERY_STATISTICS_MSG_TYPE, 5);
00454     AddSerialMsgTrailer();
00455 }   /*** End QueryStatisticsMsg ***/
00456 
00457 
00458 /**
00459 * Sends message type 0x16 (Clear Statistics) to the module via UART communication.  This will spark an ACK message 
00460 * from the module to the Arduino of type 0x96.  Subscribing to 0x96 in your main application will allow you to 
00461 * Parse the response data.  See the description for SubscribeRxMsgCallback for more information.
00462 *
00463 */
00464 void LsrModule::ClearStatisticsMsg(void)
00465 {
00466     AddSerialMsgHeader(LSR_MODULE_CLEAR_STATISTICS_MSG_TYPE, 5);
00467     AddSerialMsgTrailer();
00468 }   /*** End ClearStatisticsMsg ***/
00469 
00470 
00471 /**
00472 * Sends message type 0x18 (Set Host Data Rate) to the module via UART communication.  This will spark an ACK message 
00473 * from the module to the Arduino of type 0x98.  Subscribing to 0x98 in your main application will allow you to parse 
00474 * the response data.  See the description for SubscribeRxMsgCallback for more information.
00475 *
00476 */
00477 void LsrModule::SetHostDataRateMsg(uint8_t u8HostDataRate ///< Data rate for module to use when communicating via UART:
00478                                  ///< 0 = 1,200 bits/s
00479                                  ///< 1 = 2,400 bits/s
00480                                  ///< 2 = 4,800 bits/s
00481                                  ///< 3 = 9,600 bits/s
00482                                  ///< 4 = 19,200 bits/s
00483                                  ///< 5 = 38,400 bits/s
00484                                  ///< 6 = 57,600 bits/s
00485                                  ///< 7 = 115,200 bits/s
00486                                      )
00487 {
00488     if (u8HostDataRate <= LSR_MODULE_HOST_DATA_RATE_MAX)
00489     {
00490         AddSerialMsgHeader(LSR_MODULE_SET_HOST_DATA_RATE_MSG_TYPE, 6);
00491         AddSerialByteToMsgBuffer(u8HostDataRate);
00492         AddSerialMsgTrailer();
00493         
00494         // 2.4 ms for the data rate change packet to be transmitted.
00495         wait_ms(3);
00496         
00497         switch (u8HostDataRate)
00498         {
00499             case LSR_MODULE_HOST_DATA_RATE_1200:
00500                 baud(1200);
00501                 break;
00502             case LSR_MODULE_HOST_DATA_RATE_2400:
00503                 baud(2400);
00504                 break;
00505             case LSR_MODULE_HOST_DATA_RATE_4800:
00506                 baud(4800);
00507                 break;
00508             case LSR_MODULE_HOST_DATA_RATE_9600:
00509                 baud(9600);
00510                 break;
00511             case LSR_MODULE_HOST_DATA_RATE_19200:
00512                 baud(19200);
00513                 break;
00514             case LSR_MODULE_HOST_DATA_RATE_38400:
00515                 baud(38400);
00516                 break;
00517             case LSR_MODULE_HOST_DATA_RATE_57600:
00518                 baud(57600);
00519                 break;
00520             case LSR_MODULE_HOST_DATA_RATE_115200:
00521                 baud(115200);
00522                 break;
00523             case LSR_MODULE_HOST_DATA_RATE_230400:
00524                 baud(230400);
00525                 break;
00526             case LSR_MODULE_HOST_DATA_RATE_460800:
00527                 baud(460800);
00528                 break;
00529             case LSR_MODULE_HOST_DATA_RATE_921600:
00530                 baud(921600);
00531                 break;
00532         }
00533     }
00534 }   /*** End SetHostDataRateMsg ***/
00535 
00536 
00537 /**
00538 * Sends message type 0x19 (Set RF Data Rate) to the module via UART communication.  This will spark an ACK message 
00539 * from the module to the Arduino of type 0x98.  Subscribing to 0x98 in your main application will allow you to parse 
00540 * the response data.  See the description for SubscribeRxMsgCallback for more information.
00541 *
00542 */
00543 void LsrModule::SetRfDataRateMsg(uint8_t u8RfDataRate ///< Data rate for module to use when communicating via radio:
00544                                  ///< 0 = 1,200 bits/s
00545                                  ///< 1 = 2,400 bits/s
00546                                  ///< 2 = 4,800 bits/s
00547                                  ///< 3 = 9,600 bits/s
00548                                  ///< 4 = 19,200 bits/s
00549                                  ///< 5 = 38,400 bits/s
00550                                  ///< 6 = 57,600 bits/s
00551                                  ///< 7 = 115,200 bits/s
00552                                      )
00553 {
00554     if (u8RfDataRate <= LSR_MODULE_RF_DATA_RATE_MAX)
00555     {
00556         AddSerialMsgHeader(LSR_MODULE_SET_RF_DATA_RATE_MSG_TYPE, 6);
00557         AddSerialByteToMsgBuffer(u8RfDataRate);
00558         AddSerialMsgTrailer();
00559     }
00560 }   /*** End SetRfDataRateMsg ***/
00561 
00562 /**
00563 * Sends message type 0x20 (Send Simple Short Address RF Data Packet) to the module via UART communication.
00564 * This will spark an ACK message from the module to the Arduino of type 0xA0.  Subscribing to 0xA0 in 
00565 * your main application will allow you to parse the response data.  See the description for SubscribeRxMsgCallback
00566 * for more information.
00567 *
00568 * Example:
00569 *
00570 * uint8_t u8Data[5] = {4, 7, 3, 5, 8};
00571 * uint8_t u8PacketID;
00572 *
00573 * SendSimpleShortAddrRfDataPacketMsg(&u8Data, sizeof(u8Data, 213, 0, packetID++);
00574 *
00575 */
00576 void LsrModule::SendSimpleShortAddrRfDataPacketMsg(uint8_t* pu8Data ///< Pointer to data being sent.
00577                                                     , uint8_t u8DataLength ///< Length of data being sent.
00578                             , uint16_t u16DestAddress ///< 2 byte destination address.
00579                             , uint8_t u8TxOptions ///< 1 byte bit mask of transmit options.
00580                             , uint8_t u8PacketId ///< ID assigned to packet.
00581                              )
00582 {
00583     if ((u8TxOptions <= LSR_MODULE_TX_OPTIONS_MAX) &&
00584         ((((u8TxOptions & LSR_MODULE_TX_OPTIONS_USE_SECURITY_BITMASK) != 0) && (u8DataLength <= (LSR_MODULE_SIMPLE_SHORT_RF_DATA_LENGTH - LSR_MODULE_SECURITY_OVERHEAD))) ||
00585          (((u8TxOptions & LSR_MODULE_TX_OPTIONS_USE_SECURITY_BITMASK) == 0) && (u8DataLength <= LSR_MODULE_SIMPLE_SHORT_RF_DATA_LENGTH))))
00586     {
00587         AddSerialMsgHeader(LSR_MODULE_SEND_SIMPLE_SHORT_RF_DATA_PACKET_MSG_TYPE, (u8DataLength + 9));
00588     
00589         AddSerialByteToMsgBuffer(u8TxOptions);
00590         AddSerialByteToMsgBuffer(u16DestAddress % 256);
00591         AddSerialByteToMsgBuffer(u16DestAddress >> 8);
00592         AddSerialByteToMsgBuffer(u8PacketId);
00593           
00594         while (u8DataLength != 0)
00595         {
00596             AddSerialByteToMsgBuffer(*pu8Data);
00597             pu8Data++;
00598             u8DataLength--;
00599         }
00600         
00601         AddSerialMsgTrailer();
00602     }
00603 }   /*** End SendSimpleShortAddrRfDataPacketMsg ***/
00604 
00605 
00606 /**
00607 * Sends message type 0x22 (Send Advanced Short Address RF Data Packet) to the module via UART communication.
00608 * This will spark an ACK message from the module to the Arduino of type 0xA2.  Subscribing to 0xA2 in 
00609 * your main application will allow you to parse the response data.  See the description for SubscribeRxMsgCallback
00610 * for more information.
00611 *
00612 * Example:
00613 *
00614 * uint8_t u8Data[5] = {4, 7, 3, 5, 8};
00615 * uint8_t u8PacketID;
00616 *
00617 * SendAdvancedShortAddrRfDataPacketMsg(&u8Data, sizeof(u8Data, 1111, 213, 0, packetID++);
00618 *
00619 */
00620 void LsrModule::SendAdvancedShortAddrRfDataPacketMsg(uint8_t* pu8Data ///< Pointer to data being sent.
00621                                                       , uint8_t u8DataLength ///< Length of data being sent.
00622                               , uint16_t u16DestPanId ///< 2 byte Personal Area Network (PAN) ID.
00623                               , uint16_t u16DestAddress ///< 2 byte destination address.
00624                               , uint8_t u8TxOptions ///< 1 byte bit mask of transmit options.
00625                               , uint8_t u8PacketId ///< ID assigned to packet.
00626                             )
00627 {
00628     if ((u8TxOptions <= LSR_MODULE_TX_OPTIONS_MAX) &&
00629         ((((u8TxOptions & LSR_MODULE_TX_OPTIONS_USE_SECURITY_BITMASK) != 0) && (u8DataLength <= (LSR_MODULE_ADVANCED_SHORT_RF_DATA_LENGTH - LSR_MODULE_SECURITY_OVERHEAD))) ||
00630          (((u8TxOptions & LSR_MODULE_TX_OPTIONS_USE_SECURITY_BITMASK) == 0) && (u8DataLength <= LSR_MODULE_ADVANCED_SHORT_RF_DATA_LENGTH))))
00631     {
00632         AddSerialMsgHeader(LSR_MODULE_SEND_ADVANCED_SHORT_RF_DATA_PACKET_MSG_TYPE, (u8DataLength + 11));
00633     
00634         AddSerialByteToMsgBuffer(u8TxOptions);
00635         AddSerialByteToMsgBuffer(u16DestPanId % 256);
00636         AddSerialByteToMsgBuffer(u16DestPanId >> 8);
00637         AddSerialByteToMsgBuffer(u16DestAddress % 256);
00638         AddSerialByteToMsgBuffer(u16DestAddress >> 8);
00639         AddSerialByteToMsgBuffer(u8PacketId);
00640           
00641         while (u8DataLength != 0)
00642         {
00643             AddSerialByteToMsgBuffer(*pu8Data);
00644             pu8Data++;
00645             u8DataLength--;
00646         }
00647         
00648         AddSerialMsgTrailer();
00649     }
00650 }   /*** End SendAdvancedShortAddrRfDataPacketMsg ***/
00651 
00652 
00653 /**
00654 * Sends message type 0x24 (Send Simple Long Address RF Data Packet) to the module via UART communication.
00655 * This will spark an ACK message from the module to the Arduino of type 0xA4.  Subscribing to 0xA4 in 
00656 * your main application will allow you to parse the response data.  See the description for SubscribeRxMsgCallback
00657 * for more information.
00658 *
00659 * Example:
00660 *
00661 * uint8_t u8Data[5] = {4, 7, 3, 5, 8};
00662 * uint8_t u8DestAddress[8] = {2, 3, 6, 5, 2, 3, 6, 5};
00663 * uint8_t u8PacketID;
00664 *
00665 * SendSimpleLongAddrRfDataPacketMsg(&u8Data, sizeof(u8Data), &u8DestAddress, 0, packetID++);
00666 *
00667 */
00668 void LsrModule::SendSimpleLongAddrRfDataPacketMsg(uint8_t* pu8Data ///< Pointer to data being sent.
00669                                                    , uint8_t u8DataLength ///< Length of data being sent.
00670                            , uint8_t* pu8DestAddress ///< Pointer to 8 byte destination address.
00671                            , uint8_t u8TxOptions ///< 1 byte bit mask of transmit options.
00672                            , uint8_t u8PacketId ///< ID assigned to packet.
00673                             )
00674 {
00675     if ((u8TxOptions <= LSR_MODULE_TX_OPTIONS_MAX) &&
00676         ((((u8TxOptions & LSR_MODULE_TX_OPTIONS_USE_SECURITY_BITMASK) != 0) && (u8DataLength <= (LSR_MODULE_SIMPLE_LONG_RF_DATA_LENGTH - LSR_MODULE_SECURITY_OVERHEAD))) ||
00677          (((u8TxOptions & LSR_MODULE_TX_OPTIONS_USE_SECURITY_BITMASK) == 0) && (u8DataLength <= LSR_MODULE_SIMPLE_LONG_RF_DATA_LENGTH))))
00678     {
00679         AddSerialMsgHeader(LSR_MODULE_SEND_SIMPLE_LONG_RF_DATA_PACKET_MSG_TYPE, (u8DataLength + 15));
00680     
00681         AddSerialByteToMsgBuffer(u8TxOptions);
00682         
00683         for (u8ForLoopCounter = 0; u8ForLoopCounter < 8; u8ForLoopCounter++)
00684         {
00685             AddSerialByteToMsgBuffer(*pu8DestAddress);
00686             pu8DestAddress++;
00687         }
00688         
00689         AddSerialByteToMsgBuffer(u8PacketId);
00690           
00691         while (u8DataLength != 0)
00692         {
00693             AddSerialByteToMsgBuffer(*pu8Data);
00694             pu8Data++;
00695             u8DataLength--;
00696         }
00697         
00698         AddSerialMsgTrailer();
00699     }
00700 }   /*** End SendSimpleLongAddrRfDataPacketMsg ***/
00701 
00702 
00703 /**
00704 * Sends message type 0x26 (Send Advanced Long Address RF Data Packet) to the module via UART communication.
00705 * This will spark an ACK message from the module to the Arduino of type 0xA6.  Subscribing to 0xA6 in 
00706 * your main application will allow you to parse the response data.  See the description for SubscribeRxMsgCallback
00707 * for more information.
00708 *
00709 * Example:
00710 *
00711 * uint8_t u8Data[5] = {4, 7, 3, 5, 8};
00712 * uint8_t u8DestAddress[8] = {2, 3, 6, 5, 2, 3, 6, 5};
00713 * uint8_t u8PacketID;
00714 *
00715 * SendAdvancedLongAddrRfDataPacketMsg(&u8Data, sizeof(u8Data), 1111, &u8DestAddress, 0, packetID++);
00716 *
00717 */
00718 void LsrModule::SendAdvancedLongAddrRfDataPacketMsg(uint8_t* pu8Data ///< Pointer to data being sent.
00719                                                      , uint8_t u8DataLength ///< Length of data being sent.
00720                              , uint16_t u16DestPanId ///< 2 byte Personal Area Network (PAN) ID.
00721                              , uint8_t* pu8DestAddress ///< Pointer to 8 byte destination address.
00722                              , uint8_t u8TxOptions ///< 1 byte bit mask of transmit options.
00723                              , uint8_t u8PacketId ///< ID assigned to packet.
00724                                )
00725 {
00726     if ((u8TxOptions <= LSR_MODULE_TX_OPTIONS_MAX) &&
00727         ((((u8TxOptions & LSR_MODULE_TX_OPTIONS_USE_SECURITY_BITMASK) != 0) && (u8DataLength <= (LSR_MODULE_ADVANCED_LONG_RF_DATA_LENGTH - LSR_MODULE_SECURITY_OVERHEAD))) ||
00728          (((u8TxOptions & LSR_MODULE_TX_OPTIONS_USE_SECURITY_BITMASK) == 0) && (u8DataLength <= LSR_MODULE_ADVANCED_LONG_RF_DATA_LENGTH))))
00729     {
00730         AddSerialMsgHeader(LSR_MODULE_SEND_ADVANCED_LONG_RF_DATA_PACKET_MSG_TYPE, (u8DataLength + 17));
00731     
00732         AddSerialByteToMsgBuffer(u8TxOptions);
00733         AddSerialByteToMsgBuffer(u16DestPanId % 256);
00734         AddSerialByteToMsgBuffer(u16DestPanId >> 8);
00735 
00736         for (u8ForLoopCounter = 0; u8ForLoopCounter < 8; u8ForLoopCounter++)
00737         {
00738             AddSerialByteToMsgBuffer(*pu8DestAddress);
00739             pu8DestAddress++;
00740         }
00741 
00742         AddSerialByteToMsgBuffer(u8PacketId);
00743           
00744         while (u8DataLength != 0)
00745         {
00746             AddSerialByteToMsgBuffer(*pu8Data);
00747             pu8Data++;
00748             u8DataLength--;
00749         }
00750         
00751         AddSerialMsgTrailer();
00752     }
00753 }   /*** End SendAdvancedLongAddrRfDataPacketMsg ***/
00754 
00755 
00756 /**
00757 * Sends message type 0x44 (Channel Energy Scan) to the module via UART communication.  This will spark a response message from the module 
00758 * to the host of type 0xC5.  Subscribing to 0xC5 in your main application will allow you to parse the response 
00759 * data.  See the description for SubscribeRxMsgCallback for more information.
00760 *
00761 * Example (Channel 5 for SiFLEX02, Channel 15 for ProFLEX01):
00762 *
00763 * ChannelEnergyScanMsg(11110111, 7);
00764 *
00765 */
00766 void LsrModule::ChannelEnergyScanMsg(uint16_t u16ChannelMask ///< Two byte bitmask (LSB to MSB) of the RF channels to perfom an enrgy scan on.
00767                                       , uint8_t u8ScanDuration ///< Duration to scan for:
00768                                    ///< 0 = 61.4 mSec
00769                                    ///< 1 = 92.2 mSec
00770                                    ///< 2 = 154 mSec
00771                                    ///< 3 = 276 mSec
00772                                    ///< 4 = 522 mSec
00773                                    ///< 5 = 1.01 Sec
00774                                    ///< 6 = 2.00 Sec
00775                                    ///< 7 = 3.96 Sec
00776                                    ///< 8 = 7.90 Sec
00777                                    ///< 9 = 15.8 Sec
00778                                    ///< 10 = 31.5 Sec
00779                                    ///< 11 = 62.9 Sec
00780                                    ///< 12 = 126 Sec
00781                                    ///< 13 = 252 Sec
00782                                    ///< 14 = 503 Sec
00783                                                                 
00784                                        )
00785 {
00786     Wordu_t wuChannelMask;
00787     
00788     wuChannelMask.u16 = u16ChannelMask;
00789     
00790     if (u8ScanDuration <= LSR_MODULE_SCAN_DURATION_MAX)
00791     {
00792         AddSerialMsgHeader(LSR_MODULE_CHANNEL_ENERGY_SCAN_MSG_TYPE, 8);
00793         AddSerialByteToMsgBuffer(wuChannelMask.ws.lb);
00794         AddSerialByteToMsgBuffer(wuChannelMask.ws.hb);
00795         AddSerialByteToMsgBuffer(u8ScanDuration);
00796         AddSerialMsgTrailer();
00797     }
00798 }   /*** End ChannelEnergyScanMsg ***/
00799 
00800 /**
00801 * Sends message type 0x51 (Query Host Interface Configuration) to the module via UART communication.  This will spark a 
00802 * response message from the module to the host of type 0xD1.  Subscribing to 0xD1 in your main application
00803 * will allow you to parse the response data.  See the description for SubscribeRxMsgCallback for more information.
00804 *
00805 */
00806 void LsrModule::QueryHostInterfaceConfiguration(void)
00807 {
00808     AddSerialMsgHeader(LSR_MODULE_QUERY_HOST_INTERFACE_CONFIGURATION, 5);
00809     AddSerialMsgTrailer();
00810 }   /*** End QuerySupplyVoltageMsg ***/
00811 
00812 
00813 
00814 /**
00815 * Verifies msg type and length.
00816 * @return True: Valid msg length and type.  False: Invalid msg length or type.
00817 *
00818 */
00819 bool LsrModule::ValidMsgLengthAndType(uint8_t u8MsgType ///< Received UART message type.
00820                                        , uint8_t u8MsgLength ///< Received UART message length.
00821                                         )
00822 {
00823     if ((u8MsgLength >= cau8RxMsgLengthAndTypeTable[u8MsgType - LSR_MODULE_MIN_SERIAL_RX_MSG_TYPE][0]) &&
00824         (u8MsgLength <= cau8RxMsgLengthAndTypeTable[u8MsgType - LSR_MODULE_MIN_SERIAL_RX_MSG_TYPE][1]))
00825     {
00826         return true;
00827     }
00828     return false;
00829 }  /*** End ValidMsgLengthAndType ***/
00830 
00831 
00832 /**
00833 * Verifies message checksum.
00834 * @return True: Valid checksum.  False: Invalid checksum.
00835 *
00836 */
00837 bool LsrModule::ValidRxChecksum(uint8_t* pu8MsgBuffer ///< Pointer to received UART buffer.
00838                                  , uint8_t u8MsgLength ///< Received UART message length.
00839                                   )
00840 {
00841     uint8_t u8Checksum = 0;
00842 
00843     for (u8ForLoopCounter = 0; u8ForLoopCounter < (u8MsgLength - 2); u8ForLoopCounter++)
00844     {
00845         u8Checksum += au8UartRxBuffer[u8ForLoopCounter];
00846     }
00847 
00848     if (au8UartRxBuffer[u8MsgLength-2] == u8Checksum)
00849     {
00850         return true;
00851     }
00852     
00853     return false;
00854 }  /*** End ValidRxChecksum ***/
00855 
00856 
00857 /**
00858 * Calls appropriate callback function for received message.
00859 * 
00860 */
00861 void LsrModule::HostProcessCallbackMsgStart(uint8_t* pu8MsgBuffer ///< Pointer to received message.
00862                                              , uint8_t u8Length ///< Length of received message.
00863                                               )
00864 {
00865     if ((ptrRxMsgCallbackTable[(*(pu8MsgBuffer + LSR_MODULE_MSG_TYPE_BYTE_INDEX)) - LSR_MODULE_MIN_SERIAL_RX_MSG_TYPE]) != NULL)
00866     {
00867         ptrRxMsgCallbackTable[(*(pu8MsgBuffer + LSR_MODULE_MSG_TYPE_BYTE_INDEX)) - LSR_MODULE_MIN_SERIAL_RX_MSG_TYPE]();
00868     }
00869 }   /*** End HostProcessCallbackMsgStart ***/
00870 
00871 
00872 /**
00873 * Determines if appropriate serial port is available.
00874 * @return True: Serial is available.  False: Serial is unavailable.
00875 *
00876 */
00877 bool LsrModule::SerialAvailable(void)
00878 {
00879     if (readable())
00880     {
00881         return true;
00882     }
00883     
00884     return false;
00885 }   /*** End SerialAvailable ***/
00886 
00887 
00888 /**
00889 * Reads appropriate serial port.
00890 * @return Byte read.
00891 *
00892 */
00893 uint8_t LsrModule::SerialRead(void)
00894 {
00895     return getc();
00896     
00897 }   /*** End SerialRead ***/
00898 
00899 
00900 /**
00901 * Refreshes and restarts Rx state machine.
00902 *
00903 */
00904 void LsrModule::SerialRxCleanupRestart(void)
00905 {
00906     SerialFlush();
00907     u8UartRxBufferIndex = LSR_MODULE_MSG_START_BYTE_INDEX;
00908     ptrHostState = &LsrModule::HostRxWaitForMsgStartByteState;
00909 }   /*** End SerialRxCleanupRestart ***/
00910 
00911 
00912 /**
00913 * Waits for data packet start byte.
00914 *
00915 */
00916 void LsrModule::HostRxWaitForMsgStartByteState(void)
00917 {
00918     while (readable() && (SerialRead() == LSR_MODULE_SERIAL_MSG_START_BYTE))
00919     {
00920         au8UartRxBuffer[u8UartRxBufferIndex++] = LSR_MODULE_SERIAL_MSG_START_BYTE;
00921         ptrHostState = &LsrModule::HostRxGetMsgLengthState;
00922     }
00923 }   /*** End HostRxWaitForMsgStartByteState ***/
00924 
00925 
00926 /**
00927 * Gets data packet length byte.
00928 *
00929 */
00930 void LsrModule::HostRxGetMsgLengthState(void)
00931 {
00932     while (readable())
00933     {
00934         u8RxReadByte = SerialRead();
00935 
00936         if ((u8RxReadByte >= LSR_MODULE_MIN_SERIAL_RX_MSG_LENGTH) &&
00937             (u8RxReadByte <= LSR_MODULE_MAX_SERIAL_RX_MSG_LENGTH))
00938         {
00939             au8UartRxBuffer[u8UartRxBufferIndex++] = u8RxReadByte;
00940             ptrHostState = &LsrModule::HostRxGetMsgTypeState;
00941         }
00942         else
00943         {
00944             ptrHostState = &LsrModule::SerialRxCleanupRestart;
00945         }
00946     }
00947 }   /*** End HostRxGetMsgLengthState ***/
00948 
00949 
00950 /**
00951 * Gets data packet type byte.
00952 *
00953 */
00954 void LsrModule::HostRxGetMsgTypeState(void)
00955 {
00956     while (readable())
00957     {
00958 
00959         u8RxReadByte = SerialRead();
00960         
00961         if (ValidMsgLengthAndType(u8RxReadByte, au8UartRxBuffer[LSR_MODULE_MSG_LENGTH_BYTE_INDEX]))
00962         {
00963             au8UartRxBuffer[u8UartRxBufferIndex++] = u8RxReadByte;
00964             ptrHostState = &LsrModule::HostRxWaitToGetRestOfMsgState;
00965         }
00966         else
00967         {
00968             ptrHostState = &LsrModule::SerialRxCleanupRestart;
00969         }
00970     }
00971 }   /*** End HostRxGetMsgTypeState ***/
00972 
00973 
00974 /**
00975 * Grabs rest of data packet bytes.
00976 *
00977 */
00978 void LsrModule::HostRxWaitToGetRestOfMsgState(void)
00979 {
00980     while (readable())
00981     {
00982         u8RxReadByte = SerialRead();
00983         au8UartRxBuffer[u8UartRxBufferIndex++] = u8RxReadByte;
00984         
00985         if (u8UartRxBufferIndex > LSR_MODULE_MAX_SERIAL_RX_MSG_LENGTH)
00986         {
00987             ptrHostState = &LsrModule::SerialRxCleanupRestart;
00988         }
00989         else if ((u8RxReadByte == LSR_MODULE_SERIAL_MSG_END_BYTE) && (u8UartRxBufferIndex == au8UartRxBuffer[LSR_MODULE_MSG_LENGTH_BYTE_INDEX]))
00990         {
00991             ptrHostState = &LsrModule::HostRxValidateMsgState;
00992         }
00993     }
00994 }   /*** End HostRxWaitToGetRestOfMsgState ***/
00995 
00996 
00997 /**
00998 * Validates received message.
00999 *
01000 */
01001 void LsrModule::HostRxValidateMsgState(void)
01002 {
01003 
01004     if (ValidRxChecksum(au8UartRxBuffer, au8UartRxBuffer[LSR_MODULE_MSG_LENGTH_BYTE_INDEX]))    // Is checksum good?
01005     {
01006         ptrHostState = &LsrModule::HostRxGoodMsgState;     // Good checksum - next state
01007     }
01008     else
01009     {
01010         ptrHostState = &LsrModule::SerialRxCleanupRestart;   // Bad checksum - restart
01011     }
01012 }   /*** End HostRxValidateMsgState ***/
01013 
01014 
01015 /**
01016 * Calls appropriate received UART message callback and starts state machine over.
01017 *
01018 */
01019 void LsrModule::HostRxGoodMsgState(void)
01020 {   
01021     pu8RxBuffer = au8UartRxBuffer;
01022     u8RxMsgLength = au8UartRxBuffer[LSR_MODULE_MSG_LENGTH_BYTE_INDEX];
01023     HostProcessCallbackMsgStart(au8UartRxBuffer, u8RxMsgLength);
01024     ptrHostState = &LsrModule::SerialRxCleanupRestart;      // Start new RX sequence
01025 }   /*** End HostRxGoodMsgState ***/