📄 usbdrv.c
字号:
break;
}
rx_event &= ~evnt_mask;
evnt_mask = evnt_mask << 1;
}
}
/*=====================================================================
* Usb module external interface implementations
*=====================================================================*/
/*---------------------------------------------------------------------
* USB_Send_Data()
*
* Sends data through the bulk pipes
*
* Input:
* data_ptr - pointer to data to be send
* data_size - size of data (in bytes) to be send
* Output: None
*---------------------------------------------------------------------*/
void USB_Send_Data (int data_size, BYTE* data_ptr) {
int i;
volatile u_long j;
for(j=0;j<WAITING_THRESHOLD&&direct_send_active;j++);
if (j==WAITING_THRESHOLD)
PANIC("USB_Send_Data timeout");
USB_int_disable();
if (data_size <= TX_BULK_EP_FIFO_SIZE)
{ //if cyclic buffer is empty && data size is no more than the fifo length
//then transfer the data directly to the
//fifo without cyclic buffer
direct_send_active = 1;
USBADDR = usbn9604_tx_endpoint_addr[ENDPOINT_1];
for (i=0;i<data_size;i++) {
//transfer data directly to the fifo
//address updating does not needed
USBDATA = data_ptr[i];
}
}
//enable ENDPOINT_1 data transmittion
usbn9604_tx_enable(ENDPOINT_1);
USB_int_enable();
}
__inline__ void USB_bulk_write_data (int data_size, byte data)
{
int i;
USB_int_disable();
USBADDR = usbn9604_tx_endpoint_addr[ENDPOINT_1];
for (i=0;i<data_size;i++)
USBDATA = data;
//enable ENDPOINT_1 data transmittion
usbn9604_tx_enable(ENDPOINT_1);
USB_int_enable();
}
/*---------------------------------------------------------------------
* USB_Get_Data()
*
* Receives data from the host through the bulk pipes
*
* Input:
* data_ptr - pointer to data to be received
* data_size - size of data (in bytes) to be received
* Output: buffer with received data (through the data_ptr pointer)
*---------------------------------------------------------------------*/
#pragma set_options("-funroll-loops")
__inline__ void USB_bulk_fast_read(byte data_size, byte* data_ptr)
{
int i;
register byte bytes_count = data_size;
USB_int_disable();
USBADDR = RXD1;
for(i=0;i<bytes_count;i++)
*(data_ptr ++) = USBDATA;
ENABLE_RX(ENDPOINT_2);
USB_int_enable();
}
#pragma set_options("-funroll-loops")
__inline__ int USB_bulk_read_compare(byte data_size, byte data)
{
int i;
register byte bytes_count = data_size;
register byte dataToCompare = data;
byte numOfErrors = 0;
USB_int_disable();
USBADDR = RXD1;
for(i=0;i<bytes_count;i++)
if ( USBDATA!= dataToCompare)
numOfErrors++;
ENABLE_RX(ENDPOINT_2);
USB_int_enable();
return numOfErrors;
}
byte USB_Get_Data (int data_size, byte* data_ptr)
{
byte bytes_count;
byte bytes_sum = 0;
int i;
// volatile u_long j;
volatile byte count = 0;
// while (data_size){
//end of the critical section
// for(j=0;j<WAITING_THRESHOLD&&!wating_rx_data;j++);
// if (j==WAITING_THRESHOLD)
// PANIC("USB_Get_Data timeout");
//while(wating_rx_data == 0);
// USB_int_disable();
while( (bytes_count = min(data_size, RX_EP_COUNTER(ENDPOINT_2))) )
{
USBADDR = RXD1;
for(i=0;i<bytes_count;i++)
{
*(data_ptr ++) = USBDATA;
}
data_size -= bytes_count;
bytes_sum += bytes_count;
}
if (RX_EP_COUNTER(ENDPOINT_2)==0){
ENABLE_RX(ENDPOINT_2);
wating_rx_data = 0;
}
// USB_int_enable();
return bytes_sum;
// }
}
/*---------------------------------------------------------------------
* USB_Send_Interrupt()
*
* Sends data through the interrupt pipe
*
* Input:
* Pid - byte of data to be send
* Output: None
*---------------------------------------------------------------------*/
void USB_Send_Interrupt (byte pid)
{
ICU_disable_interrupts();
//clear and disable the tx interrupt endpoint
FLUSHTX3;
//write data to the ep fifo
write_usb(usbn9604_tx_endpoint_addr[ENDPOINT_5], pid);
//is toggle bit needed?
usbn9604_tx_enable(ENDPOINT_5);
ICU_enable_interrupts();
}
/*=====================================================================
* Usb module services implementations
*=====================================================================*/
/*---------------------------------------------------------------------
* send_control_data()
*
* Sends data through the control pipe
*
* Input:
* data_ptr - pointer to the data buffer to be send
* data_size - data buffer size
* Output: None
*---------------------------------------------------------------------*/
void send_control_data(byte *data_ptr, int data_size)
{
FLUSHTX0;
control_send_buffer.data = data_ptr;
control_send_buffer.bytes_counter = data_size;
fill_control_fifo();
usbn9604_tx_enable(ENDPOINT_0);
}
/*---------------------------------------------------------------------
* zero_length_data_response
*
* Generates zero length data packet
*
* Input: EP number (ENDPOINT_0..ENDPOINT_6)
* Output: None
*---------------------------------------------------------------------*/
void zero_length_data_response(endpoint_t ep_num)
{
FLUSH_TXEP(ep_num);
FLUSH_RXEP(ep_num);
usbn9604_tx_enable(ep_num);
}
/*---------------------------------------------------------------------
* fill_control_fifo()
*
* Transfers data from the control buffer to zero endpoint control fifo.
*
* Input: None
* Output: None
*---------------------------------------------------------------------*/
void fill_control_fifo()
{
byte *data_ptr = control_send_buffer.data;
//number of bytes actually to be sent
int count = min(control_send_buffer.bytes_counter, EP0_FIFO_SIZE);
FLUSH_RXEP(ENDPOINT_0);
FLUSH_TXEP(ENDPOINT_0);
//update control buffer parameters
control_send_buffer.data += count;
control_send_buffer.bytes_counter -= count;
while(count--)
EP_FIFO_WRITE(ENDPOINT_0, *data_ptr++);
}
/*---------------------------------------------------------------------
* usbn9604_tx_enable()
*
* Enable tx endpoint transmission
*
* Input: EP number (ENDPOINT_0..ENDPOINT_6)
*
* Output: None
*---------------------------------------------------------------------*/
void usbn9604_tx_enable(int ep_num)
{
byte Toggle = endpoint_stat[ep_num]->toggle_bit;
//update toggle bit of appropriate endpoint
endpoint_stat[ep_num]->toggle_bit = !endpoint_stat[ep_num]->toggle_bit;
Toggle = Toggle << 2;
if (ep_num == ENDPOINT_0) {
write_usb(EP_TXC(ep_num), Toggle|TX_EN);
write_usb(EP_RXC(ENDPOINT_0), 0x0);
}
else
write_usb(EP_TXC(ep_num), Toggle|TX_LAST|TX_EN);
}
/*---------------------------------------------------------------------
* usbn9604_tx_retransmit_enable()
*
* Enable tx data retransmission
*
* Input: EP number (ENDPOINT_0..ENDPOINT_6)
*
* Output: None
*---------------------------------------------------------------------*/
void usbn9604_tx_retransmit_enable(int ep_num)
{
//use previous toggle bit value
byte Toggle = endpoint_stat[ep_num]->toggle_bit;
Toggle = Toggle << 2;
if (ep_num == ENDPOINT_0)
/*there is no retransmission from the endpoint zero*/
return;
else
write_usb(EP_TXC(ep_num), Toggle|TX_LAST|TX_EN|RFF);
}
/*----------------------------------------------------------------------------
* usb_node_handler()
*
* USB interrupt handler.
*
* Input: None
*----------------------------------------------------------------------------*/
#pragma interrupt(usb_node_handler/*, save_regs=int_regs*/)
void usb_node_handler(void){
byte usbn_event;
write_7seg(IVCT);
// Clear the interrupt
ICU_clear_int(USB_NODE_INT);
while( (usbn_event = (read_usb(MAEV) & read_usb(MAMSK))) )
{
if (usbn_event & RX_EV)
{
USBN9604_rx_event_handler();
}
if (usbn_event & ALT)
USBN9604_alt_event_handler();
if (usbn_event & TX_EV)
USBN9604_tx_event_handler();
if (usbn_event & NAK) {
if (read_usb(NAKEV) & 0x10)
{//NAK OUT
FLUSHTX0;
FLUSHRX0;
//re enable receving
DISABLE_TX(ENDPOINT_0);
ENABLE_RX(ENDPOINT_0);
}
}
}
}
/*
void usb_node_handler(void){
byte usbn_event;
byte evnt_mask = 1;
byte nak_event;
write_7seg(IVCT);
// Clear the interrupt
ICU_clear_int(USB_NODE_INT);
usbn_event = read_usb(MAEV) & read_usb(MAMSK);
while(usbn_event) {
switch(usbn_event & evnt_mask) {
case ALT:
USBN9604_alt_event_handler();
break;
case TX_EV:
USBN9604_tx_event_handler();
break;
case RX_EV:
USBN9604_rx_event_handler();
break;
case NAK:
nak_event = read_usb(NAKEV);
if (nak_event&0x1)
{//NAK IN
FLUSHTX0;
FLUSHRX0;
write_usb(TXC0, TX_EN|TX_TOGL);
}
else if (nak_event&0x10)
{//NAK OUT
FLUSHTX0;
FLUSHRX0;
//re enable receving
DISABLE_TX(ENDPOINT_0);
ENABLE_RX(ENDPOINT_0);
}
break;
case FRAME:
case ULD:
case WARN:
case INTR_E:
break;
default:
// No event with this event mask
break;
}
usbn_event &= ~evnt_mask;
evnt_mask = evnt_mask << 1;
}
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -