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

📄 bot.c

📁 HID-Ukey底层源码实现(st72651芯片) windows上层驱动
💻 C
字号:
/**************** (c) 2000  STMicroelectronics **********************

PROJECT : USB - ST7 FULL SPEED

VERSION :  v 0.96

CREATION DATE :  01/12/2000

AUTHOR : MICROCONTROLLER DIVISION / ST Rousset

-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

MODIFICATIONS : 

******************************************************************************/

#include "mcu_conf.h"
#include "usb_reg.h"
#include "usb_def.h"
#include "usb_lib.h"
#include "usb_eps.h"
#include "define.h"

#include "lib_bits.h"
#include "MSL.h"
#include "BOT.h"
#include "RBC.h"
#include "SenseDat.h"

#include "HID_usb.h"

#include "MConfig.h"

#pragma DATA_SEG CLASS_RAM
extern unsigned char MSL_Param_Buffer[SIZ_MSL_PARAM];

/******************************* Variables ***********************************/
typedef struct _sBOT_CBW{
	char	dCBWSignature[4];
	char	dCBWTag[4];
	_UDWORD	CBWDataTransferLength;
	char	bmCBWFlags;
	char	bCBWLUN;
	char	bCBWCBLength;
	char	CBWCB[16];
} _BOT_CBW;

typedef struct _sBOT_CSW{
	long	dCSWSignature;
	long	dCSWTag;
	long	dCSWDataResidue;
	char	bCSWStatus;
} _BOT_CSW;

#define	dCBWDataTransferLength	(CBWDataTransferLength.dword)
#define	b0CBWDataTransferLength	(CBWDataTransferLength.byte[0])
#define	b1CBWDataTransferLength	(CBWDataTransferLength.byte[1])
#define	b2CBWDataTransferLength	(CBWDataTransferLength.byte[2])
#define	b3CBWDataTransferLength	(CBWDataTransferLength.byte[3])

static unsigned char BOT_CSW[13];


#pragma DATA_SEG SHORT CLASS_RAM0
static unsigned char BOT_CBW_Flags;
static unsigned char BOT_CBW_Length;
static unsigned char BOT_DevLun;

static unsigned char *pMSL_Param_Buf;		// Pointer to the parameter buffer
static _UDWORD		CBWDataTransferLength;
static unsigned char BOTStateMachine;

extern unsigned char MSL_Param_Size;

#pragma CODE_SEG CLASS_ROM

/****************************** Static Functions *****************************/
void BOT_CBW_Received(void);
/*****************************************************************************/

#define BOT_SendCSW() { BOT_CSW[8] = b3CBWDataTransferLength; BOT_CSW[9] = b2CBWDataTransferLength; BOT_CSW[10] = b1CBWDataTransferLength; BOT_CSW[11] = b0CBWDataTransferLength; }

/*****************************************************************************/

void BOT_Action(void)
{
	if (BOTStateMachine == BOT_READY) {
		MSL_Param_Size = USB_TakeDataEP2();
		if (MSL_Param_Size != 0xFF) {				// Check if the receiving finishes
			extern void RBC_CopyCmd(unsigned char *pRBC);
			
			BOT_CBW_Received();
			RBC_CopyCmd(MSL_Param_Buffer + 15);

			if (BOTStateMachine == BOT_DATA_OUT) {
				// Initialization of receiving the parameter
				USB_RecvDataEP2(MSL_Param_Buffer, sizeof(MSL_Param_Buffer));
				return;
			}

		//	USB_SetRxEP2Status(STALL);		// Do not accept any more data

			BOT_CSW[12] = RBC_Process( BOT_DevLun );
			if (BOT_CSW[12] == BOT_STATUS_FAIL && BOTStateMachine != BOT_CSW_SEND)
				BOTStateMachine = BOT_ABORT;	// Transaction with data
												// Transaction w/o data will not STALL the bus

			if (BOTStateMachine == BOT_DATA_IN) {
				// According to the command parsing, calculate CSWDataResidue
				if (dCBWDataTransferLength < MSL_Param_Size)
					MSL_Param_Size = dCBWDataTransferLength;

				if (MSL_Param_Size < dCBWDataTransferLength)
					dCBWDataTransferLength -= MSL_Param_Size;
				else {
					MSL_Param_Size = dCBWDataTransferLength;
					dCBWDataTransferLength = 0;
				}
			}
		}
	}
	else if (BOTStateMachine == BOT_CSW_SEND) {
		if (USB_EP2_isSent()) {			// EP2 IN pipe is free => Send new data
			// Copy the data remain length
			BOT_CSW[8] = b3CBWDataTransferLength;
			BOT_CSW[9] = b2CBWDataTransferLength;
			BOT_CSW[10] = b1CBWDataTransferLength;
			BOT_CSW[11] = b0CBWDataTransferLength;
		USB_SetRxEP2Status(EP_NAK);	// for unexpect ACK status
			if	(USB_SendDataEP2(BOT_CSW, 13) == REQ_SUCCESS)
				BOTStateMachine = BOT_WAIT_CSW_SENT;
		}
	}
	else if (BOTStateMachine == BOT_WAIT_CSW_SENT) {
		if (USB_EP2_isSent()) {			// EP2 IN pipe is free => CSW is sent
			BOTStateMachine = BOT_READY;					
			USB_RecvDataEP2(MSL_Param_Buffer, MAX_EP2_PACKET_SIZE);	// must return REQ_SUCCESS
		}					
	}
	else if (BOTStateMachine == BOT_DATA_OUT) {
		unsigned char Length;
		Length = USB_TakeDataEP2();
		if (Length == 0xFF)
			return;

		if (dCBWDataTransferLength < Length) {
			SenseCode(ILLEGAL_REQUEST, INVALID_COMMAND_CODE);	// too much parameter
			BOTStateMachine = BOT_ABORT;
		}
		else {
			dCBWDataTransferLength -= Length;

			// All the output parameters are received
			BOT_CSW[12] = RBC_Process( BOT_DevLun );			// Execute it!
			if (BOT_CSW[12] == BOT_STATUS_FAIL)
				BOTStateMachine = BOT_ABORT;
			else
				BOTStateMachine = BOT_CSW_SEND;
		}
	}

	//////////////////////////////////////////////////////////////////////////
	if (BOTStateMachine == BOT_ABORT) {
		if (!(BOT_CBW_Flags & 0x80))	// next OUT token have to be Stalled
			if(dCBWDataTransferLength)
				USB_SetRxEP2Status(EP_STALL);	// STALL EP and wait for clear_feature 
		USB_SetTxEP2Status(EP_STALL);		// STALL EP and wait for clear_feature 
		BOTStateMachine = BOT_CSW_SEND;	// Wait clear feautre(EP) to send CSW abort.
	}
	else if (BOTStateMachine == BOT_DATA_IN) {
		if (USB_SendDataEP2(MSL_Param_Buffer, MSL_Param_Size) == REQ_SUCCESS)
			BOTStateMachine = BOT_CSW_SEND;
	}
}
	
/*****************************************************************************/

void BOT_Init()
{
	BOT_CSW[0] = 0x55;
	BOT_CSW[1] = 0x53;
	BOT_CSW[2] = 0x42;
	BOT_CSW[3] = 0x53;

	RBC_Init();
	
//Prepare the Endpoints, ready for reception, nothing to send
	BOTStateMachine = BOT_READY;

	USB_SetRxEP2Status(EP_NAK);
	USB_SetTxEP2Status(EP_NAK);
	USB_RecvDataEP2(MSL_Param_Buffer, MAX_EP2_PACKET_SIZE);	// must return REQ_SUCCESS
}


/*****************************************************************************/
//	On Input:
//		MSL_Param_Buffer contains the CBW
//		MSL_Param_Size is the size of the CBW
//	On Output:
//		BOT_DATA_IN: MSL_Param_Size is the size of data to be sent
//		BOT_DATA_OUT: MSL_Param_Size is the size of data to be received
// Possible value of BOT_DATA_OUT are:
//		BOT_CSW_SEND	for command without parameters
//		BOT_SDATA_IN	for commands with stream data
//		BOT_SDATA_OUT	for commands with stream data
//		BOT_DATA_IN		for commands with input parameters
//		BOT_DATA_OUT	for commands with output parameters

void BOT_CBW_Received( )
{
extern unsigned char Max_Lun;

	BOT_DevLun = MSL_Param_Buffer[13];			// CBW LUN
	if ( !((MSL_Param_Buffer[0] == 0x55) && (MSL_Param_Buffer[1] == 0x53)
			&& (MSL_Param_Buffer[2] == 0x42) && (MSL_Param_Buffer[3] == 0x43)
			&& (MSL_Param_Size == 31) && (BOT_DevLun <= Max_Lun)) ) {	// Wrong CBW
		BOTStateMachine = BOT_ABORT;
		SenseCode(ILLEGAL_REQUEST, INVALID_COMMAND_CODE);
		return;
	}

	// Copy the CBW Tag
	BOT_CSW[7] = MSL_Param_Buffer[7];    // CBW Tag
	BOT_CSW[6] = MSL_Param_Buffer[6];    // CBW Tag
	BOT_CSW[5] = MSL_Param_Buffer[5];    // CBW Tag
	BOT_CSW[4] = MSL_Param_Buffer[4];    // CBW Tag

	b0CBWDataTransferLength	= MSL_Param_Buffer[11];
	b1CBWDataTransferLength	= MSL_Param_Buffer[10];
	b2CBWDataTransferLength	= MSL_Param_Buffer[9];
	b3CBWDataTransferLength	= MSL_Param_Buffer[8];

	BOT_CBW_Flags = MSL_Param_Buffer[12];		// CBW Flags
	BOT_CBW_Length = MSL_Param_Buffer[14];		// CBW Length
#define RBC_Opcode	MSL_Param_Buffer[15]

	if (dCBWDataTransferLength == 0)
		BOTStateMachine = BOT_CSW_SEND;
	else {
		pMSL_Param_Buf = MSL_Param_Buffer;	// initialisation of pointer
		if (BOT_CBW_Flags & 0x80) { // Data transfer from device to host => DATA_IN
			if (RBC_Opcode == 0x28) // READ(10) need DTC machine
				BOTStateMachine = BOT_SDATA_IN;
			else
				BOTStateMachine = BOT_DATA_IN;
		}
		else {
			if ((RBC_Opcode == 0x2A)||(RBC_Opcode == 0x2F)) // WRITE and VERIFY need DTC machine
				BOTStateMachine = BOT_SDATA_OUT;
			else
				BOTStateMachine = BOT_DATA_OUT;
		} 
	}
}

/********************************* BOT_Reset *********************************/
/*****************************************************************************/
void BOT_Reset(void)
{
	RBC_Reset();
	BOTStateMachine = BOT_READY;
}

/****************************** BOT_Clear_Feature_EP *************************/
/*****************************************************************************/
void BOT_Clear_Feature_EP(void)
{
	if (BOTStateMachine == BOT_READY)
	//	if (USB_isRxStatus(2, NAK))
	//		USB_SetRxEP2Status(VALID);
		USB_RecvDataEP2(MSL_Param_Buffer, MAX_EP2_PACKET_SIZE);	// must return REQ_SUCCESS
}

/********************************* MSL_MAL_Finish ****************************/
// This function will be called from the interrupt routine!
/*****************************************************************************/
void MSL_MAL_Finish(char Status)
{
	if (Status) {
		BOTStateMachine = BOT_CSW_SEND; 
		BOT_CSW[12] = BOT_STATUS_GOOD;
	}
	else {
		BOTStateMachine = BOT_ABORT; // Skey should be allready set to the failing cause
		BOT_CSW[12] = BOT_STATUS_FAIL;
	}

	dCBWDataTransferLength = RBC_Finish();	// dCSWDataResidue
}

/**************** (c) 2000  STMicroelectronics **********************/

⌨️ 快捷键说明

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