📄 usb.c
字号:
//================================================
void usb_trn_setup_std_dev(void)
{
switch(usb_buf_ep0_out.request)
{
case _RQ_SET_ADDRESS:
usb_addr = usb_buf_ep0_out.value_W._b0;
USB_ADDR_1_FLAG = 1;
usb_ep0_load_0len();
usb_state = USB_STATE_ADDRESS_PENDING;
break;
case _RQ_GET_DESCRIPTOR:
usb_trn_setup_std_dev_getdsc();
break;
case _RQ_SET_CONFIGURATION:
usb_config = usb_buf_ep0_out.value_W._b0;
usb_ep0_load_0len();
usb_state = USB_STATE_CONFIGURED;
USB_READY_FLAG = 1;
break;
//--- not supported
case _RQ_CLEAR_FEATURE:
case _RQ_SET_FEATURE:
case _RQ_GET_INTERFACE:
case _RQ_SET_INTERFACE:
case _RQ_SYNC_FRAME:
case _RQ_GET_STATUS:
case _RQ_SET_DESCRIPTOR:
case _RQ_GET_CONFIGURATION:
default:
usb_ep0_trn_unsupported();
break;
}
}
//================================================
//--- usb_trn_setup_std_intf()
//
// overview:
// process "SETUP" transactions for STD, INTF
//================================================
void usb_trn_setup_std_intf(void)
{
switch(usb_buf_ep0_out.request)
{
case _RQ_GET_DESCRIPTOR:
usb_trn_setup_std_intf_getdsc();
break;
//--- not supported
default:
usb_ep0_trn_unsupported();
break;
}
}
//================================================
//--- usb_trn_setup_class_intf()
//
// overview:
// process "SETUP" transactions for CLASS, INTF
//================================================
void usb_trn_setup_class_intf(void)
{
switch(usb_buf_ep0_out.request)
{
case _RQ_SET_IDLE:
usb_ep0_load_0len();
break;
case _RQ_GET_REPORT:
usb_trn_setup_class_intf_getreport();
break;
default:
usb_ep0_trn_unsupported();
break;
}
}
//================================================
//--- usb_trn_setup_class_intf_getreport()
//
// overview:
// process "SETUP" transactions for CLASS, INTF
// GET_REPORT
//================================================
void usb_trn_setup_class_intf_getreport(void)
{
switch(usb_buf_ep0_out.value_W._b1)
{
case 0:
case 1:
case 2:
case 3:
default:
usb_bdt_ep0_in.count = 2;
usb_buf_ep0_in._b0 = 0x01;
usb_buf_ep0_in._b1 = 0x02;
break;
}
}
//================================================
//--- usb_trn_setup_std_dev_getdsc()
//
// overview:
// process "SETUP" transactions for STD, DEV
// GET_DESCRIPTOR
//================================================
void usb_trn_setup_std_dev_getdsc(void)
{
#ifdef __DEBUG_TRACE
cbuf1_put(0xF6);
cbuf1_put(usb_buf_ep0_out.value_W._b1);
#endif
switch(usb_buf_ep0_out.value_W._b1)
{
case _DESC_TYPE_DEV:
usb_count = sizeof(usb_dsc_dev);
usb_src_p.rom_b = (rom TD_BYTE *)&usb_dsc_dev;
usb_ep0_load_flash_init();
break;
case _DESC_TYPE_CFG:
usb_count = sizeof(usb_dsc_cfg_01);
usb_src_p.rom_b = (rom TD_BYTE *)&usb_dsc_cfg_01;
usb_ep0_load_flash_init();
break;
case _DESC_TYPE_RPT:
usb_count = sizeof(usb_dsc_hid_rpt_01);
usb_src_p.rom_b = (rom TD_BYTE *)&usb_dsc_hid_rpt_01;
usb_ep0_load_flash_init();
break;
case _DESC_TYPE_STR:
usb_trn_setup_std_dev_getstring();
break;
//--- not supported
case _DESC_TYPE_INTF:
case _DESC_TYPE_EP:
case _DESC_TYPE_DEVQUAL:
case _DESC_TYPE_OSC:
default:
usb_ep0_trn_unsupported();
break;
}
}
//================================================
//--- usb_trn_setup_std_intf_getdsc()
//
// overview:
// process "SETUP" transactions for STD, INTF
// GET_DESCRIPTOR
//================================================
void usb_trn_setup_std_intf_getdsc(void)
{
switch(usb_buf_ep0_out.value_W._b1)
{
case _DESC_TYPE_RPT:
usb_count = sizeof(usb_dsc_hid_rpt_01);
usb_src_p.rom_b = (rom TD_BYTE *)&usb_dsc_hid_rpt_01;
usb_ep0_load_flash_init();
break;
//--- not supported
default:
usb_ep0_trn_unsupported();
break;
}
}
//================================================
//--- usb_trn_setup_std_dev_getstring()
//
// overview:
// process "SETUP" transactions for STD, DEV
// GET_DESCRIPTOR
//================================================
void usb_trn_setup_std_dev_getstring(void)
{
switch(usb_buf_ep0_out.value_W._b0)
{
case 0:
usb_src_p.rom_w = (rom TD_WORD *)&usb_dsc_str_00;
usb_count = sizeof(usb_dsc_str_00);
usb_ep0_load_flash_init();
break;
case 1:
usb_src_p.rom_w = (rom TD_WORD *)&usb_dsc_str_01;
usb_count = sizeof(usb_dsc_str_01);
usb_ep0_load_flash_init();
break;
case 2:
usb_src_p.rom_w = (rom TD_WORD *)&usb_dsc_str_02;
usb_count = sizeof(usb_dsc_str_02);
usb_ep0_load_flash_init();
break;
//--- not supported
default:
usb_ep0_trn_unsupported();
break;
}
}
//==========================================================
//=== UTILITIES
//==========================================================
//================================================
//--- usb_ep0_load_flash_init()
//
// overview:
// setup to xmit FLASH data to EP0,IN buffer
//================================================
void usb_ep0_load_flash_init()
{
USB_IN_BUSY_FLAG = 1;
usb_bdt_ep0_in.status._b = _BDS_DTSEN;
usb_ep0_load_flash();
}
//================================================
//--- usb_ep0_load_flash()
//
// overview:
// xmit FLASH data to EP0,IN buffer
//================================================
void usb_ep0_load_flash(void)
{
if(usb_count > usb_buf_ep0_out.length_W._b0)
usb_count = usb_buf_ep0_out.length_W._b0;
usb_count_temp = usb_count;
if(usb_count_temp > USB_EP0_SIZE_MAX)
usb_count_temp = USB_EP0_SIZE_MAX;
usb_count -= usb_count_temp;
usb_bdt_ep0_in.count = usb_count_temp;
usb_dst_p.ram_b = (TD_BYTE *)&usb_buf_ep0_in;
while(usb_count_temp--)
*usb_dst_p.ram_b++ = *usb_src_p.rom_b++;
usb_ep0_in_finish();
}
//================================================
//--- usb_ep0_trn_unsupported()
//
// overview:
// EP0 transaction is not supported, set STALL
//================================================
void usb_ep0_trn_unsupported(void)
{
UEP0bits.EPSTALL = 1;
}
//================================================
//--- usb_ep0_load_0len
//
// overview:
// setup/enable ZERO-LENGTH INPUT transaction
//================================================
void usb_ep0_load_0len()
{
usb_bdt_ep0_in.count = 0;
usb_bdt_ep0_in.status._b = _BDS_DTSEN;
usb_ep0_in_finish();
}
//================================================
//--- usb_ep0_in_finish()
//
// overview:
// enable USB, EP0 INPUT transaction
//================================================
void usb_ep0_in_finish(void)
{
usb_bdt_ep0_in.status._b = \
((usb_bdt_ep0_in.status._b & _BDS_DTS) ^ _BDS_DTS) | _BDS_UOWN | _BDS_DTSEN;
#ifdef __DEBUG_TRACE
cbuf1_put(0xF7);
cbuf1_put(usb_bdt_ep0_in.count);
#endif
}
//================================================
//--- usb_ep0_out_finish
//
// overview:
// reset buffer descriptor for ep0 out
//================================================
void usb_ep0_out_finish(void)
{
UCONbits.PKTDIS = 0;
usb_bdt_ep0_out.count = USB_EP0_SIZE_MAX;
usb_bdt_ep0_out.status._b = _BDS_UOWN;
}
//==========================================================
//=== EP1 (DATA I/O) UTILS
//==========================================================
#pragma code _usb_ep1
//================================================
//--- usb_ep1_check
//
// overview:
// prepare flags for calling routine(s)
//
// the calling routine execute usb_ep1_check()"
// before relying on buffer ready/not-ready flags
//================================================
void usb_ep1_check(void)
{
if(USB_READY_FLAG)
{
USB_RCVBUF_READY_FLAG = not usb_bdt_ep1_out.status.uown;
USB_XMTBUF_READY_FLAG = not usb_bdt_ep1_in.status.uown;
}
else
{
USB_RCVBUF_READY_FLAG = 0;
USB_XMTBUF_READY_FLAG = 0;
}
}
//================================================
//--- usb_ep1_in_finish
//
// overview:
// reset buffer descriptor: ep1, in
// (data is ready, make available to the host)
//================================================
void usb_ep1_in_finish(void)
{
usb_bdt_ep1_in.status._b = \
((usb_bdt_ep1_in.status._b & _BDS_DTS) ^ _BDS_DTS) | _BDS_UOWN;
usb_ep1_check();
}
//================================================
//--- usb_ep1_out_finish
//
// overview:
// reset buffer descriptor: ep1, out
// (data rcv'd from host has been processed - rls buffer)
//================================================
void usb_ep1_out_finish(void)
{
usb_bdt_ep1_out.status._b = \
((usb_bdt_ep1_out.status._b & _BDS_DTS) ^ _BDS_DTS) | _BDS_UOWN;
usb_ep1_check();
}
//================================================
//--- usb_ep1_out_get
//
// overview:
// block waiting for rcv buffer
// move receive buffer to destination
// release receive buffer
//================================================
void usb_ep1_out_get(TD_BYTE *dst_p)
{
usb_src_p.ram_b = USB_RCVBUF_POINTER;
usb_count = USB_RCVBUF_SIZE;
while(usb_count--)
*dst_p++ = *usb_src_p.ram_b++;
USB_RCVBUF_RELEASE_FUNC();
}
//================================================
//--- usb_ep1_in_put
//
// overview:
// block waiting for xmt buffer avail
// move caller data to xmt buffer
// release/send xmt buffer
//================================================
void usb_ep1_in_put(TD_BYTE *src_p)
{
usb_dst_p.ram_b = USB_XMTBUF_POINTER;
usb_count = USB_XMTBUF_SIZE;
while(usb_count--)
*usb_dst_p.ram_b++ = *src_p++;
USB_XMTBUF_RELEASE_FUNC();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -