?? usb_main.c
字號:
ENABLE;
}
//void D12_SendResume(void)
//{
// outportcmd(0xF6);
//}
unsigned char D12_WriteEndpoint(unsigned char endp, unsigned char len, unsigned char * buf)
{
unsigned char i;
if(bEPPflags.bits.in_isr == 0)
DISABLE;
//---------------------
outportcmd(endp); //選擇端點
inportb(); //讀入滿/空狀態
outportcmd(0xF0); //寫緩沖區命令
outportdata(0);
outportdata(len);
for(i=0; i<len; i++)
outportdata(*(buf+i));
outportcmd(0xFA); //駛購沖區有效
//--------------------------------
if(bEPPflags.bits.in_isr == 0)
ENABLE;
return len;
}
void D12_AcknowledgeEndpoint(unsigned char endp)
{
outportcmd( endp); //選擇端點
outportcmd(0xF1); //應答設置
if(endp == 0)
outportcmd(0xF2); //緩沖區清零
}
unsigned char D12_ReadInterruptRegister(void)
{
unsigned char b1;
unsigned int j;
j=0;
//outportb(D12_COMMAND, 0xF4);
outportcmd(0xF4);
b1 = inportb();
j = inportb();
return b1;
//j = inportb();
//j <<= 8;
//j += b1;
//return j;
}
unsigned char D12_ReadLastTransactionStatus(unsigned char bEndp)
{
//outportb(D12_COMMAND, 0x40 + bEndp);
outportcmd(0x40 + bEndp);
return inportb();
}
unsigned char D12_ReadEndpoint(unsigned char endp, unsigned char len, unsigned char * buf)
{
unsigned char i, j;
if(bEPPflags.bits.in_isr == 0)
DISABLE;
//--------------------------------
outportcmd(endp); //選擇端點
if((inportb() & D12_FULLEMPTY) == 0) { //如果緩沖區為空,則返回
if(bEPPflags.bits.in_isr == 0)
ENABLE;
return 0;
}
outportcmd(0xF0); //讀緩沖區
j = inportb();
j = inportb();
if(j > len)
j = len;
for(i=0; i<j; i++)
*(buf+i) = inportb();
outportcmd(0xF2); //緩沖區清空
//-------------------------------
if(bEPPflags.bits.in_isr == 0)
ENABLE;
return j;
}
unsigned char D12_SelectEndpoint(unsigned char bEndp)
{
unsigned char c;
if(bEPPflags.bits.in_isr == 0)
DISABLE;
outportcmd(bEndp);
c = inportb();
if(bEPPflags.bits.in_isr == 0)
ENABLE;
return c;
}
//P57命令接口-D12CI.C ----結束
//===============================================================
//===============================================================
//P61中斷服務程序-ISR.C
//===============================================================
//===============================================================
void bus_reset(void)
{
}
//void dma_eot(void)
//{
//}
//---------------------------------
void ep0_rxdone(void)
{
unsigned char ep_last, i;
ep_last = D12_ReadLastTransactionStatus(0); // Clear interrupt flag
if (ep_last & D12_SETUPPACKET) {
ControlData.wLength = 0;
ControlData.wCount = 0;
//判斷端點是否滿,如是,則取出
if( D12_ReadEndpoint(0, sizeof(ControlData.DeviceRequest),
(unsigned char *)(&(ControlData.DeviceRequest))) != sizeof(DEVICE_REQUEST) ) {
D12_SetEndpointStatus(0, 1);
D12_SetEndpointStatus(1, 1);
bEPPflags.bits.control_state = USB_IDLE;
return;
}
ControlData.DeviceRequest.wValue = SWAP(ControlData.DeviceRequest.wValue);
ControlData.DeviceRequest.wIndex = SWAP(ControlData.DeviceRequest.wIndex);
ControlData.DeviceRequest.wLength = SWAP(ControlData.DeviceRequest.wLength);
// Acknowledge setup here to unlock in/out endp
//向控制輸出端點發送應答建立命令以重新使能下一個建立階段
D12_AcknowledgeEndpoint(0);
D12_AcknowledgeEndpoint(1);
ControlData.wLength = ControlData.DeviceRequest.wLength;
ControlData.wCount = 0;
//需要證實控制傳輸是控制讀還是寫,如果是讀:
//如果控制傳輸是一個控制讀類型那就是說器件需要在下一個數據階段向
//主機發回數據包.MCU需要設置一個標志以指示USB 設備現在正處于傳輸
//模式即準備在主機發送請求時發送數據
if (ControlData.DeviceRequest.bmRequestType & (unsigned char)USB_ENDPOINT_DIRECTION_MASK) {
bEPPflags.bits.setup_packet = 1;
bEPPflags.bits.control_state = USB_IDLE; /* get command */
}
//如果是寫
else {
if (ControlData.DeviceRequest.wLength == 0) {
bEPPflags.bits.setup_packet = 1;
bEPPflags.bits.control_state = USB_IDLE; /* set command */
}
else {
if(ControlData.DeviceRequest.wLength > MAX_CONTROLDATA_SIZE) {
bEPPflags.bits.control_state = USB_IDLE;
D12_SetEndpointStatus(0, 1);
D12_SetEndpointStatus(1, 1);
}
else {
bEPPflags.bits.control_state = USB_RECEIVE; /* set command with OUT token */
}
} // set command with data
} // else set command
} // if setup packet
else if (bEPPflags.bits.control_state == USB_RECEIVE) {
i = D12_ReadEndpoint(0, EP0_PACKET_SIZE,
ControlData.dataBuffer + ControlData.wCount);
ControlData.wCount += i;
if( i != EP0_PACKET_SIZE || ControlData.wCount >= ControlData.wLength) {
bEPPflags.bits.setup_packet = 1;
bEPPflags.bits.control_state = USB_IDLE;
}
}
else {
bEPPflags.bits.control_state = USB_IDLE;
}
}
//----------------------------------
void ep0_txdone(void)
{
short i = ControlData.wLength - ControlData.wCount;
D12_ReadLastTransactionStatus(1); // Clear interrupt flag
if (bEPPflags.bits.control_state != USB_TRANSMIT)
return;
//-------------------------
if( i >= EP0_PACKET_SIZE) {
D12_WriteEndpoint(1, EP0_PACKET_SIZE, ControlData.pData + ControlData.wCount);
ControlData.wCount += EP0_PACKET_SIZE;
bEPPflags.bits.control_state = USB_TRANSMIT;
}
else if( i != 0) {
D12_WriteEndpoint(1, i, ControlData.pData + ControlData.wCount);
ControlData.wCount += i;
bEPPflags.bits.control_state = USB_IDLE;
}
else if (i == 0){
D12_WriteEndpoint(1, 0, 0); // Send zero packet at the end ???
bEPPflags.bits.control_state = USB_IDLE;
}
}
//----------------------------------
void ep1_txdone(void)
{
D12_ReadLastTransactionStatus(3); /* Clear interrupt flag */
}
void ep1_rxdone(void)
{
unsigned char len;
D12_ReadLastTransactionStatus(2); /* Clear interrupt flag */
len = D12_ReadEndpoint(2, sizeof(GenEpBuf), GenEpBuf);
if(len != 0)
bEPPflags.bits.ep1_rxdone = 1;
}
//---------------------------------
void main_txdone(void)
{
unsigned char len;
D12_ReadLastTransactionStatus(5); /* Clear interrupt flag */
len = ioSize - ioCount;
if(len == 0) {
if(bEPPflags.bits.dma_state == DMA_PENDING)
bEPPflags.bits.setup_dma ++;
else
bEPPflags.bits.dma_state = DMA_IDLE;
}
else {
if(len > 64)
len = 64;
if(bNoRAM)
len = D12_WriteEndpoint(5, len, EpBuf + ioCount);
else
len = D12_WriteEndpoint(5, len, MainEpBuf + ioCount);
ioCount += len;
}
}
void main_rxdone(void)
{
unsigned char len;
D12_ReadLastTransactionStatus(4); /* Clear interrupt flag */
if(bNoRAM)
len = D12_ReadEndpoint(4, 64, EpBuf + ioCount);
else
len = D12_ReadEndpoint(4, 64, MainEpBuf + ioCount);
ioCount += len;
if(bNoRAM)
len = D12_ReadEndpoint(4, 64, EpBuf + ioCount);
else
len = D12_ReadEndpoint(4, 64, MainEpBuf + ioCount);
ioCount += len;
if(ioCount >= ioSize) {
if(bEPPflags.bits.dma_state == DMA_PENDING)
bEPPflags.bits.setup_dma ++;
else
bEPPflags.bits.dma_state = DMA_IDLE;
}
}
//P61中斷服務程序-ISR.C ----結束
//===============================================================
//===============================================================
//P70標準設備請求函數-CHAP_9.C
//===============================================================
//===============================================================
void reserved(void)
{
stall_ep0();
}
/*
//*************************************************************************
// USB standard device requests
//*************************************************************************
*/
void get_status(void)
{
unsigned char endp, txdat[2];
unsigned char bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;
unsigned char c;
if (bRecipient == USB_RECIPIENT_DEVICE) {
if(bEPPflags.bits.remote_wakeup == 1)
txdat[0] = 3;
else
txdat[0] = 1;
txdat[1]=0;
single_transmit(txdat, 2);
} else if (bRecipient == USB_RECIPIENT_INTERFACE) {
txdat[0]=0;
txdat[1]=0;
single_transmit(txdat, 2);
} else if (bRecipient == USB_RECIPIENT_ENDPOINT) {
endp = (unsigned char)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
if (ControlData.DeviceRequest.wIndex & (unsigned char)USB_ENDPOINT_DIRECTION_MASK)
c = D12_SelectEndpoint(endp*2 + 1); /* Control-in */
else
c = D12_SelectEndpoint(endp*2); /* Control-out */
if(c & D12_STALL)
txdat[0] = 1;
else
txdat[0] = 0;
txdat[1] = 0;
single_transmit(txdat, 2);
} else
stall_ep0();
}
void clear_feature(void)
{
unsigned char endp;
unsigned char bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;
if (bRecipient == USB_RECIPIENT_DEVICE
&& ControlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP) {
DISABLE;
bEPPflags.bits.remote_wakeup = 0;
ENABLE;
single_transmit(0, 0);
}
else if (bRecipient == USB_RECIPIENT_ENDPOINT
&& ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL) {
endp = (unsigned char)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
if (ControlData.DeviceRequest.wIndex & (unsigned char)USB_ENDPOINT_DIRECTION_MASK)
// clear TX stall for IN on EPn.
D12_SetEndpointStatus(endp*2 + 1, 0);
else
// clear RX stall for OUT on EPn.
D12_SetEndpointStatus(endp*2, 0);
single_transmit(0, 0);
} else
stall_ep0();
}
void set_feature(void)
{
unsigned char endp;
unsigned char bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;
if (bRecipient == USB_RECIPIENT_DEVICE
&& ControlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP) {
DISABLE;
bEPPflags.bits.remote_wakeup = 1;
ENABLE;
single_transmit(0, 0);
}
else if (bRecipient == USB_RECIPIENT_ENDPOINT
&& ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL) {
endp = (unsigned char)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
if (ControlData.DeviceRequest.wIndex & (unsigned char)USB_ENDPOINT_DIRECTION_MASK)
// clear TX stall for IN on EPn.
D12_SetEndpointStatus(endp*2 + 1, 1);
else
// clear RX stall for OUT on EPn.
D12_SetEndpointStatus(endp*2, 1);
single_transmit(0, 0);
} else
stall_ep0();
}
void set_address(void)
{
D12_SetAddressEnable((unsigned char)(ControlData.DeviceRequest.wValue &
DEVICE_ADDRESS_MASK), 1);
single_transmit(0, 0);
}
void get_descriptor(void)
{
unsigned char bDescriptor = MSB(ControlData.DeviceRequest.wValue);
if (bDescriptor == USB_DEVICE_DESCRIPTOR_TYPE) {
code_transmit((unsigned char code *)&DeviceDescr, sizeof(USB_DEVICE_DESCRIPTOR));
}
else if (bDescriptor == USB_CONFIGURATION_DESCRIPTOR_TYPE) {
code_transmit((unsigned char code *)&ConfigDescr, CONFIG_DESCRIPTOR_LENGTH);
}
else
stall_ep0();
}
void get_configuration(void)
{
unsigned char c = bEPPflags.bits.configuration;
single_transmit(&c, 1);
}
void set_configuration(void)
{
if (ControlData.DeviceRequest.wValue == 0) {
//* put device in unconfigured state
single_transmit(0, 0);
DISABLE;
bEPPflags.bits.configuration = 0;
ENABLE;
init_unconfig();
} else if (ControlData.DeviceRequest.wValue == 1) {
// Configure device
single_transmit(0, 0);
init_unconfig();
init_config();
DISABLE;
bEPPflags.bits.configuration = 1;
ENABLE;
} else
stall_ep0();
}
void get_interface(void)
{
unsigned char txdat = 0; // Only/Current interface = 0
single_transmit(&txdat, 1);
}
void set_interface(void)
{
if (ControlData.DeviceRequest.wValue == 0 && ControlData.DeviceRequest.wIndex == 0)
single_transmit(0, 0);
else
stall_ep0();
}
//P70標準設備請求函數-CHAP_9.C ----結束
//===============================================================
//===============================================================
//P81廠商請求函數-PROTODMA.C
//===============================================================
//===============================================================
void get_firmware_version()
{
unsigned char i;
i = 0x30; // firmware version number
single_transmit((unsigned char *)&i, 1);
}
void get_buffer_size()
{
unsigned char i[4];
if(bNoRAM == TRUE) {
i[0] = EP2_PACKET_SIZE;
i[1] = 0;
i[2] = 0;
i[3] = 0;
} else {
i[0] = 0;
i[1] = 1;
i[2] = 0;
i[3] = 0;
}
single_transmit(i, 4);
}
void setup_dma_request()
{
memcpy((unsigned char *)&ioRequest + ControlData.DeviceRequest.wValue,
ControlData.dataBuffer,
ControlData.DeviceRequest.wLength);
ioRequest.uSize = SWAP(ioRequest.uSize);
ioRequest.uAddressL = SWAP(ioRequest.uAddressL);
if(ioRequest.uSize > DMA_BUFFER_SIZE) { // Unaccepted request
stall_ep0();
}
else if(bNoRAM == TRUE && ioRequest.uSize > EP2_PACKET_SIZE) {
stall_ep0();
}
else {
if(bEPPflags.bits.dma_state == DMA_IDLE) {
DISABLE;
bEPPflags.bits.setup_dma ++;
ENABLE;
}
else {
DISABLE;
bEPPflags.bits.dma_state = DMA_PENDING;
ENABLE;
}
} // else if accepted request
}
void read_write_register(void)
{
unsigned char i;
if(ControlData.DeviceRequest.bmRequestType & (unsigned char)USB_ENDPOINT_DIRECTION_MASK) {
if(bEPPflags.bits.verbose)
printf("Read Registers: Offset = 0x%x, Length = 0x%x, Index = 0x%x.\n",
ControlData.DeviceRequest.wValue,
ControlData.DeviceRequest.wLength,
ControlData.DeviceRequest.wIndex);
if(ControlData.DeviceRequest.wIndex == GET_FIRMWARE_VERSION &&
ControlData.DeviceRequest.wValue == 0 &&
ControlData.DeviceRequest.wLength == 1)
get_firmware_version();
else
if(ControlData.DeviceRequest.wIndex == GET_BUFFER_SIZE &&
ControlData.DeviceRequest.wValue == 0 &&
ControlData.DeviceRequest.wLength == 4)
get_buffer_size();
else
stall_ep0();
} // if read register
else{
if(bEPPflags.bits.verbose) {
//printf("Write Registers: Offset = 0x%x, Length = 0x%x, Index = 0x%x.\n",
// ControlData.DeviceRequest.wValue,
// ControlData.DeviceRequest.wLength,
// ControlData.DeviceRequest.wIndex);
//printf("Data: ");
for(i = 0; i < ControlData.DeviceRequest.wLength; i ++)
printf("0x%bx, ", *((ControlData.dataBuffer)+i));
printf("\n");
}
if(ControlData.DeviceRequest.wIndex == SETUP_DMA_REQUEST &&
ControlData.DeviceRequest.wValue == 0 &&
ControlData.DeviceRequest.wLength == 6)
setup_dma_request();
//stall_ep0();
else
stall_ep0();
} // if write register
}
//P81廠商請求函數-PROTODMA.C ----結束
//===============================================================
//===============================================================
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -