| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667 |
- #include "include.h"
- #include "usb_com.h"
- #include "usb_desc.h"
- #include "usb_hid.h"
- #include "usb_vendor.h"
- #include "usb_audio.h"
- ude_cb_t ude_cb;
- u8 cfg_desc_buf[0x100] AT(.usb_buf.device.desc.buf);
- void ude_state_reset(ude_cb_t *ude)
- {
- ude->devaddr = 0;
- ude->cfgval = 0;
- }
- //Get Status
- static bool do_get_status(uint status)
- {
- u8 buf[2];
- buf[0] = status;
- buf[1] = 0;
- return usb_ep0_start_transfer(buf, 2);
- }
- //Get Device Status
- static bool do_get_device_status(void)
- {
- if (0 == ude_cb.devaddr) { //判断地址是否设置
- return false;
- }
- return do_get_status(0);
- }
- //Get Interface Status
- static bool do_get_interface_status(void)
- {
- if (0 == ude_cb.cfgval) { //判断是否已配置
- return false;
- }
- return do_get_status(0);
- }
- //Get EndPoint Status
- static bool do_get_ep_status(spb_wrap_t *spb)
- {
- epcb_t *ep;
- uint req_epnum = BYTE0(spb->index);
- uint status = 0;
- if (0 == ude_cb.devaddr) { //判断地址是否设置
- return false;
- }
- if (0 == ude_cb.cfgval && 0 != req_epnum) {
- return false;
- }
- //查询Endpoint的Stall状态
- uint temp = BYTE0(spb->index);
- uint8_t index = temp & 0x7f;
- uint8_t dir = temp & BIT(7) ? 1:0;
- ep = usb_ep_get_for_index(index, dir);
- status = ep->halt;
- return do_get_status(status);
- }
- //Clear Feature
- static bool do_clear_feature_for_endpoint(spb_wrap_t *spb)
- {
- if (0 == ude_cb.devaddr) { //判断地址是否设置
- return false;
- }
- uint req_epnum = BYTE0(spb->index);
- if (0 == ude_cb.cfgval && 0 != req_epnum) {
- return false;
- }
- if (FT_EP_STALL != spb->val) {
- return false;
- }
- uint temp = BYTE0(spb->index);
- uint8_t index = temp & 0x7f;
- uint8_t dir = temp & BIT(7) ? 1:0;
- epcb_t *ep = usb_ep_get_for_index(index, dir);
- usb_ep_clear(ep);
- return true;
- }
- //Set Feature
- static bool do_set_feature_for_endpoint(spb_wrap_t *spb)
- {
- printf("-->do_set_feature_for_endpoint\n");
- uint req_epnum = BYTE0(spb->index);
- if (0 == ude_cb.cfgval && 0 != req_epnum) {
- return false;
- }
- if (FT_EP_STALL != spb->val) {
- return false;
- }
- uint temp = BYTE0(spb->index);
- uint8_t index = temp & 0x7f;
- uint8_t dir = temp & BIT(7) ? 1:0;
- epcb_t *ep = usb_ep_get_for_index(index, dir);
- usb_ep_halt(ep);
- return true;
- }
- static bool do_set_feature_for_device(spb_wrap_t *spb)
- {
- printf("-->do_set_feature_for_device\n");
- uint req_epnum = BYTE0(spb->index);
- if (0 == ude_cb.cfgval && 0 != req_epnum) {
- return false;
- }
- if (FT_DEV_REM_WAKEUP != spb->val) {
- return false;
- }
- usb_device_suspend_enable();
- return true;
- }
- static bool do_clear_feature_for_device(spb_wrap_t *spb)
- {
- printf("-->do_clear_feature_for_device\n");
- if (0 == ude_cb.devaddr) { //判断地址是否设置
- return false;
- }
- uint req_epnum = BYTE0(spb->index);
- if (0 == ude_cb.cfgval && 0 != req_epnum) {
- return false;
- }
- if (FT_DEV_REM_WAKEUP != spb->val) {
- return false;
- }
- return true;
- }
- //Get Descriptor通用
- static bool do_transfer_descriptor(spb_wrap_t *spb, const void *buf, uint len)
- {
- uint inlen = spb->len;
- if (inlen > len) {
- inlen = len;
- }
- return usb_ep0_start_transfer((uint8_t*)buf, inlen);
- }
- //Get String Descriptor
- static bool do_get_string_descriptor(spb_wrap_t *spb)
- {
- uint index = BYTE0(spb->val);
- u8 *buf = NULL;
- u8 length = 0;
- switch (index) {
- case STR_LANGUAGE_ID:
- buf = usb_get_lang_id_str_descriptor(&length);
- return do_transfer_descriptor(spb, buf, length);
- case STR_MANUFACTURER:
- buf = usb_get_manufacturer_str_descriptor(&length);
- return do_transfer_descriptor(spb, buf, length);
- case STR_PRODUCT:
- buf = usb_get_product_str_descriptor(&length);
- return do_transfer_descriptor(spb, buf, length);
- case STR_SERIAL_NUM:
- buf = usb_get_serial_str_descriptor(&length);
- return do_transfer_descriptor(spb, buf, length);
- default:
- return false;
- }
- }
- //获取配置描述符,并自动裁剪
- AT(.usbdev.com)
- void get_config_descriptor(void)
- {
- u16 cfg_desc_len;
- u8 *desc_ptr = &cfg_desc_buf[0];
- u8 *buf = NULL;
- u8 length = 0;
- //copy general config descriptor
- buf = usb_get_cfg_descriptor(&length);
- if (length) {
- memcpy(desc_ptr, buf, length);
- desc_ptr += length;
- } else {
- // unexpected case
- printf("[Error] you must be rewrite 'usb_get_cfg_descriptor' and return valid cfg desc.\n");
- return;
- }
- #if USB_AUDIO_EN
- buf = usb_audio_itf_header_desc_get(&length);
- if (length) {
- memcpy(desc_ptr, buf, length);
- desc_ptr += length;
- }
- #if USB_SPEAKER_EN
- buf = usb_audio_itf_speaker_stream_desc_get(&length);
- if (length) {
- memcpy(desc_ptr, buf, length);
- desc_ptr += length;
- }
- #endif // USB_SPEAKER_EN
- #if USB_MIC_EN
- buf = usb_audio_itf_mic_stream_desc_get(&length);
- if (length) {
- memcpy(desc_ptr, buf, length);
- desc_ptr += length;
- }
- #endif // USB_MIC_EN
- #endif
- #if USB_HID_EN
- buf = usb_hid_itf_desc_get(&length);
- if (length) {
- memcpy(desc_ptr, buf, length);
- desc_ptr += length;
- }
- #endif // USB_HID_EN
- #if USB_VENDOR_EN
- buf = usb_vendor_itf_desc_get(&length);
- if (length) {
- memcpy(desc_ptr, buf, length);
- desc_ptr += length;
- }
- #endif
- cfg_desc_len = (u32)desc_ptr - (u32)cfg_desc_buf;
- cfg_desc_buf[2] = (u8)cfg_desc_len; //update total size of config descriptor
- cfg_desc_buf[3] = (u8)(cfg_desc_len >> 8);
- printf("desc: %d\n", cfg_desc_len);
- if (cfg_desc_len > sizeof(cfg_desc_buf)) {
- printf("--->err: cfg_desc_buf overflow!\n");
- while(1);
- }
- }
- //Get Descriptor
- AT(.usbdev.com)
- static bool do_get_descriptor(spb_wrap_t *spb)
- {
- uint desc_type = BYTE1(spb->val);
- u8 *buf = NULL;
- u8 length = 0;
- switch (desc_type) {
- case DEVICE_DESCRIPTOR:
- //1: 设备描述符
- buf = usb_get_device_descriptor(&length);
- return do_transfer_descriptor(spb, buf, length);
- case CONFIGURATION_DESCRIPTOR:
- //2: 配置描述符
- get_config_descriptor();
- return do_transfer_descriptor(spb, cfg_desc_buf, ((u16)cfg_desc_buf[3] << 8) | cfg_desc_buf[2]);
- case STRING_DESCRIPTOR:
- //3: 字符串描述符
- return do_get_string_descriptor(spb);
- case INTERFACE_DESCRIPTOR:
- //4: 接口描述符
- break;
- case ENDPOINT_DESCRIPTOR:
- //5: 端点描述符
- break;
- case HID_DESCRIPTOR:
- break;
- case HID_REPORT_DESCRIPTOR:
- printf("usb_hid_report_desc_get:%x\n",spb->index);
- #if USB_HID_EN
- if (spb->index == USB_HID_ITF_INDEX) {
- buf = usb_hid_report_desc_get(&length);
- return do_transfer_descriptor(spb, buf, length);
- }
- #endif
- #if USB_VENDOR_EN
- if (spb->index == USB_VENDOR_ITF_INDEX) {
- buf = usb_vendor_report_desc_get(&length);
- return do_transfer_descriptor(spb, buf, length);
- }
- #endif
- default:
- break;
- }
- return false;
- }
- //Get Configuration
- static bool do_get_configuration(void)
- {
- if (0 == ude_cb.devaddr) { //判断地址是否设置
- return false;
- }
- return usb_ep0_start_transfer(&ude_cb.cfgval, 1);
- }
- //Set Configuration
- static bool do_set_configuration(spb_wrap_t *spb)
- {
- if (0 == ude_cb.devaddr) { //判断地址是否设置
- return false;
- }
- if (spb->val > 1) {
- return false;
- }
- ude_cb.cfgval = spb->val;
- #if USB_HID_EN
- ude_hid_setvalid(true);
- #endif
- #if USB_VENDOR_EN
- ude_vendor_setvalid(true);
- #endif
- return true;
- }
- //Get Interface
- static bool do_get_interface(spb_wrap_t *spb)
- {
- u8 buf[1] = {0};
- if (0 == ude_cb.devaddr) { //判断地址是否设置
- return false;
- }
- #if USB_MIC_EN
- if (USB_AUDIO_STREAM_MIC_ITF_INDEX == (u8)spb->index) {
- buf[0] = uda_get_isocin_flag();
- }
- #endif
- #if USB_SPEAKER_EN
- if (USB_AUDIO_STREAM_SPEAKER_ITF_INDEX == (u8)spb->index) {
- buf[0] = uda_get_isocout_flag();
- }
- #endif
- return usb_ep0_start_transfer(buf, 1);
- }
- //Set Interface
- static bool do_set_interface(spb_wrap_t *spb)
- {
- if (0 == ude_cb.devaddr) { //判断地址是否设置
- return false;
- }
- #if USB_MIC_EN
- if (USB_AUDIO_STREAM_MIC_ITF_INDEX == spb->index) {
- //每次开启和关闭MIC之前,都会set interface
- if (spb->val) {
- //start mic
- printf("start mic\n");
- uda_set_isocin_flag(1);
- } else {
- //stop mic
- printf("stop mic\n");
- uda_set_isocin_flag(0);
- }
- }
- #endif
- #if USB_SPEAKER_EN
- if (USB_AUDIO_STREAM_SPEAKER_ITF_INDEX == spb->index) {
- //每次开启和关闭speaker之前,都会set interface
- if (spb->val) {
- printf("start speaker\n");
- uda_set_isocout_flag(1);
- } else {
- printf("stop speaker\n");
- uda_set_isocout_flag(0);
- }
- }
- #endif
- return true;
- }
- static bool usb_set_address(spb_wrap_t *spb)
- {
- ude_cb.devaddr = BYTE0(spb->val);
- return true;
- }
- //处理标准命令,主机数据方向为in
- AT(.usbdev.com)
- static bool do_standard_in(spb_wrap_t *spb)
- {
- switch (spb->recipient) {
- case ST_REQ_DEVICE:
- switch (spb->req) {
- case UR_GET_STATUS:
- //00: GetStatus
- return do_get_device_status();
- case UR_GET_DESCRIPTOR:
- //06: GetDescriptor
- return do_get_descriptor(spb);
- case UR_GET_CONFIGURATION:
- //08: GetConfiguration
- return do_get_configuration();
- default:
- break;
- }
- break;
- case ST_REQ_INTERFACE:
- switch (spb->req) {
- case UR_GET_STATUS:
- if (spb->req == UR_GET_STATUS) {
- return do_get_interface_status();
- }
- break;
- case UR_GET_INTERFACE:
- //0a: GetInterface
- return do_get_interface(spb);
- case UR_GET_DESCRIPTOR:
- //06: GetDescriptor
- return do_get_descriptor(spb);
- default:
- break;
- }
- break;
- case ST_REQ_ENDPOINT:
- switch (spb->req) {
- case UR_GET_STATUS:
- if (spb->req == UR_GET_STATUS) {
- return do_get_ep_status(spb);
- }
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- return false;
- }
- //处理类命令,主机数据为向为in
- AT(.usbdev.com)
- static bool do_class_in(spb_wrap_t *spb)
- {
- switch (spb->recipient) {
- case ST_REQ_DEVICE:
- break;
- case ST_REQ_INTERFACE:
- switch (spb->req) {
- #if USB_AUDIO_EN
- case UA_GET_CUR:
- case UA_GET_MIN:
- case UA_GET_MAX:
- case UA_GET_RES:
- if (BYTE1(spb->index) == UA_SPEAKER_UNIT_ID) {
- #if USB_SPEAKER_EN
- //Speaker Get Feature Unit Control Request
- if (BYTE1(spb->val) == UA_MUTE_CTL) {
- //Mute Control
- printf("do_get_spk_mute\n");
- return uda_get_spk_mute();
- } else if (BYTE1(spb->val) == UA_VOL_CTL){
- //Volume Control
- printf("do_get_spk_volume\n");
- return uda_get_spk_volume(spb->req);
- }
- #endif
- } else if(BYTE1(spb->index) == UA_MIC_UNIT_ID){
- #if USB_MIC_EN
- //MIC Get Feature Unit Control Request
- if (BYTE1(spb->val) == UA_MUTE_CTL) {
- //Mute Control
- printf("do_get_mic_mute\n");
- return uda_get_mic_mute();
- } else if (BYTE1(spb->val) == UA_VOL_CTL) {
- //Volume Control
- printf("do_get_mic_volume\n");
- return uda_get_mic_volume(spb->req);
- }
- #endif
- }
- break;
- #endif
- default:
- break;
- }
- break;
- case ST_REQ_ENDPOINT:
- break;
- default:
- break;
- }
- return false;
- }
- //处理标准命令,主机数据方向为out
- AT(.usbdev.com)
- static bool do_standard_out(spb_wrap_t *spb)
- {
- switch (spb->recipient) {
- case ST_REQ_DEVICE:
- switch (spb->req) {
- case UR_SET_ADDRESS:
- //05: SetAddress
- return usb_set_address(spb);
- case UR_SET_CONFIGURATION:
- //09: SetConfiguration
- return do_set_configuration(spb);
- case UR_CLEAR_FEATURE:
- return do_clear_feature_for_device(spb);
- case UR_SET_FEATURE:
- return do_set_feature_for_device(spb);
- default:
- break;
- }
- break;
- case ST_REQ_INTERFACE:
- switch (spb->req) {
- case UR_SET_INTERFACE:
- //0b: SetInterface
- return do_set_interface(spb);
- default:
- break;
- }
- break;
- case ST_REQ_ENDPOINT:
- switch (spb->req) {
- case UR_CLEAR_FEATURE:
- return do_clear_feature_for_endpoint(spb);
- case UR_SET_FEATURE:
- return do_set_feature_for_endpoint(spb);
- default:
- break;
- }
- break;
- default:
- break;
- }
- return false;
- }
- static bool do_class_out(spb_wrap_t *spb, uint8_t *data, uint16_t data_len)
- {
- if ((spb->reqtype == 0x21) && (spb->req == UA_SET_CUR)) {
- if (BYTE1(spb->index) == UA_SPEAKER_UNIT_ID) {
- if (BYTE1(spb->val) == UA_MUTE_CTL) {
- //Speaker SET MUTE
- #if USB_SPEAKER_EN
- uda_set_spk_mute(data[0]);
- #endif // USB_SPEAKER_EN
- } else if (BYTE1(spb->val) == UA_VOL_CTL) {
- //Speaker SET VOLUME
- #if USB_SPEAKER_EN
- uda_set_spk_volume(GET_LE16(&data[0]));
- #endif // USB_SPEAKER_EN
- }
- } else if (BYTE1(spb->index) == UA_MIC_UNIT_ID) {
- if (BYTE1(spb->val) == UA_MUTE_CTL) {
- //MIC SET MUTE
- #if USB_MIC_EN
- uda_set_mic_mute(data[0]);
- #endif // USB_MIC_EN
- } else if (BYTE1(spb->val) == UA_VOL_CTL) {
- //MIC SET VOLUME
- #if USB_MIC_EN
- uda_set_mic_volume(GET_LE16(&data[0]));
- #endif // USB_MIC_EN
- }
- }
- }
- return true;
- }
- AT(.usbdev.com)
- bool usb_ep0_ctl_callback(spb_wrap_t *spb, uint8_t *data, uint16_t data_len)
- {
- //printf("ep0_rx: \n");
- //print_r(spb, sizeof(spb_wrap_t));
- if (spb->dir == EP_DIR_IN) {
- if (spb->type == ST_TYPE_STANDARD) {
- return do_standard_in(spb); //Standard in
- } else if (spb->type == ST_TYPE_CLASS) {
- return do_class_in(spb); //Class in
- } else {
- return false;
- }
- } else {
- bool res;
- if (spb->type == ST_TYPE_STANDARD) {
- res = do_standard_out(spb); //Standard out
- } else if (spb->type == ST_TYPE_CLASS) {
- res = do_class_out(spb, data, data_len); //Class out
- } else {
- return false;
- }
- return res;
- }
- return false;
- }
|