📄 usb.c
字号:
#include "..\include\all.h"
////////////////////////////////////////////////////
/// Externs
////////////////////////////////////////////////////
extern const int usbn9604_tx_endpoint_addr[];
extern const int usbn9604_rx_endpoint_addr[];
extern const int fifo_sizes[];
////////////////////////////////////////////////////
/// Globals
////////////////////////////////////////////////////
extern volatile byte direct_send_active;
extern volatile byte wating_rx_data;
//Data buffers
extern control_buffer_t control_send_buffer;
extern control_buffer_t control_receive_buffer;
extern byte Bulk_Parser(USB_request_t *req);
extern void Gen_Parser(USB_request_t *req);
extern byte Interrupt_Parser(USB_request_t *req);
/* The USB device status */
DEVICE_status_t device_status;
Device_buffers_t device_buffers;
UJA_Device_ID_t uja_device_id;
////////////////////////////////////////////////////
/// Prototypes
////////////////////////////////////////////////////
void usb_dev_enable_ep(const USB_endpoint_desc_t *ep);
void usb_dev_disable_ep(const USB_endpoint_desc_t *ep);
byte get_deep_switch_settings() { return GET_DIP_SW1()&0x3f; }
void set_uja_device_id_value()
{ uja_device_id.UJA_Device_ID_Value = GET_DIP_SW1()&0x3f; }
/*---------------------------------------------------------------------
* USBN9604_init()
*
* Initializes the USBN9604
*
*---------------------------------------------------------------------*/
void USBN9604_init(void)
{
volatile unsigned int i;
PDALT |= 0x02; /* Set the alternate function pins to interrupt[iopd1] from USB INTR pin */
/* Hardware reset */
/*Enable pull-up at port E */
PEALT &= ~0x40;/* This port alternate function is GPIO */
//for (i = 0; i < 0xffff; i++); //Give the USB some time to reset itself
PEWPU = 0x40;/* Enable the IOPE6 pull-up in order to output the USB from reset */
for (i = 0; i < 0x4000; i++); //USB node should have 2^14 cycles of idle run after reset
//check if chip stabilized if not reset the chip
for (i = 0; i < 0xffff; i++){
write_usb(CCONF, i % 0x10);
if (read_usb(CCONF) != (i % 0x10))
WATCHDOG_RESET;
}
/* Initialize the clock generator as input for the SCANPSC100F
* prior to this point, the clock output will be 4 Mhz. After,
* it will be (48 MHz/CLKDIV)
*/
if (GET_DIP_SW1() & 0x80)
write_usb(CCONF, CLKDIV_SLOW-1);
else
write_usb(CCONF, CLKDIV_FAST-1);
write_7seg(read_usb(CCONF));
/* Give a software reset, then set ints to active high push pull */
write_usb(MCNTRL, SRST);
/* Wait for end of the initiated reset */
while(read_usb(MCNTRL) & SRST);
/* Set Rising Edge interrupt type and internal voltage */
write_usb(MCNTRL, INT_H_P | VGE);
/*mask all USB node events*/
DISABLE_NODE_INTS
/* Set up interrupt masks */
ENABLE_NAK_INTS(NAK_OUT0) /* NAK OUT FIFO 0 evnt */
ENABLE_TX_INTS(TX_FIFO0|TX_FIFO1|TX_FIFO2|TX_FIFO3) /* enable TX events */
ENABLE_RX_INTS(RX_FIFO0|RX_FIFO1) /* enable RX events */
ENABLE_ALT_INTS(ALT_SD3|ALT_RESET) /* ALT events */
/* Enable all below interrupts */
ENABLE_NODE_INTS(INTR_E|RX_EV|NAK|TX_EV|ALT)
reset_usb();
GOTO_STATE(OPR_ST) /* Go operational */
ATTACH_NODE
for (i = 0; i < 0xffff; i++);
}
void reset_usb(void)
{
/* set default address for endpoint 0*/
SET_EP_ADDRESS(EPC0, 0x0)
/*set usb default device address (FAR register)*/
SET_USB_DEVICE_ADDRESS(0x0)
/*enable USB device address (FAR register)*/
USB_DEVICE_ADDRESS_ENABLE
/*enable responce to the default address
regardless to the value of the EPC0 and FAR registers*/
/* Reset all endpoints */
/* for (i=1; i<MAX_NUM_OF_ENDPOINTS; i++)
{
if (uja_dev_endpoints[i] != NULL)
usb_dev_disable_ep(uja_dev_endpoints[i]);
}
*/
FLUSHTX0 //ep0
FLUSHTX1 //ep1
FLUSHTX3 //ep5
FLUSHRX0 //ep0
FLUSHRX1 //ep2
/* Global initalizations */
clear_control_buffer(&control_send_buffer);
clear_control_buffer(&control_receive_buffer);
endpoint_status_init();
direct_send_active = 0;
wating_rx_data = 0;
/* Enable the receiver */
ENABLE_RX0
}
/*----------------------------------------------------------------------------
* uja_device_reset
*
* USB device reset
*
* Input: None
* Output: None
*--------------------------------------------------------------------------*/
void uja_device_reset(void)
{
//SET_DEVICE_ADDRESS(device_status, 0);
device_status.last_req = RESERVED_REQ;
if (DEVICE_STATE(device_status) == DEV_ADDRESS || DEVICE_STATE(device_status) == DEV_CONFIGURED)
SET_DEVICE_STATE(device_status, DEV_ATTACHED);
device_buffers.zero_data = 0;
}
/*====================================================================
* UJA Control Pipe Protocol Definitions
*====================================================================*/
/*=================================================================
* UJA device Descriptors
*=================================================================*/
/*Device UJA device descriptor*/
const USB_device_desc_t uja_device_desc =
{
sizeof(USB_device_desc_t),
DEVICE_DESCRIPTOR,
USB_SPEC_VERSION,
CLASS_NOT_DEFINED, //CLASS_VENDOR, /* vendor specific */
0, /* Device Sub-Class */
0, /* Device Protocol */
EP0_FIFO_SIZE, /* Max Packet Size for EndPoint Zero*/
NSC_ID_VENDOR,
NSC_ID_PRODUCT,
0x0100, //device release number: 01.00 NSC_BCDDEVICE,
STR_MANUFACTURER,
STR_PRODUCT,
0, /* Device's serial number */
1 /* Num of configurations */
};
/*==================================================================
* Endpoints Descriptors
*==================================================================*/
/* Device Long Configuration descriptor */
const USB_long_config_desc_t uja_dev_long_config_desc =
{
/* Device Configuration descriptor */
{
sizeof(USB_config_desc_t), //CONFIG_DESC_LENGTH
CONFIG_DESCRIPTOR,
sizeof(USB_long_config_desc_t), //TOTAL CONFIG_DESC_LENGTH
1, /* one interface supported */
1, /* Configuration number */
0, //no descriptor string //STR_PRODUCT,
0x80, //bus powered //SELF_POWERED,
100 //0.2A (200mA) /* Max power consumption */
},
/* UJA device interface descriptor */
{
sizeof(USB_interface_desc_t),
INTERFACE_DESCRIPTOR,
0, /* The only interface concurrently supported by this configuration */
0, /* Alternate Setting */
CURR_NUM_OF_ENDPOINTS, /* Num of endpoints of this interface excluding endpoint zero */
CLASS_VENDOR, /* Vendor specific */
0, /* Sub class */
CLASS_VENDOR, /* Vendor Specific Interface Protocol */
0
},
/* The IN endpoint 1 is used for bulk data transfer */
{
sizeof(USB_endpoint_desc_t),
ENDPOINT_DESCRIPTOR,
{
ENDPOINT_1,
0,
IN
},
BULK_ENDPOINT,
TX_BULK_EP_FIFO_SIZE, /* Max Packet Size */
0 /* Irrelevant */
},
/* The OUT endpoint 2 is used for bulk data transfer */
{
sizeof(USB_endpoint_desc_t),
ENDPOINT_DESCRIPTOR,
{
ENDPOINT_2,
0,
OUT
},
BULK_ENDPOINT,
RX_BULK_EP_FIFO_SIZE, /* Max Packet Size */
0 /* Irrelevant */
},
/* The IN endpoint 5 is used for interrupt data transfer */
{
sizeof(USB_endpoint_desc_t),
ENDPOINT_DESCRIPTOR,
{
ENDPOINT_5,
0,
IN
},
INTERRUPT_ENDPOINT,
TX_INTR_EP_FIFO_SIZE, /* Max Packet Size */
0x1 /* Interrupt Interval, 1ms */
}
};
/* List of endpoint descriptors */
const USB_endpoint_desc_t *uja_dev_endpoints[] =
{
NULL, /* Endpoint 0 */
&uja_dev_long_config_desc.uja_dev_endpoint1_desc, /* Endpoint 1 */
&uja_dev_long_config_desc.uja_dev_endpoint2_desc, /* Endpoint 2 */
NULL, //&uja_dev_endpoint3_desc, /* Endpoint 3 */
NULL, //&uja_dev_endpoint4_desc, /* Endpoint 4 */
&uja_dev_long_config_desc.uja_dev_endpoint5_desc, /* Endpoint 5 */
NULL //&uja_dev_endpoint6_desc /* Endpoint 6 */
};
/*=================================================================*
* Vendor Device Descriptor
*=================================================================*/
UJA_Device_ID_t uja_device_id =
{
0x0, /* default uja device id*/
HARDWARE_UJA_ID /* default uja device id source */
};
const UJA_vendor_device_desc_t uja_vendor_dev_desc =
{
sizeof(UJA_vendor_device_desc_t),
UJA_DEVICE_DESCRIPTOR,
0x0
};
/*=================================================================*
* String Descriptors *
*=================================================================*/
/* String descriptors */
const struct {
byte bLength;
byte bDescriptorType;
word bstring;
} langid_str_desc = {sizeof(langid_str_desc), STRING_DESCRIPTOR, ENGLISH_US};
const struct {
byte bLength;
byte bDescriptorType;
char bstring[sizeof(MANUFACTURER_STR)];
} manufacturer_str_desc = {sizeof(manufacturer_str_desc), STRING_DESCRIPTOR, MANUFACTURER_STR};
const struct {
byte bLength;
byte bDescriptorType;
char bstring[sizeof(PRODUCT_STR)];
} product_str_desc = {sizeof(product_str_desc), STRING_DESCRIPTOR, PRODUCT_STR};
const struct {
byte bLength;
byte bDescriptorType;
char bstring[sizeof(VERSION_STR)];
} version_str_desc = {sizeof(version_str_desc), STRING_DESCRIPTOR, VERSION_STR};
/* List of all string descriptors, Be sure that the order
* of the list is the same as String_index_t enum */
const USB_string_desc_t *string_descs[] = {
(USB_string_desc_t*)&langid_str_desc,
(USB_string_desc_t*)&manufacturer_str_desc,
(USB_string_desc_t*)&product_str_desc,
(USB_string_desc_t*)&version_str_desc
};
void build_string_desc(USB_string_desc_t* dsc, byte* dsc_buff)
{
int i;
byte* dsc_buff_p;
dsc_buff[0] = dsc->bLength;
dsc_buff[1] = dsc->bDescriptorType;
//make the string UNICODE encoded
//each char is two bytes long
dsc_buff_p = (byte *)(dsc_buff+2);
for(i=0;i<dsc->bLength; i++)
{
*dsc_buff_p++ = dsc->bstring[i];
*dsc_buff_p++ = 0x00;
}
}
/*=================================================================*
* Standard device request handlers *
*=================================================================*/
/* requests' sequence is according to USB 1.1 spec values */
const USB_req_handler_t usb_std_device_req[] =
{
usb_dev_get_status,
usb_dev_clear_feature,
USB_req_reserved,
usb_dev_set_feature,
USB_req_reserved,
usb_dev_set_address,
usb_std_dev_get_descriptor,
usb_std_dev_set_descriptor,
usb_dev_get_config,
usb_dev_set_config,
usb_dev_get_interface,
usb_dev_set_interface,
usb_dev_sync_frame,
USB_req_reserved,
USB_req_reserved,
USB_req_reserved
};
/*=================================================================*
* Vendor device request handlers *
*=================================================================*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -