?? main.c
字號(hào):
#include "InsUsb.h"
#include <intrins.h>
#define _Debug_
//global structure variable
SYS_INFORMATION data sSysInformation;
//global array variable
unsigned char xdata mEp0OutBuffer[EP0_OUT_BUFFER_SIZE];
unsigned char data mEp0InBuffer[EP0_IN_BUFFER_SIZE];
unsigned char data mEp1OutBuffer[EP1_OUT_BUFFER_SIZE]; //store led status
unsigned char data mEp1InBuffer[EP1_IN_BUFFER_SIZE]; //store switch status
unsigned char xdata mRamBuffer[RAM_BUFFER_SIZE];
unsigned char xdata mSerialNumber[4];
void UsbBusReset(void);
extern void D12SetMode(unsigned char bConfiguration, unsigned char bClockkDivision);
extern void D12SetAddressEnable(unsigned char bAddress, unsigned char bEnable);
extern void D12SetEndpointStatus(unsigned char bEndpointIndex, unsigned char bStalled);
extern void D12WriteBuffer(unsigned char bEndpointIndex,unsigned char bLength, unsigned char * pBuffer);
extern void D12SetEndpointEnable(unsigned char bEndpointEnable);
extern void D12SetDMA(unsigned char bValue);
extern void D12SendResume(void);
extern void UsbIsr(void);
extern void UsbSetUpDeal(void);
extern void ControlOutDealWith(void);
//
//*************************************************************************
// Paremeter:
// In : None
// Out: None
// Function:
// On PDIUSBD12 Develop Board,the interrupt pin of PDIUSBD12 is connected
// to INT0 of P89C51RD2.When interrupt has happened,this function
// will call UsbIsr(),which will deal with USB interrupt
void UsbInterrupt(void) interrupt 0
{
#ifdef _INT_MODE_
UsbIsr(); //USB interrupt service routine
#endif
}
//
//*************************************************************************
// Paremeter:
// In : None
// Out: None
// Function:
// This interrupt is use to refresh LED and switch status
void Timer0Interrupt(void) interrupt 1
{
static unsigned char data bTimer0Tiems = 0x00;
if ((++bTimer0Tiems) >= 5) //5*65535*6*(1/18.432)=107ms
{
sSysInformation.bTimer0 = TRUE;
bTimer0Tiems = 0x00;
}
TH0 = 0x00;
TL0 = 0x00;
}
//
//*************************************************************************
// Paremeter:
// In : None
// Out: None
// Function:
// After system power on reset finished,this function will initialize
// system,include reset PDIUSBD12,initialize all variable,test innteral
// RAM of P89C51RD2,and set UART,set LED,Switch
void SysInitialize(void)
{
unsigned int data i;
unsigned char xdata * data pInnerRam = &MCU_INNER_RAM;
D12_RESET = 0; //reset PDIUSBD12
LED_ADDRESS = 0xFF; //all led will turn off
sSysInformation.bRamError = FALSE; //no error
sSysInformation.bTimer0 =FALSE; //bTimer0
sSysInformation.bBusReset = FALSE;
sSysInformation.bSuspendChange = FALSE;
sSysInformation.bInSuspend = FALSE;
sSysInformation.bRemoteWakeUpEnable = FALSE;
sSysInformation.bD12ConfigurationValue = 0x00;
sSysInformation.bSetup = FALSE;
sSysInformation.bUsbStatus = IDLE;
sSysInformation.sUsbSetUpDealwith.wRemaindLength = 0;
sSysInformation.sUsbSetUpDealwith.bControlOutDataComplete = TRUE;
sSysInformation.sUsbSetUpDealwith.bControOutCommandIsPending = FALSE;
sSysInformation.sRamControl.bRamCommand = RAM_COMMAND_LOOPBACK;
sSysInformation.sRamControl.bRamRwStatus = IDLE;
sSysInformation.sRamControl.iRamStartAddress = &mRamBuffer;
sSysInformation.sRamControl.iRamRwLength = 0;
sSysInformation.sRamControl.iRamRemaindLength = 0;
//check internal ram of P89C51RD2,it has a internal ram which size is 768 byte.
//first write 0x5a to all ram unit ,then read and compare,if error happened,
//set bRamError flag
for (i=0;i<768;i++)
{
*pInnerRam = 0x5A; //all inner ram is written to 0x5a
pInnerRam++;
}
pInnerRam = &MCU_INNER_RAM;
for (i=0;i<768;i++)
{
if (*pInnerRam != 0x5A) //read back from high address of inner ram
{
sSysInformation.bRamError = TRUE; //if not equal to 0x5a,error happened
break; //and exit from this cycle
}
pInnerRam++;
}
//second write 0xa5 to all ram unit ,then read and compare,if error happened,
//set bRamError flag
pInnerRam = &MCU_INNER_RAM;
if (sSysInformation.bRamError==FALSE)//test inner ram the second time,write 0xa5
{
for (i=0;i<768;i++)
{
*pInnerRam = 0xA5;
pInnerRam++;
}
pInnerRam = &MCU_INNER_RAM;
for (i=1;i<768;i++)
{
if (*pInnerRam != 0xA5)
{
sSysInformation.bRamError = TRUE;
break;
}
pInnerRam++;
}
}
//if no ram error found,initialize all ram unit to 0xFF
pInnerRam = &MCU_INNER_RAM;
for (i=0;i<768;i++)
{
*pInnerRam = 0xFF;
pInnerRam++;
}
//Timer1 set,used as UART baud rate generator
TMOD = 0x20;
SCON = 0x50;
PCON = 0x80;
TH1 = 0xFB; //OSC is 18.432MHz,MCU is 6 clock mode,then BaudRate will be 38400
TL1 = 0xFB;
TI=1;
TR1=1;
//INT0 set,interrupt source is PDIUSBD12
#ifdef _INT_MODE_
IT0 = 0; //low level trigle
EX0 = 1;
PX0 = 0;
#endif
//Timer0 set, used as switch and led refresh timing
TMOD &= 0XF0;
TMOD |= 0X1;
TL0 = 0X0;
TH0 = 0X0;
ET0 = 1;
TR0 = 1;
PT0 = 1;
D12_RESET = 1; //release PDIUSBD12 reset
}
//
//*************************************************************************
// Paremeter:
// In : None
// Out: None
// Function:
// This is main function of firmware.It is an infinate cycle and check
// sSysInformation,if any flag is set, call corresponding function to
// deal with it.
void main(void)
{
unsigned char data i;
unsigned int data j;
EA = 0; //MCU global interrupt is enabled
SysInitialize();
#ifdef _Debug_
j = FIRMWARE_VERSION;
printf("Interface Studio PDIUSBD12 USB1.1 Develop Board FirmWare V%x.\n,",j);
#endif
if (sSysInformation.bRamError == FALSE)
{
#ifdef _Debug_
printf("On Chip XRAM tested,and no error.\n");
#endif
}
else
{
#ifdef _Debug_
printf("On Chip XRAM error.\n");
#endif
while(1); //if on chip XRAM error,data transfer of bulk transfer will
//be error,so here is a dead cycle;
}
D12_SUSPEND = 0; //pull down D12_SUSPEND pin for access it
D12SetAddressEnable(USB_DEFAULT_DEVICE_ADDRESS,TRUE); //after reset D12,use default address,namely endpoint0,address 0
D12SetMode(0x00, 0x4B);
D12SetDMA(0xC0);
#ifdef _Debug_
printf("Connecting to USB...");
#else
//we found that if here has no delay,PDIUSBD12 can not setup USB connection correctly!!
for (j=0;j<1000;j++) _nop_ ();
#endif
D12SetMode(0x10,0x4B); //enable soft connect
#ifdef _Debug_
printf("Connection finished!\n");
#endif
for (j=0;j<10000;j++) _nop_ ();
mEp1InBuffer[0] = SWITCH_ADDRESS;
EA = 1; //MCU global interrupt is enabled
//Main program loop
while(1)
{
#ifndef _INT_MODE_
if (U_INT!=1)
{
UsbIsr(); //USB interrupt service routine
}
#endif
if (sSysInformation.bTimer0)
{
//if Host driver has successfully configed our device
if (sSysInformation.bD12ConfigurationValue != 0x00)
{
i = SWITCH_ADDRESS;
if (mEp1InBuffer[0] != i)
{
//Here we will write switch status to endpoint1-in buffer if switch status changed.
//When interrupt IN token is received,this switch status will be transmit to Host
//automatically by PDIUSBD12.Host software should transmit IN token periodly according
//to the interval describled by endpoint descriptor.If no switch status change,
//endpoint1-in buffer has no valid data and when Host transmit IN token,PDIUSBD12
//will return NAK automatically.
mEp1InBuffer[0] = i;
D12WriteBuffer(D12_SELECT_ENDPOINT_ENDPOINT1_IN,0x01,&mEp1InBuffer[0]);
}
//refresh led status,always be executed periodly
LED_ADDRESS = mEp1OutBuffer[0];
sSysInformation.bTimer0 = FALSE;
}
}
if (sSysInformation.bSuspendChange)
{
//According to USB specification,when Host request device enter suspend state,
//device should draw no more than 500uA current.This requirement is very strict.
//Interface studio USB1.1 develop board is self powered,so we can ignore this
//requirement.We just set bInSuspend flag,but run our firmware as usual.
#ifdef _Debug_
printf("Suspend change.\n");
#endif
D12_SUSPEND = 1; //release SUSPEND pin,if D12 enter SUSPEND state,
//this pin will be drive high by D12;
//else if D12 exit SUSPEND,this pin will be drive low by D12
for (i=0;i<10;i++); //delay for suspend pin is stable driven by PDIUSBD12
if(D12_SUSPEND == 1)
{
D12_SUSPEND = 0; //pull low to access D12
LED_ADDRESS = 0xFF; //close all led for save power
sSysInformation.bSuspendChange = FALSE; //clear suspend flag
sSysInformation.bInSuspend = TRUE; //set suspend flag,used for MCU is exit powrdown mode
D12_SUSPEND = 1;
#ifdef _Debug_
printf("Enter suspend.\n");
#endif
}
else
{
sSysInformation.bInSuspend = FALSE; //set suspend flag,used for MCU is exit powrdown mode
sSysInformation.bSuspendChange = FALSE; //clear suspend flag
#ifdef _Debug_
printf("Exit suspend.\n");
#endif
}
}
if (sSysInformation.bBusReset)
{
UsbBusReset();
#ifdef _Debug_
printf("Bus reset.\n");
#endif
}
//if received a setup packet
if (sSysInformation.bSetup)
{
EA = 0;
#ifdef _Debug_
printf("--------------------------------------------\n");
printf("SetUp: bRequest code is :");
printf("%x,%x,%x,%x,%x,\n", (unsigned int)(sSysInformation.sUsbDeviceRequest.bmRequestType),
(unsigned int)(sSysInformation.sUsbDeviceRequest.bRequest),
(sSysInformation.sUsbDeviceRequest.wValue),
(sSysInformation.sUsbDeviceRequest.wIndex),
(sSysInformation.sUsbDeviceRequest.wLength));
#endif
UsbSetUpDeal();
sSysInformation.bSetup = FALSE;
EA = 1;
}
//if there is a uncompleted control-out transfer
if (sSysInformation.sUsbSetUpDealwith.bControOutCommandIsPending)
{
ControlOutDealWith();
}
} // Main Loop end
}
void UsbBusReset(void)
{
//When first connect to Host, Host will always issue a bus reset command.
//And if USB communication has error,host may issue bus reset command also.
//When no USB cable connect between Host and PDIUSBD12,D+ and D- wire will be
//high impedance,and no USB event should be produced by PDIUSBD12;but unfortunately,
//unsure state of D+/D- will make PDIUSBD12 produce error USB bus event to MCU.
//To avoid this case,we can attach a 1Mohm pullup resistor to D-,and a 1Mohm
//pulldown resistor to D+,thus when there has no USB connection,PDIUSBD12 will
//report a bus reset state to MCU.but this has no trouble to our application.
//If Host transmit bus reset signal
sSysInformation.bBusReset = FALSE;
sSysInformation.bRemoteWakeUpEnable = FALSE;
sSysInformation.bD12ConfigurationValue = 0x00;
sSysInformation.bSetup = FALSE;
sSysInformation.bUsbStatus = IDLE;
sSysInformation.sUsbSetUpDealwith.wRemaindLength = 0;
sSysInformation.sUsbSetUpDealwith.bControlOutDataComplete = TRUE;
sSysInformation.sUsbSetUpDealwith.bControOutCommandIsPending = FALSE;
sSysInformation.sRamControl.bRamCommand = RAM_COMMAND_LOOPBACK;
sSysInformation.sRamControl.bRamRwStatus = IDLE;
sSysInformation.sRamControl.iRamStartAddress = &mRamBuffer;
sSysInformation.sRamControl.iRamRwLength = 0;
sSysInformation.sRamControl.iRamRemaindLength = 0;
D12SetAddressEnable(USB_DEFAULT_DEVICE_ADDRESS,TRUE); //after reset D12,use default address,namely endpoint0,address 0
D12SetEndpointEnable(0x00); //disable generic/isochronous endpoint
}
//
//*************************************************************************
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -