⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 enumappnote_bf1.c

📁 BR1 source code
💻 C
📖 第 1 页 / 共 2 页
字号:
{
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 + -