📄 usb2ser.c
字号:
#pragma NOIV // Do not generate interrupt vectors
//-----------------------------------------------------------------------------
// File: usb2ser.c (from periph.c)
// Contents: Hooks required to implement USB peripheral function.
//
// Copyright (c) 2000 Cypress Semiconductor, Inc. All rights reserved
//-----------------------------------------------------------------------------
#include "ezusb.h"
#include "ezregs.h"
#include "serial.h"
//////////////////////////////////////
// //
// Conditional-Compilation Switches //
// //
//////////////////////////////////////
#define DEBUG TRUE // TRUE = Indicate progress via Port A output pins
// FALSE = Port A pins are configured as Hi-Z inputs
#define PARITY FALSE // TRUE = Use Serial Port Mode 3 (parity enabled)
// FALSE = Use Serial Port Mode 1 (no parity)
#define PASS_DTR TRUE // TRUE = Pass DTR state from host to RS-232.
// FALSE = DTR always on.
#define USE_CTS FALSE // TRUE = Only transmit when CTS is ON.
// FALSE = Transmit regardless of CTS state.
#define USE_DSR TRUE // TRUE = Only transmit when DSR is ON.
// FALSE = Transmit regardless of DSR state.
#define RTS_MODE 1 // 0 = Local RTS state: Always ON.
// 1 = Local RTS state: ON when ready to send, OFF otherwise.
// 2 = Local RTS state: ON when ready to receive, OFF otherwise.
#define COMBINE_RTS TRUE // TRUE = Combine (AND) the host's RTS state with our own local
// RTS state, so the RTS pin will only be ON if we and
// the host BOTH want it ON.
// FALSE = Ignore the host's RTS state and simply pass our local
// state to the RTS pin.
#define STRICT_RTS_SPEC FALSE // TRUE = In RTS_MODE 1, the RTS pin strictly follows the RS-232 spec:
// it only transistions from OFF to ON while CTS is OFF.
// FALSE = In RTS_MODE 1, the RTS pin transitions from OFF to ON
// regardless of the state of the CTS pin.
////////////
// //
// Macros //
// //
////////////
#define min(a,b) (((a)<(b))?(a):(b))
////////////////////
// //
// RS-232 Defines //
// //
////////////////////
// Timing
#define BAUDRATE_57600 0xE1 // 0xE100
#define BAUDRATE_38400 0x96 // 0x9600
#define BAUDRATE_28800 0x70 // 0x7080
#define BAUDRATE_19200 0x4B // 0x4B00
#define BAUDRATE_9600 0x25 // 0x2580
#define BAUDRATE_4800 0x12 // 0x12C0
#define BAUDRATE_2400 0x09 // 0x0960
#define BAUDRATE_1200 0x04 // 0x04B0
#define BAUDRATE_300 0x01 // 0x012C
// Handshake Pins
#define CTSin (PINSC & bmBIT2)
#define DSRin (PINSC & bmBIT3)
#define RTSout (PINSC & bmBIT4)
#define DCDin (PINSC & bmBIT6)
#define RIin (PINSC & bmBIT7)
#define RTSoff (OUTC |= bmBIT4)
#define RTSon (OUTC &= ~bmBIT4)
#define DTRoff (OUTC |= bmBIT5)
#define DTRon (OUTC &= ~bmBIT5)
#define CTSisOn (!(CTSin))
#define DSRisOn (!(DSRin))
#define DCDisOn (!(DCDin))
#define RIisOn (!(RIin))
#define RTSisOn (!(RTSout))
/////////////////
// //
// HID Defines //
// //
/////////////////
#define GD_HID 0x21
#define GD_REPORT 0x22
#define CR_SET_REPORT 0x09
#define CR_GET_REPORT 0x01
#define HID_OUTPUT_REPORT 2
#define TOTAL_IN_LENGTH 64 // Length of IN Byte Count
///////////////
// //
// Variables //
// //
///////////////
// USB
extern BOOL GotSUD; // Received setup data flag
extern BOOL Sleep;
BYTE Configuration; // Current configuration
BYTE AlternateSetting; // Alternate settings
// HID
extern code HIDDscr;
extern code ReportDscr;
extern code ReportDscrEnd;
WORD pHIDDscr;
WORD pReportDscr;
WORD pReportDscrEnd;
// TX Buffer
#define TX_BUFFER_SIZE 1024
BYTE xdata txBuffer[TX_BUFFER_SIZE] _at_ 0x2000; // 1K ISO Buffer space
static WORD txInPtr; // Buffer fills (from USB) here
static WORD txOutPtr; // Buffer empties (to RS-232) here
// RX Buffer
#define RX_BUFFER_SIZE 1024
BYTE xdata rxBuffer[RX_BUFFER_SIZE] _at_ 0x2400; // 1K ISO Buffer space
static WORD rxInPtr; // Buffer fills (from RS-232) here
static WORD rxOutPtr; // Buffer empties (to USB) here
WORD nextRxInPtr; // Used by "From RS-232" routine
// Misc
static BYTE Ep1Index; // Index into the EP1 buffer
static BYTE Ep2Index; // Index into the EP2 buffer
BYTE bdata bitTemp; // Temporary storage for the
// states of the handshake pins
sbit ri = bitTemp ^ 7; //
sbit cd = bitTemp ^ 6; //
sbit dsr = bitTemp ^ 5; //
sbit cts = bitTemp ^ 4; //
static BYTE bdata oldTemp; // holds the last-read status of the handshake pins.
BYTE bdata bitFlags; // Miscellaneous flags.
sbit localRTS = bitFlags ^ 7; // local RTS state
sbit hostRTS = bitFlags ^ 6; // host's RTS state
sbit sendToUSB = bitFlags ^ 5; // 1 = we have data (or handshake-pin changes) to send to USB
/////////////////////////
// //
// Function Prototypes //
// //
/////////////////////////
void TD_Init (void); // Initialization -- Called once from FW.C
void TD_Poll (void); // Main routine -- Called repeatedly from FW.C's main()
void setup_uart (BYTE []); // Setup the baud rate -- Called whenever we receive a SET_REPORT
//-----------------------------------------------------------------------------
// Task Dispatcher hooks
// The following hooks are called by the task dispatcher.
//-----------------------------------------------------------------------------
//
// This function is called once at startup
//
void TD_Init(void)
{
// Initialize Endpoints
IN07VAL |= bmEP1; // Enable EP1IN
OUT07VAL |= bmEP2; // Enable EP2OUT
OUT07IEN = 0; // Make sure endpoint interrupts are disabled.
USBPAIR |= 0x08; // Double-buffer EP2OUT
Ep2Index = 2; // Initialize the Endpoint-buffer indexes.
Ep1Index = 0; //
// Initialize I/O Ports
PORTCCFG = 0x03; // PC0 and PC1 are configured for alternate functions RXD0 & TXD0
OEC = 0x30; // Use the rest as I/O pins:
OUTC = 0xDF; // PC2: CTS (input)
// PC3: DSR (input)
// PC4: RTS (output)
// PC5: DTR (output)
// PC6: DCD (input)
// PC7: RI (input)
#if (DEBUG)
PORTACFG = 0x00;
OEA = 0xFF;
OUTA = 0x00;
#endif
// Initialize TX / RX Buffers and pointers
ISOCTL |= 0x01; // Free up isochronous endpoint RAM for TX/RX buffer space
txInPtr = txOutPtr = 0; // Reset TX- & RX-buffer pointers to zero
rxInPtr = rxOutPtr = 0; //
// Setup breakpoint to trigger on TD_Poll() so the green
// LED will light to indicate that the code's running.
BPADDR = (WORD)TD_Poll; // Point breakpoint at TD_Poll()
USBBAV |= bmBPEN; // Enable the breakpoint
USBBAV &= ~bmBPPULSE; // Configure it to pulse when hit
// Initialize the UART (baud rate is set later, whenever we receive
// SET_REPORT packets from the host).
ES0 = 0; // Make sure RX/TX interrupts are disabled.
TI = 1; // Arm the TI bit to kick-start the transmitter.
DTRon; // Initialize DTR ON.
#if ((RTS_MODE == 0) || (RTS_MODE == 2)) // If RTS_MODE = 0 (always ON) or 2 (ON when
localRTS = 1; // ready to receive), initialize local RTS ON.
#else // Otherwise, initialize local RTS OFF.
localRTS = 0; //
#endif //
hostRTS = 1; // Assume host's RTS state is ON.
}
//
// This function is called repeatedly by the main loop in FW.C
//
void TD_Poll(void)
{
#if (DEBUG)
OUTA ^= 0x01;
#endif
//
// Every time through the loop, set or clear RTS appropriately.
//
#if (COMBINE_RTS)
if (localRTS && hostRTS)
#else
if (localRTS)
#endif
{
RTSon;
}
else
{
RTSoff;
}
//
// TO USB
//
if (!(IN1CS & bmEPBUSY)) // If EP1IN is idle
{
#if (DEBUG)
OUTA ^= 0x02;
#endif
bitTemp = 0;
ri = RIisOn;
cd = DCDisOn;
dsr = DSRisOn;
cts = CTSisOn;
Ep1Index = 2;
sendToUSB = 0; // Assume we won't be sending to USB.
if (bitTemp != oldTemp) // If the handshake pins have changed...
{
oldTemp = bitTemp; // update oldTemp with the new pin status.
sendToUSB = 1; // let everyone know that we'll be sending a packet to USB.
}
if (rxOutPtr != rxInPtr) // if we have data to send...
{
do
{
IN1BUF[Ep1Index] = rxBuffer[rxOutPtr];
rxOutPtr = (rxOutPtr + 1) % RX_BUFFER_SIZE;
Ep1Index++;
} while ( (Ep1Index < TOTAL_IN_LENGTH) && (rxOutPtr != rxInPtr) );
sendToUSB = 1; // let everyone know that we'll be sending a packet to USB.
}
if (sendToUSB) // if we have something to send...
{
IN1BUF[0] = bitTemp;
IN1BUF[1] = Ep1Index - 2;
IN1BC = Ep1Index;
}
}
//
// FROM USB
//
if ( !(OUT2CS & bmEPBUSY) ) // If data's waiting in EP2OUT
{
BYTE outLength;
#if (DEBUG)
OUTA ^= 0x04;
#endif
#if (PASS_DTR)
if (OUT2BUF[0] & bmBIT5) DTRon;
else DTRoff;
#endif
if (OUT2BUF[0] & bmBIT4) hostRTS = 1;
else hostRTS = 0;
outLength = OUT2BUF[1]+2;
while ( (Ep2Index != outLength)
&& (((txInPtr + 1) % TX_BUFFER_SIZE) != txOutPtr) )
{
#if (DEBUG)
OUTA ^= 0x20;
#endif
txBuffer[txInPtr] = OUT2BUF[Ep2Index];
txInPtr = (txInPtr + 1) % TX_BUFFER_SIZE;
Ep2Index++;
}
if (Ep2Index == outLength)
{
Ep2Index = 2;
OUT2BC = 0;
}
}
//
// TO RS-232
//
if (TI)
{
#if (DEBUG)
OUTA ^= 0x08;
#endif
#if (USE_DSR)
if (DSRisOn)
#endif
{
if (txOutPtr != txInPtr) // If we have data in txBuffer[]
{
#if (DEBUG)
OUTA ^= 0x40;
#endif
#if (RTS_MODE == 1)
if (RTSisOn)
#endif
{
#if (USE_CTS)
if (CTSisOn)
#endif
{
TI = 0;
SBUF0 = txBuffer[txOutPtr];
txOutPtr = (txOutPtr + 1) % TX_BUFFER_SIZE;
}
}
#if (RTS_MODE == 1)
else
{
#if (STRICT_RTS_SPEC)
if (!CTSisOn)
#endif
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -