📄 mbxtcl.c
字号:
/****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 + -