📄 usb_utils.c
字号:
/*
Copyright 2003 Cygnal Integrated Products, Inc.
File: usb_utils.c
Author: JS
Created: JAN 03
Modified: SEP 03 -- FB (FIFORead() - disabled auto read before last byte.)
Target Device: C8051F320
Source file for USB firmware. Includes the following support routines:
- HaltEndpoint()
- EnableEndpoint()
- GetEpStatus()
- SetConfiguration()
- SetInterface()
- FIFOWrite()
- FIFORead()
******************************************/
#include "c8051F320.h"
#include "usb_regs.h"
#include "usb_structs.h"
#include "usb_main.h"
#include "usb_desc.h"#include "usb_config.h"
#include "usb_request.h"
extern DEVICE_STATUS gDeviceStatus;
extern code DESCRIPTORS gDescriptorMap;
extern DEVICE_STATUS gDeviceStatus;
extern EP_STATUS gEp0Status;
extern EP_STATUS gEp2OutStatus;
extern EP_STATUS gEp1InStatus;
//---------------------------
// HaltEndpoint()
//---------------------------
//
BYTE HaltEndpoint (UINT uEp)
{
BYTE bReturnState, bIndex;
// Save current INDEX value and target selected endpoint
UREAD_BYTE (INDEX, bIndex);
UWRITE_BYTE (INDEX, (BYTE)uEp & 0x00EF);
// Halt selected endpoint and update its status flag
switch (uEp)
{
case EP1_IN:
UWRITE_BYTE (EINCSRL, rbInSDSTL);
gEp1InStatus.bEpState = EP_HALTED;
bReturnState = EP_IDLE; // Return success flag
break;
case EP2_OUT:
UWRITE_BYTE (EOUTCSRL, rbOutSDSTL);
gEp2OutStatus.bEpState = EP_HALTED;
bReturnState = EP_IDLE; // Return success flag
break;
default:
bReturnState = EP_ERROR; // Return error flag
// if endpoint not found
break;
}
UWRITE_BYTE (INDEX, bIndex); // Restore saved INDEX
return bReturnState;
}
//---------------------------
// EnableEndpoint()
//---------------------------
//
BYTE EnableEndpoint (UINT uEp)
{
BYTE bReturnState, bIndex;
// Save current INDEX value and target selected endpoint
UREAD_BYTE (INDEX, bIndex);
UWRITE_BYTE (INDEX, (BYTE)uEp & 0x00EF);
// Flag selected endpoint has HALTED
switch (uEp)
{
case EP1_IN:
// Disable STALL condition and clear the data toggle
UWRITE_BYTE (EINCSRL, rbInCLRDT);
gEp1InStatus.bEpState = EP_IDLE; // Return success
bReturnState = EP_IDLE;
break;
case EP2_OUT:
// Disable STALL condition and clear the data toggle
UWRITE_BYTE (EOUTCSRL, rbOutCLRDT);
gEp2OutStatus.bEpState = EP_IDLE;// Return success
bReturnState = EP_IDLE;
break;
default:
bReturnState = EP_ERROR; // Return error
// if no endpoint found
break;
}
UWRITE_BYTE (INDEX, bIndex); // Restore INDEX
return bReturnState;
}
//---------------------------
// GetEpStatus()
//---------------------------
//
BYTE GetEpStatus (UINT uEp)
{
BYTE bReturnState;
// Get selected endpoint status
switch (uEp)
{
case EP1_IN:
bReturnState = gEp1InStatus.bEpState;
break;
case EP2_OUT:
bReturnState = gEp2OutStatus.bEpState;
break;
default:
bReturnState = EP_ERROR;
break;
}
return bReturnState;
}
//---------------------------
// SetConfiguration()
//---------------------------
//
//
BYTE SetConfiguration(BYTE SelectConfig)
{
BYTE bReturnState = EP_IDLE; // Endpoint state return value
PIF_STATUS pIfStatus; // Pointer to interface status
// structure
// Store address of selected config desc
gDeviceStatus.pConfig = &gDescriptorMap.bCfg1;
// Confirm that this configuration descriptor matches the requested
// configuration value
if (gDeviceStatus.pConfig[cfg_bConfigurationValue] != SelectConfig)
{
bReturnState = EP_ERROR;
}
else
{
// Store number of interfaces for this configuration
gDeviceStatus.bNumInterf = gDeviceStatus.pConfig[cfg_bNumInterfaces];
// Store total number of interface descriptors for this configuration
gDeviceStatus.bTotalInterfDsc = MAX_IF;
// Get pointer to the interface status structure
pIfStatus = (PIF_STATUS)&gDeviceStatus.IfStatus[0];
// Build Interface status structure for Interface0
pIfStatus->bIfNumber = 0; // Set interface number
pIfStatus->bCurrentAlt = 0; // Select alternate number zero
pIfStatus->bNumAlts = 0; // No other alternates
SetInterface(pIfStatus); // Configure Interface0, Alternate0
gDeviceStatus.bDevState = DEV_CONFIG;// Set device state to configured
gDeviceStatus.bCurrentConfig = SelectConfig;// Store current config
}
return bReturnState;
}
//---------------------------
// SetInterface()
//---------------------------
// Configure endpoints for the selected interface
//BYTE SetInterface(PIF_STATUS pIfStatus)
{
BYTE bReturnState = EP_IDLE;
BYTE bIndex;
// Save current INDEX value
UREAD_BYTE (INDEX, bIndex);
// Add actions for each possible interface alternate selections
switch(pIfStatus->bIfNumber)
{
// Configure endpoints for interface0
case 0:
// Configure Endpoint1 IN
UWRITE_BYTE(INDEX, 1); // Index to Endpoint1 registers
UWRITE_BYTE(EINCSRH, 0x20); // FIFO split disabled,
// direction = OUT
UWRITE_BYTE(EOUTCSRH, 0); // Double-buffering disabled
gEp1InStatus.uNumBytes = 0; // Reset byte counter
gEp1InStatus.uMaxP = EP1_IN_MAXP;// Set maximum packet size
gEp1InStatus.bEp = EP1_IN; // Set endpoint address
gEp1InStatus.bEpState = EP_IDLE; // Set endpoint state
// Endpoint2 OUT
UWRITE_BYTE(INDEX, 2); // Index to Endpoint2 registers
UWRITE_BYTE(EINCSRH, 0x04); // FIFO split enabled,
// direction = OUT
gEp2OutStatus.uNumBytes = 0; // Reset byte counter
gEp2OutStatus.uMaxP = EP2_OUT_MAXP;// Set maximum packet size
gEp2OutStatus.bEp = EP2_OUT; // Set endpoint number
gEp2OutStatus.bEpState = EP_IDLE;// Set endpoint state
// Load first outgoing (IN) packet into FIFO
BulkOrInterruptIn(&gEp1InStatus);
UWRITE_BYTE(INDEX, 0); // Return to index 0
break;
// Configure endpoints for interface1
case 1:
// Configure endpoints for interface2
case 2:
// Default (error)
default:
bReturnState = EP_ERROR;
}
UWRITE_BYTE (INDEX, bIndex); // Restore INDEX
return bReturnState;
}
//---------------------------// FIFO Read//---------------------------//// Read from the selected endpoint FIFO
//
// Inputs:
// bEp: target endpoint
// uNumBytes: number of bytes to unload
// pData: read data destination
//
void FIFORead (BYTE bEp, UINT uNumBytes, BYTE * pData){ BYTE TargetReg;
UINT i; // If >0 bytes requested,
if (uNumBytes)
{
TargetReg = FIFO_EP0 + bEp; // Find address for target
// endpoint FIFO
USB0ADR = (TargetReg & 0x3F); // Set address (mask out bits7-6)
USB0ADR |= 0xC0; // Set auto-read and initiate
// first read
// Unload <NumBytes - 1> from the selected FIFO
for(i=0; i<(uNumBytes-1); i++)
{
while(USB0ADR & 0x80); // Wait for BUSY->'0' (data ready)
pData[i] = USB0DAT; // Copy data byte
}
// Disable auto read and copy last byte
USB0ADR = (TargetReg & 0x3F); // Set address (mask out bits7-6)
while(USB0ADR & 0x80); // Wait for BUSY->'0' (data ready)
pData[i] = USB0DAT; // Copy final data byte
}}//---------------------------// FIFO Write//---------------------------//// Write to the selected endpoint FIFO
//
// Inputs:
// bEp: target endpoint
// uNumBytes: number of bytes to write
// pData: location of source data
//void FIFOWrite (BYTE bEp, UINT uNumBytes, BYTE * pData)
{
BYTE TargetReg;
UINT i;
// If >0 bytes requested,
if (uNumBytes)
{
TargetReg = FIFO_EP0 + bEp; // Find address for target
// endpoint FIFO
while(USB0ADR & 0x80); // Wait for BUSY->'0'
// (register available)
USB0ADR = (TargetReg & 0x3F); // Set address (mask out bits7-6)
// Write <NumBytes> to the selected FIFO
for(i=0;i<uNumBytes;i++)
{
USB0DAT = pData[i];
while(USB0ADR & 0x80); // Wait for BUSY->'0' (data ready)
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -