DAPLink (CMSIS-DAP) porting to Artery AT32F425, WCH CH32V203 and WCH CH32V305.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

382 lines
8.8 KiB

#include <string.h>
#include "usb_std.h"
#include "usbd_sdr.h"
#include "usbd_core.h"
#include "vcom_serial.h"
#include "hid_transfer.h"
static usb_setup_type Setup;
static uint8_t hid_rx_buff[64];
/**
* @brief initialize usb endpoint
* @param udev: to the structure of usbd_core_type
* @retval status of usb_sts_type
*/
static usb_sts_type class_init_handler(void *udev)
{
usbd_core_type *usbd = (usbd_core_type *)udev;
#ifdef DAP_FW_V1
usbd_ept_open(usbd, HID_INT_IN_EP, EPT_INT_TYPE, HID_INT_IN_SZ);
usbd_ept_open(usbd, HID_INT_OUT_EP, EPT_INT_TYPE, HID_INT_OUT_SZ);
#else
usbd_ept_open(usbd, HID_INT_IN_EP, EPT_BULK_TYPE, HID_INT_IN_SZ);
usbd_ept_open(usbd, HID_INT_OUT_EP, EPT_BULK_TYPE, HID_INT_OUT_SZ);
#endif
usbd_ept_recv(usbd, HID_INT_OUT_EP, hid_rx_buff, HID_INT_OUT_SZ);
usbd_ept_open(usbd, CDC_INT_IN_EP, EPT_INT_TYPE, CDC_INT_IN_SZ);
usbd_ept_open(usbd, CDC_BULK_IN_EP, EPT_BULK_TYPE, CDC_BULK_IN_SZ);
usbd_ept_open(usbd, CDC_BULK_OUT_EP, EPT_BULK_TYPE, CDC_BULK_OUT_SZ);
usbd_ept_recv(usbd, CDC_BULK_OUT_EP, (uint8_t *)Vcom.out_buff, CDC_BULK_OUT_SZ);
Vcom.in_ready = 1;
return USB_OK;
}
/**
* @brief clear endpoint or other state
* @param udev: to the structure of usbd_core_type
* @retval status of usb_sts_type
*/
static usb_sts_type class_clear_handler(void *udev)
{
usbd_core_type *usbd = (usbd_core_type *)udev;
usbd_ept_close(usbd, HID_INT_IN_EP);
usbd_ept_close(usbd, HID_INT_OUT_EP);
usbd_ept_close(usbd, CDC_INT_IN_EP);
usbd_ept_close(usbd, CDC_BULK_IN_EP);
usbd_ept_close(usbd, CDC_BULK_OUT_EP);
return USB_OK;
}
/**
* @brief usb device class setup request handler
* @param udev: to the structure of usbd_core_type
* @param setup: setup packet
* @retval status of usb_sts_type
*/
static usb_sts_type class_setup_handler(void *udev, usb_setup_type *setup)
{
usbd_core_type *usbd = (usbd_core_type *)udev;
memcpy(&Setup, setup, sizeof(usb_setup_type));
switch(setup->bmRequestType & USB_REQ_TYPE_RESERVED)
{
case USB_REQ_TYPE_STANDARD:
switch(setup->bRequest)
{
case USB_STD_REQ_GET_DESCRIPTOR:
if((setup->wValue >> 8) == HID_REPORT_DESC)
{
extern uint8_t g_hid_report[];
extern uint8_t g_config_descriptor[];
usbd_ctrl_send(usbd, g_hid_report, MIN(g_config_descriptor[9+9+7], setup->wLength));
}
else if((setup->wValue >> 8) == HID_DESCRIPTOR_TYPE)
{
extern uint8_t g_config_descriptor[];
usbd_ctrl_send(usbd, &g_config_descriptor[9+9], MIN(9, setup->wLength));
}
break;
default:
break;
}
break;
/* class request */
case USB_REQ_TYPE_CLASS:
switch(setup->bRequest)
{
case GET_LINE_CODING:
usbd_ctrl_send(usbd, (uint8_t *)&LineCfg, MIN(setup->wLength, 7));
break;
case SET_LINE_CODING:
usbd_ctrl_recv(usbd, (uint8_t *)&LineCfg, MIN(setup->wLength, 7));
break;
case 0x22: // SET_CONTROL_LINE
Vcom.hw_flow = setup->wValue;
break;
case HID_REQ_SET_IDLE: // set Idle Rate for a particular Input report
break;
case HID_REQ_GET_IDLE:
case HID_REQ_SET_REPORT: //
case HID_REQ_GET_REPORT:
case HID_REQ_SET_PROTOCOL: // switch between Boot Protocol and Report Protocol
case HID_REQ_GET_PROTOCOL:
default:
usbd_ctrl_unsupport(usbd);
break;
}
break;
default:
usbd_ctrl_unsupport(usbd);
break;
}
return USB_OK;
}
/**
* @brief usb device endpoint 0 in status stage complete
* @param udev: to the structure of usbd_core_type
* @retval status of usb_sts_type
*/
static usb_sts_type class_ept0_tx_handler(void *udev)
{
return USB_OK;
}
/**
* @brief usb device endpoint 0 out status stage complete
* @param udev: to the structure of usbd_core_type
* @retval status of usb_sts_type
*/
static usb_sts_type class_ept0_rx_handler(void *udev)
{
if(Setup.bRequest == SET_LINE_CODING)
{
VCOM_LineCoding(&LineCfg);
}
return USB_OK;
}
/**
* @brief usb device transmision complete handler
* @param udev: to the structure of usbd_core_type
* @param ept_num: endpoint number
* @retval status of usb_sts_type
*/
static usb_sts_type class_in_handler(void *udev, uint8_t ept_num)
{
switch(0x80 | ept_num)
{
case HID_INT_IN_EP:
HID_SetInReport();
break;
case CDC_BULK_IN_EP:
Vcom.in_ready = 1;
break;
}
return USB_OK;
}
/**
* @brief usb device endpoint receive data
* @param udev: to the structure of usbd_core_type
* @param ept_num: endpoint number
* @retval status of usb_sts_type
*/
static usb_sts_type class_out_handler(void *udev, uint8_t ept_num)
{
usbd_core_type *usbd = (usbd_core_type *)udev;
uint32_t recv_len = usbd_get_recv_len(usbd, ept_num);
switch(ept_num)
{
case HID_INT_OUT_EP:
HID_GetOutReport(hid_rx_buff, recv_len);
/* start receive next packet */
usbd_ept_recv(usbd, HID_INT_OUT_EP, hid_rx_buff, HID_INT_OUT_SZ);
break;
case CDC_BULK_OUT_EP:
Vcom.out_bytes = recv_len;
break;
}
return USB_OK;
}
/**
* @brief usb device sof handler
* @param udev: to the structure of usbd_core_type
* @retval status of usb_sts_type
*/
static usb_sts_type class_sof_handler(void *udev)
{
return USB_OK;
}
/**
* @brief usb device event handler
* @param udev: to the structure of usbd_core_type
* @param event: usb device event
* @retval status of usb_sts_type
*/
static usb_sts_type class_event_handler(void *udev, usbd_event_type event)
{
switch(event)
{
case USBD_RESET_EVENT:
break;
case USBD_SUSPEND_EVENT:
break;
case USBD_WAKEUP_EVENT:
break;
default:
break;
}
return USB_OK;
}
usbd_class_handler hid_class_handler =
{
class_init_handler,
class_clear_handler,
class_setup_handler,
class_ept0_tx_handler,
class_ept0_rx_handler,
class_in_handler,
class_out_handler,
class_sof_handler,
class_event_handler,
NULL
};
/***************************************************************/
#include "DAP_Config.h"
#include "DAP.h"
static volatile uint8_t USB_RequestFull; // Request Buffer Full Flag
static volatile uint32_t USB_RequestIn; // Request Buffer In Index
static volatile uint32_t USB_RequestOut; // Request Buffer Out Index
static volatile uint8_t USB_ResponseIdle = 1; // Response Buffer Idle Flag
static volatile uint8_t USB_ResponseFull; // Response Buffer Full Flag
static volatile uint32_t USB_ResponseIn; // Response Buffer In Index
static volatile uint32_t USB_ResponseOut; // Response Buffer Out Index
static uint8_t USB_Request [DAP_PACKET_COUNT][DAP_PACKET_SIZE]; // Request Buffer
static uint8_t USB_Response[DAP_PACKET_COUNT][DAP_PACKET_SIZE]; // Response Buffer
static uint16_t USB_ResponseSize[DAP_PACKET_COUNT]; // number of bytes in response
extern otg_core_type Otg;
uint8_t usbd_hid_process(void)
{
uint32_t n;
if((USB_RequestOut != USB_RequestIn) || USB_RequestFull)
{
USB_ResponseSize[USB_ResponseIn] = DAP_ProcessCommand(USB_Request[USB_RequestOut], USB_Response[USB_ResponseIn]);
n = USB_RequestOut + 1;
if(n == DAP_PACKET_COUNT)
n = 0;
USB_RequestOut = n;
if(USB_RequestOut == USB_RequestIn)
USB_RequestFull = 0;
if(USB_ResponseIdle)
{
USB_ResponseIdle = 0;
#ifdef DAP_FW_V1
usbd_ept_send(&Otg.dev, HID_INT_IN_EP, USB_Response[USB_ResponseIn], DAP_PACKET_SIZE);
#else
usbd_ept_send(&Otg.dev, HID_INT_IN_EP, USB_Response[USB_ResponseIn], USB_ResponseSize[USB_ResponseIn]);
#endif
}
else
{
n = USB_ResponseIn + 1;
if(n == DAP_PACKET_COUNT)
n = 0;
USB_ResponseIn = n;
if(USB_ResponseIn == USB_ResponseOut)
USB_ResponseFull = 1;
}
return 1;
}
return 0;
}
void HID_GetOutReport(uint8_t * buf, uint32_t len)
{
if(buf[0] == ID_DAP_TransferAbort)
{
DAP_TransferAbort = 1;
return;
}
if((USB_RequestIn == USB_RequestOut) && USB_RequestFull) // Request Buffer Full
return;
memcpy(USB_Request[USB_RequestIn], buf, len);
USB_RequestIn++;
if(USB_RequestIn == DAP_PACKET_COUNT)
USB_RequestIn = 0;
if(USB_RequestIn == USB_RequestOut)
USB_RequestFull = 1;
}
void HID_SetInReport(void)
{
if((USB_ResponseOut != USB_ResponseIn) || USB_ResponseFull)
{
#ifdef DAP_FW_V1
usbd_ept_send(&Otg.dev, HID_INT_IN_EP, USB_Response[USB_ResponseOut], DAP_PACKET_SIZE);
#else
usbd_ept_send(&Otg.dev, HID_INT_IN_EP, USB_Response[USB_ResponseOut], USB_ResponseSize[USB_ResponseOut]);
#endif
USB_ResponseOut++;
if(USB_ResponseOut == DAP_PACKET_COUNT)
USB_ResponseOut = 0;
if(USB_ResponseOut == USB_ResponseIn)
USB_ResponseFull = 0;
}
else
{
USB_ResponseIdle = 1;
}
}