⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 exm.c

📁 关于微型操作系统的小代码作为特殊通信用的
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright (c) 1999-2002 ITRAN Communications, Ltd. All rights reserved */

/*
  This application is a simple example of using the modem for switching lamp. We have only two devices in
  our network: "switch" and "lamp". The present application impements all functions for the switch. It has 
  one button and indicator. When the user presses the button the aplication sends command to the lamp via 
  the PLC network. The lamp receives the command and turns into desired state. Then the lamp sends the answer
  about its state to the switch via the network. If the switch device does not receive the answer for some reason
  it decides that the target had not received its command and repeats the reques again. 
  */

#include "Portability.h"
#include "HalExm.h"
#include "WtIfcDef.h"
#include "DLHdi.h"

// ****************************************************************************************************

// sizes of the application buffers
#define Exm_RESP_SIZE           164
#define Exm_PKT_SIZE            164

// indices of the command payload
#define Exm_CMDIDX_ATTN         0
#define Exm_CMDIDX_ID           1
#define Exm_CMDIDX_LENLO        2
#define Exm_CMDIDX_LENHI        3 
#define Exm_CMDIDX_PL           4

#define Exm_ANSW_PL_IDX_CMDID   0
#define Exm_ANSW_PL_IDX_RESULT  1

// packet header parameters
#define Exm_LEN_HEADER          4
#define Exm_LEN_PKT_FILEDS      8

// device address in the network
#define Exm_NETID               73
#define Exm_NODEID              19
#define Exm_TARGET1ID           3

// parameters of media access
#define Exm_REPEATS             3
#define Exm_RETRIES             3
#define Exm_RXTYPE              1

// ****************************************************************************************************

#define Exm_W2B( x ) (BYTE)x, (BYTE)(x >> 8)  // converts one wort into list of two bytes

// reset command
BYTE Exm_Cmd_Reset[]   = { WtIfcDef_ATTN, WtIfcDef_ePcCmd_RST, 1, 0, 0 };

// start single device mode command
BYTE Exm_Cmd_StartSdm[]   = { WtIfcDef_ATTN, WtIfcDef_ePcCmd_SSD, 1, 0, 0 };

// set modulation command
BYTE Exm_Cmd_Modulation[] = { WtIfcDef_ATTN, WtIfcDef_ePcCmd_CW,  1, 0, DLHdi_CODE_RATEMODE_DCSK4 };

// set repeats and retries command
BYTE Exm_Cmd_Repeats[]    = { WtIfcDef_ATTN, WtIfcDef_ePcCmd_SRC, 2, 0, Exm_REPEATS, Exm_RETRIES };

// set RX packet type command
BYTE Exm_Cmd_RxType[]     = { WtIfcDef_ATTN, WtIfcDef_ePcCmd_RPT, 1, 0, Exm_RXTYPE };

// set address command
BYTE Exm_Cmd_SetAddress[] = { WtIfcDef_ATTN, WtIfcDef_ePcCmd_ADE, 4, 0, Exm_W2B(Exm_NETID), Exm_W2B(Exm_NODEID)  };

BYTE Exm_Cmd_SendCfgPacket[] =
{
  WtIfcDef_ATTN,
  WtIfcDef_ePcCmd_SC,
  16, 0,
  0xF8,                       // configuration packet
  0x3F, 0xC4, 0xDE, 0x3C,
  0x6E, 0x28, 0x28, 0x64,
  0x64, 0xB8, 0x4F, 0x51,
  0x00, 0x00, 0x00
};

BYTE Exm_Cmd_ReadEEPROM[] =
{
  WtIfcDef_ATTN,
  WtIfcDef_ePcCmd_REP,
  5, 0,
  10, 0, 0, 0,                   // arbitrary address to read data from
  20                              // size of the data
}; 

BYTE Exm_Cmd_WriteEEPROM[] = 
{ 
  WtIfcDef_ATTN, 
  WtIfcDef_ePcCmd_REP, 
  9, 0,              
  14, 0, 0, 0,                   // arbitrary address to write data to
  0x01, 0x0A, 0x0B, 0x04, 0x02   // some data
}; 

BYTE Exm_Cmd_GetDLLParam[] = { WtIfcDef_ATTN, WtIfcDef_ePcCmd_GCD, 1, 0, 0 };

// this packet will be sent to the target device when the application decides to turn the "lamp" on
BYTE Exm_LampOnPkt[] = 
{ 
  WtIfcDef_ATTN, 
  WtIfcDef_ePcCmd_PT, 
  Exm_LEN_PKT_FILEDS + 11, 
  0, 
  DLHdi_CodeCmdSpPrty_NORM,
  DLHdi_CodeCmdSpServ_REP,
  Exm_W2B(Exm_NETID),
  Exm_W2B(Exm_NODEID),
  Exm_W2B(Exm_TARGET1ID),
  'L', 'a', 'm', 'p', '_', 'O', 'N', '_', '_', '_', 'R' 
}; 

// this packet will be sent to the target device when the application decides to turn the "lamp" off
BYTE Exm_LampOffPkt[] = 
{ 
  WtIfcDef_ATTN, 
  WtIfcDef_ePcCmd_PT, 
  Exm_LEN_PKT_FILEDS + 11, 
  0, 
  DLHdi_CodeCmdSpPrty_NORM,
  DLHdi_CodeCmdSpServ_REP,
  Exm_W2B(Exm_NETID),
  Exm_W2B(Exm_NODEID),
  Exm_W2B(Exm_TARGET1ID),
  'L', 'a', 'm', 'p', '_', 'O', 'F', 'F', '_', '_', 'R' 
}; 


// keywords in the answer packets from the target device ("the lamp" )
char Exm_LampOnAnsw[]  = "LampIsOn";
char Exm_LampOffAnsw[] = "LampIsOff";

// **************************************************************************************************** 
// **************************************************************************************************** 
// states of the application receiver 

typedef
  enum tagExm_eRecState_t
  {
    Exm_eRecState_Attn          = 0,  // the receiver waits for incoming data from the modem       
    Exm_eRecState_Command       = 1,  // it is receiving the answer ID
    Exm_eRecState_Length_Low    = 3,  // it is receiving the low byte of the length 
    Exm_eRecState_Length_High   = 4,  // it is receiving the high byte of the length 
    Exm_eRecState_Payload       = 5   // it is receiving the answer or packet payload 
  } Exm_eRecState_t;

// **************************************************************************************************** 
// global variables of the application

typedef
  struct tagExm_GLOBAL_T
  {
    Exm_eRecState_t eRecState;                  // the application receiver state
    WORD            wRecPLIdx;                  // current index of incoming answer or packet payload 
    WORD            wRecLength;                 // incoming answer/packet length
    BYTE            byRecAnswID;                // ID value of incomin answer 
    BYTE            sRecAnswBuf[Exm_RESP_SIZE]; // buffer for storing the incoming answer   
    BOOL            bRecAnsw;                   // flag for signaling that the receiver has new answer in its buffer  
    BOOL            bResetDetected;             // flag for signaling the modem reset
    BYTE            sPktBuf[Exm_PKT_SIZE];      // buffer for storing the incoming packet
    BOOL            bSwState;                   // the "switch" state
    BOOL            bRemoteLampState;           // state of the target device "lamp" as it known to our application 
    BOOL            bLampOffPktReceived;        // the application has received "the lamp is off" feedback from the target device
    BOOL            bLampOnPktReceived;         // the application has received "the lamp is on" feedback from the target device
  } Exm_GLOBAL_T;

// **************************************************************************************************** 

Exm_GLOBAL_T Exm;

// **************************************************************************************************** 
//                       on sending data end callback 
//
// Description: this function is called by HAL module when the transmission ends 
//
// **************************************************************************************************** 

void HalExm_CB_OnSendDataEnd( void )
{
}

// **************************************************************************************************** 
//                      fill the answer buffer            
//
// Description: this function fills the modem answer buffer with a byte and moves the current payload
//              index  
//
// Arguments:   byData is one byte of answer payload
//
// **************************************************************************************************** 

void s_FillAnswBuf( BYTE byData )
{
  Exm.sRecAnswBuf[Exm.wRecPLIdx++] = byData;                          // put the byte into the answer buffer 
                                                                      // and increment the index
  if( Exm.wRecPLIdx == Exm.wRecLength )                               // check if the buffer is full 
  {          
    Exm.eRecState = Exm_eRecState_Attn;                               // reset the receiver state 
    Exm.bRecAnsw  = TRUE;                                             // set "we have got an answer" flag
    if( Exm.byRecAnswID == WtIfcDef_eDLLCmd_Responce                  // if we have received the "reset" notification  
        && Exm.sRecAnswBuf[Exm_ANSW_PL_IDX_CMDID] == WtIfcDef_ePcCmd_RST )
    {
      Exm.bResetDetected = TRUE;                                      // set the reset flag 
    }
  }          
}

// **************************************************************************************************** 
//                      fill the answer buffer            
//
// Description: this function fills the packet buffer with a byte and moves the current payload
//              index  
//
// Arguments:   byData is one byte of packet payload
//
// **************************************************************************************************** 

#define Exm_INC_PKT_PL_START_IDX  15                            // index of the data start in the packet payload

void s_FillPktBuf( BYTE byData )
{
  static BOOL bLmpOnD, bLmpOffD;                                // variables for detecting the keyword in the packet
 
  if( Exm.wRecPLIdx == 0 )                                      // if the byte is the first one in the packet payload
  {
    bLmpOnD  = TRUE;                                            // reset the variables
    bLmpOffD = TRUE;
  }  
    
  if( Exm.wRecPLIdx >= Exm_INC_PKT_PL_START_IDX )               // if the index has reached the keyword   
  {
    // compare the data with "on" keyword  
    if( byData != Exm_LampOnAnsw[Exm.wRecPLIdx - Exm_INC_PKT_PL_START_IDX] )  {  bLmpOnD  = FALSE; }
    // compare with off keyword
    if( byData != Exm_LampOffAnsw[Exm.wRecPLIdx - Exm_INC_PKT_PL_START_IDX] ) {  bLmpOffD  = FALSE; }
  }  
  Exm.sPktBuf[Exm.wRecPLIdx] = byData;                          // store the data in the packet buffer   
  if( ++Exm.wRecPLIdx == Exm.wRecLength )                       // increment the payload index and chek for the packet end
  {
    Exm.eRecState = Exm_eRecState_Attn;                         // reset the receiver state
    if( bLmpOnD ) { Exm.bLampOnPktReceived = TRUE; }            // if the packet contains the "lamp is on" answer
    if( bLmpOffD ) { Exm.bLampOffPktReceived = TRUE; }          // if the packet contains the "lamp is off" answer
  }
}

// **************************************************************************************************** 
//                error case hander
//
// Description: Just reset the receiver state 
//
// **************************************************************************************************** 

void s_OtherType( void )
{
  if( ++Exm.wRecPLIdx == Exm.wRecLength ) { Exm.eRecState = Exm_eRecState_Attn; }     // reset the receiver state
}

// **************************************************************************************************** 
//              "on data received" callback
//
// Description: This function is called when the USART receives one byte from the modem 
//
// Arguments:   byData is one byte from the USART 
//
// **************************************************************************************************** 

void HalExm_CB_OnDataReceived( BYTE byData )
{
  switch( Exm.eRecState )
  {
    case Exm_eRecState_Attn:
      if( byData == WtIfcDef_ATTN )                   // if the first byte is ATTN  
      { 
        Exm.eRecState = Exm_eRecState_Command;        // start the receiving, set "command" state 
      }    
      break;

    case Exm_eRecState_Command:
      Exm.byRecAnswID = byData;                       // save the ID
      Exm.eRecState  = Exm_eRecState_Length_Low;      // set "length low" state
      break;

    case Exm_eRecState_Length_Low:                  
      Exm.wRecLength = byData;                        // store the low byte of the length
      Exm.eRecState  = Exm_eRecState_Length_High;     // set "length high" state
      break;

    case Exm_eRecState_Length_High:
      Exm.wRecLength |= (((WORD)byData) << 8) ;       // store the length high byte
      Exm.eRecState  = Exm_eRecState_Payload;         // start receiving the payload
      Exm.wRecPLIdx  = 0;                             // reset the payload index
      break;

    case Exm_eRecState_Payload:                       // all othe bytes fill the payload buffer 
      if( Exm.wRecPLIdx < Exm.wRecLength )            // if the payload index is below the length
      {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -