📄 usb3wcmd.c
字号:
//-----------------------------------------------------------------------------
// File: Usb3wCmd.c
// Contents: Process 3W-commands received from the USB host
//
// Copyright (c) 2004 ItoM Semiconductor. All rights reserved
//-----------------------------------------------------------------------------
#include <stdio.h>
#include "common.h"
#include "Lv24Ekit.h"
// ==================================================================
#ifdef USE_USB // The whole file can be discarded if USB is not used
// ==================================================================
#include "Usb3wCmd.h"
//-----------------------------------------------------------------------------
// Command table, used by the command dispatcher (Process3wCommand)
//-----------------------------------------------------------------------------
typedef BYTE (*CMD_FUNC)(void); // Command function
typedef struct
{
BYTE byCmd; // Command opcode
CMD_FUNC CmdFunc; // Command processing function
} CMD_ENTRY;
#define TO_BE_DONE NULL // Temp.!!!
CMD_ENTRY _rom g_CmdTable[] =
{
// RC_NOP_CMD, NULL, // No Operation - not implemented yet
RC_OPEN_CLOSE_3WBUS_CMD, UsbOpen3wCmd, // Open/Close the 3-wire bus on USB adaptor
RC_GET_FIRMWARE_REV_CMD, UsbGetFirmwareVersion, // Get Firmware revision: I:<Cmd> O:<Maj><.><Min><Sub>
RC_WRITE3W_CMD, UsbWrite3W, // Write 3W
RC_READ3W_CMD, UsbRead3W, // Read 3W
ERC_PULSE3W_CMD, UsbExtPulse3W, // Extended Pulse 3W
RC_RD3WLINES_CMD, UsbRw3WireLines, // Read 3W lines I:<cmd><Set_L><Set_H> O:<cmd><datL><datH>
RC_SET_DGT_INTF_CMD, UsbSet3wDgtInterface, // Set chip digital interface version
RC_WRITE3W_MUL_CMD, UsbWrite3W_Multiple, // Write 3W multiple data
RC_REPEAT_IO_PAT_CMD, UsbRepeatIo3W, // Repeat IO pattern
RC_SET_CHIP_INTF_CMD, TO_BE_DONE, // Set known chip interface I:<cmd><Intf ID> O:<cmd><0: OK else error>
#ifdef USE_IRQSCRIPT
RC_IRQ_CONTROL_CMD, UsbIrqControl, // Interrupt control from USB host
ERC_EXEC_SCRIPT_CMD, UsbExecScript, // Execute the passed along script command
#endif //USE_IRQSCRIPT
// Following commands will not be implemented (not necessary)
// RC_PULSE3W_CMD, NULL, // Pulse count
// RC_PULSE3W_USE_INTF_CMD, NULL // Pulse count use known interface
// RC_RDSTAT_USE_INTF_CMD, NULL // Read status use known interface I:<cmd> O:<cmd><Stat_L><Stat_H>
// ERC_PULSE3W_USE_INTF_CMD, NULL, // Extended pulse count use known interface
// Following commands will not be implemented (not used by any application)
// RC_GET_HARDWARE_REV_CMD, NULL, // Get hardware revision
};
#define CMD_TABLE_SIZE (sizeof(g_CmdTable)/sizeof(g_CmdTable[0]))
//-----------------------------------------------------------------------------
// Init the hardware/software for using I3W interface
//-----------------------------------------------------------------------------
/*
void Init3w()
{
// Program Clock, nRW of 3W bus as output of the uc, DATA as input
I3W_DIRPORT |= (I3W_CLK_PIN_BM | I3W_NRW_PIN_BM);
I3W_DIRPORT &= (BYTE)~I3W_DATA_PIN_BM;
// Drive clock and nRW low (Let the chip drive the data pin)
I3W_PORT &= (BYTE)~(I3W_CLK_PIN_BM | I3W_NRW_PIN_BM);
// Software init
g_bySwFlag1 = 0; // Reset our software flag
g_by3wIntf = DGT_INTF_V4; // default digital interface
_putbit(1, I3W_PORT, I3W_CLK_PIN); // Clock high by default for V4
} // End Init3w()
*/
//-----------------------------------------------------------------------------
// Command displatcher, called by the task dispatcher.
// Input: number of byte in g_ReceiveBuf (g_ReceiveBuf[0] is the command opcode)
// Output: number of byte filled in g_ReplyBuf
//-----------------------------------------------------------------------------
#pragma optimize ac // Enable relax alias checking and common subexpression elimination
BYTE UsbProcess3wCmd(BYTE byReceiveCnt)
{
// Return number of byte in the g_ReplyBuf
BYTE i;
// Do nothing if no input data
if (byReceiveCnt==0)
return(0);
g_ReplyBuf[0] = g_ReceiveBuf[0]; // Default: copy the command to reply buffer
for (i=0; i<(BYTE)CMD_TABLE_SIZE; i++) // Look up the command function through its opcode
{
if (g_CmdTable[i].byCmd == g_ReceiveBuf[0])
{
if ( g_CmdTable[i].CmdFunc != NULL )
return ( g_CmdTable[i].CmdFunc() ); // Invoke function and exit
}
}
// Command is not handled
g_ReplyBuf[1] = 0xFF; // error
return(2); // 2 byte filled
} // End UsbProcess3wCmd
#pragma endoptimize //optimize ac
BYTE UsbGetFirmwareVersion()
{
// I:<cmd>
// O:<MajorVer> <dot> <MinorVer> <SubVer> -> Example: "0.0A"
g_ReplyBuf[0] = I3W_MAJ_VER;
g_ReplyBuf[1] = '.';
g_ReplyBuf[2] = I3W_MIN_VER;
g_ReplyBuf[3] = I3W_SUB_VER;
// Return number of byte filled
return(4);
} // End UsbGetFirmwareVersion
BYTE UsbOpen3wCmd()
{
// Open/Close the 3-wire bus on USB adaptor
// I:<cmd><Open or Close><Bus number>
// O:<cmd><0: OK else error><0>
// Check the bus number (we only support bus 0)
if ( g_ReceiveBuf[2] != 0 )
{
g_ReplyBuf[1] = 1; // Return non zero value (error)
}
else
{
if (g_ReceiveBuf[1] == ROC_OPEN_3W) // Open USB request
{
// If we are not in USB mode, switch to new mode and save the new mode
if ( (g_bySwFlag1 & SF1_USB_HOST_CON) == 0 )
{
SetOperateMode(OPM_USB);
g_bySwFlag1 |= SF1_USB_HOST_CON; // New mode
}
}
else // Close USB request
{
// If we are not in stand-alone mode, switch to new mode and save the new mode
if ( (g_bySwFlag1 & SF1_USB_HOST_CON) != 0 )
{
SetOperateMode(OPM_STAND_ALONE);
g_bySwFlag1 &= (BYTE)(~SF1_USB_HOST_CON);
}
}
g_ReplyBuf[1] = 0; // Return no error
}
return(2); // return 2 byte to host
} // End UsbOpen3wCmd
BYTE UsbSet3wDgtInterface()
{
// I:<cmd><Intf Ver><0><0> O:<cmd><Result: 0=OK else error>
BYTE byReqVer;
// Check if we support the requested interface (We only support digital V3 or V4)
byReqVer = g_ReceiveBuf[1]; // Examine the requested version
if (byReqVer == DGT_INTF_V3)
{
_putbit(0, I3W_PORT, I3W_CLK_PIN); // Clock low by default for V3
}
else if (byReqVer == DGT_INTF_V4)
{
_putbit(1, I3W_PORT, I3W_CLK_PIN); // Clock high by default for V4
}
else
{
byReqVer = 0xFF; // Error - not supported
}
if (byReqVer != 0xFF)
{
g_by3wIntf = byReqVer; // Set the requested interface
g_ReplyBuf[1] = 0; // Return 0 (no error)
}
else
{
g_ReplyBuf[1] = DGT_INTF_LAST; // Return a non zero value to host (Last supported 3W-interface)
}
return(2); // Return number of byte fille
} // End UsbSet3wDgtInterface
BYTE UsbWrite3W()
{
// I:<cmd><datL><datH> O:No reply
UsbWrite3wV3V4(g_ReceiveBuf[1], g_ReceiveBuf[2]);
return(0); // Return number of byte filled
} // End UsbWrite3W
BYTE UsbRead3W()
{
// I:<cmd><datL><datH> - O:<cmd><ReadDatL><ReadDatH>
// Write the low byte to the device and read data
g_ReplyBuf[1] = UsbRead3wV3V4(g_ReceiveBuf[1]);
g_ReplyBuf[2] = 0; // only return 8 bit - high data is 0
return(3); // Return number of byte filled
} // End UsbRead3W
#pragma optimize ac // Enable relax alias checking and common subexpression elimination
BYTE UsbWrite3W_Multiple()
{
// I:<cmd><Cnt=n><datL0><datH0><datL1><datH1><datL2><datH2>...<datLn><datHn>
// O:No reply
BYTE i, byOffs;
byOffs = 2; // Offset to data in the g_ReceiveBuf
for (i=0; i<g_ReceiveBuf[1]; i++)
{
UsbWrite3wV3V4(g_ReceiveBuf[byOffs], g_ReceiveBuf[byOffs+1]);
byOffs += 2; // Next write pattern
}
// No reply
//return(0);
// Reply OK
g_ReplyBuf[1] = 0; // Return 0 (no error)
return(2); // 1 byte command + 1 byte result
} // End UsbWrite3W_Multiple
#pragma endoptimize //optimize ac
BYTE UsbExtPulse3W()
{
// Extended Pulse 3W:
// - Write the Start pattern (wStartL/H) to 3-wires bus
// - Pulse the R/W line high (read mode) for specified interval (using timer interrupt)
// - Write the the stop pattern (wStopL/H) to 3-wires bus
// I:<cmd><TimeMs><NA><NA><wStartL><wStartH><wStopL><wStopH>
// O:<cmd><TimeUs[7:0]><TimeUs[15:8]><TimeUs[23:16]><TimeUs[31:24]>
DWORD dwTimeUs;
WORD wStart, wStop;
// Convert input interval from ms to us
dwTimeUs = g_ReceiveBuf[1];
dwTimeUs *= 1000;
// Pulse the NRW
wStart = MAKEWORD(g_ReceiveBuf[4], g_ReceiveBuf[5]);
wStop = MAKEWORD(g_ReceiveBuf[6], g_ReceiveBuf[7]);
dwTimeUs = Pulse3wNRW(wStart, wStop, dwTimeUs);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -