📄 usbhid.c
字号:
/*
* Copyright (c) 2004,成都港顺科技发展有限公司
* All rights reserved.
*
* 编 译 器:Keil:C Compiler:7.20;Assembler:7.10
* 工程名称:POS-Test.UV2
* 文件名称:Main_usb.C
* 摘 要:USB与PC通讯
*
* 单 片 机:uPSD3254
* 当前版本:0.4
* 作 者:林云
* 完成日期:2004-12-7 14:45
*/
#pragma NOAREGS //this source must use relative registers !!!
//#include "app_intr.h"
#include "Main.h"
#include "Upsdusb.h"
#define CMD_RESET 0x01
#define CMD_ERASE 0x02
#define CMD_WRITE 0x03
#define CMD_READ 0x04
#define CMD_STATUS 0x05
#define CMD_SET_REGS 0x06
#define CMD_SET_PAGE 0x07
#define CMD_SET_VM 0x08
#define PRIMARY_FLASH 0
#define SECONDARY_FLASH 1
#define INPUT_REPORT_SIZE 8
#define OUTPUT_REPORT_SIZE 64
#define FEATURE_REPORT_SIZE (OUTPUT_REPORT_SIZE)
#define CMD_SIZE (OUTPUT_REPORT_SIZE)
#ifdef WIN32
typedef unsigned char uchar;
typedef unsigned short uint16;
typedef unsigned int uint32;
#else
typedef unsigned int uint16;
typedef unsigned long uint32;
#endif
/////////////////// MCU_CMD
//
// Feature and output report structure.
typedef struct
{
union
{
uchar cmd; // CMD_xxx code
struct
{
uchar cmd; // CMD_ERASE
uchar flash; // PRIMARY_FLASH or SECONDARY_FLASH
uint16 address; // Any address in any sector
} erase;
struct
{
uchar cmd; // CMD_READ or CMD_WRITE
uchar flash; // PRIMARY_FLASH or SECONDARY_FLASH
uint16 address; // Target xdata address
uint16 nBytes; // Num bytes to read/write
} rw;
struct
{
uchar cmd; // CMD_SET_xxx
uchar page; // Desired page register value
uchar vm; // Desired VM register value
} setRegs;
struct
{
uchar cmd; // CMD_GET_STATUS
uchar currentCmd; // Returns current command being processed
uchar page; // Returns page register value
uchar vm; // Returns VM register value
uchar ret; // Return value from flash routine
uchar checkSum; // Check sum for write commands
} status;
uchar buffer[CMD_SIZE];
} u;
} MCU_CMD, *PMCU_CMD;
//数据接收
#define RxbuffLength 300
uchar USBRxdBuf[RxbuffLength+1];
uchar USBTxdBuf[256];
uint rxin = 0, rxout = 0;
//发送数据
char MySendFlag = 0;
uint MySendLen, SendPos;
//----------------------------------------------------------
void InitUSB(void);
uchar Check_InBuff(void);
void UsbSend(uint Len, uchar *Dat);
unsigned char USB_GetByte(void);
//-----------------------------------------------------------
/*========= Prototypes =========*/
extern uchar flash_write_with_poll(volatile uchar xdata *addr, uchar dat);
extern uchar flash_boot_write_with_poll(volatile uchar xdata *addr, uchar dat);
extern uchar flash_erase_sector(volatile uchar xdata* addr);
extern uchar flash_boot_erase_sector(volatile uchar xdata* addr);
extern void flash_reset();
extern void flash_boot_reset();
//extern
extern PSD_REGS PSD_REG; // UPSD registers (upsd_cfg.c)
extern data uchar LCD_buffer[]; // LCD mirror buffer (lcd_32xx.c)
void M25P80_Write(uchar chip,ulong address,uint Len,uchar *Dat);
unsigned char DDCCONintc = 0;
data int counter; // Incremented in do_timer0 (timer_func.c)
MCU_CMD status; // Status from last command executed
data uchar returnStatus; // Set TRUE if we should return status record to host
MCU_CMD currentCmd; // Current command we're working on
MCU_CMD rcvReport; // Incoming report
data uchar rcvIndex; // Current byte position in incoming report
MCU_CMD txReport; // Outgoing report
data uchar txIndex;
xdata char AuxTXBuf[8]; //Aux. buffer for TXing of LCD content
data uchar LCDBufTXIndex; //current position of LCD buffer for USB TX
data unsigned int g_debugUSB_INT_CNT = 0;
uchar RecvFlagPacket = 0;
void LcdClear(uchar LastCol);
void LcdDisplay(uchar x,uchar y,uchar *str,uchar mode);
#ifdef DisconnectOnDemand
static void ReConnectUSB()
/******************************************************************************
Function : static void ReConnectUSB()
Parameters : none
Description: Use insted of UsbInitialize when DisconnectOnDemand feature
is implemented.
Be sure that the DisconnectOnDemand feature is present on DK3200.
******************************************************************************/
{
data int w;
UIEN = 0; // Disable all USB interrupts
UADR = 0; // Disable USB hardware
LCDBufTXIndex = 0; // LCD disp position for USB
PSD_REG.DATAOUT_C &= 0xEF; // PC4=0
PSD_REG.DRIVE_C |= 0x10; // set as OpenDrain
PSD_REG.DIRECTION_C |= 0x10; // set as output
// printfLCD("\rUSB Disconnected");
while ((PSD_REG.DATAIN_B & 0x04)==0)
{
for (w=0;w<600*50;w++); // wait 50 ms
}
PSD_REG.DRIVE_C &= 0xEF; // set PC4 as input
PSD_REG.DIRECTION_C &= 0xEF; // set PC4 as input
UsbInitialize();
// printfLCD("\rUSB Reconnected.");
}
#endif
uchar Check_InBuff(void)
{
if(rxin != rxout)
return(1);
return(0);
}
//返回串口接收的数据(1 Byte)
unsigned char USB_GetByte(void)
{
unsigned char byte;
//while (!Check_InBuff());
byte = USBRxdBuf[rxout++];
if (rxout > RxbuffLength)
rxout = 0;
return(byte);
}
//USB数据发送
/*
static void WriteBufferToFlash(uchar flash, uint16 address, uchar* buf, uint16 cb)
******************************************************************************
Function : static void WriteBufferToFlash()
Parameters : (uchar flash, uint16 address, uchar* buf, uint16 cb)
Description: WriteBufferToFlash()
******************************************************************************
{
// Assume desired flash segment is mapped into high 32k of xdata space
volatile uchar xdata* p = (volatile uchar xdata*) address;
if (flash == PRIMARY_FLASH)
{
while (cb--)
{
// flash_write_with_poll(p, *buf++);
status.u.status.checkSum += *p++;
}
}
else
{
while (cb--)
{
// flash_boot_write_with_poll(p, *buf++);
status.u.status.checkSum += *p++;
}
}
}
*/
static void ReadBufferFromFlash(uint16 address, uchar* buf, uint16 cb)
/******************************************************************************
Function : static void ReadBufferFromFlash()
Parameters : (uint16 address, uchar* buf, uint16 cb)
Description: ReadBufferFromFlash()
******************************************************************************/
{
// Assume desired flash segment is mapped into high 32k of xdata space
volatile uchar xdata* p = (volatile uchar xdata*) address;
while (cb--)
{
*buf++ = *p++;
}
}
void OnDeviceConfigured()
/******************************************************************************
Function : void OnDeviceConfigured()
Parameters : none
Description: Called after device is completely configured.
******************************************************************************/
{
TXD1F = 1; // Set up first tx on EP1 if not
}
static void PrepareTransmitSegment(uchar index)
/******************************************************************************
Function : static void PrepareTransmitSegment()
Parameters : (uchar index) - current byte index into txReport.
Description: Prepare next segment of feature report for transmission.
******************************************************************************/
{
data uchar cbData;
data uchar i;
if (returnStatus)
{
if (index == 0) // Prepare the whole status report on first call
{
status.u.cmd = CMD_STATUS;
status.u.status.currentCmd = currentCmd.u.cmd;
status.u.status.page = PSD_REG.PAGE;
status.u.status.vm = PSD_REG.VM;
memcpy(&txReport, &status, CMD_SIZE);
}
return;
}
/*= The Read command is executed very fast, it can be present at this place.
If you use some time-consuming operations
or your routine takes more than 450us, place your code
instead of CMD_ERASE, where can be long services ... =*/
switch (currentCmd.u.cmd)
{
case CMD_READ:
if (index == 0) // First segment needs 0 command byte to indicate data
{
cbData = min(currentCmd.u.rw.nBytes, EP0_SIZE - 1);
index = 1;
txReport.u.cmd = 0;
}
else
{
cbData = min(currentCmd.u.rw.nBytes, EP0_SIZE);
}
ReadBufferFromFlash(
currentCmd.u.rw.address,
txReport.u.buffer + index,
cbData);
currentCmd.u.rw.address += cbData;
if ((currentCmd.u.rw.nBytes -= cbData) == 0)
{
currentCmd.u.cmd = 0; // All done
}
break;
default:
for (i = 0; i < EP0_SIZE; i++)
{
txReport.u.buffer[index + i] = 0;
}
break;
}
}
static void OnReportTransmitted()
/******************************************************************************
Function : static void OnReportTransmitted()
Parameters : none
Description: A complete feature report has been successfully transmitted.
******************************************************************************/
{
if (returnStatus)
{
returnStatus = FALSE;
}
if (currentCmd.u.cmd) // If there's more data to go ...
{
PrepareTransmitSegment(0); // Prepare first segment of next report
}
}
static void OnReportSegmentReceived(uchar cbReceived)
//******************************************************************************
// Function : static void OnReportSegmentReceived()
// Parameters : (uchar cbReceived)
// Description: Called as each EP0_SIZE segment of a report is received.
//******************************************************************************
{
data uchar cbData;
data uchar index;
// If this is data coming in (not a new command) ...
if (rcvReport.u.cmd == 0)
{
// Process the incoming data based on the current command
switch (currentCmd.u.cmd)
{
case CMD_WRITE:
if (rcvIndex == 0) // Skip over command byte in first packet
{
if (cbReceived <= 1)
{
return; // Error
}
cbData = min(currentCmd.u.rw.nBytes, cbReceived - 1);
index = rcvIndex + 1;
}
else
{
cbData = min(currentCmd.u.rw.nBytes, cbReceived);
index = rcvIndex;
}
/*
WriteBufferToFlash(
currentCmd.u.rw.flash,
currentCmd.u.rw.address,
rcvReport.u.buffer + index,
cbData);
*/
currentCmd.u.rw.address += cbData;
currentCmd.u.rw.nBytes -= cbData;
if (currentCmd.u.rw.nBytes == 0)
{
currentCmd.u.cmd = 0; // All done
if (currentCmd.u.rw.flash == PRIMARY_FLASH)
{
// flash_reset();
}
else
{
// flash_boot_reset();
}
}
break;
default:
break;
}
}
}
static void OnReportReceived()
/******************************************************************************
Function : static void OnReportReceived()
Parameters : none
Description: Called after all segments of a report have been received.
******************************************************************************/
{
// Here you can have SRC routine long as you want ..
// static uchar val = 0;
if (rcvReport.u.cmd) // If this is a new command coming in ...
{
if (rcvReport.u.cmd == 0x55)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -