mxpopstar
2022-05-04 fc9a39919da8db88c68ee1c41c01f6c26b88f12c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
/*!
    \file    audio_core.h
    \brief   the header file of USB audio device class core functions
 
    \version 2020-08-01, V3.0.0, 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 __AUDIO_CORE_H
#define __AUDIO_CORE_H
 
#include "usbd_enum.h"
 
#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
   that it is an even number and higher than 3 */
#define OUT_PACKET_NUM                               4U
 
/* 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 AUDIO_CONFIG_DESC_SET_LEN                    109U
#define AUDIO_INTERFACE_DESC_SIZE                    9U
 
#define USB_AUDIO_DESC_SIZ                           0x09U
#define AUDIO_STANDARD_EP_DESC_SIZE                  0x09U
#define AUDIO_STREAMING_EP_DESC_SIZE                 0x07U
 
/* audio interface class code */
#define USB_CLASS_AUDIO                              0x01U
 
/* audio interface subclass codes */
#define AUDIO_SUBCLASS_CONTROL                       0x01U
#define AUDIO_SUBCLASS_AUDIOSTREAMING                0x02U
#define AUDIO_SUBCLASS_MIDISTREAMING                 0x03U
 
/* audio interface protocol codes */
#define AUDIO_PROTOCOL_UNDEFINED                     0x00U
#define AUDIO_STREAMING_GENERAL                      0x01U
#define AUDIO_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
 
/* 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)
 
 
#pragma pack(1)
 
typedef struct
{
    usb_desc_header header;           /*!< descriptor header, including type and size */
    uint8_t  bDescriptorSubtype;      /*!< header descriptor subtype */
    uint16_t bcdADC;                  /*!< audio device class specification release number in binary-coded decimal */
    uint16_t wTotalLength;            /*!< total number of bytes */
    uint8_t  bInCollection;           /*!< the number of the streaming interfaces */
    uint8_t  baInterfaceNr;           /*!< interface number of the streaming interfaces */
} usb_desc_AC_itf;
 
typedef struct
{
    usb_desc_header header;           /*!< descriptor header, including type and size */
    uint8_t  bDescriptorSubtype;      /*!< AS_GENERAL descriptor subtype */
    uint8_t  bTerminalLink;           /*!< the terminal ID */
    uint8_t  bDelay;                  /*!< delay introduced by the data path */
    uint16_t wFormatTag;              /*!< the audio data format */
} usb_desc_AS_itf;
 
typedef struct
{
    usb_desc_header header;           /*!< descriptor header, including type and size */
    uint8_t  bDescriptorSubtype;      /*!< INPUT_TERMINAL descriptor subtype. */
    uint8_t  bTerminalID;             /*!< constant uniquely identifying the terminal within the audio function */
    uint16_t wTerminalType;           /*!< constant characterizing the type of terminal */
    uint8_t  bAssocTerminal;          /*!< ID of the output terminal */
    uint8_t  bNrChannels;             /*!< number of logical output channels */
    uint16_t wChannelConfig;          /*!< describes the spatial location of the logical channels */
    uint8_t  iChannelNames;           /*!< index of a string descriptor */
    uint8_t  iTerminal;               /*!< index of a string descriptor */
} usb_desc_input_terminal;
 
typedef struct
{
    usb_desc_header header;           /*!< descriptor header, including type and size */
    uint8_t  bDescriptorSubtype;      /*!< OUTPUT_TERMINAL descriptor subtype */
    uint8_t  bTerminalID;             /*!< constant uniquely identifying the terminal within the audio function */
    uint16_t wTerminalType;           /*!< constant characterizing the type of terminal */
    uint8_t  bAssocTerminal;          /*!< constant, identifying the input terminal to which this output terminal is associated */
    uint8_t  bSourceID;               /*!< ID of the unit or terminal */
    uint8_t  iTerminal;               /*!< index of a string descriptor */
} usb_desc_output_terminal;
 
typedef struct
{
    usb_desc_header header;           /*!< descriptor header, including type and size */
    uint8_t  bDescriptorSubtype;      /*!< FEATURE_UNIT descriptor subtype */
    uint8_t  bUnitID;                 /*!< constant uniquely identifying the unit within the audio function */
    uint8_t  bSourceID;               /*!< ID of the unit or terminal */
    uint8_t  bControlSize;            /*!< size in bytes of an element of the bmaControls() array */
    uint8_t  bmaControls0;            /*!< a bit set to 1 indicates that the mentioned control is supported for master channel 0 */
    uint8_t  bmaControls1;            /*!< a bit set to 1 indicates that the mentioned control is supported for logical channel 1 */
    uint8_t  iFeature;                /*!< index of a string descriptor */
} usb_desc_mono_feature_unit;
 
typedef struct
{
    usb_desc_header header;           /*!< descriptor header, including type and size */
    uint8_t  bDescriptorSubtype;      /*!< FEATURE_UNIT descriptor subtype */
    uint8_t  bUnitID;                 /*!< constant uniquely identifying the unit within the audio function */
    uint8_t  bSourceID;               /*!< ID of the unit or terminal */
    uint8_t  bControlSize;            /*!< size in bytes of an element of the bmaControls() array */
    uint16_t bmaControls0;            /*!< a bit set to 1 indicates that the mentioned control is supported for master channel 0 */
    uint16_t bmaControls1;            /*!< a bit set to 1 indicates that the mentioned control is supported for logical channel 1 */
    uint16_t bmaControls2;            /*!< a bit set to 1 indicates that the mentioned control is supported for logical channel 2 */
    uint8_t  iFeature;                /*!< index of a string descriptor */
} usb_desc_stereo_feature_unit;
 
typedef struct
{
    usb_desc_header header;           /*!< descriptor header, including type and size */
    uint8_t  bDescriptorSubtype;      /*!< FORMAT_TYPE descriptor subtype */
    uint8_t  bFormatType;             /*!< constant identifying the format type */
    uint8_t  bNrChannels;             /*!< indicates the number of physical channels in the audio data stream */
    uint8_t  bSubFrameSize;           /*!< the number of bytes occupied by one audio sub-frame */
    uint8_t  bBitResolution;          /*!< the number of effectively used bits from the available bits in an audio sub-frame */
    uint8_t  bSamFreqType;            /*!< indicates how the sampling frequency can be programmed */
    uint8_t  bSamFreq[3];             /*!< sampling frequency ns in Hz for this isochronous data endpoint */
} usb_desc_format_type;
 
typedef struct
{
    usb_desc_header header;           /*!< descriptor header, including type and size */
    uint8_t  bEndpointAddress;        /*!< the address of the endpoint */
    uint8_t  bmAttributes;            /*!< transfer type and synchronization type */
    uint16_t wMaxPacketSize;          /*!< maximum packet size this endpoint is capable of sending or receiving */
    uint8_t  bInterval;               /*!< left to the designer's discretion */
    uint8_t  bRefresh;                /*!< reset to 0 */
    uint8_t  bSynchAddress;           /*!< reset to 0 */
} usb_desc_std_ep;
 
typedef struct
{
    usb_desc_header header;           /*!< descriptor header, including type and size */
    uint8_t  bDescriptorSubtype;      /*!< EP_GENERAL descriptor subtype */
    uint8_t  bmAttributes;            /*!< transfer type and synchronization type */
    uint8_t  bLockDelayUnits;         /*!< indicates the units used for the wLockDelay field */
    uint16_t wLockDelay;              /*!< indicates the time it takes this endpoint to reliably lock its internal clock recovery circuitry */
} usb_desc_AS_ep;
 
#pragma pack()
 
/* USB configuration descriptor structure */
typedef struct
{
    usb_desc_config             config;
    usb_desc_itf                std_itf;
    usb_desc_AC_itf             ac_itf;
    usb_desc_input_terminal     in_terminal;
    usb_desc_mono_feature_unit  feature_unit;
    usb_desc_output_terminal    out_terminal;
    usb_desc_itf                std_as_itf_zeroband;
    usb_desc_itf                std_as_itf_opera;
    usb_desc_AS_itf             as_itf;
    usb_desc_format_type        format_typeI;
    usb_desc_std_ep             std_endpoint;
    usb_desc_AS_ep              as_endpoint;
} usb_desc_config_set;
 
typedef struct
{
    /* main buffer for audio data out transfers and its relative pointers */
    uint8_t  isoc_out_buff[TOTAL_OUT_BUF_SIZE * 2U];
    uint8_t* isoc_out_wrptr;
    uint8_t* isoc_out_rdptr;
 
    /* main buffer for audio control requests transfers and its relative variables */
    uint8_t  audioctl[64];
    uint8_t  audioctl_unit;
    uint32_t audioctl_len;
 
    uint32_t play_flag;
} usbd_audio_handler;
 
extern usb_desc audio_desc;
extern usb_class audio_class;
 
#endif /* __AUDIO_CORE_H */