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

📄 stream2.c

📁 SECS I, SECS II协议通讯源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * Stream2.c
 *
 * preset handling, service program load/save, commands, time, reset, loopback
 *
 *
 * Code by David Lindauer, CIMple technologies
 *
 */
#include <string.h>
#include <stdio.h>
#include "menus.h"
#include "secs2.h"
#include "units.h"

extern char secs_model[6];
extern PR_STRUC secs_presetlist[];
extern BOOL *secs_cmdlist[];
extern uint language;
extern char **unitext[];
extern int enquire_list[NUMBER_ENQUIRIES];
extern int receive_number;
extern BOOL reset_disable;
extern int reset_type;
extern PROGFUNC secs2_spl_functions[];

/* Number of preset specifiers */
static int number_preset = 0;
/* Number of command specifiers */
static int number_cmd = 0;
/* Response code for changing preset values */
static int response_code;

/* Used during service program i/o */
static CTEXT spid[SPID_LENGTH+1];
static PLFUNC spl_func;

/*
* Note: a PRESET is the same as a SELECT variable;
*       an ACTUAL is the same as a STATUS variable
* Unlike the MENUS portion of the code which can only handle
* FLOATING format, secs-2 protocol can handle virtually any format.
* Thus binary, integer, and floating data can be sent intermixed
*
* the routines which put values out and get values in are largely
* untested for other than the deffault format
*/
// Service Program routines will mostly work if the data transfer routines are
// written for the specific program type
// Refer to code for stream 8 code for an idea how to do this
// Routine to load the SPID
static void LoadSpid(void)
{
  int i;

  // Verify data
  if (FV(FM_BINARY) != SPID_LENGTH)
    Secs2BaddataError();

  // Read in string
  for (i=0;i<SPID_LENGTH;i++)
    spid[i] = (BYTE) RB();
  spid[SPID_LENGTH] = '\0';
}
// Routine to parse the SPID and return a function to load/save data
static BOOL GetSpidFunc(void)
{
  PROGFUNC *spv = secs2_spl_functions;
  // Invalidate Grants whenever a new SPID comes in
  spl_func = 0;

  while(spv->validate) {
    if ((*spv->validate)(spid)) {
      // Get the exec routine, this being non-zero will allow it to be called
      spl_func = spv->exec;
      return(TRUE);
    }
    spv++;
  }
  return(FALSE);
}

// See if we have enough space to load a program
// SERVICE PROGRAM LOAD ENQUIRE
static void S2f1(void)
{
  BYTE return_code = GRANT_OK;
  int length;

  // Get the SPID and the requested length
  LoadSpid();
  if (FV(FM_UINT) != 4)
    Secs2BaddataError();
  length = RI();

  // See if we recognize this SPID and there is enough buffer space
  // for reception
  if (GetSpidFunc()) {
    // Valid SPID, now see if length + FM_BYTE format is available
    if (length + 4 > MraFreeBuffers()*MAX_BLOCK_LEN)
      return_code = GRANT_NOSPACE;
  }
  else
    return_code = GRANT_BADSPID;

  // If error, disallow grant
  if (return_code != GRANT_OK)
    spl_func = 0;

  // Now tell the host
  IF_BINARY(1);
  SB(return_code);
}
// Get a program
// SERVICE PROGRAM SEND
static void S2f3(void)
{
  BYTE return_code;

  // if no GRANT was requested return with an error
  if (spl_func == 0) {
    return_code = SPAACK_NOGRANT;
    receive_number = RECEIVE_COMPLETE;
  }
  else
    return_code = (*spl_func)(SPL_SEND);

  // Can't do it again
  spl_func = 0;

  // Out the return_code
  IF_BINARY(1);
  SB(return_code);
}
// Send a program
// SERVICE PROGRAM LOAD REQUEST
static void S2f5(void)
{
  // Get the SPID
  LoadSpid();
  if (GetSpidFunc())
    (*spl_func)(SPL_LOAD);
  else
    IF_BINARY(0);

  // Invalidate send requests
  spl_func = 0;
}
// Run a program
// SERVICE PROGRAM RUN SEND
static void S2f7(void)
{
  BYTE return_code;

  // Get the SPID and run the program

  LoadSpid();
  if (GetSpidFunc())
    return_code = (*spl_func)(SPL_RUN);
  else
    return_code = CSAACK_BADSPID;

  // Not intended for GRANTS
  spl_func = 0;

  // Send the return code
  IF_BINARY(1);
  SB(return_code);
}
/*
* Put out a preset value
*/
static void PrPutValue(int number)
{
  switch (secs_presetlist[number].units) {
    int temp;
    case UN_BINARY:
            IF_BINARY(1);
            SB(* ((BYTE *) (secs_presetlist[number].value)));
            break;
    case UN_BOOL:
            IF_BOOL(1);
            SB(* ((BYTE *) (secs_presetlist[number].value)));
            break;
    case UN_ASCII:
            IF_ASCII(temp = strlen((char *) secs_presetlist[number].value));
            SA((char *) secs_presetlist[number].value,temp);
            break;
    case UN_MODE:
            IF_INT(1);
            SI(((MODIFY *)secs_presetlist[number].value)->value);
            break;
    case UN_INT:
            IF_INT(1);
            SI(* ((int *) (secs_presetlist[number].value)));
            break;
    case UN_FLOAT:
            IF_FLOAT(1);
            SF(* ((float *) (secs_presetlist[number].value)));
            break;
    default:
            Secs2bSendValue(((PREREC *)secs_presetlist[number].value)->preset->value,
              ((PREREC *)secs_presetlist[number].value)->preset->units);
            break;
  }
}
/*
* Put out a preset low limit
*/
static void PrPutLowLim(int number)
{
  switch (secs_presetlist[number].units) {
    case UN_BINARY:
            IF_BINARY(1);
            SB(0);
            break;
    case UN_BOOL:
            IF_BOOL(1);
            SB(0);
            break;
    case UN_ASCII:
            IF_ASCII(0);
            break;
    case UN_MODE:
            IF_INT(1);
            SI(0);
            break;
    case UN_INT:
            IF_INT(1);
            SI(0);
            break;
    case UN_FLOAT:
            IF_FLOAT(1);
            SF(0.0F);
            break;
    default:
            Secs2bSendValue( (float) ((PREREC *)secs_presetlist[number].value)->lolim,
              ((PREREC *)secs_presetlist[number].value)->preset->units);
            break;
  }
}
/*
* Put out a preset high limit
*/
static void PrPuthilim(int number)
{
  switch (secs_presetlist[number].units) {
    case UN_BINARY:
            IF_BINARY(1);
            SB(255);
            break;
    case UN_BOOL:
            IF_BOOL(1);
            SB(255);
            break;
    case UN_ASCII:
            IF_ASCII(0);
            break;
    case UN_MODE:
            IF_INT(1);
            SI(((MODIFY *)secs_presetlist[number].value)->limit-1);
            break;
    case UN_INT:
            IF_INT(1);
            SI(0);
            break;
    case UN_FLOAT:
            IF_FLOAT(1);
            SF( 0.0F);
            break;
    default:
            Secs2bSendValue( (float) ((PREREC *)secs_presetlist[number].value)->hilim,
              ((PREREC *)secs_presetlist[number].value)->preset->units);
            break;
  }
}
/*
* Put out a preset default
*/
static void PrPutDefault(int number)
{
  switch (secs_presetlist[number].units) {
    case UN_BINARY:
            IF_BINARY(1);
            SB(0 );
            break;
    case UN_BOOL:
            IF_BOOL(1);
            SB(0);
            break;
    case UN_ASCII:
            IF_ASCII(0);
            break;
    case UN_MODE:
            IF_INT(1);
            SI(0);
            break;
    case UN_INT:
            IF_INT(1);
            SI(0);
            break;
    case UN_FLOAT:
            IF_FLOAT(1);
            SF(0.0F);
            break;
    default:
            Secs2bSendValue((float) ((PREREC *)secs_presetlist[number].value)->preset->value,
              ((PREREC *)secs_presetlist[number].value)->preset->units);
            break;
  }
}
/*
* Receive a preset value
* Note that receiving binary or ascii strings is dangerous because no
* limit checking is done on the incoming length
*/
static void PrGetValue(BOOL changing)
{
  uint i, len;
  int number, itemp;
  float ftemp;
  if (FV(FM_LIST) != 2)
    Secs2BaddataError();
  if (FV(FM_UWORD) != 2)
    Secs2BaddataError();
  number = RW();

  if (number >= number_preset) {
    response_code = EAC_BADCONST;
    return;
  }
  switch (secs_presetlist[number].units) {
    case UN_BINARY:
            len = FV(FM_BINARY);
            for (i=0; i<len; i++)
              if (changing)
                *(((BYTE *)secs_presetlist[number].value)+i) = (BYTE) RB();
              else
                RB();
            break;
    case UN_BOOL:
            FV(FM_BOOL);
            if (changing) {
              if (RB())
                *((BOOL *)secs_presetlist[number].value) = TRUE;
              else
                *((BOOL *)secs_presetlist[number].value) = FALSE;
            }
            else
                RB();
            break;

⌨️ 快捷键说明

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