feat: usb and HID demo
This commit is contained in:
parent
20f6c22f22
commit
27790cc05b
437
demo/usb/usb_hid.c
Normal file
437
demo/usb/usb_hid.c
Normal file
@ -0,0 +1,437 @@
|
||||
// Copyright 2021 IOsetting <iosetting(at)outlook.com>
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "fw_hal.h"
|
||||
|
||||
__CODE uint8_t DEVICEDESC[18];
|
||||
__CODE uint8_t CONFIGDESC[41];
|
||||
__CODE uint8_t HIDREPORTDESC[27];
|
||||
__CODE uint8_t LANGIDDESC[4];
|
||||
__CODE uint8_t MANUFACTDESC[8];
|
||||
__CODE uint8_t PRODUCTDESC[30];
|
||||
__XDATA uint8_t HidFreature[64];
|
||||
__XDATA uint8_t HidInput[64];
|
||||
__XDATA uint8_t HidOutput[64];
|
||||
SETUP Setup;
|
||||
EP0STAGE Ep0Stage;
|
||||
|
||||
void USB_Init();
|
||||
uint8_t CalCheckSum(uint8_t *buf, uint8_t len);
|
||||
|
||||
void main()
|
||||
{
|
||||
uint8_t i;
|
||||
GPIO_P3_SetMode(GPIO_Pin_0|GPIO_Pin_1, GPIO_Mode_Input_HIP);
|
||||
|
||||
USB_Init();
|
||||
EA = 1;
|
||||
HidOutput[0]=0xaa;
|
||||
HidOutput[1]=0x55;
|
||||
HidOutput[2]=0x02;
|
||||
for(i=3;i<64;i++) HidOutput[i] = 0;
|
||||
HidOutput[3] = (uint8_t)(0x01);
|
||||
HidOutput[4] = (uint8_t)(0x02);
|
||||
HidOutput[5] = (uint8_t)(0x01);
|
||||
HidOutput[6] = (uint8_t)(0x02);
|
||||
HidOutput[7] = CalCheckSum(HidOutput,7);
|
||||
|
||||
while (1);
|
||||
}
|
||||
|
||||
void USB_Init()
|
||||
{
|
||||
SYS_EnableOscillator48M();
|
||||
USBCLK = 0x00;
|
||||
USBCON = 0x90;
|
||||
IP2H |= 0x80; // highest priority
|
||||
IP2 |= 0x80;
|
||||
USB_WriteReg(FADDR, 0x00);
|
||||
USB_WriteReg(POWER, 0x08);
|
||||
USB_WriteReg(INTRIN1E, 0x3f);
|
||||
USB_WriteReg(INTROUT1E, 0x3f);
|
||||
USB_WriteReg(INTRUSBE, 0x00);
|
||||
USB_WriteReg(POWER, 0x01);
|
||||
Ep0Stage.bStage = EPIDLE;
|
||||
IE2 |= 0x80;
|
||||
}
|
||||
|
||||
INTERRUPT(USB_Routine, EXTI_VectUSB)
|
||||
{
|
||||
uint8_t intrusb;
|
||||
uint8_t intrin;
|
||||
uint8_t introut;
|
||||
uint8_t csr;
|
||||
uint8_t cnt;
|
||||
uint16_t len;
|
||||
intrusb = USB_ReadReg(INTRUSB);
|
||||
intrin = USB_ReadReg(INTRIN1);
|
||||
introut = USB_ReadReg(INTROUT1);
|
||||
if (intrusb & RSTIF)
|
||||
{
|
||||
USB_WriteReg(INDEX, 1);
|
||||
USB_WriteReg(INCSR1, INCLRDT);
|
||||
USB_WriteReg(INDEX, 1);
|
||||
USB_WriteReg(OUTCSR1, OUTCLRDT);
|
||||
Ep0Stage.bStage = EPIDLE;
|
||||
}
|
||||
if (intrin & EP0IF)
|
||||
{
|
||||
USB_WriteReg(INDEX, 0);
|
||||
csr = USB_ReadReg(CSR0);
|
||||
if (csr & STSTL)
|
||||
{
|
||||
USB_WriteReg(CSR0, csr & ~STSTL);
|
||||
Ep0Stage.bStage = EPIDLE;
|
||||
}
|
||||
if (csr & SUEND)
|
||||
{
|
||||
USB_WriteReg(CSR0, csr | SSUEND);
|
||||
}
|
||||
switch (Ep0Stage.bStage)
|
||||
{
|
||||
case EPIDLE:
|
||||
if (csr & OPRDY)
|
||||
{
|
||||
Ep0Stage.bStage = EPSTATUS;
|
||||
USB_ReadFIFO(FIFO0, (uint8_t *)&Setup);
|
||||
((uint8_t *)&Ep0Stage.wResidue)[0] = Setup.wLengthH;
|
||||
((uint8_t *)&Ep0Stage.wResidue)[1]= Setup.wLengthL;
|
||||
switch (Setup.bmRequestType & REQUEST_MASK)
|
||||
{
|
||||
case STANDARD_REQUEST:
|
||||
switch (Setup.bRequest)
|
||||
{
|
||||
case SET_ADDRESS:
|
||||
USB_WriteReg(FADDR, Setup.wValueL);
|
||||
break;
|
||||
|
||||
case SET_CONFIG:
|
||||
USB_WriteReg(INDEX, 1);
|
||||
USB_WriteReg(INCSR2, INMODEIN);
|
||||
USB_WriteReg(INMAXP, 8);
|
||||
USB_WriteReg(INDEX, 1);
|
||||
USB_WriteReg(INCSR2, INMODEOUT);
|
||||
USB_WriteReg(OUTMAXP, 8);
|
||||
USB_WriteReg(INDEX, 0);
|
||||
break;
|
||||
|
||||
case GET_DESCRIPTOR:
|
||||
Ep0Stage.bStage = EPDATAIN;
|
||||
switch (Setup.wValueH)
|
||||
{
|
||||
case DESC_DEVICE:
|
||||
Ep0Stage.pData = DEVICEDESC;
|
||||
len = sizeof(DEVICEDESC);
|
||||
break;
|
||||
|
||||
case DESC_CONFIG:
|
||||
Ep0Stage.pData = CONFIGDESC;
|
||||
len = sizeof(CONFIGDESC);
|
||||
break;
|
||||
|
||||
case DESC_STRING:
|
||||
switch (Setup.wValueL)
|
||||
{
|
||||
case 0:
|
||||
Ep0Stage.pData = LANGIDDESC;
|
||||
len = sizeof(LANGIDDESC);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
Ep0Stage.pData = MANUFACTDESC;
|
||||
len = sizeof(MANUFACTDESC);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
Ep0Stage.pData = PRODUCTDESC;
|
||||
len = sizeof(PRODUCTDESC);
|
||||
break;
|
||||
|
||||
default:
|
||||
Ep0Stage.bStage = EPSTALL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case DESC_HIDREPORT:
|
||||
Ep0Stage.pData = HIDREPORTDESC;
|
||||
len = sizeof(HIDREPORTDESC);
|
||||
break;
|
||||
|
||||
default:
|
||||
Ep0Stage.bStage = EPSTALL;
|
||||
break;
|
||||
}
|
||||
if (len < Ep0Stage.wResidue)
|
||||
{
|
||||
Ep0Stage.wResidue = len;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Ep0Stage.bStage = EPSTALL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case CLASS_REQUEST:
|
||||
switch (Setup.bRequest)
|
||||
{
|
||||
case GET_REPORT:
|
||||
Ep0Stage.pData = HidFreature;
|
||||
Ep0Stage.bStage = EPDATAIN;
|
||||
break;
|
||||
|
||||
case SET_REPORT:
|
||||
Ep0Stage.pData = HidFreature;
|
||||
Ep0Stage.bStage = EPDATAOUT;
|
||||
break;
|
||||
|
||||
case SET_IDLE:
|
||||
break;
|
||||
|
||||
case GET_IDLE:
|
||||
case GET_PROTOCOL:
|
||||
case SET_PROTOCOL:
|
||||
default:
|
||||
Ep0Stage.bStage = EPSTALL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Ep0Stage.bStage = EPSTALL;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (Ep0Stage.bStage)
|
||||
{
|
||||
case EPDATAIN:
|
||||
USB_WriteReg(CSR0, SOPRDY);
|
||||
goto L_Ep0SendData;
|
||||
break;
|
||||
|
||||
case EPDATAOUT:
|
||||
USB_WriteReg(CSR0, SOPRDY);
|
||||
break;
|
||||
|
||||
case EPSTATUS:
|
||||
USB_WriteReg(CSR0, SOPRDY | DATEND);
|
||||
Ep0Stage.bStage = EPIDLE;
|
||||
break;
|
||||
|
||||
case EPSTALL:
|
||||
USB_WriteReg(CSR0, SOPRDY | SDSTL);
|
||||
Ep0Stage.bStage = EPIDLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EPDATAIN:
|
||||
if (!(csr & IPRDY))
|
||||
{
|
||||
L_Ep0SendData:
|
||||
cnt = Ep0Stage.wResidue > 64 ? 64 : Ep0Stage.wResidue;
|
||||
USB_WriteFIFO(FIFO0, Ep0Stage.pData, cnt);
|
||||
Ep0Stage.wResidue -= cnt;
|
||||
Ep0Stage.pData += cnt;
|
||||
if (Ep0Stage.wResidue == 0)
|
||||
{
|
||||
USB_WriteReg(CSR0, IPRDY | DATEND);
|
||||
Ep0Stage.bStage = EPIDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
USB_WriteReg(CSR0, IPRDY);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EPDATAOUT:
|
||||
if (csr & OPRDY)
|
||||
{
|
||||
cnt = USB_ReadFIFO(FIFO0, Ep0Stage.pData);
|
||||
Ep0Stage.wResidue -= cnt;
|
||||
Ep0Stage.pData += cnt;
|
||||
if (Ep0Stage.wResidue == 0)
|
||||
{
|
||||
USB_WriteReg(CSR0, SOPRDY | DATEND);
|
||||
Ep0Stage.bStage = EPIDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
USB_WriteReg(CSR0, SOPRDY);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (intrin & EP1INIF)
|
||||
{
|
||||
USB_WriteReg(INDEX, 1);
|
||||
csr = USB_ReadReg(INCSR1);
|
||||
if (csr & INSTSTL)
|
||||
{
|
||||
USB_WriteReg(INCSR1, INCLRDT);
|
||||
}
|
||||
if (csr & INUNDRUN)
|
||||
{
|
||||
USB_WriteReg(INCSR1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (introut & EP1OUTIF)
|
||||
{
|
||||
USB_WriteReg(INDEX, 1);
|
||||
csr = USB_ReadReg(OUTCSR1);
|
||||
if (csr & OUTSTSTL)
|
||||
{
|
||||
USB_WriteReg(OUTCSR1, OUTCLRDT);
|
||||
}
|
||||
if (csr & OUTOPRDY)
|
||||
{
|
||||
USB_ReadFIFO(FIFO1, HidInput);
|
||||
USB_WriteReg(OUTCSR1, 0);
|
||||
|
||||
if((HidInput[0]==0xaa) && (HidInput[1]==0x55) && (HidInput[2]==0x01))
|
||||
{
|
||||
USB_WriteReg(INDEX, 1);
|
||||
USB_WriteFIFO(FIFO1, HidOutput, 64);
|
||||
USB_WriteReg(INCSR1, INIPRDY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__CODE uint8_t DEVICEDESC[18] =
|
||||
{
|
||||
0x12, //bLength(18);
|
||||
0x01, //bDescriptorType(Device);
|
||||
0x00,0x02, //bcdUSB(2.00);
|
||||
0x00, //bDeviceClass(0);
|
||||
0x00, //bDeviceSubClass0);
|
||||
0x00, //bDeviceProtocol(0);
|
||||
0x40, //bMaxPacketSize0(64);
|
||||
0x54,0x53, //idVendor(5354);
|
||||
0x80,0x43, //idProduct(4380);
|
||||
0x00,0x01, //bcdDevice(1.00);
|
||||
0x01, //iManufacturer(1);
|
||||
0x02, //iProduct(2);
|
||||
0x00, //iSerialNumber(0);
|
||||
0x01, //bNumConfigurations(1);
|
||||
};
|
||||
|
||||
__CODE uint8_t CONFIGDESC[41] =
|
||||
{
|
||||
0x09, //bLength(9);
|
||||
0x02, //bDescriptorType(Configuration);
|
||||
0x29,0x00, //wTotalLength(41);
|
||||
0x01, //bNumInterfaces(1);
|
||||
0x01, //bConfigurationValue(1);
|
||||
0x00, //iConfiguration(0);
|
||||
0x80, //bmAttributes(BUSPower);
|
||||
0x32, //MaxPower(100mA);
|
||||
0x09, //bLength(9);
|
||||
0x04, //bDescriptorType(Interface);
|
||||
0x00, //bInterfaceNumber(0);
|
||||
0x00, //bAlternateSetting(0);
|
||||
0x02, //bNumEndpoints(2);
|
||||
0x03, //bInterfaceClass(HID);
|
||||
0x00, //bInterfaceSubClass(0);
|
||||
0x00, //bInterfaceProtocol(0);
|
||||
0x00, //iInterface(0);
|
||||
0x09, //bLength(9);
|
||||
0x21, //bDescriptorType(HID);
|
||||
0x01,0x01, //bcdHID(1.01);
|
||||
0x00, //bCountryCode(0);
|
||||
0x01, //bNumDescriptors(1);
|
||||
0x22, //bDescriptorType(HID Report);
|
||||
0x1b,0x00, //wDescriptorLength(27);
|
||||
0x07, //bLength(7);
|
||||
0x05, //bDescriptorType(Endpoint);
|
||||
0x81, //bEndpointAddress(EndPoint1 as IN);
|
||||
0x03, //bmAttributes(Interrupt);
|
||||
0x40,0x00, //wMaxPacketSize(64);
|
||||
0x01, //bInterval(10ms);
|
||||
0x07, //bLength(7);
|
||||
0x05, //bDescriptorType(Endpoint);
|
||||
0x01, //bEndpointAddress(EndPoint1 as OUT);
|
||||
0x03, //bmAttributes(Interrupt);
|
||||
0x40,0x00, //wMaxPacketSize(64);
|
||||
0x01, //bInterval(10ms);
|
||||
};
|
||||
|
||||
__CODE uint8_t HIDREPORTDESC[27] =
|
||||
{
|
||||
0x05,0x0c, //USAGE_PAGE(Consumer);
|
||||
0x09,0x01, //USAGE(Consumer Control);
|
||||
0xa1,0x01, //COLLECTION(Application);
|
||||
0x15,0x00, // LOGICAL_MINIMUM(0);
|
||||
0x25,0xff, // LOGICAL_MAXIMUM(255);
|
||||
0x75,0x08, // REPORT_SIZE(8);
|
||||
0x95,0x40, // REPORT_COUNT(64);
|
||||
0x09,0x01, // USAGE(Consumer Control);
|
||||
0xb1,0x02, // FEATURE(Data,Variable);
|
||||
0x09,0x01, // USAGE(Consumer Control);
|
||||
0x81,0x02, // INPUT(Data,Variable);
|
||||
0x09,0x01, // USAGE(Consumer Control);
|
||||
0x91,0x02, // OUTPUT(Data,Variable);
|
||||
0xc0, //END_COLLECTION;
|
||||
};
|
||||
|
||||
__CODE uint8_t LANGIDDESC[4] =
|
||||
{
|
||||
0x04,0x03,
|
||||
0x09,0x04,
|
||||
};
|
||||
|
||||
__CODE uint8_t MANUFACTDESC[8] =
|
||||
{
|
||||
0x08,0x03,
|
||||
'S',0,
|
||||
'T',0,
|
||||
'C',0,
|
||||
};
|
||||
|
||||
__CODE uint8_t PRODUCTDESC[30] =
|
||||
{
|
||||
0x1e,0x03,
|
||||
'S',0,
|
||||
'T',0,
|
||||
'C',0,
|
||||
'8',0,
|
||||
' ',0,
|
||||
'F',0,
|
||||
'w',0,
|
||||
'L',0,
|
||||
'i',0,
|
||||
'b',0,
|
||||
' ',0,
|
||||
'H',0,
|
||||
'I',0,
|
||||
'D',0,
|
||||
};
|
||||
|
||||
uint8_t CalCheckSum(uint8_t *buf, uint8_t len)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t cs=0;
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
cs += buf[i];
|
||||
}
|
||||
return cs;
|
||||
}
|
@ -37,6 +37,7 @@
|
||||
#include "fw_pwm.h"
|
||||
#include "fw_rtc.h"
|
||||
#include "fw_dma.h"
|
||||
#include "fw_usb.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -52,7 +52,9 @@ SFR(RSTCFG, 0xFF);
|
||||
#define IRC32KCR (*(unsigned char volatile __XDATA *)0xfe04)
|
||||
#define MCLKOCR (*(unsigned char volatile __XDATA *)0xfe05)
|
||||
#define IRCDB (*(unsigned char volatile __XDATA *)0xfe06)
|
||||
#define IRC48MCR (*(unsigned char volatile __XDATA *)0xfe07)
|
||||
#define X32KCR (*(unsigned char volatile __XDATA *)0xfe08)
|
||||
#define RSTFLAG (*(unsigned char volatile __XDATA *)0xfe09)
|
||||
#define PxPU 0xfe10
|
||||
#define P0PU SFRX(PxPU + 0)
|
||||
#define P1PU SFRX(PxPU + 1)
|
||||
|
@ -142,6 +142,24 @@ typedef enum
|
||||
*/
|
||||
#define SYS_SetClockOutputPin(__PORT__) SFRX_ASSIGN(MCLKOCR, 7, (__STATE__))
|
||||
|
||||
/**
|
||||
* Enable 48MHz USB OSC
|
||||
*/
|
||||
#define SYS_EnableOscillator48M() do { \
|
||||
SFRX_ON(); \
|
||||
RSTFLAG = 0x07; \
|
||||
(IRC48MCR) = (IRC48MCR) | (0x01 << 7); \
|
||||
while (!(IRC48MCR & 0x01)); \
|
||||
SFRX_OFF(); \
|
||||
} while(0)
|
||||
/**
|
||||
* Disable 48MHz USB OSC
|
||||
*/
|
||||
#define SYS_DisableOscillator48M() do { \
|
||||
SFRX_ON(); \
|
||||
(IRC48MCR) = (IRC48MCR) & ~(0x01 << 7); \
|
||||
SFRX_OFF(); \
|
||||
} while(0)
|
||||
|
||||
void SYS_SetClock(void);
|
||||
void SYS_Delay(uint16_t t);
|
||||
|
175
include/fw_usb.h
Normal file
175
include/fw_usb.h
Normal file
@ -0,0 +1,175 @@
|
||||
// Copyright 2021 IOsetting <iosetting(at)outlook.com>
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ___FW_USB_H___
|
||||
#define ___FW_USB_H___
|
||||
|
||||
#include "fw_conf.h"
|
||||
#include "fw_types.h"
|
||||
|
||||
/**
|
||||
* STC8H8K64U(LQFP48) (LQFP64)
|
||||
*/
|
||||
|
||||
#define FADDR 0x00
|
||||
#define POWER 0x01
|
||||
#define INTRIN1 0x02
|
||||
#define EP5INIF 0x20
|
||||
#define EP4INIF 0x10
|
||||
#define EP3INIF 0x08
|
||||
#define EP2INIF 0x04
|
||||
#define EP1INIF 0x02
|
||||
#define EP0IF 0x01
|
||||
#define INTROUT1 0x04
|
||||
#define EP5OUTIF 0x20
|
||||
#define EP4OUTIF 0x10
|
||||
#define EP3OUTIF 0x08
|
||||
#define EP2OUTIF 0x04
|
||||
#define EP1OUTIF 0x02
|
||||
#define INTRUSB 0x06
|
||||
#define SOFIF 0x08
|
||||
#define RSTIF 0x04
|
||||
#define RSUIF 0x02
|
||||
#define SUSIF 0x01
|
||||
#define INTRIN1E 0x07
|
||||
#define EP5INIE 0x20
|
||||
#define EP4INIE 0x10
|
||||
#define EP3INIE 0x08
|
||||
#define EP2INIE 0x04
|
||||
#define EP1INIE 0x02
|
||||
#define EP0IE 0x01
|
||||
#define INTROUT1E 0x09
|
||||
#define EP5OUTIE 0x20
|
||||
#define EP4OUTIE 0x10
|
||||
#define EP3OUTIE 0x08
|
||||
#define EP2OUTIE 0x04
|
||||
#define EP1OUTIE 0x02
|
||||
#define INTRUSBE 0x0B
|
||||
#define SOFIE 0x08
|
||||
#define RSTIE 0x04
|
||||
#define RSUIE 0x02
|
||||
#define SUSIE 0x01
|
||||
#define FRAME1 0x0C
|
||||
#define FRAME2 0x0D
|
||||
#define INDEX 0x0E
|
||||
#define INMAXP 0x10
|
||||
#define CSR0 0x11
|
||||
#define SSUEND 0x80
|
||||
#define SOPRDY 0x40
|
||||
#define SDSTL 0x20
|
||||
#define SUEND 0x10
|
||||
#define DATEND 0x08
|
||||
#define STSTL 0x04
|
||||
#define IPRDY 0x02
|
||||
#define OPRDY 0x01
|
||||
#define INCSR1 0x11
|
||||
#define INCLRDT 0x40
|
||||
#define INSTSTL 0x20
|
||||
#define INSDSTL 0x10
|
||||
#define INFLUSH 0x08
|
||||
#define INUNDRUN 0x04
|
||||
#define INFIFONE 0x02
|
||||
#define INIPRDY 0x01
|
||||
#define INCSR2 0x12
|
||||
#define INAUTOSET 0x80
|
||||
#define INISO 0x40
|
||||
#define INMODEIN 0x20
|
||||
#define INMODEOUT 0x00
|
||||
#define INENDMA 0x10
|
||||
#define INFCDT 0x08
|
||||
#define OUTMAXP 0x13
|
||||
#define OUTCSR1 0x14
|
||||
#define OUTCLRDT 0x80
|
||||
#define OUTSTSTL 0x40
|
||||
#define OUTSDSTL 0x20
|
||||
#define OUTFLUSH 0x10
|
||||
#define OUTDATERR 0x08
|
||||
#define OUTOVRRUN 0x04
|
||||
#define OUTFIFOFUL 0x02
|
||||
#define OUTOPRDY 0x01
|
||||
#define OUTCSR2 0x15
|
||||
#define OUTAUTOCLR 0x80
|
||||
#define OUTISO 0x40
|
||||
#define OUTENDMA 0x20
|
||||
#define OUTDMAMD 0x10
|
||||
#define COUNT0 0x16
|
||||
#define OUTCOUNT1 0x16
|
||||
#define OUTCOUNT2 0x17
|
||||
#define FIFO0 0x20
|
||||
#define FIFO1 0x21
|
||||
#define FIFO2 0x22
|
||||
#define FIFO3 0x23
|
||||
#define FIFO4 0x24
|
||||
#define FIFO5 0x25
|
||||
#define UTRKCTL 0x30
|
||||
#define UTRKSTS 0x31
|
||||
|
||||
#define EPIDLE 0
|
||||
#define EPSTATUS 1
|
||||
#define EPDATAIN 2
|
||||
#define EPDATAOUT 3
|
||||
#define EPSTALL -1
|
||||
|
||||
#define GET_STATUS 0x00
|
||||
#define CLEAR_FEATURE 0x01
|
||||
#define SET_FEATURE 0x03
|
||||
#define SET_ADDRESS 0x05
|
||||
#define GET_DESCRIPTOR 0x06
|
||||
#define SET_DESCRIPTOR 0x07
|
||||
#define GET_CONFIG 0x08
|
||||
#define SET_CONFIG 0x09
|
||||
#define GET_INTERFACE 0x0A
|
||||
#define SET_INTERFACE 0x0B
|
||||
#define SYNCH_FRAME 0x0C
|
||||
#define GET_REPORT 0x01
|
||||
#define GET_IDLE 0x02
|
||||
#define GET_PROTOCOL 0x03
|
||||
#define SET_REPORT 0x09
|
||||
#define SET_IDLE 0x0A
|
||||
#define SET_PROTOCOL 0x0B
|
||||
#define DESC_DEVICE 0x01
|
||||
#define DESC_CONFIG 0x02
|
||||
#define DESC_STRING 0x03
|
||||
#define DESC_HIDREPORT 0x22
|
||||
#define STANDARD_REQUEST 0x00
|
||||
#define CLASS_REQUEST 0x20
|
||||
#define VENDOR_REQUEST 0x40
|
||||
#define REQUEST_MASK 0x60
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bRequest;
|
||||
uint8_t wValueL;
|
||||
uint8_t wValueH;
|
||||
uint8_t wIndexL;
|
||||
uint8_t wIndexH;
|
||||
uint8_t wLengthL;
|
||||
uint8_t wLengthH;
|
||||
} SETUP;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bStage;
|
||||
uint16_t wResidue;
|
||||
uint8_t *pData;
|
||||
} EP0STAGE;
|
||||
|
||||
|
||||
uint8_t USB_ReadReg(uint8_t addr);
|
||||
void USB_WriteReg(uint8_t addr, uint8_t dat);
|
||||
uint8_t USB_ReadFIFO(uint8_t fifo, uint8_t *pdat);
|
||||
void USB_WriteFIFO(uint8_t fifo, uint8_t *pdat, uint8_t cnt);
|
||||
|
||||
#endif
|
39
src/fw_usb.c
Normal file
39
src/fw_usb.c
Normal file
@ -0,0 +1,39 @@
|
||||
#include "fw_usb.h"
|
||||
#include "fw_sys.h"
|
||||
|
||||
uint8_t USB_ReadReg(uint8_t addr)
|
||||
{
|
||||
uint8_t dat;
|
||||
while (USBADR & 0x80);
|
||||
USBADR = addr | 0x80;
|
||||
while (USBADR & 0x80);
|
||||
dat = USBDAT;
|
||||
return dat;
|
||||
}
|
||||
|
||||
void USB_WriteReg(uint8_t addr, uint8_t dat)
|
||||
{
|
||||
while (USBADR & 0x80);
|
||||
USBADR = addr & 0x7f;
|
||||
USBDAT = dat;
|
||||
}
|
||||
|
||||
uint8_t USB_ReadFIFO(uint8_t fifo, uint8_t *pdat)
|
||||
{
|
||||
uint8_t cnt;
|
||||
uint8_t ret;
|
||||
ret = cnt = USB_ReadReg(COUNT0);
|
||||
while (cnt--)
|
||||
{
|
||||
*pdat++ = USB_ReadReg(fifo);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void USB_WriteFIFO(uint8_t fifo, uint8_t *pdat, uint8_t cnt)
|
||||
{
|
||||
while (cnt--)
|
||||
{
|
||||
USB_WriteReg(fifo, *pdat++);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user