diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/audio/Include/audio_core.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/audio/Include/audio_core.h index 134aac9e..a1abc632 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/audio/Include/audio_core.h +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/audio/Include/audio_core.h @@ -3,10 +3,11 @@ \brief the header file of USB audio device class core functions \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -39,84 +40,90 @@ OF SUCH DAMAGE. #define FORMAT_24BIT(x) (uint8_t)(x);(uint8_t)((x) >> 8);(uint8_t)((x) >> 16) -/* audio_freq * data_size (2 bytes) * num_channels (stereo: 2) */ -#define DEFAULT_OUT_BIT_RESOLUTION 16U -#define DEFAULT_OUT_CHANNEL_NBR 2U /* mono = 1, stereo = 2 */ -#define AUDIO_OUT_PACKET (uint32_t)(((USBD_AUDIO_FREQ_16K * \ - (DEFAULT_OUT_BIT_RESOLUTION / 8U) *\ - DEFAULT_OUT_CHANNEL_NBR) / 1000U)) - -/* number of sub-packets in the audio transfer buffer. you can modify this value but always make sure +/* number of sub-packets in the audio transfer buffer. user can modify this value but always make sure that it is an even number and higher than 3 */ -#define OUT_PACKET_NUM 4U +#define OUT_PACKET_NUM 120U /* total size of the audio transfer buffer */ -#define OUT_BUF_MARGIN 4U -#define TOTAL_OUT_BUF_SIZE ((uint32_t)((AUDIO_OUT_PACKET + OUT_BUF_MARGIN) * OUT_PACKET_NUM)) +#define OUT_BUF_MARGIN 0U +#define TOTAL_OUT_BUF_SIZE ((uint32_t)((SPEAKER_OUT_PACKET + OUT_BUF_MARGIN) * OUT_PACKET_NUM)) -#define AUDIO_CONFIG_DESC_SET_LEN 109U -#define AUDIO_INTERFACE_DESC_SIZE 9U +#define AD_CONFIG_DESC_SET_LEN (sizeof(usb_desc_config_set)) +#define AD_INTERFACE_DESC_SIZE 9U -#define USB_AUDIO_DESC_SIZ 0x09U -#define AUDIO_STANDARD_EP_DESC_SIZE 0x09U -#define AUDIO_STREAMING_EP_DESC_SIZE 0x07U +#define USB_AD_DESC_SIZ 0x09U +#define AD_STANDARD_EP_DESC_SIZE 0x09U +#define AD_STREAMING_EP_DESC_SIZE 0x07U /* audio interface class code */ -#define USB_CLASS_AUDIO 0x01U +#define USB_CLASS_AUDIO 0x01U /* audio interface subclass codes */ -#define AUDIO_SUBCLASS_CONTROL 0x01U -#define AUDIO_SUBCLASS_AUDIOSTREAMING 0x02U -#define AUDIO_SUBCLASS_MIDISTREAMING 0x03U +#define AD_SUBCLASS_CONTROL 0x01U +#define AD_SUBCLASS_AUDIOSTREAMING 0x02U +#define AD_SUBCLASS_MIDISTREAMING 0x03U /* audio interface protocol codes */ -#define AUDIO_PROTOCOL_UNDEFINED 0x00U -#define AUDIO_STREAMING_GENERAL 0x01U -#define AUDIO_STREAMING_FORMAT_TYPE 0x02U +#define AD_PROTOCOL_UNDEFINED 0x00U +#define AD_STREAMING_GENERAL 0x01U +#define AD_STREAMING_FORMAT_TYPE 0x02U /* audio class-specific descriptor types */ -#define AUDIO_DESCTYPE_UNDEFINED 0x20U -#define AUDIO_DESCTYPE_DEVICE 0x21U -#define AUDIO_DESCTYPE_CONFIGURATION 0x22U -#define AUDIO_DESCTYPE_STRING 0x23U -#define AUDIO_DESCTYPE_INTERFACE 0x24U -#define AUDIO_DESCTYPE_ENDPOINT 0x25U +#define AD_DESCTYPE_UNDEFINED 0x20U +#define AD_DESCTYPE_DEVICE 0x21U +#define AD_DESCTYPE_CONFIGURATION 0x22U +#define AD_DESCTYPE_STRING 0x23U +#define AD_DESCTYPE_INTERFACE 0x24U +#define AD_DESCTYPE_ENDPOINT 0x25U /* audio control interface descriptor subtypes */ -#define AUDIO_CONTROL_HEADER 0x01U -#define AUDIO_CONTROL_INPUT_TERMINAL 0x02U -#define AUDIO_CONTROL_OUTPUT_TERMINAL 0x03U -#define AUDIO_CONTROL_MIXER_UNIT 0x04U -#define AUDIO_CONTROL_SELECTOR_UNIT 0x05U -#define AUDIO_CONTROL_FEATURE_UNIT 0x06U -#define AUDIO_CONTROL_PROCESSING_UNIT 0x07U -#define AUDIO_CONTROL_EXTENSION_UNIT 0x08U - -#define AUDIO_INPUT_TERMINAL_DESC_SIZE 0x0CU -#define AUDIO_OUTPUT_TERMINAL_DESC_SIZE 0x09U -#define AUDIO_STREAMING_INTERFACE_DESC_SIZE 0x07U - -#define AUDIO_CONTROL_MUTE 0x0001U - -#define AUDIO_FORMAT_TYPE_I 0x01U -#define AUDIO_FORMAT_TYPE_III 0x03U - -#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01U -#define AUDIO_ENDPOINT_GENERAL 0x01U - -#define AUDIO_REQ_GET_CUR 0x81U -#define AUDIO_REQ_SET_CUR 0x01U - -#define AUDIO_OUT_STREAMING_CTRL 0x02U - -#define PACKET_SIZE(freq) (((freq) * 2U) * 2U / 1000U) - -#define AUDIO_PACKET_SIZE(frq) (uint8_t)(PACKET_SIZE(frq) & 0xFFU), \ - (uint8_t)((PACKET_SIZE(frq) >> 8U) & 0xFFU) - -#define SAMPLE_FREQ(frq) (uint8_t)(frq), (uint8_t)((frq) >> 8U), \ - (uint8_t)((frq) >> 16U) +#define AD_CONTROL_HEADER 0x01U +#define AD_CONTROL_INPUT_TERMINAL 0x02U +#define AD_CONTROL_OUTPUT_TERMINAL 0x03U +#define AD_CONTROL_MIXER_UNIT 0x04U +#define AD_CONTROL_SELECTOR_UNIT 0x05U +#define AD_CONTROL_FEATURE_UNIT 0x06U +#define AD_CONTROL_PROCESSING_UNIT 0x07U +#define AD_CONTROL_EXTENSION_UNIT 0x08U + +#define AD_INPUT_TERMINAL_DESC_SIZE 0x0CU +#define AD_OUTPUT_TERMINAL_DESC_SIZE 0x09U +#define AD_STREAMING_INTERFACE_DESC_SIZE 0x07U + +#define AD_CONTROL_MUTE 0x01U +#define AD_CONTROL_VOLUME 0x02U + +#define AD_FORMAT_TYPE_I 0x01U +#define AD_FORMAT_TYPE_III 0x03U + +#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01U +#define AD_ENDPOINT_GENERAL 0x01U + +#define AD_REQ_UNDEFINED 0x00U +#define AD_REQ_SET_CUR 0x01U +#define AD_REQ_GET_CUR 0x81U +#define AD_REQ_SET_MIN 0x02U +#define AD_REQ_GET_MIN 0x82U +#define AD_REQ_SET_MAX 0x03U +#define AD_REQ_GET_MAX 0x83U +#define AD_REQ_SET_RES 0x04U +#define AD_REQ_GET_RES 0x84U +#define AD_REQ_SET_MEM 0x05U +#define AD_REQ_GET_MEM 0x85U +#define AD_REQ_GET_STAT 0xFFU + +#define AD_OUT_STREAMING_CTRL 0x02U +#define AD_IN_STREAMING_CTRL 0x05U + +/* audio stream interface number */ +enum +{ + SPEAK_INTERFACE_COUNT, + CONFIG_DESC_AS_ITF_COUNT, +}; +#define AC_ITF_TOTAL_LEN (sizeof(usb_desc_AC_itf) + CONFIG_DESC_AS_ITF_COUNT*(sizeof(usb_desc_input_terminal) + \ + sizeof(usb_desc_mono_feature_unit) + sizeof(usb_desc_output_terminal))) #pragma pack(1) @@ -246,6 +253,12 @@ typedef struct uint8_t* isoc_out_wrptr; uint8_t* isoc_out_rdptr; + uint16_t buf_free_size; + uint16_t dam_tx_len; + + /* usb receive buffer */ + uint8_t usb_rx_buffer[SPEAKER_OUT_MAX_PACKET]; + /* main buffer for audio control requests transfers and its relative variables */ uint8_t audioctl[64]; uint8_t audioctl_unit; diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/audio/Include/audio_out_itf.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/audio/Include/audio_out_itf.h index 74835503..d325093a 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/audio/Include/audio_out_itf.h +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/audio/Include/audio_out_itf.h @@ -3,10 +3,11 @@ \brief audio OUT (playback) interface header file \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -37,38 +38,10 @@ OF SUCH DAMAGE. #include "usbd_conf.h" -/* audio commands enumeration */ -typedef enum -{ - AUDIO_CMD_PLAY = 1U, - AUDIO_CMD_PAUSE, - AUDIO_CMD_STOP, -}audio_cmd_enum; - -/* mute commands */ -#define AUDIO_MUTE 0x01U -#define AUDIO_UNMUTE 0x00U - -/* functions return value */ -#define AUDIO_OK 0x00U -#define AUDIO_FAIL 0xFFU - -/* audio machine states */ -#define AUDIO_STATE_INACTIVE 0x00U -#define AUDIO_STATE_ACTIVE 0x01U -#define AUDIO_STATE_PLAYING 0x02U -#define AUDIO_STATE_PAUSED 0x03U -#define AUDIO_STATE_STOPPED 0x04U -#define AUDIO_STATE_ERROR 0x05U - typedef struct { - uint8_t (*audio_init) (uint32_t audio_freq, uint32_t volume, uint32_t options); + uint8_t (*audio_init) (uint32_t audio_freq, uint32_t volume); uint8_t (*audio_deinit) (uint32_t options); uint8_t (*audio_cmd) (uint8_t* pbuf, uint32_t size, uint8_t cmd); - uint8_t (*audio_volume_ctl) (uint8_t vol); - uint8_t (*audio_mute_ctl) (uint8_t cmd); - uint8_t (*audio_periodic_tc) (uint8_t cmd); - uint8_t (*audio_state_get) (void); } audio_fops_struct; extern audio_fops_struct audio_out_fops; diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/audio/Source/audio_core.c b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/audio/Source/audio_core.c index e491ec27..40248076 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/audio/Source/audio_core.c +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/audio/Source/audio_core.c @@ -3,10 +3,11 @@ \brief USB audio device class core functions \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -35,20 +36,29 @@ OF SUCH DAMAGE. #include "usbd_transc.h" #include "audio_out_itf.h" #include "audio_core.h" + #include #define USBD_VID 0x28E9U #define USBD_PID 0x9574U +#define VOL_MIN 0U /* volume minimum value */ +#define VOL_MAX 100U /* volume maximum value */ +#define VOL_RES 1U /* volume resolution */ +#define VOL_0dB 70U /* 0dB is in the middle of VOL_MIN and VOL_MAX */ + /* local function prototypes ('static') */ -static uint8_t usbd_audio_sof (usb_dev *udev); +static uint8_t audio_sof (usb_dev *udev); static uint8_t audio_init (usb_dev *udev, uint8_t config_index); static uint8_t audio_deinit (usb_dev *udev, uint8_t config_index); static uint8_t audio_req_handler (usb_dev *udev, usb_req *req); static uint8_t audio_ctlx_out (usb_dev *udev); static void audio_data_out (usb_dev *udev, uint8_t ep_num); -usb_class audio_class = { +static void audio_set_itf (usb_dev *udev, usb_req *req); + +usb_class audio_class = +{ .init = audio_init, .deinit = audio_deinit, .req_process = audio_req_handler, @@ -58,7 +68,7 @@ usb_class audio_class = { usbd_int_cb_struct usb_inthandler = { - usbd_audio_sof, + audio_sof, }; /* note:it should use the c99 standard when compiling the below codes */ @@ -94,8 +104,8 @@ usb_desc_config_set audio_config_set = .bLength = sizeof(usb_desc_config), .bDescriptorType = USB_DESCTYPE_CONFIG }, - .wTotalLength = AUDIO_CONFIG_DESC_SET_LEN, - .bNumInterfaces = 0x02U, + .wTotalLength = AD_CONFIG_DESC_SET_LEN, + .bNumInterfaces = 0x01U + CONFIG_DESC_AS_ITF_COUNT, .bConfigurationValue = 0x01U, .iConfiguration = 0x00U, .bmAttributes = 0xC0U, @@ -113,8 +123,8 @@ usb_desc_config_set audio_config_set = .bAlternateSetting = 0x00U, .bNumEndpoints = 0x00U, .bInterfaceClass = USB_CLASS_AUDIO, - .bInterfaceSubClass = AUDIO_SUBCLASS_CONTROL, - .bInterfaceProtocol = AUDIO_PROTOCOL_UNDEFINED, + .bInterfaceSubClass = AD_SUBCLASS_CONTROL, + .bInterfaceProtocol = AD_PROTOCOL_UNDEFINED, .iInterface = 0x00U }, @@ -123,12 +133,12 @@ usb_desc_config_set audio_config_set = .header = { .bLength = sizeof(usb_desc_AC_itf), - .bDescriptorType = AUDIO_DESCTYPE_INTERFACE + .bDescriptorType = AD_DESCTYPE_INTERFACE }, .bDescriptorSubtype = 0x01U, .bcdADC = 0x0100U, - .wTotalLength = 0x0027U, - .bInCollection = 0x01U, + .wTotalLength = AC_ITF_TOTAL_LEN, + .bInCollection = CONFIG_DESC_AS_ITF_COUNT, .baInterfaceNr = 0x01U }, @@ -137,13 +147,13 @@ usb_desc_config_set audio_config_set = .header = { .bLength = sizeof(usb_desc_input_terminal), - .bDescriptorType = AUDIO_DESCTYPE_INTERFACE + .bDescriptorType = AD_DESCTYPE_INTERFACE }, - .bDescriptorSubtype = 0x02U, + .bDescriptorSubtype = AD_CONTROL_INPUT_TERMINAL, .bTerminalID = 0x01U, .wTerminalType = 0x0101U, .bAssocTerminal = 0x00U, - .bNrChannels = 0x01U, + .bNrChannels = 0x02U, .wChannelConfig = 0x0000U, .iChannelNames = 0x00U, .iTerminal = 0x00U @@ -154,13 +164,13 @@ usb_desc_config_set audio_config_set = .header = { .bLength = sizeof(usb_desc_mono_feature_unit), - .bDescriptorType = AUDIO_DESCTYPE_INTERFACE + .bDescriptorType = AD_DESCTYPE_INTERFACE }, - .bDescriptorSubtype = AUDIO_CONTROL_FEATURE_UNIT, - .bUnitID = AUDIO_OUT_STREAMING_CTRL, + .bDescriptorSubtype = AD_CONTROL_FEATURE_UNIT, + .bUnitID = AD_OUT_STREAMING_CTRL, .bSourceID = 0x01U, .bControlSize = 0x01U, - .bmaControls0 = AUDIO_CONTROL_MUTE, + .bmaControls0 = AD_CONTROL_MUTE | AD_CONTROL_VOLUME, .bmaControls1 = 0x00U, .iFeature = 0x00U }, @@ -170,9 +180,9 @@ usb_desc_config_set audio_config_set = .header = { .bLength = sizeof(usb_desc_output_terminal), - .bDescriptorType = AUDIO_DESCTYPE_INTERFACE + .bDescriptorType = AD_DESCTYPE_INTERFACE }, - .bDescriptorSubtype = AUDIO_CONTROL_OUTPUT_TERMINAL, + .bDescriptorSubtype = AD_CONTROL_OUTPUT_TERMINAL, .bTerminalID = 0x03U, .wTerminalType = 0x0301U, .bAssocTerminal = 0x00U, @@ -191,8 +201,8 @@ usb_desc_config_set audio_config_set = .bAlternateSetting = 0x00U, .bNumEndpoints = 0x00U, .bInterfaceClass = USB_CLASS_AUDIO, - .bInterfaceSubClass = AUDIO_SUBCLASS_AUDIOSTREAMING, - .bInterfaceProtocol = AUDIO_PROTOCOL_UNDEFINED, + .bInterfaceSubClass = AD_SUBCLASS_AUDIOSTREAMING, + .bInterfaceProtocol = AD_PROTOCOL_UNDEFINED, .iInterface = 0x00U }, @@ -207,8 +217,8 @@ usb_desc_config_set audio_config_set = .bAlternateSetting = 0x01U, .bNumEndpoints = 0x01U, .bInterfaceClass = USB_CLASS_AUDIO, - .bInterfaceSubClass = AUDIO_SUBCLASS_AUDIOSTREAMING, - .bInterfaceProtocol = AUDIO_PROTOCOL_UNDEFINED, + .bInterfaceSubClass = AD_SUBCLASS_AUDIOSTREAMING, + .bInterfaceProtocol = AD_PROTOCOL_UNDEFINED, .iInterface = 0x00U }, @@ -217,9 +227,9 @@ usb_desc_config_set audio_config_set = .header = { .bLength = sizeof(usb_desc_AS_itf), - .bDescriptorType = AUDIO_DESCTYPE_INTERFACE + .bDescriptorType = AD_DESCTYPE_INTERFACE }, - .bDescriptorSubtype = AUDIO_STREAMING_GENERAL, + .bDescriptorSubtype = AD_STREAMING_GENERAL, .bTerminalLink = 0x01U, .bDelay = 0x01U, .wFormatTag = 0x0001U, @@ -230,17 +240,17 @@ usb_desc_config_set audio_config_set = .header = { .bLength = sizeof(usb_desc_format_type), - .bDescriptorType = AUDIO_DESCTYPE_INTERFACE + .bDescriptorType = AD_DESCTYPE_INTERFACE }, - .bDescriptorSubtype = AUDIO_STREAMING_FORMAT_TYPE, - .bFormatType = AUDIO_FORMAT_TYPE_III, - .bNrChannels = 0x02U, + .bDescriptorSubtype = AD_STREAMING_FORMAT_TYPE, + .bFormatType = AD_FORMAT_TYPE_III, + .bNrChannels = SPEAKER_OUT_CHANNEL_NBR, .bSubFrameSize = 0x02U, - .bBitResolution = 0x10U, + .bBitResolution = SPEAKER_OUT_BIT_RESOLUTION, .bSamFreqType = 0x01U, - .bSamFreq[0] = (uint8_t)USBD_AUDIO_FREQ_16K, - .bSamFreq[1] = USBD_AUDIO_FREQ_16K >> 8, - .bSamFreq[2] = USBD_AUDIO_FREQ_16K >> 16 + .bSamFreq[0] = (uint8_t)USBD_SPEAKER_FREQ, + .bSamFreq[1] = USBD_SPEAKER_FREQ >> 8, + .bSamFreq[2] = USBD_SPEAKER_FREQ >> 16 }, .std_endpoint = @@ -250,9 +260,9 @@ usb_desc_config_set audio_config_set = .bLength = sizeof(usb_desc_std_ep), .bDescriptorType = USB_DESCTYPE_EP }, - .bEndpointAddress = AUDIO_OUT_EP, + .bEndpointAddress = AD_OUT_EP, .bmAttributes = USB_ENDPOINT_TYPE_ISOCHRONOUS, - .wMaxPacketSize = PACKET_SIZE(USBD_AUDIO_FREQ_16K), + .wMaxPacketSize = SPEAKER_OUT_PACKET, .bInterval = 0x01U, .bRefresh = 0x00U, .bSynchAddress = 0x00U @@ -263,9 +273,9 @@ usb_desc_config_set audio_config_set = .header = { .bLength = sizeof(usb_desc_AS_ep), - .bDescriptorType = AUDIO_DESCTYPE_ENDPOINT + .bDescriptorType = AD_DESCTYPE_ENDPOINT }, - .bDescriptorSubtype = AUDIO_ENDPOINT_GENERAL, + .bDescriptorSubtype = AD_ENDPOINT_GENERAL, .bmAttributes = 0x00U, .bLockDelayUnits = 0x00U, .wLockDelay = 0x0000U, @@ -331,7 +341,6 @@ usb_desc audio_desc = { .strings = usbd_audio_strings }; - /*! \brief initialize the audio device \param[in] udev: pointer to USB device instance @@ -356,7 +365,7 @@ static uint8_t audio_init (usb_dev *udev, uint8_t config_index) }; /* initialize RX endpoint */ - usbd_ep_init(udev, EP_BUF_DBL, AUDIO_BUF_ADDR, &ep); + usbd_ep_init(udev, EP_BUF_DBL, AD_BUF_ADDR, &ep); usbd_int_fops = &usb_inthandler; @@ -364,16 +373,16 @@ static uint8_t audio_init (usb_dev *udev, uint8_t config_index) audio_handler.isoc_out_wrptr = audio_handler.isoc_out_buff; /* initialize the audio output hardware layer */ - if (USBD_OK != audio_out_fops.audio_init(USBD_AUDIO_FREQ_16K, DEFAULT_VOLUME, 0U)) { + if (USBD_OK != audio_out_fops.audio_init(USBD_SPEAKER_FREQ, DEFAULT_VOLUME)) { return USBD_FAIL; } - udev->ep_transc[AUDIO_OUT_EP][TRANSC_OUT] = audio_class.data_out; + udev->ep_transc[AD_OUT_EP][TRANSC_OUT] = audio_class.data_out; /* prepare out endpoint to receive audio data */ - usbd_ep_recev (udev, AUDIO_OUT_EP, (uint8_t*)audio_handler.isoc_out_buff, (uint16_t)AUDIO_OUT_PACKET); + usbd_ep_recev (udev, AD_OUT_EP, (uint8_t*)audio_handler.usb_rx_buffer, SPEAKER_OUT_MAX_PACKET); - udev->class_data[USBD_AUDIO_INTERFACE] = (void *)&audio_handler; + udev->class_data[USBD_AD_INTERFACE] = (void *)&audio_handler; return USBD_OK; } @@ -388,7 +397,7 @@ static uint8_t audio_init (usb_dev *udev, uint8_t config_index) static uint8_t audio_deinit (usb_dev *udev, uint8_t config_index) { /* deinitialize audio endpoints */ - usbd_ep_deinit(udev, AUDIO_OUT_EP); + usbd_ep_deinit(udev, AD_OUT_EP); /* deinitialize the audio output hardware layer */ if (USBD_OK != audio_out_fops.audio_deinit(0U)) { @@ -409,20 +418,24 @@ static uint8_t audio_req_handler (usb_dev *udev, usb_req *req) { uint8_t status = REQ_NOTSUPP; - usbd_audio_handler *audio = (usbd_audio_handler *)udev->class_data[USBD_AUDIO_INTERFACE]; + usbd_audio_handler *audio = (usbd_audio_handler *)udev->class_data[USBD_AD_INTERFACE]; switch (req->bRequest) { - case AUDIO_REQ_GET_CUR: + case USB_SET_INTERFACE: + audio_set_itf(udev, req); + break; + + case AD_REQ_GET_CUR: usb_transc_config(&udev->transc_in[0], audio->audioctl, req->wLength, 0U); status = REQ_SUPP; break; - case AUDIO_REQ_SET_CUR: + case AD_REQ_SET_CUR: if (req->wLength) { usb_transc_config(&udev->transc_out[0], audio->audioctl, req->wLength, 0U); - udev->class_core->req_cmd = AUDIO_REQ_SET_CUR; + udev->class_core->req_cmd = AD_REQ_SET_CUR; audio->audioctl_len = req->wLength; audio->audioctl_unit = BYTE_HIGH(req->wIndex); @@ -431,6 +444,27 @@ static uint8_t audio_req_handler (usb_dev *udev, usb_req *req) } break; + case AD_REQ_GET_MIN: + audio->audioctl[0] = VOL_MIN; + usb_transc_config(&udev->transc_in[0], audio->audioctl, req->wLength, 0U); + + status = REQ_SUPP; + break; + + case AD_REQ_GET_MAX: + audio->audioctl[0] = VOL_MAX; + usb_transc_config(&udev->transc_in[0], audio->audioctl, req->wLength, 0U); + + status = REQ_SUPP; + break; + + case AD_REQ_GET_RES: + audio->audioctl[0] = VOL_RES; + usb_transc_config(&udev->transc_in[0], audio->audioctl, req->wLength, 0U); + + status = REQ_SUPP; + break; + default: break; } @@ -438,6 +472,36 @@ static uint8_t audio_req_handler (usb_dev *udev, usb_req *req) return status; } +/*! + \brief handle the audio set interface requests + \param[in] udev: pointer to USB device instance + \param[in] req: device class-specific request + \param[out] none + \retval USB device operation status +*/ +static void audio_set_itf(usb_dev *udev, usb_req *req) +{ + usbd_audio_handler *audio = (usbd_audio_handler *)udev->class_data[USBD_AD_INTERFACE]; + + if (0xFF != req->wValue){ + if (0 != req->wValue){ + /* deinit audio handler */ + memset((void *)audio, 0, sizeof(usbd_audio_handler)); + + audio->play_flag = 0; + audio->isoc_out_rdptr = audio->isoc_out_buff; + audio->isoc_out_wrptr = audio->isoc_out_buff; + } else { + /* stop audio output */ + audio_out_fops.audio_cmd(audio->isoc_out_rdptr, SPEAKER_OUT_PACKET / 2, AD_CMD_STOP); + + audio->play_flag = 0; + audio->isoc_out_rdptr = audio->isoc_out_buff; + audio->isoc_out_wrptr = audio->isoc_out_buff; + } + } +} + /*! \brief handles the audio out data stage \param[in] udev: pointer to USB device instance @@ -447,25 +511,74 @@ static uint8_t audio_req_handler (usb_dev *udev, usb_req *req) */ static void audio_data_out (usb_dev *udev, uint8_t ep_num) { - usbd_audio_handler *audio = (usbd_audio_handler *)udev->class_data[USBD_AUDIO_INTERFACE]; + usbd_audio_handler *audio = (usbd_audio_handler *)udev->class_data[USBD_AD_INTERFACE]; - if (AUDIO_OUT_EP == ep_num) { - /* increment the Buffer pointer or roll it back when all buffers are full */ - if (audio->isoc_out_wrptr >= (audio->isoc_out_buff + (AUDIO_OUT_PACKET * OUT_PACKET_NUM))) { - /* all buffers are full: roll back */ - audio->isoc_out_wrptr = audio->isoc_out_buff; + if (AD_OUT_EP == ep_num) { + uint16_t usb_rx_length, tail_len; + + /* get receive length */ + usb_rx_length = udev->transc_out[ep_num].xfer_count; + + if (audio->isoc_out_wrptr >= audio->isoc_out_rdptr) { + audio->buf_free_size = TOTAL_OUT_BUF_SIZE + audio->isoc_out_rdptr - audio->isoc_out_wrptr; } else { - /* increment the buffer pointer */ - audio->isoc_out_wrptr += AUDIO_OUT_PACKET; + audio->buf_free_size = audio->isoc_out_rdptr - audio->isoc_out_wrptr; + } + + /* free buffer enough to save rx data */ + if (audio->buf_free_size > usb_rx_length) { + if (audio->isoc_out_wrptr >= audio->isoc_out_rdptr) { + tail_len = audio->isoc_out_buff + TOTAL_OUT_BUF_SIZE - audio->isoc_out_wrptr; + + if(tail_len >= usb_rx_length){ + memcpy(audio->isoc_out_wrptr, audio->usb_rx_buffer, usb_rx_length); + + /* increment the buffer pointer */ + audio->isoc_out_wrptr += usb_rx_length; + + /* increment the Buffer pointer or roll it back when all buffers are full */ + if (audio->isoc_out_wrptr >= (audio->isoc_out_buff + TOTAL_OUT_BUF_SIZE)) { + /* all buffers are full: roll back */ + audio->isoc_out_wrptr = audio->isoc_out_buff; + } + } else { + memcpy(audio->isoc_out_wrptr, audio->usb_rx_buffer, tail_len); + + /* adjust write pointer */ + audio->isoc_out_wrptr = audio->isoc_out_buff; + + memcpy(audio->isoc_out_wrptr, &audio->usb_rx_buffer[tail_len], usb_rx_length - tail_len); + + /* adjust write pointer */ + audio->isoc_out_wrptr += usb_rx_length - tail_len; + } + } else { + memcpy(audio->isoc_out_wrptr, audio->usb_rx_buffer, usb_rx_length); + + /* increment the buffer pointer */ + audio->isoc_out_wrptr += usb_rx_length; + } } /* prepare out endpoint to receive next audio packet */ - usbd_ep_recev (udev, AUDIO_OUT_EP, (uint8_t*)(audio->isoc_out_wrptr), (uint16_t)AUDIO_OUT_PACKET); + usbd_ep_recev (udev, AD_OUT_EP, audio->usb_rx_buffer, SPEAKER_OUT_MAX_PACKET); - /* trigger the start of streaming only when half buffer is full */ - if ((0U == audio->play_flag) && (audio->isoc_out_wrptr >= (audio->isoc_out_buff + ((AUDIO_OUT_PACKET * OUT_PACKET_NUM) / 2U)))) { + if (audio->isoc_out_wrptr >= audio->isoc_out_rdptr) { + audio->buf_free_size = TOTAL_OUT_BUF_SIZE + audio->isoc_out_rdptr - audio->isoc_out_wrptr; + } else { + audio->buf_free_size = audio->isoc_out_rdptr - audio->isoc_out_wrptr; + } + + if ((0U == audio->play_flag) && (audio->buf_free_size < TOTAL_OUT_BUF_SIZE / 2)) { /* enable start of streaming */ audio->play_flag = 1U; + + /* initialize the audio output hardware layer */ + if (USBD_OK != audio_out_fops.audio_cmd(audio->isoc_out_rdptr, SPEAKER_OUT_MAX_PACKET / 2, AD_CMD_PLAY)) { + return; + } + + audio->dam_tx_len = SPEAKER_OUT_MAX_PACKET; } } } @@ -478,19 +591,16 @@ static void audio_data_out (usb_dev *udev, uint8_t ep_num) */ static uint8_t audio_ctlx_out (usb_dev *udev) { - usbd_audio_handler *audio = (usbd_audio_handler *)udev->class_data[USBD_AUDIO_INTERFACE]; + usbd_audio_handler *audio = (usbd_audio_handler *)udev->class_data[USBD_AD_INTERFACE]; /* check if an audio_control request has been issued */ - if (AUDIO_REQ_SET_CUR == udev->class_core->req_cmd) { + if (AD_REQ_SET_CUR == udev->class_core->req_cmd) { /* in this driver, to simplify code, only SET_CUR request is managed */ /* check for which addressed unit the audio_control request has been issued */ - if (AUDIO_OUT_STREAMING_CTRL == audio->audioctl_unit) { + if (AD_OUT_STREAMING_CTRL == audio->audioctl_unit) { /* in this driver, to simplify code, only one unit is manage */ - /* call the audio interface mute function */ - audio_out_fops.audio_mute_ctl(audio->audioctl[0]); - /* reset the audioctl_cmd variable to prevent re-entering this function */ udev->class_core->req_cmd = 0U; @@ -507,43 +617,7 @@ static uint8_t audio_ctlx_out (usb_dev *udev) \param[out] none \retval USB device operation status */ -static uint8_t usbd_audio_sof (usb_dev *udev) +static uint8_t audio_sof (usb_dev *udev) { - usbd_audio_handler *audio = (usbd_audio_handler *)udev->class_data[USBD_AUDIO_INTERFACE]; - - /* check if there are available data in stream buffer. - in this function, a single variable (play_flag) is used to avoid software delays. - the play operation must be executed as soon as possible after the SOF detection. */ - if (audio->play_flag) { - /* start playing received packet */ - audio_out_fops.audio_cmd((uint8_t*)(audio->isoc_out_rdptr), /* samples buffer pointer */ - AUDIO_OUT_PACKET, /* number of samples in Bytes */ - AUDIO_CMD_PLAY); /* command to be processed */ - - /* increment the Buffer pointer or roll it back when all buffers all full */ - if (audio->isoc_out_rdptr >= (audio->isoc_out_buff + (AUDIO_OUT_PACKET * OUT_PACKET_NUM))) { - /* roll back to the start of buffer */ - audio->isoc_out_rdptr = audio->isoc_out_buff; - } else { - /* increment to the next sub-buffer */ - audio->isoc_out_rdptr += AUDIO_OUT_PACKET; - } - - /* if all available buffers have been consumed, stop playing */ - if (audio->isoc_out_rdptr == audio->isoc_out_wrptr) { - /* pause the audio stream */ - audio_out_fops.audio_cmd((uint8_t*)(audio->isoc_out_buff), /* samples buffer pointer */ - AUDIO_OUT_PACKET, /* number of samples in Bytes */ - AUDIO_CMD_PAUSE); /* command to be processed */ - - /* stop entering play loop */ - audio->play_flag = 0U; - - /* reset buffer pointers */ - audio->isoc_out_rdptr = audio->isoc_out_buff; - audio->isoc_out_wrptr = audio->isoc_out_buff; - } - } - return USBD_OK; } diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/audio/Source/audio_out_itf.c b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/audio/Source/audio_out_itf.c index 1bb07e82..4604a675 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/audio/Source/audio_out_itf.c +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/audio/Source/audio_out_itf.c @@ -3,10 +3,11 @@ \brief audio OUT (playback) interface functions \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -36,70 +37,63 @@ OF SUCH DAMAGE. #include "audio_out_itf.h" /* local function prototypes ('static') */ -static uint8_t init (uint32_t audio_freq, uint32_t volume, uint32_t options); +static uint8_t init (uint32_t audio_freq, uint32_t volume); static uint8_t deinit (uint32_t options); static uint8_t audio_cmd (uint8_t* pbuf, uint32_t size, uint8_t cmd); -static uint8_t volume_ctl (uint8_t vol); -static uint8_t mute_ctl (uint8_t cmd); -static uint8_t periodic_tc (uint8_t cmd); -static uint8_t get_state (void); audio_fops_struct audio_out_fops = { - init, - deinit, - audio_cmd, - volume_ctl, - mute_ctl, - periodic_tc, - get_state + .audio_init = init, + .audio_deinit = deinit, + .audio_cmd = audio_cmd, }; -static uint8_t audio_state = AUDIO_STATE_INACTIVE; +static uint8_t audio_state = AD_STATE_INACTIVE; /*! \brief initialize and configures all required resources for audio play function \param[in] audio_freq: statrt_up audio frequency \param[in] volume: start_up volume to be set - \param[in] options: specific options passed to low layer function \param[out] none - \retval AUDIO_OK if all operations succeed, otherwise, AUDIO_FAIL. + \retval AD_OK if all operations succeed, otherwise, AD_FAIL. */ -static uint8_t init (uint32_t audio_freq, uint32_t volume, uint32_t options) +static uint8_t init (uint32_t audio_freq, uint32_t volume) { static uint32_t initialized = 0U; /* check if the low layer has already been initialized */ if (0U == initialized) { - /* call low layer function */ - if (0U != eval_audio_init(OUTPUT_DEVICE_AUTO, volume, audio_freq)) { - audio_state = AUDIO_STATE_ERROR; + /* initialize GPIO */ + codec_gpio_init(); - return AUDIO_FAIL; - } + /* initialize i2s */ + codec_audio_interface_init(audio_freq); + + /* initialize DMA */ + codec_i2s_dma_init(); /* set the initialization flag to prevent reinitializing the interface again */ initialized = 1U; } /* update the audio state machine */ - audio_state = AUDIO_STATE_ACTIVE; + audio_state = AD_STATE_ACTIVE; - return AUDIO_OK; + return AD_OK; } /*! \brief free all resources used by low layer and stops audio-play function \param[in] options: specific options passed to low layer function \param[out] none - \retval AUDIO_OK if all operations succeed, otherwise, AUDIO_FAIL. + \retval AD_OK if all operations succeed, otherwise, AD_FAIL. */ static uint8_t deinit (uint32_t options) { /* update the audio state machine */ - audio_state = AUDIO_STATE_INACTIVE; + audio_state = AD_STATE_INACTIVE; - return AUDIO_OK; + return AD_OK; } /*! @@ -107,136 +101,70 @@ static uint8_t deinit (uint32_t options) \param[in] pbuf: address from which file should be played \param[in] size: size of the current buffer/file \param[in] cmd: command to be executed, can be: - \arg AUDIO_CMD_PLAY - \arg AUDIO_CMD_PAUSE - \arg AUDIO_CMD_RESUME - \arg AUDIO_CMD_STOP + \arg AD_CMD_PLAY + \arg AD_CMD_PAUSE + \arg AD_CMD_RESUME + \arg AD_CMD_STOP \param[out] none - \retval AUDIO_OK if all operations succeed, otherwise, AUDIO_FAIL. + \retval AD_OK if all operations succeed, otherwise, AD_FAIL. */ static uint8_t audio_cmd (uint8_t* pbuf, uint32_t size, uint8_t cmd) { - uint8_t status = AUDIO_OK; - /* check the current state */ - if ((AUDIO_STATE_INACTIVE == audio_state) || (AUDIO_STATE_ERROR == audio_state)) { - audio_state = AUDIO_STATE_ERROR; + if ((AD_STATE_INACTIVE == audio_state) || (AD_STATE_ERROR == audio_state)) { + audio_state = AD_STATE_ERROR; - return AUDIO_FAIL; + return AD_FAIL; } switch (cmd) { - /* process the play command */ - case AUDIO_CMD_PLAY: - /* if current state is active or stopped */ - if ((AUDIO_STATE_ACTIVE == audio_state) || \ - (AUDIO_STATE_STOPPED == audio_state) || \ - (AUDIO_STATE_PLAYING == audio_state)) { - audio_mal_play((uint32_t)pbuf, (size / 2U)); - audio_state = AUDIO_STATE_PLAYING; - } else if (AUDIO_STATE_PAUSED == audio_state) { - if (eval_audio_pause_resume(AUDIO_RESUME, (uint32_t)pbuf, (size / 2U))) { - audio_state = AUDIO_STATE_ERROR; - - status = AUDIO_FAIL; - } else { - audio_state = AUDIO_STATE_PLAYING; - } - } else { - status = AUDIO_FAIL; - } - break; - - /* process the stop command */ - case AUDIO_CMD_STOP: - if (AUDIO_STATE_PLAYING != audio_state) { - /* unsupported command */ - status = AUDIO_FAIL; - } else if (eval_audio_stop(CODEC_PDWN_SW)) { - audio_state = AUDIO_STATE_ERROR; - - status = AUDIO_FAIL; - } else { - audio_state = AUDIO_STATE_STOPPED; - } - break; - - /* process the pause command */ - case AUDIO_CMD_PAUSE: - if (AUDIO_STATE_PLAYING != audio_state) { - /* unsupported command */ - status = AUDIO_FAIL; - } else if (eval_audio_pause_resume(AUDIO_PAUSE, (uint32_t)pbuf, (size / 2U))) { - audio_state = AUDIO_STATE_ERROR; - - status = AUDIO_FAIL; - } else { - audio_state = AUDIO_STATE_PAUSED; - } - break; - - /* unsupported command */ - default: - break; - } - - return status; -} + /* process the play command */ + case AD_CMD_PLAY: + /* if current state is active or stopped */ + if ((AD_STATE_ACTIVE == audio_state) || \ + (AD_STATE_STOPPED == audio_state) || \ + (AD_STATE_PLAYING == audio_state)) { + audio_play((uint32_t)pbuf, size); + audio_state = AD_STATE_PLAYING; + + return AD_OK; + } else if (AD_STATE_PAUSED == audio_state) { + audio_pause_resume(AD_RESUME, (uint32_t)pbuf, (size/2)); + audio_state = AD_STATE_PLAYING; + + return AD_OK; + } else { + return AD_FAIL; + } -/*! - \brief set the volume level - \param[in] vol: volume level to be set in % (from 0% to 100%) - \param[out] none - \retval AUDIO_OK if all operations succeed, otherwise, AUDIO_FAIL. -*/ -static uint8_t volume_ctl (uint8_t vol) -{ - /* call low layer volume setting function */ - if (eval_audio_volume_ctl(vol)) { - audio_state = AUDIO_STATE_ERROR; + /* process the stop command */ + case AD_CMD_STOP: + if (AD_STATE_PLAYING != audio_state) { + /* unsupported command */ + return AD_FAIL; + } else { + audio_stop(); + audio_state = AD_STATE_STOPPED; - return AUDIO_FAIL; - } + return AD_OK; + } - return AUDIO_OK; -} + /* process the pause command */ + case AD_CMD_PAUSE: + if (AD_STATE_PLAYING != audio_state) { + /* unsupported command */ + return AD_FAIL; + } else { + audio_pause_resume(AD_PAUSE, (uint32_t)pbuf, (size/2)); + audio_state = AD_STATE_PAUSED; -/*! - \brief mute or unmute the audio current output - \param[in] cmd: can be 0 to unmute, or 1 to mute - \param[out] none - \retval AUDIO_OK if all operations succeed, otherwise, AUDIO_FAIL. -*/ -static uint8_t mute_ctl (uint8_t cmd) -{ - /* call low layer mute setting function */ - if (eval_audio_mute((uint32_t)cmd)) { - audio_state = AUDIO_STATE_ERROR; + return AD_OK; + } - return AUDIO_FAIL; + /* unsupported command */ + default: + break; } - return AUDIO_OK; -} - -/*! - \brief periodic transfer control - \param[in] cmd: command - \param[out] none - \retval AUDIO_OK if all operations succeed, otherwise, AUDIO_FAIL. -*/ -static uint8_t periodic_tc (uint8_t cmd) -{ - return AUDIO_OK; -} - -/*! - \brief return the current state of the audio machine - \param[in] none - \param[out] none - \retval AUDIO_OK if all operations succeed, otherwise, AUDIO_FAIL. -*/ -static uint8_t get_state (void) -{ - return audio_state; + return AD_FAIL; } diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/cdc/Include/cdc_acm_core.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/cdc/Include/cdc_acm_core.h index d5576d2b..2ac1e6fb 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/cdc/Include/cdc_acm_core.h +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/cdc/Include/cdc_acm_core.h @@ -3,10 +3,11 @@ \brief the header file of cdc acm driver \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/cdc/Source/cdc_acm_core.c b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/cdc/Source/cdc_acm_core.c index 9d3fb187..bed08823 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/cdc/Source/cdc_acm_core.c +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/cdc/Source/cdc_acm_core.c @@ -3,10 +3,11 @@ \brief CDC ACM driver \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -278,7 +279,7 @@ usb_class cdc_class = { \brief receive CDC ACM data \param[in] udev: pointer to USB device instance \param[out] none - \retval USB device operation status + \retval none */ void cdc_acm_data_receive(usb_dev *udev) { @@ -294,7 +295,7 @@ void cdc_acm_data_receive(usb_dev *udev) \brief send CDC ACM data \param[in] udev: pointer to USB device instance \param[out] none - \retval USB device operation status + \retval none */ void cdc_acm_data_send (usb_dev *udev) { @@ -367,7 +368,7 @@ static uint8_t cdc_acm_init (usb_dev *udev, uint8_t config_index) } /*! - \brief de-initialize the CDC ACM device + \brief deinitialize the CDC ACM device \param[in] udev: pointer to USB device instance \param[in] config_index: configuration index \param[out] none @@ -405,13 +406,12 @@ static uint8_t cdc_acm_ctlx_out (usb_dev *udev) return USBD_OK; } - /*! \brief handle CDC ACM data in transaction \param[in] udev: pointer to USB device instance \param[in] ep_num: endpoint number \param[out] none - \retval USB device operation status + \retval none */ static void cdc_acm_data_in (usb_dev *udev, uint8_t ep_num) { @@ -431,7 +431,7 @@ static void cdc_acm_data_in (usb_dev *udev, uint8_t ep_num) \param[in] udev: pointer to USB device instance \param[in] ep_num: endpoint number \param[out] none - \retval USB device operation status + \retval none */ static void cdc_acm_data_out (usb_dev *udev, uint8_t ep_num) { diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/dfu/Include/dfu_core.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/dfu/Include/dfu_core.h index 113259cd..b157043b 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/dfu/Include/dfu_core.h +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/dfu/Include/dfu_core.h @@ -3,10 +3,11 @@ \brief the header file of USB DFU device class core functions \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -85,7 +86,8 @@ OF SUCH DAMAGE. #define DFU_DESC_TYPE 0x21U /* DFU device state enumeration */ -typedef enum { +typedef enum +{ STATE_APP_IDLE = 0x00U, STATE_APP_DETACH, STATE_DFU_IDLE, @@ -100,7 +102,8 @@ typedef enum { } dfu_state; /* DFU device status enumeration */ -typedef enum { +typedef enum +{ STATUS_OK = 0x00U, STATUS_ERR_TARGET, STATUS_ERR_FILE, @@ -120,7 +123,8 @@ typedef enum { } dfu_status; /* DFU class-specific requests enumeration */ -typedef enum { +typedef enum +{ DFU_DETACH = 0U, DFU_DNLOAD, DFU_UPLOAD, @@ -149,7 +153,9 @@ typedef struct typedef struct { usb_desc_config config; - usb_desc_itf dfu_itf; + usb_desc_itf dfu_itf0; + usb_desc_itf dfu_itf1; + usb_desc_itf dfu_itf2; usb_desc_dfu_func dfu_func; } usb_dfu_desc_config_set; @@ -164,7 +170,7 @@ typedef struct uint8_t iString; uint8_t manifest_state; - uint16_t data_len; + uint32_t data_len; uint16_t block_num; uint32_t base_addr; diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/dfu/Include/dfu_mem.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/dfu/Include/dfu_mem.h new file mode 100644 index 00000000..41403852 --- /dev/null +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/dfu/Include/dfu_mem.h @@ -0,0 +1,84 @@ +/*! + \file dfu_mem.h + \brief USB DFU device media access layer header file + + \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __DFU_MEM_H +#define __DFU_MEM_H + +#include "usbd_conf.h" + +typedef struct _dfu_mem_prop +{ + const uint8_t* pstr_desc; + + uint8_t (*mem_init) (void); + uint8_t (*mem_deinit) (void); + uint8_t (*mem_erase) (uint32_t addr); + uint8_t (*mem_write) (uint8_t *buf, uint32_t addr, uint32_t len); + uint8_t* (*mem_read) (uint8_t *buf, uint32_t addr, uint32_t len); + uint8_t (*mem_checkaddr) (uint32_t addr); + + const uint32_t erase_timeout; + const uint32_t write_timeout; +} dfu_mem_prop; + +typedef enum +{ + MEM_OK = 0, + MEM_FAIL +} mem_status; + +#define _1ST_BYTE(x) (uint8_t)((x) & 0xFF) /*!< addressing cycle 1st byte */ +#define _2ND_BYTE(x) (uint8_t)(((x) & 0xFF00) >> 8) /*!< addressing cycle 2nd byte */ +#define _3RD_BYTE(x) (uint8_t)(((x) & 0xFF0000) >> 16) /*!< addressing cycle 3rd byte */ + +#define POLLING_TIMEOUT_SET(x) buffer[0] = _1ST_BYTE(x);\ + buffer[1] = _2ND_BYTE(x);\ + buffer[2] = _3RD_BYTE(x); + +/* function declarations */ +/* initialize the memory media on the GD32 */ +uint8_t dfu_mem_init(void); +/* deinitialize the memory media on the GD32 */ +uint8_t dfu_mem_deinit(void); +/* erase a memory sector */ +uint8_t dfu_mem_erase(uint32_t addr); +/* write data to sectors of memory */ +uint8_t dfu_mem_write(uint8_t *buf, uint32_t addr, uint32_t len); +/* read data from sectors of memory */ +uint8_t* dfu_mem_read(uint8_t *buf, uint32_t addr, uint32_t len); +/* get the status of a given memory and store in buffer */ +uint8_t dfu_mem_getstatus(uint32_t addr, uint8_t cmd, uint8_t *buffer); + +#endif /* __DFU_MEM_H */ diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/dfu/Source/dfu_core.c b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/dfu/Source/dfu_core.c index 21f95762..69afa5e2 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/dfu/Source/dfu_core.c +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/dfu/Source/dfu_core.c @@ -3,10 +3,11 @@ \brief USB DFU device class core functions \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -34,7 +35,7 @@ OF SUCH DAMAGE. #include "dfu_core.h" #include "systick.h" - +#include "dfu_mem.h" #include #define USBD_VID 0x28E9U @@ -54,9 +55,15 @@ static void dfu_getstatus (usb_dev *udev, usb_req *req); static void dfu_clrstatus (usb_dev *udev, usb_req *req); static void dfu_getstate (usb_dev *udev, usb_req *req); static void dfu_abort (usb_dev *udev, usb_req *req); +static void string_to_unicode (uint8_t *str, uint16_t *pbuf); + static void dfu_mode_leave (usb_dev *udev); static uint8_t dfu_getstatus_complete (usb_dev *udev); +extern dfu_mem_prop dfu_inter_flash_cb; +extern dfu_mem_prop dfu_nor_flash_cb; +extern dfu_mem_prop dfu_nand_flash_cb; + static void (*dfu_request_process[])(usb_dev *udev, usb_req *req) = { [DFU_DETACH] = dfu_detach, @@ -101,7 +108,7 @@ usb_dfu_desc_config_set dfu_config_desc = .bLength = sizeof(usb_desc_config), .bDescriptorType = USB_DESCTYPE_CONFIG }, - .wTotalLength = USB_DFU_CONFIG_DESC_SIZE, + .wTotalLength = sizeof(usb_dfu_desc_config_set), .bNumInterfaces = 0x01U, .bConfigurationValue = 0x01U, .iConfiguration = 0x00U, @@ -109,7 +116,7 @@ usb_dfu_desc_config_set dfu_config_desc = .bMaxPower = 0x32U }, - .dfu_itf = + .dfu_itf0 = { .header = { @@ -122,7 +129,39 @@ usb_dfu_desc_config_set dfu_config_desc = .bInterfaceClass = USB_DFU_CLASS, .bInterfaceSubClass = USB_DFU_SUBCLASS_UPGRADE, .bInterfaceProtocol = USB_DFU_PROTOCL_DFU, - .iInterface = 0x00U + .iInterface = STR_IDX_ALT_ITF0 + }, + + .dfu_itf1 = + { + .header = + { + .bLength = sizeof(usb_desc_itf), + .bDescriptorType = USB_DESCTYPE_ITF + }, + .bInterfaceNumber = 0x00U, + .bAlternateSetting = 0x01U, + .bNumEndpoints = 0x00U, + .bInterfaceClass = USB_DFU_CLASS, + .bInterfaceSubClass = USB_DFU_SUBCLASS_UPGRADE, + .bInterfaceProtocol = USB_DFU_PROTOCL_DFU, + .iInterface = STR_IDX_ALT_ITF1 + }, + + .dfu_itf2 = + { + .header = + { + .bLength = sizeof(usb_desc_itf), + .bDescriptorType = USB_DESCTYPE_ITF + }, + .bInterfaceNumber = 0x00U, + .bAlternateSetting = 0x02U, + .bNumEndpoints = 0x00U, + .bInterfaceClass = USB_DFU_CLASS, + .bInterfaceSubClass = USB_DFU_SUBCLASS_UPGRADE, + .bInterfaceProtocol = USB_DFU_PROTOCL_DFU, + .iInterface = STR_IDX_ALT_ITF2 }, .dfu_func = @@ -135,14 +174,15 @@ usb_dfu_desc_config_set dfu_config_desc = .bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_CAN_UPLOAD | USB_DFU_WILL_DETACH, .wDetachTimeOut = 0x00FFU, .wTransferSize = TRANSFER_SIZE, - .bcdDFUVersion = 0x011AU, + .bcdDFUVersion = 0x0110U, }, }; /* USB language ID descriptor */ static usb_desc_LANGID usbd_language_id_desc = { - .header = { + .header = + { .bLength = sizeof(usb_desc_LANGID), .bDescriptorType = USB_DESCTYPE_STR }, @@ -192,15 +232,33 @@ static usb_desc_str config_string = .unicode_string = {'G', 'D', '3', '2', ' ', 'U', 'S', 'B', ' ', 'C', 'O', 'N', 'F', 'I', 'G'} }; -static usb_desc_str interface_string = +/* alternate interface 0 string */ +static usb_desc_str interface_string0 = { .header = { - .bLength = USB_STRING_LEN(15U), + .bLength = USB_STRING_LEN(2U), .bDescriptorType = USB_DESCTYPE_STR, }, - .unicode_string = {'@', 'I', 'n', 't', 'e', 'r', 'n', 'a', 'l', 'F', 'l', 'a', 's', 'h', ' ', '/', '0', 'x', '0', '8', '0', '0', - '0', '0', '0', '0', '/', '1', '6', '*', '0', '0', '1', 'K', 'a', ',', '4', '8', '*', '0', '0', '1', 'K', 'g'} +}; +/* alternate interface 1 string */ +static usb_desc_str interface_string1 = +{ + .header = + { + .bLength = USB_STRING_LEN(2U), + .bDescriptorType = USB_DESCTYPE_STR, + }, +}; + +/* alternate interface 2 string */ +static usb_desc_str interface_string2 = +{ + .header = + { + .bLength = USB_STRING_LEN(2U), + .bDescriptorType = USB_DESCTYPE_STR, + }, }; uint8_t* usbd_dfu_strings[] = @@ -210,7 +268,9 @@ uint8_t* usbd_dfu_strings[] = [STR_IDX_PRODUCT] = (uint8_t *)&product_string, [STR_IDX_SERIAL] = (uint8_t *)&serial_string, [STR_IDX_CONFIG] = (uint8_t *)&config_string, - [STR_IDX_ITF] = (uint8_t *)&interface_string + [STR_IDX_ALT_ITF0] = (uint8_t *)&interface_string0, + [STR_IDX_ALT_ITF1] = (uint8_t *)&interface_string1, + [STR_IDX_ALT_ITF2] = (uint8_t *)&interface_string2 }; usb_desc dfu_desc = { @@ -238,7 +298,7 @@ static uint8_t dfu_init (usb_dev *udev, uint8_t config_index) static usbd_dfu_handler dfu_handler; /* unlock the internal flash */ - fmc_unlock(); + dfu_mem_init(); systick_config(); @@ -251,6 +311,10 @@ static uint8_t dfu_init (usb_dev *udev, uint8_t config_index) udev->class_data[USBD_DFU_INTERFACE] = (void *)&dfu_handler; + /* create interface string */ + string_to_unicode((uint8_t *)dfu_inter_flash_cb.pstr_desc, (uint16_t *)udev->desc->strings[STR_IDX_ALT_ITF0]); + string_to_unicode((uint8_t *)dfu_nor_flash_cb.pstr_desc, (uint16_t *)udev->desc->strings[STR_IDX_ALT_ITF1]); + string_to_unicode((uint8_t *)dfu_nand_flash_cb.pstr_desc, (uint16_t *)udev->desc->strings[STR_IDX_ALT_ITF2]); return USBD_OK; } @@ -272,7 +336,7 @@ static uint8_t dfu_deinit (usb_dev *udev, uint8_t config_index) dfu->bStatus = STATUS_OK; /* lock the internal flash */ - fmc_lock(); + dfu_mem_deinit(); return USBD_OK; } @@ -334,7 +398,7 @@ static uint8_t dfu_getstatus_complete (usb_dev *udev) } else if (ERASE == dfu->buf[0]) { dfu->base_addr = *(uint32_t *)(dfu->buf + 1U); - fmc_page_erase(dfu->base_addr); + dfu_mem_erase(dfu->base_addr); } else { /* no operation */ } @@ -342,24 +406,10 @@ static uint8_t dfu_getstatus_complete (usb_dev *udev) /* no operation */ } } else if (dfu->block_num > 1U) { /* regular download command */ - /* preform the write operation */ - uint32_t idx = 0U; - /* decode the required address */ addr = (dfu->block_num - 2U) * TRANSFER_SIZE + dfu->base_addr; - if (dfu->data_len & 0x03U) { /* not an aligned data */ - for (idx = dfu->data_len; idx < ((dfu->data_len & 0xFFFCU) + 4U); idx++) { - dfu->buf[idx] = 0xFFU; - } - } - - /* data received are word multiple */ - for (idx = 0U; idx < dfu->data_len; idx += 4U) { - fmc_word_program(addr, *(uint32_t *)(dfu->buf + idx)); - - addr += 4U; - } + dfu_mem_write (dfu->buf, addr, dfu->data_len); dfu->block_num = 0U; } else { @@ -508,7 +558,10 @@ static void dfu_upload (usb_dev *udev, usb_req *req) addr = (dfu->block_num - 2U) * TRANSFER_SIZE + dfu->base_addr; /* return the physical address where data are stored */ - phy_addr = (uint8_t *)(addr); + // phy_addr = (uint8_t *)(addr); + + /* return the physical address where data are stored */ + phy_addr = dfu_mem_read (dfu->buf, addr, dfu->data_len); /* send the status data over EP0 */ transc->xfer_buf = phy_addr; @@ -648,6 +701,26 @@ static void dfu_abort (usb_dev *udev, usb_req *req) } } +/*! + \brief convert string value into unicode char + \param[in] str: pointer to plain string + \param[in] pbuf: buffer pointer to store unicode char + \param[out] none + \retval none +*/ +static void string_to_unicode (uint8_t *str, uint16_t *pbuf) +{ + uint8_t index = 0; + + if (str != NULL) { + pbuf[index++] = ((strlen((const char *)str) * 2U + 2U) & 0x00FFU) | ((USB_DESCTYPE_STR << 8U) & 0xFF00); + + while (*str != '\0') { + pbuf[index++] = *str++; + } + } +} + /*! \brief leave DFU mode and reset device to jump to user loaded code \param[in] udev: pointer to USB device instance @@ -666,7 +739,7 @@ static void dfu_mode_leave (usb_dev *udev) dfu->bState = STATE_DFU_MANIFEST_WAIT_RESET; /* lock the internal flash */ - fmc_lock(); + dfu_mem_deinit(); /* generate system reset to allow jumping to the user code */ NVIC_SystemReset(); diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/dfu/Source/dfu_mem.c b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/dfu/Source/dfu_mem.c new file mode 100644 index 00000000..62753be3 --- /dev/null +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/dfu/Source/dfu_mem.c @@ -0,0 +1,252 @@ +/*! + \file dfu_mem.c + \brief USB DFU device media access layer functions + + \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "dfu_mem.h" +#include "usbd_enum.h" +#include "usbd_transc.h" +#include "nor_flash_if.h" +#include "nand_flash_if.h" +#include "inter_flash_if.h" + +extern usb_dev usb_dfu; +extern dfu_mem_prop dfu_inter_flash_cb; +extern dfu_mem_prop dfu_nor_flash_cb; +extern dfu_mem_prop dfu_nand_flash_cb; + +extern struct { + uint8_t buf[TRANSFER_SIZE]; + uint16_t data_len; + uint16_t block_num; + uint32_t base_addr; +} prog; + +dfu_mem_prop* mem_tab[MAX_USED_MEMORY_MEDIA] = +{ + &dfu_inter_flash_cb, + &dfu_nor_flash_cb, + &dfu_nand_flash_cb, +}; + +/* The list of memory interface string descriptor pointers. This list + can be updated whenever a memory has to be added or removed */ +const uint8_t* USBD_DFU_StringDesc[MAX_USED_MEMORY_MEDIA] = +{ + (const uint8_t *)INTER_FLASH_IF_STR, + (const uint8_t *)NOR_FLASH_IF_STR, + (const uint8_t *)NAND_FLASH_IF_STR +}; + +static uint8_t dfu_mem_checkaddr (uint32_t addr); + +/*! + \brief initialize the memory media on the GD32 + \param[in] none + \param[out] none + \retval MEM_OK +*/ +uint8_t dfu_mem_init (void) +{ + uint32_t mem_index = 0U; + + /* initialize all supported memory medias */ + for (mem_index = 0U; mem_index < MAX_USED_MEMORY_MEDIA; mem_index++) { + /* check if the memory media exists */ + if (NULL != mem_tab[mem_index]->mem_init) { + mem_tab[mem_index]->mem_init(); + } + } + + return MEM_OK; +} + +/*! + \brief deinitialize the memory media on the GD32 + \param[in] none + \param[out] none + \retval MEM_OK +*/ +uint8_t dfu_mem_deinit (void) +{ + uint32_t mem_index = 0U; + + /* deinitialize all supported memory medias */ + for (mem_index = 0U; mem_index < MAX_USED_MEMORY_MEDIA; mem_index++) { + /* check if the memory media exists */ + if (NULL != mem_tab[mem_index]->mem_deinit) { + mem_tab[mem_index]->mem_deinit(); + } + } + + return MEM_OK; +} + +/*! + \brief erase a memory sector + \param[in] addr: memory sector address/code + \param[out] none + \retval MEM_OK +*/ +uint8_t dfu_mem_erase (uint32_t addr) +{ + uint32_t mem_index = dfu_mem_checkaddr(addr); + + /* check if the address is in protected area */ + if (IS_PROTECTED_AREA(addr)) { + return MEM_FAIL; + } + + if (mem_index < MAX_USED_MEMORY_MEDIA) { + /* check if the operation is supported */ + if (NULL != mem_tab[mem_index]->mem_erase) { + return mem_tab[mem_index]->mem_erase(addr); + } else { + return MEM_FAIL; + } + } else { + return MEM_FAIL; + } +} + +/*! + \brief write data to sectors of memory + \param[in] buf: the data buffer to be write + \param[in] addr: memory sector address/code + \param[in] len: data length + \param[out] none + \retval MEM_OK +*/ +uint8_t dfu_mem_write (uint8_t *buf, uint32_t addr, uint32_t len) +{ + uint32_t mem_index = dfu_mem_checkaddr(addr); + + /* check if the address is in protected area */ + if (IS_PROTECTED_AREA(addr)) { + return MEM_FAIL; + } + + if (OB_RDPT == (addr & MAL_MASK_OB)) { + option_byte_write(addr, buf); + + NVIC_SystemReset(); + + return MEM_OK; + } + + if (mem_index < MAX_USED_MEMORY_MEDIA) { + /* check if the operation is supported */ + if (NULL != mem_tab[mem_index]->mem_write) { + return mem_tab[mem_index]->mem_write(buf, addr, len); + } else { + return MEM_FAIL; + } + } else { + return MEM_FAIL; + } +} + +/*! + \brief read data from sectors of memory + \param[in] buf: the data buffer to be write + \param[in] addr: memory sector address/code + \param[in] len: data length + \param[out] none + \retval pointer to buffer +*/ +uint8_t* dfu_mem_read (uint8_t *buf, uint32_t addr, uint32_t len) +{ + uint32_t mem_index = 0U; + + if (OB_RDPT != addr) { + mem_index = dfu_mem_checkaddr(addr); + } + + if (mem_index < MAX_USED_MEMORY_MEDIA) { + /* check if the operation is supported */ + if (NULL != mem_tab[mem_index]->mem_read) { + return mem_tab[mem_index]->mem_read(buf, addr, len); + } else { + return buf; + } + } else { + return buf; + } +} + +/*! + \brief get the status of a given memory and store in buffer + \param[in] addr: memory sector address/code + \param[in] cmd: 0 for erase and 1 for write + \param[in] buffer: pointer to the buffer where the status data will be stored + \param[out] none + \retval MEM_OK if all operations are OK, MEM_FAIL else +*/ +uint8_t dfu_mem_getstatus (uint32_t addr, uint8_t cmd, uint8_t *buffer) +{ + uint32_t mem_index = dfu_mem_checkaddr(addr); + + if (mem_index < MAX_USED_MEMORY_MEDIA) { + if (cmd & 0x01U) { + POLLING_TIMEOUT_SET(mem_tab[mem_index]->write_timeout); + } else { + POLLING_TIMEOUT_SET(mem_tab[mem_index]->erase_timeout); + } + + return MEM_OK; + } else { + return MEM_FAIL; + } +} + +/*! + \brief check the address is supported + \param[in] addr: memory sector address/code + \param[out] none + \retval index of the addressed memory +*/ +static uint8_t dfu_mem_checkaddr (uint32_t addr) +{ + uint8_t mem_index = 0U; + + /* check with all supported memories */ + for (mem_index = 0U; mem_index < MAX_USED_MEMORY_MEDIA; mem_index++) { + /* if the check address is supported, return the memory index */ + if (MEM_OK == mem_tab[mem_index]->mem_checkaddr(addr)) { + return mem_index; + } + } + + /* if there is no memory found, return MAX_USED_MEMORY_MEDIA */ + return (MAX_USED_MEMORY_MEDIA); +} diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Include/custom_hid_core.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Include/custom_hid_core.h index 7f647c89..ab885174 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Include/custom_hid_core.h +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Include/custom_hid_core.h @@ -3,10 +3,11 @@ \brief definitions for HID core \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -43,7 +44,8 @@ OF SUCH DAMAGE. #define MAX_PERIPH_NUM 4U -typedef struct { +typedef struct +{ uint8_t data[2]; uint8_t reportID; diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Include/standard_hid_core.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Include/standard_hid_core.h index c3adcd4c..3c4377b1 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Include/standard_hid_core.h +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Include/standard_hid_core.h @@ -3,10 +3,11 @@ \brief definitions for HID core \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -41,7 +42,8 @@ OF SUCH DAMAGE. #define USB_HID_CONFIG_DESC_LEN 0x22U #define USB_HID_REPORT_DESC_LEN 0x2EU -typedef struct { +typedef struct +{ uint32_t protocol; uint32_t idle_state; @@ -49,7 +51,8 @@ typedef struct { __IO uint8_t prev_transfer_complete; } standard_hid_handler; -typedef struct { +typedef struct +{ void (*hid_itf_config) (void); void (*hid_itf_data_process) (usb_dev *udev); } hid_fop_handler; diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Include/std_hid_mouse_core.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Include/std_hid_mouse_core.h index 9eb2c939..676b2044 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Include/std_hid_mouse_core.h +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Include/std_hid_mouse_core.h @@ -3,10 +3,11 @@ \brief definitions for HID mouse core \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -44,7 +45,8 @@ OF SUCH DAMAGE. #define MOUSE_LEFT_BUTTON 0x01U #define MOUSE_RIGHT_BUTTON 0x02U -typedef struct { +typedef struct +{ uint32_t protocol; uint32_t idle_state; @@ -52,7 +54,8 @@ typedef struct { __IO uint8_t prev_transfer_complete; } standard_mice_handler; -typedef struct { +typedef struct +{ void (*mice_itf_config) (void); void (*mice_itf_data_process) (usb_dev *udev); } mice_fop_handler; diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Include/usb_hid.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Include/usb_hid.h index d82cf254..2b152853 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Include/usb_hid.h +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Include/usb_hid.h @@ -3,10 +3,11 @@ \brief definitions for the USB HID class \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Source/custom_hid_core.c b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Source/custom_hid_core.c index 6a20870e..9000644e 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Source/custom_hid_core.c +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Source/custom_hid_core.c @@ -3,10 +3,13 @@ \brief custom HID class driver \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2021-06-22, V3.0.1, firmware for GD32F30x + \version 2021-11-09, V3.0.2, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -62,6 +65,7 @@ usb_desc_dev custom_hid_dev_desc = .bNumberConfigurations = USBD_CFG_MAX_NUM, }; +/* USB device configure descriptor */ usb_hid_desc_config_set custom_hid_config_desc = { .config = @@ -169,7 +173,7 @@ static usb_desc_str product_string = .unicode_string = {'G', 'D', '3', '2', '-', 'C', 'u', 's', 't', 'o', 'm', 'H', 'I', 'D'} }; -/* USBD serial string */ +/* USB serial string */ static usb_desc_str serial_string = { .header = @@ -188,7 +192,8 @@ uint8_t* usbd_hid_strings[] = [STR_IDX_SERIAL] = (uint8_t *)&serial_string }; -usb_desc custom_hid_desc = { +usb_desc custom_hid_desc = +{ .dev_desc = (uint8_t *)&custom_hid_dev_desc, .config_desc = (uint8_t *)&custom_hid_config_desc, .strings = usbd_hid_strings @@ -313,7 +318,7 @@ uint8_t custom_hid_report_send (usb_dev *udev, uint8_t *report, uint16_t len) /*! \brief initialize the HID device - \param[in] pudev: pointer to USB device instance + \param[in] udev: pointer to USB device instance \param[in] config_index: configuration index \param[out] none \retval USB device operation status @@ -384,6 +389,11 @@ static uint8_t custom_hid_req_handler (usb_dev *udev, usb_req *req) 0U); status = REQ_SUPP; + } else if (USB_DESCTYPE_HID == (req->wValue >> 8U)) { + usb_transc_config(&udev->transc_in[0U], + (uint8_t *)(&(custom_hid_config_desc.hid_vendor)), + USB_MIN(9U, req->wLength), + 0U); } break; @@ -458,11 +468,10 @@ static void custom_hid_data_out (usb_dev *udev, uint8_t ep_num) custom_hid_handler *hid = (custom_hid_handler *)udev->class_data[CUSTOM_HID_INTERFACE]; if (CUSTOMHID_OUT_EP == ep_num){ - switch (hid->data[0]){ case 0x11: if (RESET != hid->data[1]) { - /* turn on led1 */ + /* turn on led5 */ gd_eval_led_on(LED5); } else { gd_eval_led_off(LED5); @@ -491,13 +500,13 @@ static void custom_hid_data_out (usb_dev *udev, uint8_t ep_num) break; default: /* turn off all leds */ - gd_eval_led_off(LED5); gd_eval_led_off(LED2); gd_eval_led_off(LED3); gd_eval_led_off(LED4); + gd_eval_led_off(LED5); break; } - usbd_ep_recev(udev, CUSTOMHID_IN_EP, hid->data, 2U); + usbd_ep_recev(udev, CUSTOMHID_OUT_EP, hid->data, 2U); } } diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Source/standard_hid_core.c b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Source/standard_hid_core.c index d268e1ef..280fceb0 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Source/standard_hid_core.c +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Source/standard_hid_core.c @@ -3,10 +3,11 @@ \brief HID class driver \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -34,7 +35,6 @@ OF SUCH DAMAGE. #include "usbd_transc.h" #include "standard_hid_core.h" - #include #define USBD_VID 0x28E9U @@ -194,6 +194,7 @@ static usb_desc_str serial_string = } }; +/* USB string descriptor set */ uint8_t* usbd_hid_strings[] = { [STR_IDX_LANGID] = (uint8_t *)&usbd_language_id_desc, @@ -202,7 +203,8 @@ uint8_t* usbd_hid_strings[] = [STR_IDX_SERIAL] = (uint8_t *)&serial_string }; -usb_desc hid_desc = { +usb_desc hid_desc = +{ #ifdef LPM_ENABLED .bos_desc = (uint8_t *)&USBD_BOSDesc, #endif /* LPM_ENABLED */ @@ -217,7 +219,8 @@ static uint8_t hid_deinit (usb_dev *udev, uint8_t config_index); static uint8_t hid_req_handler (usb_dev *udev, usb_req *req); static void hid_data_in_handler (usb_dev *udev, uint8_t ep_num); -usb_class hid_class = { +usb_class hid_class = +{ .init = hid_init, .deinit = hid_deinit, .req_process = hid_req_handler, diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Source/std_hid_mouse_core.c b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Source/std_hid_mouse_core.c index a6766ed1..9d63582d 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Source/std_hid_mouse_core.c +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/hid/Source/std_hid_mouse_core.c @@ -3,10 +3,11 @@ \brief HID class driver \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/iap/Include/usb_iap_core.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/iap/Include/usb_iap_core.h index b4c27239..1c6c7fc6 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/iap/Include/usb_iap_core.h +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/iap/Include/usb_iap_core.h @@ -3,10 +3,11 @@ \brief the header file of IAP driver \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/iap/Source/usb_iap_core.c b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/iap/Source/usb_iap_core.c index fca6804f..2772c98e 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/iap/Source/usb_iap_core.c +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/iap/Source/usb_iap_core.c @@ -3,10 +3,11 @@ \brief IAP driver \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -62,6 +63,7 @@ usb_desc_dev iap_dev_desc = .bNumberConfigurations = USBD_CFG_MAX_NUM }; +/* USB device configure descriptor */ usb_hid_desc_config_set iap_config_desc = { .config = @@ -169,7 +171,7 @@ static usb_desc_str product_string = .unicode_string = {'G', 'D', '3', '2', '-', 'U', 'S', 'B', '_', 'I', 'A', 'P'} }; -/* USBD serial string */ +/* USB serial string */ static usb_desc_str serial_string = { .header = @@ -179,6 +181,7 @@ static usb_desc_str serial_string = } }; +/* USB string descriptor set */ uint8_t* usbd_iap_strings[] = { [STR_IDX_LANGID] = (uint8_t *)&usbd_language_id_desc, @@ -240,7 +243,7 @@ static void iap_req_dnload (usb_dev *udev); static void iap_req_optionbyte(usb_dev *udev); static void iap_req_leave (usb_dev *udev); static void iap_address_send (usb_dev *udev); -static void iap_data_write (uint8_t *data, uint32_t addr, uint32_t len); +static void iap_data_write (uint8_t *data, uint32_t addr, uint32_t len); /*! \brief initialize the HID device @@ -480,9 +483,9 @@ static void iap_req_erase (usb_dev *udev) /* compute last packet size and transfer times */ iap->lps = iap->file_length % TRANSFER_SIZE; if (0U == iap->lps) { - iap->transfer_times = (uint16_t)iap->file_length / TRANSFER_SIZE; + iap->transfer_times = (uint16_t)(iap->file_length / TRANSFER_SIZE); } else { - iap->transfer_times = (uint16_t)iap->file_length / TRANSFER_SIZE + 1U; + iap->transfer_times = (uint16_t)(iap->file_length / TRANSFER_SIZE + 1U); } /* check if the address is in protected area */ @@ -569,7 +572,7 @@ static void iap_address_send(usb_dev *udev) \param[in] addr: sector address/code \param[in] len: length of data to be written (in bytes) \param[out] none - \retval MAL_OK if all operations are OK, MAL_FAIL else + \retval none */ static void iap_data_write (uint8_t *data, uint32_t addr, uint32_t len) { diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Include/usbd_msc_bbb.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Include/usbd_msc_bbb.h index 639fd8a1..4cd05622 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Include/usbd_msc_bbb.h +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Include/usbd_msc_bbb.h @@ -4,10 +4,11 @@ \version 2020-08-01, V3.0.0, firmware for GD32F30x \version 2021-02-20, V3.0.1, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -45,7 +46,8 @@ OF SUCH DAMAGE. #define BBB_CBW_LENGTH 31U #define BBB_CSW_LENGTH 13U -typedef struct { +typedef struct +{ uint32_t dCBWSignature; uint32_t dCBWTag; uint32_t dCBWDataTransferLength; @@ -55,7 +57,8 @@ typedef struct { uint8_t CBWCB[16]; }msc_bbb_cbw; -typedef struct { +typedef struct +{ uint32_t dCSWSignature; uint32_t dCSWTag; uint32_t dCSWDataResidue; @@ -63,7 +66,8 @@ typedef struct { }msc_bbb_csw; /* CSW command status */ -enum msc_csw_status { +enum msc_csw_status +{ CSW_CMD_PASSED = 0, CSW_CMD_FAILED, CSW_PHASE_ERROR @@ -106,7 +110,6 @@ typedef struct uint32_t scsi_blk_addr; uint32_t scsi_blk_len; -// uint32_t scsi_disk_pop; msc_scsi_sense scsi_sense[SENSE_LIST_DEEPTH]; } usbd_msc_handler; diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Include/usbd_msc_core.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Include/usbd_msc_core.h index 0eacbb8c..bd4028e2 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Include/usbd_msc_core.h +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Include/usbd_msc_core.h @@ -4,10 +4,11 @@ \version 2020-08-01, V3.0.0, firmware for GD32F30x \version 2021-02-20, V3.0.1, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Include/usbd_msc_data.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Include/usbd_msc_data.h deleted file mode 100644 index 3d6ab7a7..00000000 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Include/usbd_msc_data.h +++ /dev/null @@ -1,50 +0,0 @@ -/*! - \file usbd_msc_data.h - \brief the header file of the usbd_msc_data.c file - - \version 2020-08-01, V3.0.0, firmware for GD32F30x - \version 2021-02-20, V3.0.1, firmware for GD32F30x -*/ - -/* - Copyright (c) 2020, GigaDevice Semiconductor Inc. - - Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - 3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - -#ifndef __USBD_MSC_DATA_H -#define __USBD_MSC_DATA_H - -#include "usbd_conf.h" - -#define MODE_SENSE6_LENGTH 8U -#define MODE_SENSE10_LENGTH 8U -#define INQUIRY_PAGE00_LENGTH 96U -#define FORMAT_CAPACITIES_LENGTH 20U - -extern const uint8_t msc_page00_inquiry_data[]; -extern const uint8_t msc_mode_sense6_data[]; -extern const uint8_t msc_mode_sense10_data[]; - -#endif /* __USBD_MSC_DATA_H */ diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Include/usbd_msc_mem.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Include/usbd_msc_mem.h index e6ddf9d7..bc8490d0 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Include/usbd_msc_mem.h +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Include/usbd_msc_mem.h @@ -4,10 +4,11 @@ \version 2020-08-01, V3.0.0, firmware for GD32F30x \version 2021-02-20, V3.0.1, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Include/usbd_msc_scsi.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Include/usbd_msc_scsi.h index 22c16381..d0b57b3f 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Include/usbd_msc_scsi.h +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Include/usbd_msc_scsi.h @@ -4,10 +4,11 @@ \version 2020-08-01, V3.0.0, firmware for GD32F30x \version 2021-02-20, V3.0.1, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -36,7 +37,6 @@ OF SUCH DAMAGE. #ifndef __USBD_MSC_SCSI_H #define __USBD_MSC_SCSI_H -#include "usbd_msc_data.h" #include "usbd_msc_bbb.h" #define SENSE_LIST_DEEPTH 4U @@ -93,7 +93,13 @@ OF SUCH DAMAGE. #define STANDARD_INQUIRY_DATA_LEN 0x24U #define BLKVFY 0x04U -enum sense_state { +#define MODE_SENSE6_LENGTH 8U +#define MODE_SENSE10_LENGTH 8U +#define INQUIRY_PAGE00_LENGTH 96U +#define FORMAT_CAPACITIES_LENGTH 20U + +enum sense_state +{ NO_SENSE = 0U, RECOVERED_ERROR, NOT_READY, @@ -118,6 +124,10 @@ typedef struct { uint8_t ASCQ; } msc_scsi_sense; +extern const uint8_t msc_page00_inquiry_data[]; +extern const uint8_t msc_mode_sense6_data[]; +extern const uint8_t msc_mode_sense10_data[]; + /* function declarations */ /* process SCSI commands */ int8_t scsi_process_cmd (usb_dev *udev, uint8_t lun, uint8_t *cmd); diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Source/usbd_msc_bbb.c b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Source/usbd_msc_bbb.c index 361f54f4..6f8a4d7f 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Source/usbd_msc_bbb.c +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Source/usbd_msc_bbb.c @@ -5,10 +5,11 @@ \version 2020-08-01, V3.0.0, firmware for GD32F30x \version 2021-02-20, V3.0.1, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -182,8 +183,9 @@ void msc_bbb_csw_send (usb_dev *udev, uint8_t csw_status) void msc_bbb_clrfeature (usb_dev *udev, uint8_t ep_num) { usbd_msc_handler *msc = (usbd_msc_handler *)udev->class_data[USBD_MSC_INTERFACE]; - - if (msc->bbb_status == BBB_STATUS_ERROR)/* bad CBW signature */ { + + /* bad CBW signature */ + if (msc->bbb_status == BBB_STATUS_ERROR) { usbd_ep_stall(udev, MSC_IN_EP); msc->bbb_status = BBB_STATUS_NORMAL; diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Source/usbd_msc_core.c b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Source/usbd_msc_core.c index 00884ac5..a5ac5de1 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Source/usbd_msc_core.c +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Source/usbd_msc_core.c @@ -4,10 +4,11 @@ \version 2020-08-01, V3.0.0, firmware for GD32F30x \version 2021-02-20, V3.0.1, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -191,7 +192,8 @@ uint8_t* usbd_msc_strings[] = [STR_IDX_SERIAL] = (uint8_t *)&serial_string }; -usb_desc msc_desc = { +usb_desc msc_desc = +{ .dev_desc = (uint8_t *)&msc_dev_desc, .config_desc = (uint8_t *)&msc_config_desc, .strings = usbd_msc_strings diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Source/usbd_msc_data.c b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Source/usbd_msc_data.c deleted file mode 100644 index e1078c7b..00000000 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Source/usbd_msc_data.c +++ /dev/null @@ -1,74 +0,0 @@ -/*! - \file msc_bbb_scsi.h - \brief the header file of the msc_bbb_scsi.c - - \version 2020-08-01, V3.0.0, firmware for GD32F30x - \version 2021-02-20, V3.0.1, firmware for GD32F30x -*/ - -/* - Copyright (c) 2020, GigaDevice Semiconductor Inc. - - Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - 3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - -#include "usbd_msc_data.h" - -/* USB mass storage page 0 inquiry data */ -const uint8_t msc_page00_inquiry_data[] = -{ - 0x00U, - 0x00U, - 0x00U, - 0x00U, - (INQUIRY_PAGE00_LENGTH - 4U), - 0x80U, - 0x83U, -}; - -/* USB mass storage sense 6 data */ -const uint8_t msc_mode_sense6_data[] = -{ - 0x00U, - 0x00U, - 0x00U, - 0x00U, - 0x00U, - 0x00U, - 0x00U, - 0x00U -}; - -/* USB mass storage sense 10 data */ -const uint8_t msc_mode_sense10_data[] = -{ - 0x00U, - 0x06U, - 0x00U, - 0x00U, - 0x00U, - 0x00U, - 0x00U, - 0x00U -}; diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Source/usbd_msc_scsi.c b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Source/usbd_msc_scsi.c index 30ebe3b9..0ceccc93 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Source/usbd_msc_scsi.c +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/msc/Source/usbd_msc_scsi.c @@ -4,10 +4,11 @@ \version 2020-08-01, V3.0.0, firmware for GD32F30x \version 2021-02-20, V3.0.1, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -36,7 +37,44 @@ OF SUCH DAMAGE. #include "usbd_enum.h" #include "usbd_msc_bbb.h" #include "usbd_msc_scsi.h" -#include "usbd_msc_data.h" + +/* USB mass storage page 0 inquiry data */ +const uint8_t msc_page00_inquiry_data[] = +{ + 0x00U, + 0x00U, + 0x00U, + 0x00U, + (INQUIRY_PAGE00_LENGTH - 4U), + 0x80U, + 0x83U, +}; + +/* USB mass storage sense 6 data */ +const uint8_t msc_mode_sense6_data[] = +{ + 0x00U, + 0x00U, + 0x00U, + 0x00U, + 0x00U, + 0x00U, + 0x00U, + 0x00U +}; + +/* USB mass storage sense 10 data */ +const uint8_t msc_mode_sense10_data[] = +{ + 0x00U, + 0x06U, + 0x00U, + 0x00U, + 0x00U, + 0x00U, + 0x00U, + 0x00U +}; /* local function prototypes ('static') */ static int8_t scsi_test_unit_ready (usb_dev *udev, uint8_t lun, uint8_t *params); @@ -173,17 +211,13 @@ static int8_t scsi_test_unit_ready (usb_dev *udev, uint8_t lun, uint8_t *params) return -1; } -// if (1U == msc->scsi_disk_pop) { -// usbd_disconnect (udev); -// } - msc->bbb_datalen = 0U; return 0; } /*! - \brief process Inquiry command + \brief process mode select 6 command \param[in] udev: pointer to USB device instance \param[in] lun: logical unit number \param[in] params: command parameters @@ -200,7 +234,7 @@ static int8_t scsi_mode_select6 (usb_dev *udev, uint8_t lun, uint8_t *params) } /*! - \brief process Inquiry command + \brief process mode select 10 command \param[in] udev: pointer to USB device instance \param[in] lun: logical unit number \param[in] params: command parameters @@ -217,7 +251,7 @@ static int8_t scsi_mode_select10 (usb_dev *udev, uint8_t lun, uint8_t *params) } /*! - \brief process Inquiry command + \brief process inquiry command \param[in] udev: pointer to USB device instance \param[in] lun: logical unit number \param[in] params: command parameters @@ -256,7 +290,7 @@ static int8_t scsi_inquiry (usb_dev *udev, uint8_t lun, uint8_t *params) } /*! - \brief process Read Capacity 10 command + \brief process read capacity 10 command \param[in] udev: pointer to USB device instance \param[in] lun: logical unit number \param[in] params: command parameters @@ -287,7 +321,7 @@ static int8_t scsi_read_capacity10 (usb_dev *udev, uint8_t lun, uint8_t *params) } /*! - \brief process Read Format Capacity command + \brief process read format capacity command \param[in] udev: pointer to USB device instance \param[in] lun: logical unit number \param[in] params: command parameters @@ -324,7 +358,7 @@ static int8_t scsi_read_format_capacity (usb_dev *udev, uint8_t lun, uint8_t *pa } /*! - \brief process Mode Sense6 command + \brief process mode sense 6 command \param[in] udev: pointer to USB device instance \param[in] lun: logical unit number \param[in] params: command parameters @@ -347,7 +381,7 @@ static int8_t scsi_mode_sense6 (usb_dev *udev, uint8_t lun, uint8_t *params) } /*! - \brief process Mode Sense10 command + \brief process mode sense 10 command \param[in] udev: pointer to USB device instance \param[in] lun: logical unit number \param[in] params: command parameters @@ -370,7 +404,7 @@ static int8_t scsi_mode_sense10 (usb_dev *udev, uint8_t lun, uint8_t *params) } /*! - \brief process Request Sense command + \brief process request sense command \param[in] udev: pointer to USB device instance \param[in] lun: logical unit number \param[in] params: command parameters @@ -406,7 +440,7 @@ static int8_t scsi_request_sense (usb_dev *udev, uint8_t lun, uint8_t *params) } /*! - \brief process Start Stop Unit command + \brief process start stop unit command \param[in] udev: pointer to USB device instance \param[in] lun: logical unit number \param[in] params: command parameters @@ -418,13 +452,12 @@ static inline int8_t scsi_start_stop_unit (usb_dev *udev, uint8_t lun, uint8_t * usbd_msc_handler *msc = (usbd_msc_handler *)udev->class_data[USBD_MSC_INTERFACE]; msc->bbb_datalen = 0U; -// msc->scsi_disk_pop = 1U; return 0; } /*! - \brief process Allow Medium Removal command + \brief process allow medium removal command \param[in] udev: pointer to USB device instance \param[in] lun: logical unit number \param[in] params: command parameters @@ -441,7 +474,7 @@ static inline int8_t scsi_allow_medium_removal (usb_dev *udev, uint8_t lun, uint } /*! - \brief process Read10 command + \brief process read 10 command \param[in] udev: pointer to USB device instance \param[in] lun: logical unit number \param[in] params: command parameters @@ -494,7 +527,7 @@ static int8_t scsi_read10 (usb_dev *udev, uint8_t lun, uint8_t *params) } /*! - \brief process Write10 command + \brief process write 10 command \param[in] udev: pointer to USB device instance \param[in] lun: logical unit number \param[in] params: command parameters @@ -562,7 +595,7 @@ static int8_t scsi_write10 (usb_dev *udev, uint8_t lun, uint8_t *params) } /*! - \brief process Verify10 command + \brief process verify 10 command \param[in] udev: pointer to USB device instance \param[in] lun: logical unit number \param[in] params: command parameters @@ -689,7 +722,7 @@ static int8_t scsi_process_write (usb_dev *udev, uint8_t lun) } /*! - \brief process Format Unit command + \brief process format unit command \param[in] udev: pointer to USB device instance \param[in] lun: logical unit number \param[out] none @@ -701,7 +734,7 @@ static inline int8_t scsi_format_cmd (usb_dev *udev, uint8_t lun) } /*! - \brief process Read_Toc command + \brief process read TOC command \param[in] udev: pointer to USB device instance \param[in] lun: logical unit number \param[in] params: command parameters diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/printer/Include/printer_core.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/printer/Include/printer_core.h index f4c09951..4799b414 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/printer/Include/printer_core.h +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/printer/Include/printer_core.h @@ -3,10 +3,11 @@ \brief the header file of USB printer device class core functions \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -37,13 +38,13 @@ OF SUCH DAMAGE. #include "usbd_enum.h" -/* USB printing device class code */ +/* USB printer device class code */ #define USB_CLASS_PRINTER 0x07U -/* printing device subclass code */ +/* printer device subclass code */ #define USB_SUBCLASS_PRINTER 0x01U -/* printing device protocol code */ +/* printer device protocol code */ #define PROTOCOL_UNIDIRECTIONAL_ITF 0x01U #define PROTOCOL_BI_DIRECTIONAL_ITF 0x02U #define PROTOCOL_1284_4_ITF 0x03U @@ -53,7 +54,7 @@ OF SUCH DAMAGE. #define USB_PRINTER_CONFIG_DESC_LEN 32U -/* printing device specific-class request */ +/* printer device specific-class request */ #define GET_DEVICE_ID 0x00U #define GET_PORT_STATUS 0x01U #define SOFT_RESET 0x02U diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/printer/Source/printer_core.c b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/printer/Source/printer_core.c index f41b2cf6..f9266c7e 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/printer/Source/printer_core.c +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/class/device/printer/Source/printer_core.c @@ -3,10 +3,11 @@ \brief USB printer device class core functions \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -205,7 +206,8 @@ static uint8_t printer_req_handler (usb_dev *udev, usb_req *req); static void printer_data_in (usb_dev *udev, uint8_t ep_num); static void printer_data_out (usb_dev *udev, uint8_t ep_num); -usb_class printer_class = { +usb_class printer_class = +{ .init = printer_init, .deinit = printer_deinit, .req_process = printer_req_handler, @@ -235,7 +237,7 @@ static uint8_t printer_init (usb_dev *udev, uint8_t config_index) } /*! - \brief de-initialize the printer device + \brief deinitialize the printer device \param[in] udev: pointer to USB device instance \param[in] config_index: configuration index \param[out] none diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Include/usb_ch9_std.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Include/usb_ch9_std.h index b3694834..bd3ff3a3 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Include/usb_ch9_std.h +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Include/usb_ch9_std.h @@ -3,10 +3,11 @@ \brief USB 2.0 standard defines \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -47,7 +48,6 @@ OF SUCH DAMAGE. #define USB_SETUP_PACKET_LEN 0x08U /*!< USB SETUP packet length */ #define USB_DEVICE_CAPABITY 0x10U /*!< USB device capabity */ - /* bit 7 of bmRequestType: data phase transfer direction */ #define USB_TRX_MASK 0x80U /*!< USB transfer direction mask */ #define USB_TRX_OUT 0x00U /*!< USB transfer OUT direction */ @@ -66,7 +66,8 @@ OF SUCH DAMAGE. #define USB_STATUS_SELF_POWERED 1U /*!< USB is in self powered status */ /* bit 4..0 of bmRequestType: recipient type */ -enum _usb_recp_type { +enum _usb_recp_type +{ USB_RECPTYPE_DEV = 0x0U, /*!< USB device request type */ USB_RECPTYPE_ITF = 0x1U, /*!< USB interface request type */ USB_RECPTYPE_EP = 0x2U, /*!< USB endpoint request type */ @@ -74,7 +75,8 @@ enum _usb_recp_type { }; /* bRequest value */ -enum _usb_request { +enum _usb_request +{ USB_GET_STATUS = 0x0U, /*!< USB get status request */ USB_CLEAR_FEATURE = 0x1U, /*!< USB clear feature request */ USB_RESERVED2 = 0x2U, /*!< USB reserved2 */ @@ -91,7 +93,8 @@ enum _usb_request { }; /* descriptor types of USB specifications */ -enum _usb_desctype { +enum _usb_desctype +{ USB_DESCTYPE_DEV = 0x1U, /*!< USB device descriptor type */ USB_DESCTYPE_CONFIG = 0x2U, /*!< USB configuration descriptor type */ USB_DESCTYPE_STR = 0x3U, /*!< USB string descriptor type */ @@ -105,11 +108,12 @@ enum _usb_desctype { /* USB endpoint descriptor bmAttributes bit definitions */ /* bits 1..0 : transfer type */ -enum _usbx_type { - USB_EP_ATTR_CTL = 0x0U, /*!< USB endpoint control attributes*/ - USB_EP_ATTR_ISO = 0x1U, /*!< USB endpoint isochronous attributes*/ - USB_EP_ATTR_BULK = 0x2U, /*!< USB endpoint bulk attributes*/ - USB_EP_ATTR_INT = 0x3U /*!< USB endpoint interrupt attributes*/ +enum _usbx_type +{ + USB_EP_ATTR_CTL = 0x0U, /*!< USB endpoint control attributes */ + USB_EP_ATTR_ISO = 0x1U, /*!< USB endpoint isochronous attributes */ + USB_EP_ATTR_BULK = 0x2U, /*!< USB endpoint bulk attributes */ + USB_EP_ATTR_INT = 0x3U /*!< USB endpoint interrupt attributes */ }; /* bits 3..2 : Sync type (only if ISOCHRONOUS) */ @@ -128,7 +132,8 @@ enum _usbx_type { #pragma pack(1) /* USB standard device request structure */ -typedef struct _usb_req { +typedef struct _usb_req +{ uint8_t bmRequestType; /*!< type of request */ uint8_t bRequest; /*!< request of setup packet */ uint16_t wValue; /*!< value of setup packet */ @@ -137,19 +142,22 @@ typedef struct _usb_req { } usb_req; /* USB setup packet definition */ -typedef union _usb_setup { +typedef union _usb_setup +{ uint8_t data[8]; /*!< USB setup data */ usb_req req; /*!< USB setup request */ } usb_setup; /* USB descriptor definition */ -typedef struct _usb_desc_header { +typedef struct _usb_desc_header +{ uint8_t bLength; /*!< size of the descriptor */ uint8_t bDescriptorType; /*!< type of the descriptor */ } usb_desc_header; -typedef struct _usb_desc_dev { +typedef struct _usb_desc_dev +{ usb_desc_header header; /*!< descriptor header, including type and size */ uint16_t bcdUSB; /*!< BCD of the supported USB specification */ uint8_t bDeviceClass; /*!< USB device class */ @@ -165,7 +173,8 @@ typedef struct _usb_desc_dev { uint8_t bNumberConfigurations; /*!< total number of configurations supported by the device */ } usb_desc_dev; -typedef struct _usb_desc_config { +typedef struct _usb_desc_config +{ usb_desc_header header; /*!< descriptor header, including type and size */ uint16_t wTotalLength; /*!< size of the configuration descriptor header, and all sub descriptors inside the configuration */ uint8_t bNumInterfaces; /*!< total number of interfaces in the configuration */ @@ -175,7 +184,8 @@ typedef struct _usb_desc_config { uint8_t bMaxPower; /*!< maximum power consumption of the device while in the current configuration */ } usb_desc_config; -typedef struct _usb_desc_itf { +typedef struct _usb_desc_itf +{ usb_desc_header header; /*!< descriptor header, including type and size */ uint8_t bInterfaceNumber; /*!< index of the interface in the current configuration */ uint8_t bAlternateSetting; /*!< alternate setting for the interface number */ @@ -186,7 +196,8 @@ typedef struct _usb_desc_itf { uint8_t iInterface; /*!< index of the string descriptor describing the interface */ } usb_desc_itf; -typedef struct _usb_desc_ep { +typedef struct _usb_desc_ep +{ usb_desc_header header; /*!< descriptor header, including type and size */ uint8_t bEndpointAddress; /*!< logical address of the endpoint */ uint8_t bmAttributes; /*!< endpoint attribute */ @@ -194,13 +205,15 @@ typedef struct _usb_desc_ep { uint8_t bInterval; /*!< polling interval in milliseconds for the endpoint if it is an INTERRUPT or ISOCHRONOUS type */ } usb_desc_ep; -typedef struct _usb_desc_LANGID { - usb_desc_header header; /*!< descriptor header, including type and size. */ +typedef struct _usb_desc_LANGID +{ + usb_desc_header header; /*!< descriptor header, including type and size */ uint16_t wLANGID; /*!< LANGID code */ } usb_desc_LANGID; -typedef struct _usb_desc_str { - usb_desc_header header; /*!< descriptor header, including type and size. */ +typedef struct _usb_desc_str +{ + usb_desc_header header; /*!< descriptor header, including type and size */ uint16_t unicode_string[64]; /*!< unicode string data */ } usb_desc_str; diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Include/usbd_core.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Include/usbd_core.h index 8d5b2e5f..82a01468 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Include/usbd_core.h +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Include/usbd_core.h @@ -3,10 +3,12 @@ \brief USB device driver core \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2021-08-10, V3.0.1, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -50,7 +52,8 @@ OF SUCH DAMAGE. #define USBD_TRANSC_COUNT 3U /* USB device operation status */ -enum usbd_status { +enum usbd_status +{ USBD_UNCONNECTED = 0U, /*!< USB device unconnected status */ USBD_DEFAULT, /*!< USB device default status */ USBD_ADDRESSED, /*!< USB device addressed status */ @@ -60,12 +63,23 @@ enum usbd_status { }; /* USB device operation state */ -enum usbd_state { +enum usbd_state +{ USBD_OK = 0U, /*!< USB device OK state */ USBD_BUSY, /*!< USB device busy state */ USBD_FAIL /*!< USB device fail state */ }; +/* USB device type */ +enum usbd_ctl_state +{ + USBD_CTL_IDLE = 0U, + USBD_CTL_DATA_IN, + USBD_CTL_DATA_OUT, + USBD_CTL_STATUS_IN, + USBD_CTL_STATUS_OUT +}; + /* USB device transaction type */ enum usbd_transc { TRANSC_SETUP = 0U, /*!< SETUP transaction */ @@ -81,8 +95,9 @@ enum usbd_ep_kind { }; /* USB device transaction struct */ -typedef struct { - uint8_t max_len; /*!< packet max length */ +typedef struct +{ + uint16_t max_len; /*!< packet max length */ uint8_t ep_stall; /*!< endpoint STALL */ uint8_t *xfer_buf; /*!< transfer buffer */ @@ -91,14 +106,16 @@ typedef struct { } usb_transc; /* USB device basic struct */ -typedef struct { +typedef struct +{ uint8_t max_ep_count; /*!< endpoint max count */ uint8_t twin_buf; /*!< double buffer */ uint16_t ram_size; /*!< ram size */ } usb_basic; /* USB descriptor */ -typedef struct { +typedef struct +{ uint8_t *dev_desc; /*!< device descriptor */ uint8_t *config_desc; /*!< configure descriptor */ uint8_t *bos_desc; /*!< bos descriptor */ @@ -106,7 +123,8 @@ typedef struct { } usb_desc; /* USB power management */ -typedef struct { +typedef struct +{ uint8_t power_mode; /*!< power mode */ uint8_t power_low; /*!< power low */ uint8_t esof_count; /*!< ESOF count */ @@ -117,16 +135,19 @@ typedef struct { } usb_pm; /* USB LPM management */ -typedef struct { - uint32_t besl; /*!< besl */ +typedef struct +{ + uint32_t besl; /*!< BESL */ uint32_t L1_resume; /*!< L1 resume */ uint32_t L1_remote_wakeup; /*!< L1 remote wakeup */ } usb_lpm; /* USB control information */ -typedef struct { +typedef struct +{ usb_req req; /*!< USB request */ uint8_t ctl_zlp; /*!< control zero length packet */ + uint8_t ctl_state; /*!< control state */ } usb_control; typedef struct _usb_dev usb_dev; @@ -134,7 +155,8 @@ typedef struct _usb_handler usb_handler; typedef void (*usb_ep_transc) (usb_dev *usbd_dev, uint8_t ep_num); /* USB class struct */ -typedef struct { +typedef struct +{ uint8_t req_cmd; uint8_t req_altset; @@ -151,7 +173,8 @@ typedef struct { } usb_class; /* USB core driver struct */ -struct _usb_dev { +struct _usb_dev +{ /* basic parameters */ uint8_t config; uint8_t dev_addr; @@ -191,7 +214,8 @@ typedef struct } usbd_int_cb_struct; /* USB handler struct */ -struct _usb_handler { +struct _usb_handler +{ void (*init) (void); void (*deinit) (void); @@ -210,7 +234,7 @@ struct _usb_handler { uint16_t (*ep_read) (uint8_t *fifo, uint8_t ep_num, uint8_t buf_kind); void (*ep_stall_set) (usb_dev *udev, uint8_t ep_addr); void (*ep_stall_clear) (usb_dev *udev, uint8_t ep_addr); - uint8_t (*ep_status_get) (usb_dev *udev, uint8_t ep_addr); + uint16_t (*ep_status_get) (usb_dev *udev, uint8_t ep_addr); }; extern usbd_int_cb_struct *usbd_int_fops; @@ -322,7 +346,7 @@ __STATIC_INLINE void usbd_ep_clear_stall (usb_dev *udev, uint8_t ep_addr) \param[out] none \retval none */ -__STATIC_INLINE uint8_t usbd_ep_status_get (usb_dev *udev, uint8_t ep_addr) +__STATIC_INLINE uint16_t usbd_ep_status_get (usb_dev *udev, uint8_t ep_addr) { return udev->drv_handler->ep_status_get(udev, ep_addr); } diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Include/usbd_enum.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Include/usbd_enum.h index a6e44b44..54a1b8dc 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Include/usbd_enum.h +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Include/usbd_enum.h @@ -3,10 +3,11 @@ \brief USB enumeration definitions \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -36,7 +37,6 @@ OF SUCH DAMAGE. #define __USBD_ENUM_H #include "usbd_core.h" -#include "usb_ch9_std.h" #ifndef NULL #define NULL 0U @@ -58,13 +58,9 @@ enum _str_index STR_IDX_SERIAL = 0x3U, /* serial string index */ STR_IDX_CONFIG = 0x4U, /* configuration string index */ STR_IDX_ITF = 0x5U, /* interface string index */ - STR_IDX_MAX = 0x6U /* string index max value */ + STR_IDX_MAX = 0xEFU /* string index max value */ }; -#ifndef USB_STRING_COUNT -#error "Must define USB_STRING_COUNT" -#endif - /* PWR status enumeration */ typedef enum { diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Include/usbd_pwr.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Include/usbd_pwr.h index bcb158fa..10ac35ae 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Include/usbd_pwr.h +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Include/usbd_pwr.h @@ -3,10 +3,11 @@ \brief USB device power management functions prototype \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Include/usbd_transc.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Include/usbd_transc.h index 5499afad..b0f4c01b 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Include/usbd_transc.h +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Include/usbd_transc.h @@ -3,10 +3,11 @@ \brief USBD transaction \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -39,9 +40,10 @@ OF SUCH DAMAGE. /*! \brief USB transaction configure - \param[in] udev: pointer to USB device instance + \param[in] transc: pointer to USB device transaction instance \param[in] buf: transfer data buffer \param[in] len: transfer data length + \param[in] count: transfer data counter \param[out] none \retval none */ @@ -52,6 +54,80 @@ __STATIC_INLINE void usb_transc_config (usb_transc *transc, uint8_t *buf, uint16 transc->xfer_count = count; } +/*! + \brief USB stalled transaction + \param[in] udev: pointer to USB device instance + \param[out] none + \retval none +*/ +__STATIC_INLINE void usb_stall_transc (usb_dev *udev) +{ + usbd_ep_stall(udev, 0x0U); +} + +/*! + \brief USB control transaction status in stage + \param[in] udev: pointer to USB device instance + \param[out] none + \retval none +*/ +__STATIC_INLINE void usb_ctl_status_in (usb_dev *udev) +{ + udev->control.ctl_state = USBD_CTL_STATUS_IN; + + udev->drv_handler->ep_write(udev->transc_in[0].xfer_buf, 0U, 0U); +} + +/*! + \brief USB control transaction data in stage + \param[in] udev: pointer to USB device instance + \param[out] none + \retval none +*/ +__STATIC_INLINE void usb_ctl_data_in (usb_dev *udev) +{ + udev->control.ctl_state = USBD_CTL_DATA_IN; + + usbd_ep_send(udev, 0U, udev->transc_in[0].xfer_buf, udev->transc_in[0].xfer_len); +} + +/*! + \brief USB control transaction data out & status out stage + \param[in] udev: pointer to USB device instance + \param[out] none + \retval none +*/ +__STATIC_INLINE void usb_ctl_data_out (usb_dev *udev) +{ + udev->control.ctl_state = USBD_CTL_DATA_OUT; + + udev->drv_handler->ep_rx_enable(udev, 0U); +} + +/*! + \brief USB control transaction status OUT stage + \param[in] udev: pointer to USB device instance + \param[out] none + \retval none +*/ +static inline void usb_ctl_status_out (usb_dev *udev) +{ + udev->control.ctl_state = USBD_CTL_STATUS_OUT; + + udev->drv_handler->ep_rx_enable(udev, 0U); +} + +/*! + \brief USB send 0 length data packet + \param[in] udev: pointer to USB device instance + \param[out] none + \retval none +*/ +__STATIC_INLINE void usb_0len_packet_send (usb_dev *udev) +{ + udev->drv_handler->ep_write(udev->transc_in[0].xfer_buf, 0U, 0U); +} + /* function declarations */ /* process USB SETUP transaction */ void _usb_setup_transc (usb_dev *udev, uint8_t ep_num); diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Source/usbd_core.c b/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Source/usbd_core.c index 9fef40ec..31c12ee3 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Source/usbd_core.c +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Source/usbd_core.c @@ -3,10 +3,11 @@ \brief USB device driver \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -42,9 +43,8 @@ usbd_int_cb_struct *usbd_int_fops = NULL; /*! \brief configure USB device initialization \param[in] udev: pointer to USB core instance - \param[in] core: endpoint address + \param[in] desc: pointer to USB descriptor \param[in] usbc: USB class - \param[in] usbha: USB handler \param[out] none \retval none */ @@ -61,6 +61,8 @@ void usbd_init (usb_dev *udev, usb_desc *desc, usb_class *usbc) udev->class_core = usbc; udev->drv_handler = &usbd_drv_handler; + udev->control.ctl_state = USBD_CTL_IDLE; + udev->ep_transc[0][TRANSC_SETUP] = _usb_setup_transc; udev->ep_transc[0][TRANSC_OUT] = _usb_out0_transc; udev->ep_transc[0][TRANSC_IN] = _usb_in0_transc; diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Source/usbd_enum.c b/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Source/usbd_enum.c index e423e74b..87285751 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Source/usbd_enum.c +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Source/usbd_enum.c @@ -3,10 +3,12 @@ \brief USB enumeration function \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2021-09-27, V3.0.1, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -48,11 +50,13 @@ static usb_reqsta _usb_std_reserved (usb_dev *udev, usb_req *req); static usb_reqsta _usb_std_getinterface (usb_dev *udev, usb_req *req); static usb_reqsta _usb_std_setinterface (usb_dev *udev, usb_req *req); static usb_reqsta _usb_std_synchframe (usb_dev *udev, usb_req *req); -static uint8_t* _usb_dev_desc_get (usb_dev *udev, uint8_t index, uint16_t *len); -static uint8_t* _usb_config_desc_get (usb_dev *udev, uint8_t index, uint16_t *len); -static uint8_t* _usb_str_desc_get (usb_dev *udev, uint8_t index, uint16_t *len); -static uint8_t* _usb_bos_desc_get (usb_dev *udev, uint8_t index, uint16_t *len); -static void int_to_unicode (uint32_t value, uint8_t *pbuf, uint8_t len); + +static uint8_t* _usb_dev_desc_get (usb_dev *udev, uint8_t index, uint16_t *len); +static uint8_t* _usb_config_desc_get (usb_dev *udev, uint8_t index, uint16_t *len); +static uint8_t* _usb_str_desc_get (usb_dev *udev, uint8_t index, uint16_t *len); +static uint8_t* _usb_bos_desc_get (usb_dev *udev, uint8_t index, uint16_t *len); + +static void int_to_unicode (uint32_t value, uint8_t *pbuf, uint8_t len); /* standard device request handler */ static usb_reqsta (*_std_dev_req[]) (usb_dev *udev, usb_req *req) = { @@ -170,7 +174,7 @@ static uint8_t* _usb_config_desc_get (usb_dev *udev, uint8_t index, uint16_t *le { (void)index; - *len = udev->desc->config_desc[2]; + *len = udev->desc->config_desc[2] | (udev->desc->config_desc[3]<< 8); return udev->desc->config_desc; } @@ -253,12 +257,14 @@ static usb_reqsta _usb_std_getstatus (usb_dev *udev, usb_req *req) break; } break; + /* handle interface get status request */ case USB_RECPTYPE_ITF: if (((uint8_t)USBD_CONFIGURED == udev->cur_status) && (recp < USBD_ITF_MAX_NUM)) { req_status = REQ_SUPP; } break; + /* handle endpoint get status request */ case USB_RECPTYPE_EP: if ((uint8_t)USBD_CONFIGURED == udev->cur_status) { @@ -315,11 +321,10 @@ static usb_reqsta _usb_std_clearfeature (usb_dev *udev, usb_req *req) /* get endpoint address */ ep = BYTE_LOW(req->wIndex); - if ((uint8_t)USBD_CONFIGURED == udev->cur_status) { + if (((uint8_t)USBD_CONFIGURED == udev->cur_status) && (EP_ID(ep) < EP_COUNT)) { /* clear endpoint halt feature */ if (((uint16_t)USB_FEATURE_EP_HALT == req->wValue) && (!CTL_EP(ep))) { usbd_ep_clear_stall(udev, ep); - udev->class_core->req_process(udev, req); return REQ_SUPP; @@ -370,10 +375,11 @@ static usb_reqsta _usb_std_setfeature (usb_dev *udev, usb_req *req) /* get endpoint address */ ep = BYTE_LOW(req->wIndex); - if ((uint8_t)USBD_CONFIGURED == udev->cur_status) { + if (((uint8_t)USBD_CONFIGURED == udev->cur_status) && (EP_ID(ep) < EP_COUNT)) { /* set endpoint halt feature */ - if (((uint8_t)USB_FEATURE_EP_HALT == req->wValue) && (!CTL_EP(ep))) { + if (((uint16_t)USB_FEATURE_EP_HALT == req->wValue) && (!CTL_EP(ep))) { usbd_ep_stall(udev, ep); + udev->class_core->req_process(udev, req); return REQ_SUPP; } @@ -658,6 +664,8 @@ static usb_reqsta _usb_std_setinterface (usb_dev *udev, usb_req *req) if (BYTE_LOW(req->wIndex) < USBD_ITF_MAX_NUM) { udev->class_core->req_altset = (uint8_t)req->wValue; + udev->class_core->req_process(udev, req); + return REQ_SUPP; } break; @@ -712,7 +720,7 @@ static void int_to_unicode (uint32_t value, uint8_t *pbuf, uint8_t len) /*! \brief convert hex 32bits value into unicode char - \param[in] none + \param[in] unicode_str: pointer to unicode string \param[out] none \retval none */ diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Source/usbd_pwr.c b/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Source/usbd_pwr.c index 4ca50fd4..0bd96eb6 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Source/usbd_pwr.c +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Source/usbd_pwr.c @@ -3,10 +3,11 @@ \brief USB device power management driver \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Source/usbd_transc.c b/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Source/usbd_transc.c index e8c27a29..90ba660f 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Source/usbd_transc.c +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/device/Source/usbd_transc.c @@ -3,10 +3,11 @@ \brief USBD transaction function \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -37,9 +38,10 @@ OF SUCH DAMAGE. /* local function prototypes ('static') */ static inline void usb_stall_transc (usb_dev *udev); +static inline void usb_ctl_data_in(usb_dev *udev); static inline void usb_ctl_status_in (usb_dev *udev); -static inline void usb_ctl_data_in (usb_dev *udev); -static inline void usb_ctl_out (usb_dev *udev); +static inline void usb_ctl_data_out (usb_dev *udev); +static inline void usb_ctl_status_out (usb_dev *udev); static inline void usb_0len_packet_send (usb_dev *udev); /*! @@ -92,7 +94,7 @@ void _usb_setup_transc (usb_dev *udev, uint8_t ep_num) usb_ctl_data_in(udev); } else { /* USB control transfer data out stage */ - usb_ctl_out(udev); + usb_ctl_data_out(udev); } } } else { @@ -114,10 +116,16 @@ void _usb_out0_transc (usb_dev *udev, uint8_t ep_num) (void)udev->class_core->ctlx_out(udev); } - usb_transc_config(&udev->transc_out[ep_num], NULL, 0U, 0U); + if (USBD_CTL_DATA_OUT == udev->control.ctl_state) { + /* enter the control transaction status IN stage */ + usb_ctl_status_in(udev); + } else if (USBD_CTL_STATUS_OUT == udev->control.ctl_state) { + usb_transc_config(&udev->transc_out[ep_num], NULL, 0U, 0U); - /* enter the control transaction status in stage */ - usb_ctl_status_in(udev); + udev->control.ctl_state = USBD_CTL_IDLE; + } else { + /* no operation */ + } } /*! @@ -142,8 +150,12 @@ void _usb_in0_transc (usb_dev *udev, uint8_t ep_num) (void)udev->class_core->ctlx_in(udev); } - /* USB control transfer status out stage */ - usb_ctl_out(udev); + if (USBD_CTL_DATA_IN == udev->control.ctl_state) { + /* USB control transfer status OUT stage */ + usb_ctl_status_out(udev); + } else if (USBD_CTL_STATUS_IN == udev->control.ctl_state) { + udev->control.ctl_state = USBD_CTL_IDLE; + } if (0U != udev->dev_addr) { udev->drv_handler->set_addr(udev); @@ -151,58 +163,3 @@ void _usb_in0_transc (usb_dev *udev, uint8_t ep_num) udev->dev_addr = 0U; } } - -/*! - \brief USB stalled transaction - \param[in] udev: pointer to USB device instance - \param[out] none - \retval none -*/ -static inline void usb_stall_transc (usb_dev *udev) -{ - usbd_ep_stall(udev, 0x0U); -} - -/*! - \brief USB control transaction status in stage - \param[in] udev: pointer to USB device instance - \param[out] none - \retval none -*/ -static inline void usb_ctl_status_in (usb_dev *udev) -{ - udev->drv_handler->ep_write(udev->transc_in[0].xfer_buf, 0U, 0U); -} - -/*! - \brief USB control transaction data in stage - \param[in] udev: pointer to USB device instance - \param[out] none - \retval none -*/ -static inline void usb_ctl_data_in (usb_dev *udev) -{ - usbd_ep_send(udev, 0U, udev->transc_in[0].xfer_buf, udev->transc_in[0].xfer_len); -} - -/*! - \brief USB control transaction data out & status out stage - \param[in] udev: pointer to USB device instance - \param[out] none - \retval none -*/ -static inline void usb_ctl_out (usb_dev *udev) -{ - udev->drv_handler->ep_rx_enable(udev, 0U); -} - -/*! - \brief USB send 0 length data packet - \param[in] udev: pointer to USB device instance - \param[out] none - \retval none -*/ -static inline void usb_0len_packet_send (usb_dev *udev) -{ - udev->drv_handler->ep_write(udev->transc_in[0].xfer_buf, 0U, 0U); -} diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/usbd/Include/usbd_lld_core.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/usbd/Include/usbd_lld_core.h index b14a9130..bfd47933 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/usbd/Include/usbd_lld_core.h +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/usbd/Include/usbd_lld_core.h @@ -3,10 +3,11 @@ \brief USB device low level driver core \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/usbd/Include/usbd_lld_int.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/usbd/Include/usbd_lld_int.h index 7565660b..71e353e5 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/usbd/Include/usbd_lld_int.h +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/usbd/Include/usbd_lld_int.h @@ -3,10 +3,11 @@ \brief USB device low level interrupt handler \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/usbd/Include/usbd_lld_regs.h b/system/GD32F30x_firmware/GD32F30x_usbd_library/usbd/Include/usbd_lld_regs.h index 6d357cfc..1aef3b16 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/usbd/Include/usbd_lld_regs.h +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/usbd/Include/usbd_lld_regs.h @@ -3,10 +3,11 @@ \brief USB device low level registers \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/usbd/Source/usbd_lld_core.c b/system/GD32F30x_firmware/GD32F30x_usbd_library/usbd/Source/usbd_lld_core.c index bd0db732..68cb5b51 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/usbd/Source/usbd_lld_core.c +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/usbd/Source/usbd_lld_core.c @@ -3,10 +3,12 @@ \brief USB device low level driver core \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2021-08-10, V3.0.1, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -47,7 +49,8 @@ static usbd_ep_ram btable_ep[EP_COUNT]__attribute__((at(USBD_RAM + 2 * (BTABLE_O usb_core_drv usbd_core; -static const uint32_t ep_type[] = { +static const uint32_t ep_type[] = +{ [USB_EP_ATTR_CTL] = EP_CONTROL, [USB_EP_ATTR_BULK] = EP_BULK, [USB_EP_ATTR_INT] = EP_INTERRUPT, @@ -70,11 +73,12 @@ static uint16_t usbd_ep_data_read (uint8_t *user_fifo, uint8_t ep_num, uint8_t b static void usbd_resume (usb_dev *udev); static void usbd_suspend (void); static void usbd_leave_suspend (void); -static uint8_t usbd_ep_status (usb_dev *udev, uint8_t ep_addr); +static uint16_t usbd_ep_status (usb_dev *udev, uint8_t ep_addr); void usbd_err(uint8_t len) { (void)len; } -struct _usb_handler usbd_drv_handler = { +struct _usb_handler usbd_drv_handler = +{ .dp_pullup = usbd_dp_pullup, .init = usbd_core_reset, .deinit = usbd_core_stop, @@ -220,7 +224,7 @@ static void usbd_ep_reset (usb_dev *udev) /* reset non-control endpoints */ for (i = 1U; i < EP_COUNT; i++) { - USBD_EPxCS(i) = (USBD_EPxCS(i) & EPCS_MASK) | i; + USBD_EPxCS(i) = (USBD_EPxCS(i) & (~EPCS_MASK)) | i; } /* clear endpoint 0 register */ @@ -257,7 +261,7 @@ static void usbd_ep_setup (usb_dev *udev, uint8_t buf_kind, uint32_t buf_addr, c if (EP_DIR(ep_addr)) { transc = &udev->transc_in[ep_num]; - transc->max_len = (uint8_t)max_len; + transc->max_len = max_len; if ((uint8_t)EP_BUF_SNG == buf_kind) { btable_ep[ep_num].tx_addr = buf_addr; @@ -278,7 +282,7 @@ static void usbd_ep_setup (usb_dev *udev, uint8_t buf_kind, uint32_t buf_addr, c } else { transc = &udev->transc_out[ep_num]; - transc->max_len = (uint8_t)max_len; + transc->max_len = max_len; if ((uint8_t)EP_BUF_SNG == buf_kind) { btable_ep[ep_num].rx_addr = buf_addr; @@ -437,16 +441,16 @@ static void usbd_ep_stall_clear (usb_dev *udev, uint8_t ep_addr) \param[out] none \retval endpoint status */ -static uint8_t usbd_ep_status (usb_dev *udev, uint8_t ep_addr) +static uint16_t usbd_ep_status (usb_dev *udev, uint8_t ep_addr) { (void)udev; uint32_t epcs = USBD_EPxCS(EP_ID(ep_addr)); if (EP_DIR(ep_addr)) { - return (uint8_t)(epcs & EPxCS_TX_STA); + return (uint16_t)(epcs & EPxCS_TX_STA); } else { - return (uint8_t)(epcs & EPxCS_RX_STA); + return (uint16_t)(epcs & EPxCS_RX_STA); } } @@ -558,17 +562,6 @@ static void lowpower_mode_exit (void) /* low power sleep on exit disabled */ system_lowpower_reset(SCB_LPM_DEEPSLEEP); - -#ifdef USE_IRC48M - /* enable IRC48M clock */ - rcu_osci_on(RCU_IRC48M); - - /* wait till IRC48M is ready */ - while (SUCCESS != rcu_osci_stab_wait(RCU_IRC48M)) { - } - - rcu_ck48m_clock_config(RCU_CK48MSRC_IRC48M); -#endif } #endif /* USBD_LOWPWR_MODE_ENABLE */ @@ -631,7 +624,7 @@ static void usbd_suspend (void) /* check wakeup flag is set */ if (0U == (USBD_INTF & INTF_WKUPIF)) { /* enter DEEP_SLEEP mode with LDO in low power mode */ - pmu_to_deepsleepmode(PMU_LDO_LOWPOWER, WFI_CMD); + pmu_to_deepsleepmode(PMU_LDO_LOWPOWER, PMU_LOWDRIVER_DISABLE, WFI_CMD); } else { /* clear wakeup interrupt flag */ CLR(WKUPIF); diff --git a/system/GD32F30x_firmware/GD32F30x_usbd_library/usbd/Source/usbd_lld_int.c b/system/GD32F30x_firmware/GD32F30x_usbd_library/usbd/Source/usbd_lld_int.c index e3321132..7fa68384 100644 --- a/system/GD32F30x_firmware/GD32F30x_usbd_library/usbd/Source/usbd_lld_int.c +++ b/system/GD32F30x_firmware/GD32F30x_usbd_library/usbd/Source/usbd_lld_int.c @@ -3,10 +3,11 @@ \brief USB device low level interrupt routines \version 2020-08-01, V3.0.0, firmware for GD32F30x + \version 2022-06-10, V3.1.0, firmware for GD32F30x */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2022, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -121,7 +122,7 @@ void usbd_isr (void) if (USBD_EPxCS(ep_num) & EPxCS_SETUP) { - if (ep_num == 0U) { + if (0U == ep_num) { udev->ep_transc[ep_num][TRANSC_SETUP](udev, ep_num); } else { return; @@ -151,7 +152,7 @@ void usbd_isr (void) usb_transc *transc = &udev->transc_in[ep_num]; - if (transc->xfer_len == 0U) { + if (0U == transc->xfer_len) { if (udev->ep_transc[ep_num][TRANSC_IN]) { udev->ep_transc[ep_num][TRANSC_IN](udev, ep_num); }