📄 enumappnote_bf1.c
字号:
{
wreg(rEP0FIFO,configval); // Send the config value
wregAS(rEP0BC,1);
}
//**********************
void set_interface(void) // All we accept are Interface=0 and AlternateSetting=0, otherwise send STALL
{
BYTE dumval;
if((SUD[wValueL]==0) // wValueL=Alternate Setting index
&&(SUD[wIndexL]==0)) // wIndexL=Interface index
dumval=rregAS(rFNADDR); // dummy read to set the ACKSTAT bit
else STALL_EP0
}
//**********************
void get_interface(void) // Check for Interface=0, always report AlternateSetting=0
{
if(SUD[wIndexL]==0) // wIndexL=Interface index
{
wreg(rEP0FIFO,0); // AS=0
wregAS(rEP0BC,1); // send one byte, ACKSTAT
}
else STALL_EP0
}
//*******************
void get_status(void)
{
BYTE testbyte;
testbyte=SUD[bmRequestType];
switch(testbyte)
{
case 0x80: // directed to DEVICE
wreg(rEP0FIFO,(RWU_enabled+1)); // first byte is 000000rs where r=enabled for RWU and s=self-powered.
wreg(rEP0FIFO,0x00); // second byte is always 0
wregAS(rEP0BC,2); // load byte count, arm the IN transfer, ACK the status stage of the CTL transfer
break;
case 0x81: // directed to INTERFACE
wreg(rEP0FIFO,0x00); // this one is easy--two zero bytes
wreg(rEP0FIFO,0x00);
wregAS(rEP0BC,2); // load byte count, arm the IN transfer, ACK the status stage of the CTL transfer
break;
case 0x82: // directed to ENDPOINT
if(SUD[wIndexL]==0x83) // We only reported ep3, so it's the only one the host can stall IN3=83
{
wreg(rEP0FIFO,ep3stall); // first byte is 0000000h where h is the halt (stall) bit
wreg(rEP0FIFO,0x00); // second byte is always 0
wregAS(rEP0BC,2); // load byte count, arm the IN transfer, ACK the status stage of the CTL transfer
break;
}
else STALL_EP0 // Host tried to stall an invalid endpoint (not 3)
default: STALL_EP0 // don't recognize the request
}
}
// **********************************************************************************************
// FUNCTION: Set/Get_Feature. Call as feature(1) for Set_Feature or feature(0) for Clear_Feature.
// There are two set/clear feature requests:
// To a DEVICE: Remote Wakeup (RWU).
// To an ENDPOINT: Stall (EP3 only for this app)
//
void feature(BYTE sc)
{
BYTE mask;
if((SUD[bmRequestType]==0x02) // dir=h->p, recipient = ENDPOINT
&& (SUD[wValueL]==0x00) // wValueL is feature selector, 00 is EP Halt
&& (SUD[wIndexL]==0x83)) // wIndexL is endpoint number IN3=83
{
mask=rreg(rEPSTALLS); // read existing bits
if(sc==1) // set_feature
{
mask += bmSTLEP3IN; // Halt EP3IN
ep3stall=1;
}
else // clear_feature
{
mask &= ~bmSTLEP3IN; // UnHalt EP3IN
ep3stall=0;
wreg(rCLRTOGS,bmCTGEP3IN); // clear the EP3 data toggle
}
wreg(rEPSTALLS,(mask|bmACKSTAT)); // Don't use wregAS for this--directly writing the ACKSTAT bit
}
else if ((SUD[bmRequestType]==0x00) // dir=h->p, recipient = DEVICE
&& (SUD[wValueL]==0x01)) // wValueL is feature selector, 01 is Device_Remote_Wakeup
{
RWU_enabled = sc<<1; // =2 for set, =0 for clear feature. The shift puts it in the get_status bit position.
rregAS(rFNADDR); // dummy read to set ACKSTAT
}
else STALL_EP0
}
//************************
void send_descriptor(void)
{
WORD reqlen,sendlen,desclen;
BYTE *pDdata; // pointer to ROM Descriptor data to send
//
// NOTE This function assumes all descriptors are 64 or fewer bytes and can be sent in a single packet
//
desclen = 0; // check for zero as error condition (no case statements satisfied)
reqlen = SUD[wLengthL] + 256*SUD[wLengthH]; // 16-bit
switch (SUD[wValueH]) // wValueH is descriptor type
{
case GD_DEVICE:
desclen = DD[0]; // descriptor length
pDdata = DD;
break;
case GD_CONFIGURATION:
desclen = CD[2]; // Config descriptor includes interface, HID, report and ep descriptors
pDdata = CD;
break;
case GD_STRING:
desclen = strDesc[SUD[wValueL]][0]; // wValueL=string index, array[0] is the length
pDdata = strDesc[SUD[wValueL]]; // point to first array element
break;
case GD_HID:
desclen = CD[18];
pDdata = &CD[18];
break;
case GD_REPORT:
desclen = CD[25];
pDdata = RepD;
break;
} // end switch on descriptor type
//
if (desclen!=0) // one of the case statements above filled in a value
{
sendlen = (reqlen <= desclen) ? reqlen : desclen; // send the smaller of requested and avaiable
writebytes(rEP0FIFO,sendlen,pDdata);
wregAS(rEP0BC,sendlen); // load EP0BC to arm the EP0-IN transfer & ACKSTAT
}
else STALL_EP0 // none of the descriptor types match
}
void class_request(void)
{
STALL_EP0
}
void vendor_request(void)
{
STALL_EP0
}
// ******************** END of ENUMERATION CODE ********************
//
void Reset_MAX(void)
{
BYTE dum;
wreg(rUSBCTL,0x20); // chip reset
wreg(rUSBCTL,0x00); // remove the reset
do // Chip reset stops the oscillator. Wait for it to stabilize.
{
dum=rreg(rUSBIRQ);
dum &= bmOSCOKIRQ;
}
while (dum==0);
}
//
// ------------------------------------------------------------
// The code below customizes this app for the MAXQ2000
// microprocessor and the Rowley compiler. Only this
// section changes if you use a different uP and/or compiler.
// ------------------------------------------------------------
//
// The MAX3420E is wired to the MAXQ2000 as follows:
//
// MISO P57 (in)
// SCLK P56 (out)
// MOSI P55 (out)
// SS# P54 (out)
// GPX P53 (in)
// INT P60 (in)
sfrw SPIB = 0x53; // This is how the Rowley compiler declares MAXQ SFR registers
sfrb SPICF = 0x163;
sfrb SPICK = 0x173;
sfrb CKCN = 0xe8;
sfrb PO5 = 0x11;
sfrb PD5 = 0x111;
sfrb PD6 = 0x121;
sfrb PI6 = 0xA1;
sfrb SPICN = 0x153;
// Register SPICN bit masks
#define bmSPIEN 0x01
#define bmMSTM 0x02
#define bmSTBY 0x80
//
#define SS_HI PO5 |= 0x10; // SS# connected to Port5 bit4 in this app
#define SS_LO PO5 &= ~0x10;
BYTE MAX_Int_Pending(void)
{
return (BYTE)((PI6&0x01)==0);
}
void SPI_Init(void)
{
// Set up the MAXQ2000 SPI port
CKCN = 0x00; // system clock divisor is 1
SS_HI // SS# high
PD5 |= 0x070; // Set SPI pins (SCLK, MOSI, and SS#) as outputs
PD5 &= ~0x088; // Set SPI pins (MISO,GPX) as inputs
PD6 &= ~0x01; // Set P60 (INT) as input
SPICK = 0x00; // fastest SPI clock--div by 2
SPICF = 0x00; // mode(0,0), 8 bit data
SPICN |= bmMSTM; // Set SPI controller as master
SPICN |= bmSPIEN; // Enable the SPI controller
}
void wreg(BYTE reg, BYTE dat)
{
SS_LO // Set SS# low
SPIB = reg+2; // send the register number with the DIR bit (b1) set to WRITE
while (SPICN & bmSTBY); // loop if data still being sent
SPIB = dat; // send the data
while (SPICN & bmSTBY); // loop if data still being sent
SS_HI // set SS# high
}
// Write a MAX3410E register with the "ACK STATUS" bit set in the command byte
void wregAS(BYTE reg, BYTE dat)
{
SS_LO // Set SS# low
SPIB = reg+3; // reg number with DIR=1 (write) and ACKSTAT=1
while (SPICN & bmSTBY); // loop if data still being sent
SPIB = dat; // send the data
while (SPICN & bmSTBY); // loop if data still being sent
SS_HI // set SS# high
}
// Read a register, return its value.
BYTE rreg(BYTE reg)
{
BYTE dum;
SS_LO
SPIB = reg; // reg number w. dir=0 (IN)
while (SPICN & bmSTBY); // loop if data still being sent
dum = SPIB; // NECESSARY TO RE-ENABLE THE INPUT BUFFER in BYTE MODE
SPIB=0x00; // data is don't care, we're clocking in MISO bits
while (SPICN & bmSTBY); // loop if data still being sent
SS_HI
return(SPIB);
}
// Read a byte (as rreg), but also set the AckStat bit in the command byte.
BYTE rregAS(BYTE reg)
{
BYTE dum;
SS_LO
SPIB = reg+1; // reg number w. dir=0 (IN) and ACKSTAT=1
while (SPICN & bmSTBY); // loop if data still being sent
dum = SPIB; // NECESSARY TO RE-ENABLE THE INPUT BUFFER in BYTE MODE
SPIB=0xFF; // data is don't care, we're clocking in MISO bits
while (SPICN & bmSTBY); // loop if data still being sent
SS_HI
return(SPIB);
}
void readbytes(BYTE reg, BYTE N, BYTE *p)
{
BYTE j;
SS_LO
SPIB = reg; // write bit b1=0 to command a read operation
while (SPICN & bmSTBY); // loop if data still being sent
j = SPIB; // NECESSARY TO RE-ENABLE THE INPUT BUFFER in BYTE MODE
for(j=0; j<N; j++)
{
SPIB = 0x00; // dummy value to get the next read byte
while (SPICN & bmSTBY); // loop if data still being sent
*p = SPIB; // store it in the data array
p++; // bump the pointer
}
SS_HI
}
void writebytes(BYTE reg, BYTE N, BYTE *p)
{
BYTE j,wd;
SS_LO
SPIB = reg+2; // write bit b1=1 to command a write operation
while (SPICN & bmSTBY); // loop if data still being sent
for(j=0; j<N; j++)
{
wd = *p; // write the array value
SPIB = wd;
while (SPICN & bmSTBY); // loop if data still being sent
p++; // bump the pointer
}
SS_HI
}
//
// Diagnostic Aid:
// Call this function from main() to verify operation of your SPI port.
//
void test_SPI(void) // Use this to check your versions of the rreg and wreg functions
{
BYTE j,wr,rd;
SPI_Init(); // Configure and initialize the uP's SPI port
wreg(rPINCTL,bmFDUPSPI); // MAX3420: SPI=full-duplex
wreg(rUSBCTL,bmCHIPRES); // reset the MAX3420E
wreg(rUSBCTL,0); // remove the reset
wr=0x01; // initial register write value
for(j=0; j<8; j++)
{
wreg(rUSBIEN,wr);
rd = rreg(rUSBIEN);
wr <<= 1; // Put a breakpoint here. Values of 'rd' should be 01,02,04,08,10,20,40,80
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -