📄 bot.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 + -