📄 usbdrv.c
字号:
/*<<<-------------------------------------------------------------------------
* File Contents:
* usb.c - USB related functions
*
* Project: USB Demo firmware
* Author : Yan Nosovitsky
* Date : Oct 2001
*----------------------------------------------------------------------->>>*/
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include "..\Target\44b.h"
#include "..\Target\44blib.h"
#include "Usbdrv.h"
#include "Usb_reg.h"
/*=====================================================================
* USB Driver Definitions
*=====================================================================*/
extern Device_buffers_t device_buffers;//a union
extern void _disable_(void);
extern void _enable_(void);
extern byte code_loaded;
endpoint_t DMA_ep;//endpoint_t is an enum for EP0~EP7
endpoint_status_t tx0_ep_stat; //endpoint_status_t is a struct for endpoint's status
endpoint_status_t tx1_ep_stat, tx2_ep_stat;
endpoint_status_t rx1_ep_stat, rx2_ep_stat;
endpoint_status_t tx3_ep_stat;
State bulkState;
file_status_t FileStat;
byte buffer[2*1024];
byte *readPtr = buffer;
byte *writePtr = buffer;
endpoint_status_t *endpoint_stat[] = //pointer array
{
&tx0_ep_stat,
&tx1_ep_stat,
&rx1_ep_stat,
&tx2_ep_stat,
&rx2_ep_stat,
&tx3_ep_stat,
NULL
};
void endpoint_status_init(void) {
int i;
for(i=0;i<NUM_OF_ENDPOINTS;i++) {
if (endpoint_stat[i] != NULL) {
endpoint_stat[i]->FIFO_status = EMPTY;
if (i==0)
/*----------------
* control endpoint
*-----------------*/
endpoint_stat[i]->toggle_bit = 0x01;
else
/*----------------------
* tx & rx data endpoints
*-----------------------*/
endpoint_stat[i]->toggle_bit = 0x00;
}
}
}
const int usbn9604_tx_endpoint_addr[] =//save the address of EPx TXDx register (0,1,3,5)
{
TXD0, /* Endpoint 0 *///register name
TXD1, /* Endpoint 1 */
0xFF,
TXD2, /* Endpoint 3 */
0xFF,
TXD3, /* Endpoint 5 */
0xFF
};
const int usbn9604_rx_endpoint_addr[] =
{
RXD0, /* Endpoint 0 */
0xFF,
RXD1, /* Endpoint 2 */
0xFF,
RXD2, /* Endpoint 4 */
0xFF,
RXD3 /* Endpoint 6 */
};
const int fifo_sizes[] =
{
EP0_FIFO_SIZE, /* control tx0, rx0 *///=8
TX_BULK_EP_FIFO_SIZE, /* bulk tx *///=64
RX_BULK_EP_FIFO_SIZE, /* bulk rx */
TX_ISO_EP_FIFO_SIZE, /* ISO tx *///=64
RX_ISO_EP_FIFO_SIZE, /* ISO rx */
TX_INTR_EP_FIFO_SIZE, /* interrupt tx *///=1
RX_INTR_EP_FIFO_SIZE /* interrupt rx */
};
const int endpoint_to_fifo[] =//the set-bit content for register
{
TX_FIFO0, /* endpoint0 TX/RX FIFO0 */
TX_FIFO1, /* endpoint1 */
RX_FIFO1, /* endpoint2 */
TX_FIFO2, /* endpoint3 */
RX_FIFO2, /* endpoint4 */
TX_FIFO3, /* endpoint5 */
RX_FIFO3 /* endpoint6 */
};
/*=============================================================================
* Data Buffer Definitions
*=============================================================================*/
control_buffer_t control_send_buffer;//control_buffer_t: include byte array and length(uint)
control_buffer_t control_receive_buffer;
byte request_buffer[EP0_FIFO_SIZE];
void clear_control_buffer(control_buffer_t* control_buff) {
control_buff->data = NULL;
control_buff->bytes_counter = 0;
}
/*=====================================================================
* USB Driver Implementations
*=====================================================================*/
/*----------------------------------------------------------------------------------------------
* Prototype
* void usb_node_handler()
*
* Parameters
* None
*
* Returns
* None
*
* Description
* USB interrupt handler.
----------------------------------------------------------------------------------------------*/
//#pragma interrupt(usb_node_handler)//#pragma: can be ignored by other compiler
void __irq usb_node_handler(void){
byte usbn_event;
//PCDOUT &= 0x0;
_disable_();
//Uart_Printf("\nenter interrupt");
/*-------------------
* Clear the interrupt
*-------------------*/
//ICU_clear_int(USB_NODE_INT);
while(usbn_event = read_usb(MAEV))
{
if (usbn_event & RX_EV)
USBN9604_rx_event_handler();//received OUT command
if (usbn_event & ALT)
USBN9604_alt_event_handler();
if (usbn_event & TX_EV)
USBN9604_tx_event_handler();//complete transmit a packet
if (usbn_event & NAK) //NAK: device is busy
{
if (read_usb(NAKEV) & 0x10)//FIFO0 for OUT token
{/*----------
* NAK OUT
*---------*/
FLUSHTX0;
FLUSHRX0;
/*------------------
* re enable receving
*-------------------*/
DISABLE_TX(ENDPOINT_0);
ENABLE_RX(ENDPOINT_0);
}
}
}
_enable_();
}
/*----------------------------------------------------------------------------------------------
* Prototype
* void USBN9602_tx_event_handler()
*
* Parameters
* None
*
* Returns
* None
*
* Description
* TX event handler
----------------------------------------------------------------------------------------------*/
/*__inline*/ void USBN9604_tx_event_handler(void)
{
volatile byte tx_event = TX_EVENTS;//read_usb(TXEV)
byte evnt_mask = 1;
byte txstat;
while(tx_event)//transmission done or underrun
{
switch(tx_event & evnt_mask)//FIFO0 Tx
{
case TX_FIFO0:
/*-----------
* endpoint 0
* zero tx endpoint
*-----------*/
txstat = EP_TXSTATUS(ENDPOINT_0);//read_usb(TXS of EP0);
if (txstat & ACK_STAT) //ACK_STAT:the ACK has received for the packet previously sent.
{
/*--------------------------------------
* previous data packet from current
* ep was received successfully by host
*-------------------------------------*/
endpoint_stat[ENDPOINT_0]->FIFO_status = EMPTY;
if (control_send_buffer.bytes_counter > 0)
{
//Uart_Printf("\nbb");
/*-------------------------------------
* there is additional data to be sent
*------------------------------------*/
fill_control_fifo();
usbn9604_tx_enable(ENDPOINT_0);
}
else if (device_buffers.zero_data == 1)
{
/*-------------------
* zero data required
*-------------------*/
device_buffers.zero_data = 0;
FLUSH_TXEP(ENDPOINT_0);
usbn9604_tx_enable(ENDPOINT_0);
}
else
{
//Uart_Printf("\nsn");
FLUSH_TXEP(ENDPOINT_0);
ENABLE_RX(ENDPOINT_0);
}
}
else
//Uart_Printf("\nno");
/*-------------------
* there is no ACK
* Re-enable receiving
*--------------------*/
ENABLE_RX(ENDPOINT_0);
break;
case TX_FIFO1://a data packet completed transmission in response to an IN token
/*----------------
* endpoint 1
* bulk tx endpoint
*----------------*/
txstat = EP_TXSTATUS(ENDPOINT_1);
if (txstat & ACK_STAT)
{
/*-----------------------------------------------------------------------
* previous data packet from current ep was received successfully by host
*-----------------------------------------------------------------------*/
FLUSHTX1;
BulkTransmitEvent();
}
else
/*------------------------------------
* there is no ACK
* retransmit the previous data packet
*------------------------------------*/
usbn9604_tx_retransmit_enable(ENDPOINT_1);
break;
case TX_FIFO2:
/*-----------------------
* endpoint 3
* isochronous tx endpoint
*-----------------------*
txstat = EP_TXSTATUS(ENDPOINT_3);
// PCDOUT &= ~0x2;
// PCDOUT |= 0x2;
if (txstat & ACK_STAT)
{
*-----------------------------------------
* Data was sent in response to an IN token
*-----------------------------------------*
FLUSHTX2;
send_event(EVT_USB_ISO_TX);
}
else
{
*------------------------
* ISO frame was discarded
* Do nothing
*------------------------*
}*/
break;
case TX_FIFO3:
/*-----------------------
* endpoint 5
* interrupt tx endpoint
*-----------------------*
txstat = EP_TXSTATUS(ENDPOINT_5);
if (txstat & ACK_STAT)
{
*-----------------------------------------------------------------------
* previous data packet from current ep was received successfully by host
*-----------------------------------------------------------------------*
FLUSHTX3;
}
else
*------------------------------------
* there is no ACK
* retransmit the previous data packet
*------------------------------------*
usbn9604_tx_retransmit_enable(ENDPOINT_5);*/
break;
case TX_UDRN0:
case TX_UDRN1:
case TX_UDRN2:
case TX_UDRN3:
break;
default:
/*-------------------------------
* No event with this event mask
*-------------------------------*/
break;
}
tx_event &= ~evnt_mask;
evnt_mask = evnt_mask << 1;
}
}
/*----------------------------------------------------------------------------------------------
* Prototype
* void USBN9604_alt_event_handler()
*
* Parameters
* None
*
* Returns
* None
*
* Description
* ALT event handler
----------------------------------------------------------------------------------------------*/
void USBN9604_alt_event_handler(void)
{
volatile byte alt_event = ALT_EVENTS;//read_usb(ALTEV)
volatile byte dma_event = 0;
byte evnt_mask = 1;
byte tmp = 0;
extern void USB_dev_reset(void);
while(alt_event)
{
switch(alt_event & evnt_mask)
{
case ALT_DMA:
Uart_Printf("\nalt1");
/*------------
* DMA events
*------------*/
dma_event = DMA_EVENTS ;
/*--------------------------------
* clear all dma events to be sure
*--------------------------------*/
write_usb(DMAEV,0x00);
switch (dma_event&0xf){
case DMA_DSIZ:
/*----------------------------------------------------------
* Only for DMA receive operation
* It indicates that a packet has been received which is less
* then the full length of the FIFO. This normally indicates
* the end of transfer.
* ---------------------------------------------------------*/
/*------------------
* update toggle bit
*-------------------*/
if (DMA_NTGL&dma_event)
endpoint_stat[DMA_ep]->toggle_bit = 1;
else
endpoint_stat[DMA_ep]->toggle_bit = 0;
/*------------------------
* Insert your code here
*------------------------*/
break;
case DMA_DCNT:
/*-------------------------------------
* DMA count (DMA Count) regiser is 0
* ADMA is stopped
*------------------------------------*/
/*-----------------
* update toggle bit
*------------------*/
tmp = read_usb(DMACNTRL);
if (DMA_NTGL&dma_event)
{
tmp |= DMA_DTGL;
endpoint_stat[DMA_ep]->toggle_bit = 1;
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -