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

📄 mbxtcl.c

📁 CMX990 demonstration board (DE9901)
💻 C
📖 第 1 页 / 共 4 页
字号:
/****h* DE9901/MBXTCL
* FILE NAME
*  mbxtcl.c
* COPYRIGHT
*  (c) 2004-2005 Mobitex Technology AB - All rights reserved
* 
*  Redistribution and use in source and binary forms, with or without modification,
*  are permitted provided that the following conditions are met:
*  * 1. Redistributions of source code must retain the above copyright notice,
*       this list of conditions and the following disclaimer. 
*  * 2. Redistributions in binary form must reproduce the above copyright notice,
*       this list of conditions and the following disclaimer in the documentation
*       and/or other materials provided with the distribution.
*  * 3. The name Mobitex Technology AB may not be used to endorse or promote products
*       derived from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY MOBITEX TECHNOLOGY AB "AS IS" AND ANY EXPRESS OR
*  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
*  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
*  SHALL MOBITEX TECHNOLOGY AB BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
*  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
*  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
*  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
*  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
*  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* AUTHOR
*  MPN/Kjell Westerberg
* HISTORY
*  Changes in the file are recorded in this list.
*   Ver:  Date:       Responsible:         Comment:
*   R1A01 2005-01-17  Kjell Westerberg     Approved.
*   R1A05 2005-03-17  Kjell Westerberg     Changed thread priority.
*   R1A06 2005-04-14  Kjell Westerberg     Added flashload.
* DESCRIPTION
*  Implements all Mobitex and DE9901 specific TCL functions.
***/

#include "hel.h"
#include "tcl.h"
#include "tclInt.h"
#include "version.h"

/* This variable is used to indicate when tcl is running. */
bool mbxTclRun = FALSE;

/* Define TCL thread data. */
#define TCL_STACK_SIZE 30000

static cyg_thread tclThreadPCB;
static char tclStack[TCL_STACK_SIZE];
static cyg_handle_t tclThread;

/* Handles to the console serial port. */
static cyg_io_handle_t portHandl[2];


void Conv2BinString(char *str, int size, int val) {
  int i;
  
  for (i=size-1; i>=0; i--) {
    if (val & (1<<i)) {
      str[size-i-1] = '1';
    } else {
      str[size-i-1] = '0';
    }
  }
  str[size] = NULL;
}

/*************************************************************************/
/* Tcl functions implemented in C. */

/****f* MBXTCL/MbxTclRev
* DESCRIPTION
* Returns the current SW revision and the CMX990 revision as a list.
* The first value is the SW revision and the last value is the chip revision.
***/
static const char MbxTclRevHelp[] = 
"Returns the current software revision and the CMX990 chip revision as a list.\n\
The first value is the SW revision and the last value is the chip revision.";
static int MbxTclRev(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) {
  char str[20];
  
  if (argc != 1) {
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                     "\"", (char *)NULL);
    return TCL_ERROR;
  }
  snprintf(str, 20, "%s %s", swRevision, cmx990Revision);
  Tcl_SetResult(interp, str, TCL_VOLATILE);
  return TCL_OK;
}

/****f* MBXTCL/MbxTclHw
* DESCRIPTION
* Returns the current CPU HW.
***/
static const char MbxTclHwHelp[] = 
"Returns the current CPU hardware platform and CPU clock frequency as a list.\n\
It could be EB40A or DE9901. The clock frequency is in Hz.";
static int MbxTclHw(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) {
  char str[20];
  
  if (argc != 1) {
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                     "\"", (char *)NULL);
    return TCL_ERROR;
  }
#if defined(DE9901_BOARD)
  snprintf(str, 20, "%s %d", "DE9901", MCK);
#elif defined(EB40A_BOARD)
  snprintf(str, 20, "%s %d", "EB40A", MCK);
#else
  snprintf(str, 20, "%s %d", "UNKNOWN", MCK);
#endif
  Tcl_SetResult(interp, str, TCL_VOLATILE);
  return TCL_OK;
}

/****f* MBXTCL/MbxTclTime
* DESCRIPTION
* Returns the current system timer value in ms.
* It is the time since the system started.
***/
static const char MbxTclTimeHelp[] = 
"Returns the current system timer value in ms.\n\
It is the time since the system started.\n\
Only the lowest 32 bits are returned.";
static int MbxTclTime(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) {
  char str[20];
  
  if (argc != 1) {
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                     "\"", (char *)NULL);
    return TCL_ERROR;
  }
  snprintf(str, 20, "%ld", (unsigned long)(OS_GetTicks()&0xFFFFFFFF));
  Tcl_SetResult(interp, str, TCL_VOLATILE);
  return TCL_OK;
}

/****f* MBXTCL/MbxTclPrint
* DESCRIPTION
* Prints a string on the MASC serial port.
***/
static const char MbxTclPrintHelp[] = 
"Prints a string on the MASC serial port.\n\
Syntax:\n\
    print ?option? string\n\
where option can be:\n\
-e  print string as an event.";
static int MbxTclPrint(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) {
  char str[100];
  
  if (argc == 3) {
    if (strcmp(argv[1], "-e") == 0) {
      snprintf(str, 100, "%s", argv[2]);
      PrintEvent(str, 0, 0);
      return TCL_OK;
    } else {
      Tcl_AppendResult(interp, "wrong option: should be one of: -e", (char *)NULL);
      return TCL_ERROR;
    }
  }
  if (argc != 2) {
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                     " ?option? string\"", (char *)NULL);
    return TCL_ERROR;
  }
  snprintf(str, 100, "%s\n", argv[1]);
  Print(str);
  return TCL_OK;
}

/****f* MBXTCL/MbxTclCpuLoad
* DESCRIPTION
* This is the help string.
*/
static const char MbxTclCpuLoadHelp[] = "\
*  Returns the measured CPU load as a list of three values.\n\
*  The values are the avarage CPU load during the last 100 ms, 1 s and 10 s in %.\
";
/***/
static int MbxTclCpuLoad(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) {
  char str[60];
  cyg_uint32 t1,t2,t3;

  if (argc != 1) {
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                     "\"", (char *)NULL);
    return TCL_ERROR;
  }
  t1 = CpuLoad(CPULOAD_100MS);
  t2 = CpuLoad(CPULOAD_1S);
  t3 = CpuLoad(CPULOAD_10S);
  snprintf(str, 60, "%d %d %d", t1, t2, t3);
  Tcl_SetResult(interp, str, TCL_VOLATILE);
  return TCL_OK;
}

/****f* MBXTCL/MbxTclExit
* DESCRIPTION
* See also MbxTclStartCheck.
*/
static const char MbxTclExitHelp[] = "\
*  This stop the TCL thread and disables the command interface to DE9901.\n\
*  It can be started again by typing in the password on the console port.\
";
/***/
static int MbxTclExit(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) {
  cyg_uint32 block, len;

  if (argc != 1) {
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                     "\"", (char *)NULL);
    return TCL_ERROR;
  }
  printf("Tcl stopped!\n");
  /* Setup console port to be non-blocking until tcl is started again. */
  block = 0;
  len = sizeof(block);
  cyg_io_set_config(portHandl[0], CYG_IO_SET_CONFIG_SERIAL_READ_BLOCKING, &block, &len);
  
  mbxTclRun = FALSE;
  /* The TCL task will now be suspended and will not return from this function until started */
  /* again by the user. */
  cyg_thread_suspend(tclThread);
  return TCL_OK;
}

/****f* MBXTCL/MbxTclPio
* DESCRIPTION
* This function control the binary IO interface. See binio.c.
***/
static const char MbxTclPioHelp[] = "This controls the binary IO interface in the microcontroller.\n\
The port shall be 0-31 but port 28, 14, 15, 21 or 22 can not be used.\n\
They are controlled by the CPU.\n\
Syntax to set an output:\n\
    pio <port> 0|1\n\
Syntax to read an input:\n\
    pio <port>\n\
Syntax to set direction:\n\
    pio <port> in|out\n\
Syntax to read the direction:\n\
    pio <port> dir\n\
Syntax to control the glitch filter:\n\
    pio <port> glitch on|off";
static int MbxTclPio(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) {
  int portN, stateN;
  BINIO_Port_t port;
  BINIO_State_t state;
  char str[20];

  if (argc < 2) {
    Tcl_AppendResult(interp, "wrong # args: should at least be \"", argv[0],
                     " port\"", (char *)NULL);
    return TCL_ERROR;
  }
  /* Get port number from the first argument and check it. */
  if (Tcl_GetInt(interp, argv[1], &portN) != TCL_OK) {
    return TCL_ERROR;
  }
  if (portN >= 0 && portN < 32 && portN != 28 && portN != 14 && portN != 15 && portN != 21 && portN != 22) {
    port = (BINIO_Port_t)portN;
  } else {
    Tcl_SetResult(interp, "port must be between 0-31 and not 28, 14, 15, 21 or 22", TCL_STATIC);
    return TCL_ERROR;
  }
  /* If no more arguments we shall read the port if it is defined as input. */
  if (argc == 2) {
    /*    if (BINIO_ReadDirection(port) == BINIO_OUT) {
      Tcl_SetResult(interp, "port is an output", TCL_STATIC);
      return TCL_ERROR;
      }*/
    state = BINIO_ReadPort(port);
    sprintf(str, "%d", state);
    Tcl_SetResult(interp, str, TCL_VOLATILE);
    return TCL_OK;
  }
  /* If the third argument is "in" we shall define port as input */
  if (strcmp(argv[2], "in") == 0) {
    if (argc != 3) {
      Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                       " port in\"", (char *)NULL);
      return TCL_ERROR;
    }
    if (BINIO_ReadDirection(port) == BINIO_OUT) {
      BINIO_SetupInputPort(port);
      state = BINIO_ReadPort(port);
      PrintEvent("pio %d=%d", portN, state);
      sprintf(str, "%d", state);
      Tcl_SetResult(interp, str, TCL_VOLATILE);
    }
    return TCL_OK;
  }
  /* If the third argument is "out" we shall define port as output */
  if (strcmp(argv[2], "out") == 0) {
    if (argc != 3) {
      Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                       " port out\"", (char *)NULL);
      return TCL_ERROR;
    }
    if (BINIO_ReadDirection(port) == BINIO_IN) {
      state = BINIO_ReadPort(port);
      BINIO_SetupOutputPort(port, state);
      Tcl_SetResult(interp, "out", TCL_STATIC);
    }
    return TCL_OK;
  }
  /* If the third argument is "dir" we read the direction of the port */
  if (strcmp(argv[2], "dir") == 0) {
    BINIO_Direction_t dir;
    if (argc != 3) {
      Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                       " port dir\"", (char *)NULL);
      return TCL_ERROR;
    }
    dir = BINIO_ReadDirection(port);
    if (dir == BINIO_IN) {
      Tcl_SetResult(interp, "in", TCL_STATIC);  
    } else {
      Tcl_SetResult(interp, "out", TCL_STATIC);  
    }
    return TCL_OK;
  }
  /* If the third argument is "glitch" we shall set the glitch filter */
  if (strcmp(argv[2], "glitch") == 0) {
    int b;
    if (argc != 4) {
      Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                       " port glitch on|off\"", (char *)NULL);
      return TCL_ERROR;
    }
    if (Tcl_GetBoolean(interp, argv[3], &b) != TCL_OK) {
      return TCL_ERROR;
    }
    if (BINIO_ReadDirection(port) == BINIO_OUT) {
      Tcl_SetResult(interp, "port is an output", TCL_STATIC);
      return TCL_ERROR;
    }
    BINIO_EnableBinioFilter(port, (bool)b);
    Tcl_AppendResult(interp, argv[2], " ", argv[3], (char *)NULL);
    return TCL_OK;
  }
  /* We shall now set the state if the port is output */
  if (argc != 3) {
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                     " port state\"", (char *)NULL);
    return TCL_ERROR;
  }
  if (Tcl_GetInt(interp, argv[2], &stateN) != TCL_OK) {
    return TCL_ERROR;
  }
  if (stateN != 0 && stateN != 1) {
    Tcl_SetResult(interp, "state must be 0 or 1", TCL_STATIC);
    return TCL_ERROR;
  }
  if (BINIO_ReadDirection(port) == BINIO_IN) {
    Tcl_SetResult(interp, "port is an input", TCL_STATIC);
    return TCL_ERROR;
  }
  state = (BINIO_State_t)stateN;
  BINIO_SetPort(port, state);
  Tcl_SetResult(interp, argv[2], TCL_VOLATILE);
  return TCL_OK;
}

/****f* MBXTCL/MbxTclAdc
* DESCRIPTION
* This function controls the analog-digital converter in the CMX990.
***/
static const char MbxTclAdcHelp[] = "This reads the ADC in the CMX990.\n\
The port shall be 0-5.\n\
Syntax to read an input:\n\
    adc <port>";
static int MbxTclAdc(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) {
  int port;

⌨️ 快捷键说明

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