/* ****************************************************************************** * @file usb_audio.c * @author FreqChip Firmware Team * @version V1.0.0 * @date 2021 * @brief This file provides the high layer firmware functions to manage the * USB Audio Device. ****************************************************************************** * @attention * * Copyright (c) 2021 FreqChip. * All rights reserved. * ****************************************************************************** */ #include "usb_audio.h" uint8_t gu8_Respond[5]; uint8_t gu8_AudioReport; uint32_t gu32_BitWidthSpeaker; uint32_t gu32_BitWidthMic; uint32_t gu32_PacketLengthSpeaker; uint32_t gu32_PacketLengthMic; uint32_t gu32_SamplingFreqSpeaker; uint32_t gu32_SamplingFreqMic; uint16_t gu16_VolumeSpeaker = USB_AUDIO_VOLUME_MAX; uint16_t gu16_VolumeMic = USB_AUDIO_VOLUME_MAX; uint8_t gu8_MuteSpeaker = 0x00; uint8_t gu8_MuteMic = 0x00; /* Audio Set Control */ typedef enum { AUDIO_SET_VOL_SPEAKER, /* set Speaker Volume */ AUDIO_SET_VOL_MIC, /* set Microphone Volume */ AUDIO_SET_MUTE_SPEAKER, /* set Speaker Mute */ AUDIO_SET_MUTE_MIC, /* set Microphone Mute */ AUDIO_SET_SAMPLING_SPEAKER, /* set Speaker Sampling Frequency */ AUDIO_SET_SAMPLING_MIC, /* set Microphone Sampling Frequency */ }Audio_SetControl; Audio_SetControl ge_CTLIndex; /* USB Standard Device Descriptor */ const uint8_t USB_Audio_DeviceDesc[] = { 0x12, /* bLength */ 0x01, /* bDescriptorType */ 0x00, /* bcdUSB */ 0x02, 0x00, /* bDeviceClass */ 0x00, /* bDeviceSubClass */ 0x00, /* bDeviceProtocol */ 0x40, /* bMaxPacketSize */ 0xA4, /* idVendor */ 0xA5, /* idVendor */ 0xA6, /* idProduct */ 0xA7, /* idProduct */ 0x00, /* bcdDevice rel. 2.00 */ 0x02, 0x01, /* Index of manufacturer string */ 0x02, /* Index of product string */ 0x03, /* Index of serial number string */ 0x01, /* bNumConfigurations */ }; /* USB Standard Configuration Descriptor */ const uint8_t USB_Audio_ConfigurationDesc[] = { /* Configuration Descriptor */ 0x09, /* bLength */ 0x02, /* bDescriptorType */ 0x1C, /* wTotalLength */ 0x01, 0x04, /* bNumInterfaces */ 0x01, /* bConfigurationValue */ 0x00, /* iConfiguration */ 0xC0, /* bmAttributes */ 0x32, /* bMaxPower */ /* Audio Interface_0 Descriptor */ 0x09, /* bLength */ 0x04, /* bDescriptorType */ 0x00, /* bInterfaceNumber */ 0x00, /* bAlternateSetting */ 0x00, /* bNumEndpoints */ 0x01, /* bInterfaceClass: Audio */ 0x01, /* bInterfaceSubClass: Audio Control */ 0x00, /* bInterfaceProtocol */ 0x00, /* iInterface */ /* Audio Control Interface Header Descriptor */ 0x0A, /* bLength */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x01, /* bDescriptorSubtype: HEADER descriptor subtype */ 0x00, /* bcdADC */ 0x01, 0x4C, /* wTotalLength */ 0x00, 0x02, /* bInCollection */ 0x01, /* baInterfaceNr(1) */ 0x02, /* baInterfaceNr(2) */ /* Audio Control Input Terminal Descriptor */ 0x0C, /* bLength */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x02, /* bDescriptorSubtype: INPUT_TERMINAL */ 0x01, /* bTerminalID */ 0x01, /* wTerminalType: USB streaming */ 0x01, 0x00, /* bAssocTerminal */ 0x02, /* bNrChannels */ 0x03, /* wChannelConfig */ 0x00, 0x00, /* iChannelNames */ 0x00, /* iTerminal */ /* Audio Control Feature Unit Descriptor */ 0x0D, /* bLength */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x06, /* bDescriptorSubtype: FEATURE_UNIT */ 0x02, /* bUnitID */ 0x01, /* bSourceID */ 0x02, /* bControlSize */ 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, /* iFeature */ /* Audio Control Output Terminal Descriptor */ 0x09, /* bLength */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x03, /* bDescriptorSubtype: OUTPUT_TERMINAL */ 0x03, /* bTerminalID */ 0x02, /* wTerminalType: Headphones */ 0x03, 0x00, /* bAssocTerminal */ 0x02, /* bSourceID */ 0x00, /* iTerminal */ /* Audio Control Input Terminal Descriptor */ 0x0C, /* bLength */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x02, /* bDescriptorSubtype: INPUT_TERMINAL */ 0x04, /* bTerminalID */ 0x01, /* wTerminalType: Microphone */ 0x02, 0x00, /* bAssocTerminal */ 0x01, /* bNrChannels */ 0x04, /* wChannelConfig */ 0x00, 0x00, /* iChannelNames */ 0x00, /* iTerminal */ /* Audio Control Feature Unit Descriptor */ 0x0B, /* bLength */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x06, /* bDescriptorSubtype: FEATURE_UNIT */ 0x05, /* bUnitID */ 0x04, /* bSourceID */ 0x02, /* bControlSize */ 0x01, 0x00, 0x02, 0x00, 0x00, /* iFeature */ /* Audio Control Output Terminal Descriptor */ 0x09, /* bLength */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x03, /* bDescriptorSubtype: OUTPUT_TERMINAL */ 0x06, /* bTerminalID */ 0x01, /* wTerminalType: USB streaming */ 0x01, 0x00, /* bAssocTerminal */ 0x05, /* bSourceID */ 0x00, /* iTerminal */ /* Audio Interface_1/0 Descriptor */ 0x09, /* bLength */ 0x04, /* bDescriptorType */ 0x01, /* bInterfaceNumber */ 0x00, /* bAlternateSetting */ 0x00, /* bNumEndpoints */ 0x01, /* bInterfaceClass: Audio */ 0x02, /* bInterfaceSubClass: Audio Streaming */ 0x00, /* bInterfaceProtocol */ 0x00, /* iConfiguration */ /* HID Interface_1/1 Descriptor */ 0x09, /* bLength */ 0x04, /* bDescriptorType */ 0x01, /* bInterfaceNumber */ 0x01, /* bAlternateSetting */ 0x01, /* bNumEndpoints */ 0x01, /* bInterfaceClass: Audio */ 0x02, /* bInterfaceSubClass: Audio Streaming */ 0x00, /* bInterfaceProtocol */ 0x00, /* iConfiguration */ /* Class-Specific AS Interface Descriptor */ 0x07, /* bLength */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x01, /* bDescriptorSubtype: AS_GENERAL */ 0x01, /* bTerminalLink */ 0x00, /* bDelay */ 0x01, /* wFormatTag: PCM */ 0x00, /* Class-Specific AS Format Type Descriptor */ 0x14, /* bLength */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x02, /* bDescriptorSubtype: FORMAT_TYPE */ 0x01, /* bFormatType: FORMAT_TYPE_I */ 0x02, /* bNrChannels */ 2, /* bSubframeSize: 2-Byte */ 16, /* bBitResolution: 16-bit */ 0x04, /* bSamFreqType */ 0x80, /* tSamFreq [1] : 16K */ 0x3E, 0x00, 0x00, /* tSamFreq [2] : 32K */ 0x7D, 0x00, 0x80, /* tSamFreq [3] : 48K */ 0xBB, 0x00, 0x00, /* tSamFreq [4] : 96K */ 0x77, 0x01, /* Endpoint 2 Descriptor */ 0x09, /* bLength */ 0x05, /* bDescriptorType */ 0x02, /* bEndpointAddress: OUT 2 */ 0x0D, /* bmAttributes: Isochronous */ 0x00, /* wMaxPacketSize: 512byte */ 0x02, 0x01, /* bInterval */ 0x00, /* bRefresh */ 0x00, /* bSynchAddress */ /* Audio Streaming Isochronous Audio Data Endpoint Descriptor */ 0x07, /* bLength */ 0x25, /* bDescriptorType: CS_ENDPOINT */ 0x01, /* bDescriptorSubtype: EP_GENERAL */ 0x01, /* bmAttributes */ 0x01, /* bLockDelayUnits */ 0x01, /* wLockDelay */ 0x00, /* */ /* HID Interface_1/2 Descriptor */ 0x09, /* bLength */ 0x04, /* bDescriptorType */ 0x01, /* bInterfaceNumber */ 0x02, /* bAlternateSetting */ 0x01, /* bNumEndpoints */ 0x01, /* bInterfaceClass: Audio */ 0x02, /* bInterfaceSubClass: Audio Streaming */ 0x00, /* bInterfaceProtocol */ 0x00, /* iConfiguration */ /* Class-Specific AS Interface Descriptor */ 0x07, /* bLength */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x01, /* bDescriptorSubtype: AS_GENERAL */ 0x01, /* bTerminalLink */ 0x00, /* bDelay */ 0x01, /* wFormatTag: PCM */ 0x00, /* Class-Specific AS Format Type Descriptor */ 0x0B, /* bLength */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x02, /* bDescriptorSubtype: FORMAT_TYPE */ 0x01, /* bFormatType: FORMAT_TYPE_I */ 0x02, /* bNrChannels */ 3, /* bSubframeSize: 3-Byte */ 24, /* bBitResolution: 24-bit */ 0x04, /* bSamFreqType */ 0x80, /* tSamFreq [1] : 48K */ 0xBB, 0x00, /* Endpoint 2 Descriptor */ 0x09, /* bLength */ 0x05, /* bDescriptorType */ 0x02, /* bEndpointAddress: OUT 2 */ 0x0D, /* bmAttributes: Isochronous */ 0x00, /* wMaxPacketSize: 512byte */ 0x02, 0x01, /* bInterval */ 0x00, /* bRefresh */ 0x00, /* bSynchAddress */ /* Audio Streaming Isochronous Audio Data Endpoint Descriptor */ 0x07, /* bLength */ 0x25, /* bDescriptorType: CS_ENDPOINT */ 0x01, /* bDescriptorSubtype: EP_GENERAL */ 0x01, /* bmAttributes */ 0x01, /* bLockDelayUnits */ 0x01, /* wLockDelay */ 0x00, /* */ /* Audio Interface_2/0 Descriptor */ 0x09, /* bLength */ 0x04, /* bDescriptorType */ 0x02, /* bInterfaceNumber */ 0x00, /* bAlternateSetting */ 0x00, /* bNumEndpoints */ 0x01, /* bInterfaceClass: Audio */ 0x02, /* bInterfaceSubClass: Audio Streaming */ 0x00, /* bInterfaceProtocol */ 0x00, /* iConfiguration */ /* Audio Interface_2/1 Descriptor */ 0x09, /* bLength */ 0x04, /* bDescriptorType */ 0x02, /* bInterfaceNumber */ 0x01, /* bAlternateSetting */ 0x01, /* bNumEndpoints */ 0x01, /* bInterfaceClass: Audio */ 0x02, /* bInterfaceSubClass: Audio Streaming */ 0x00, /* bInterfaceProtocol */ 0x00, /* iConfiguration */ /* Class-Specific AS Interface Descriptor */ 0x07, /* bLength */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x01, /* bDescriptorSubtype: AS_GENERAL */ 0x06, /* bTerminalLink */ 0x00, /* bDelay */ 0x01, /* wFormatTag: PCM */ 0x00, /* Class-Specific AS Format Type Descriptor */ 0x14, /* bLength */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x02, /* bDescriptorSubtype: FORMAT_TYPE */ 0x01, /* bFormatType: FORMAT_TYPE_I */ 0x01, /* bNrChannels */ 0x02, /* bSubframeSize */ 0x10, /* bBitResolution */ 0x04, /* bSamFreqType */ 0x80, /* tSamFreq [1] */ 0x3E, 0x00, 0x00, /* tSamFreq [2] */ 0x7D, 0x00, 0x80, /* tSamFreq [3] */ 0xBB, 0x00, 0x00, /* tSamFreq [4] */ 0x77, 0x01, /* Endpoint 1 Descriptor */ 0x09, /* bLength */ 0x05, /* bDescriptorType */ 0x81, /* bEndpointAddress: IN 1 */ 0x0D, /* bmAttributes: Isochronous */ 0x00, /* wMaxPacketSize: 256byte */ 0x01, 0x01, /* bInterval */ 0x00, /* bRefresh */ 0x00, /* bSynchAddress */ /* Audio Streaming Isochronous Audio Data Endpoint Descriptor */ 0x07, /* bLength */ 0x25, /* bDescriptorType: CS_ENDPOINT */ 0x01, /* bDescriptorSubtype: EP_GENERAL */ 0x00, /* bmAttributes */ 0x01, /* bLockDelayUnits */ 0x01, /* wLockDelay */ 0x00, /* HID Interface_3/0 Descriptor */ 0x09, /* bLength */ 0x04, /* bDescriptorType */ 0x03, /* bInterfaceNumber */ 0x00, /* bAlternateSetting */ 0x01, /* bNumEndpoints */ 0x03, /* bInterfaceClass: HID */ 0x00, /* bInterfaceSubClass */ 0x00, /* bInterfaceProtocol */ 0x00, /* iConfiguration */ /* HID Descriptor */ 0x09, /* bLength */ 0x21, /* bDescriptorType: HID */ 0x10, /* bcdHID: 1.10 */ 0x01, 0x21, /* bCountryCode */ 0x01, /* bNumDescriptors */ 0x22, /* bDescriptorType: Report */ 0x2A, /* wDescriptorLength */ 0x00, /* Endpoint 2 Descriptor */ 0x07, /* bLength */ 0x05, /* bDescriptorType */ 0x82, /* bEndpointAddress: IN 2 */ 0x03, /* bmAttributes: Interrupt */ 0x02, /* wMaxPacketSize: 2byte */ 0x00, 0x14, /* bInterval: 20ms */ }; /* USB Standard Manufacture Descriptor */ const uint8_t USB_Audio_ManufactureDesc[] = { 0x12, /* bLength */ 0x03, /* bDescriptorType */ 'F', 0x00, /* BString */ 'R', 0x00, 'E', 0x00, 'Q', 0x00, 'C', 0x00, 'H', 0x00, 'I', 0x00, 'P', 0x00, }; /* USB Standard Product Descriptor */ const uint8_t USB_Audio_ProductDesc[] = { 0x1E, /* bLength */ 0x03, /* bDescriptorType */ 'F', 0x00, /* BString */ 'R', 0x00, 'E', 0x00, 'Q', 0x00, 'C', 0x00, 'H', 0x00, 'I', 0x00, 'P', 0x00, '-', 0x00, 'A', 0x00, 'u', 0x00, 'd', 0x00, 'i', 0x00, 'o', 0x00, }; /* USB Standard SerialNumber Descriptor */ const uint8_t USB_Audio_SerialNumberDesc[] = { 0x1E, /* bLength */ 0x03, /* bDescriptorType */ '2', 0x00, /* BString */ '0', 0x00, '2', 0x00, '1', 0x00, '-', 0x00, '1', 0x00, '0', 0x00, '0', 0x00, '1', 0x00, '-', 0x00, 'B', 0x00, '1', 0x00, '3', 0x00, '6', 0x00, }; /* USB Standard LanuageID Descriptor */ const uint8_t USB_Audio_LanuageIDDesc[] = { 0x04, /* bLength */ 0x03, /* bDescriptorType */ 0x09, /* BString */ 0x04, }; /* HID device report Descriptor */ uint8_t USB_HID_Audio_ReportDesc[] = { 0x2A, /* Length */ 0x06, 0x0C, 0x00, 0x09, 0x01, 0xA1, 0x01, 0x25, 0x01, 0x15, 0x00, 0x0A, 0xE2, 0x00, /* Mute */ 0x0A, 0xEA, 0x00, /* Volume Decrement */ 0x0A, 0xE9, 0x00, /* Volume Increment */ 0x0A, 0xB6, 0x00, /* Scan Previous Track */ 0x0A, 0xCD, 0x00, /* Play/Pause */ 0x0A, 0xB5, 0x00, /* Scan Next Track */ 0x0A, 0xB7, 0x00, /* STOP */ 0x0A, 0xB7, 0x00, /* STOP */ 0x75, 0x01, 0x95, 0x08, 0x81, 0x02, 0xC0, }; /********************************************************************* * @fn usb_hid_set_Audio_report * * @brief set report */ void usb_hid_set_Audio_report(uint8_t fu8_Value) { gu8_AudioReport = fu8_Value; } /********************************************************************* * @fn usb_hid_send_Audio_report * * @brief set report */ int usb_hid_send_Audio_report(void) { usb_selecet_endpoint(ENDPOINT_2); if (usb_Endpoints_GET_TxPktRdy() == false) { usb_write_fifo(ENDPOINT_2, &gu8_AudioReport, 1); usb_Endpoints_SET_TxPktRdy(); } else { return -1; } return 0; } /********************************************************************* * @fn usb_Audio_SetControl * * @brief Set Speaker volume, Set microphone volume * Set Speaker Mute, Set microphone Mute * Set Speaker sampling frequency, Set microphone sampling frequency */ static void usb_Audio_SetControl(void) { uint8_t lu8_RxCount; lu8_RxCount = usb_Endpoint0_get_RxCount(); switch (ge_CTLIndex) { case AUDIO_SET_VOL_SPEAKER: usb_read_fifo(ENDPOINT_0, (uint8_t *)&gu16_VolumeSpeaker, lu8_RxCount); break; case AUDIO_SET_VOL_MIC: usb_read_fifo(ENDPOINT_0, (uint8_t *)&gu16_VolumeMic, lu8_RxCount); break; case AUDIO_SET_MUTE_SPEAKER: usb_read_fifo(ENDPOINT_0, (uint8_t *)&gu8_MuteSpeaker, lu8_RxCount); break; case AUDIO_SET_MUTE_MIC: usb_read_fifo(ENDPOINT_0, (uint8_t *)&gu8_MuteMic, lu8_RxCount); break; case AUDIO_SET_SAMPLING_SPEAKER: { usb_read_fifo(ENDPOINT_0, (uint8_t *)&gu32_SamplingFreqSpeaker, lu8_RxCount); void usb_Audio_ChangeSamplingRate_callback(uint8_t Index); usb_Audio_ChangeSamplingRate_callback(AUDIO_SET_SAMPLING_SPEAKER); }break; case AUDIO_SET_SAMPLING_MIC: { usb_read_fifo(ENDPOINT_0, (uint8_t *)&gu32_SamplingFreqMic, lu8_RxCount); void usb_Audio_ChangeSamplingRate_callback(uint8_t Index); usb_Audio_ChangeSamplingRate_callback(AUDIO_SET_SAMPLING_MIC); }break; default: break; } usb_Endpoint0_FlushFIFO(); Endpoint_0_DataOut_Handler = NULL; } /********************************************************************* * @fn usb_Audio_ClassRequest_Handler * * @brief Audio Class Request Handler * * @param None. * @return None. */ static void usb_Audio_ClassRequest_Handler(usb_StandardRequest_t* pStandardRequest, usb_ReturnData_t* pReturnData) { if (pStandardRequest->bmRequestType & RECIPIENT_INTERFACE) { switch (pStandardRequest->bRequest) { case GET_CUR: { if (pStandardRequest->wValue[1] == MUTE_CONTROL) { if (pStandardRequest->wIndex[1] == 0x02) { gu8_Respond[0] = gu8_MuteSpeaker; } else if (pStandardRequest->wIndex[1] == 0x05) { gu8_Respond[0] = gu8_MuteMic; } pReturnData->DataBuffer = gu8_Respond; pReturnData->DataLength = 1; } else if (pStandardRequest->wValue[1] == VOLUME_CONTROL) { if (pStandardRequest->wIndex[1] == 0x02) { gu8_Respond[0] = gu16_VolumeSpeaker & 0xFF; gu8_Respond[1] = gu16_VolumeSpeaker >> 8 & 0xFF; } else if (pStandardRequest->wIndex[1] == 0x05) { gu8_Respond[0] = gu16_VolumeMic & 0xFF; gu8_Respond[1] = gu16_VolumeMic >> 8 & 0xFF; } pReturnData->DataBuffer = gu8_Respond; pReturnData->DataLength = 2; } }break; case GET_MIN: { if (pStandardRequest->wValue[1] == VOLUME_CONTROL) { gu8_Respond[0] = 0x00; gu8_Respond[1] = 0x00; pReturnData->DataBuffer = gu8_Respond; pReturnData->DataLength = 2; } }break; case GET_MAX: { if (pStandardRequest->wValue[1] == VOLUME_CONTROL) { gu8_Respond[0] = USB_AUDIO_VOLUME_MAX; gu8_Respond[1] = 0x00; pReturnData->DataBuffer = gu8_Respond; pReturnData->DataLength = 2; } }break; case GET_RES: { if (pStandardRequest->wValue[1] == VOLUME_CONTROL) { gu8_Respond[0] = 0x01; gu8_Respond[1] = 0x00; pReturnData->DataBuffer = gu8_Respond; pReturnData->DataLength = 2; } }break; case SET_CUR: { if (pStandardRequest->wValue[1] == VOLUME_CONTROL) { /* Speaker */ if (pStandardRequest->wIndex[1] == 0x02) { ge_CTLIndex = AUDIO_SET_VOL_SPEAKER; } /* microphone */ else if (pStandardRequest->wIndex[1] == 0x05) { ge_CTLIndex = AUDIO_SET_VOL_MIC; } Endpoint_0_DataOut_Handler = usb_Audio_SetControl; } else if (pStandardRequest->wValue[1] == MUTE_CONTROL) { /* Speaker */ if (pStandardRequest->wIndex[1] == 0x02) { ge_CTLIndex = AUDIO_SET_MUTE_SPEAKER; } /* microphone */ else if (pStandardRequest->wIndex[1] == 0x05) { ge_CTLIndex = AUDIO_SET_MUTE_MIC; } Endpoint_0_DataOut_Handler = usb_Audio_SetControl; } } default: break; } } else if (pStandardRequest->bmRequestType & RECIPIENT_ENDPOINT) { switch (pStandardRequest->bRequest) { case SET_CUR: { if (pStandardRequest->wValue[1] == SAMPLING_FREQ_CONTROL) { /* IN Endpoint */ if (pStandardRequest->wIndex[0] == 0x81) { ge_CTLIndex = AUDIO_SET_SAMPLING_MIC; } /* OUT Endpoint */ else if (pStandardRequest->wIndex[0] == 0x02) { ge_CTLIndex = AUDIO_SET_SAMPLING_SPEAKER; } Endpoint_0_DataOut_Handler = usb_Audio_SetControl; } }break; default: break; } } } /********************************************************************* * @fn usb_hid_StandardClassRequest_Handler * * @brief HID Standard Class Request Handler * * @param None. * @return None. */ static void usb_hid_StandardClassRequest_Handler(usb_StandardRequest_t* pStandardRequest, usb_ReturnData_t* pReturnData) { switch (pStandardRequest->wValue[1]) { case DESCRIPTOR_HID_REPORT: { if (pStandardRequest->wIndex[0] == 3){ pReturnData->DataLength = USB_HID_Audio_ReportDesc[0]; pReturnData->DataBuffer = &USB_HID_Audio_ReportDesc[1]; } }break; default: break; } } extern volatile uint16_t MIC_Buffer[960]; extern volatile uint32_t MIC_Packet; extern volatile uint32_t MIC_RxCount; extern volatile uint32_t MIC_TxCount; extern volatile bool MIC_Start; extern volatile uint32_t Speaker_Buffer[192 * 2 * 10]; extern volatile uint32_t Speaker_Packet; extern volatile uint32_t Speaker_RxCount; extern volatile uint32_t Speaker_TxCount; extern volatile bool Speaker_Start; /********************************************************************* * @fn usb_Audio_Endpoints_Handler * * @brief Audio Endpoints Handler * */ void usb_Audio_Endpoints_Handler(uint8_t RxStatus, uint8_t TxStatus) { uint32_t lu32_RxCount; /* ENDPOINT_2 Rx */ if (RxStatus & 0x04) { /* Receive audio playback data */ usb_selecet_endpoint(ENDPOINT_2); if (usb_Endpoints_GET_RxPktRdy()) { switch (gu32_BitWidthSpeaker) { case USB_AUDIO_DATA_WIDTH_16BIT: { lu32_RxCount = usb_Endpoints_get_RxCount_16bit(); usb_read_fifo(ENDPOINT_2, (uint8_t *)&Speaker_Buffer[gu32_PacketLengthSpeaker * Speaker_Packet], lu32_RxCount); usb_Endpoints_FlushRxFIFO(); Speaker_Packet += 1; if (Speaker_Packet >= 10) { Speaker_Packet = 0; } Speaker_RxCount = Speaker_Packet * gu32_PacketLengthSpeaker; if (Speaker_Packet >= 5 && Speaker_Start == false) { Speaker_Start = true; } }break; case USB_AUDIO_DATA_WIDTH_24BIT: { lu32_RxCount = usb_Endpoints_get_RxCount_16bit(); uint32_t BufferIndex = (gu32_PacketLengthSpeaker * 2) * Speaker_Packet; for(int i = 0; i < lu32_RxCount/3; i++) usb_read_fifo(ENDPOINT_2, (uint8_t *)&Speaker_Buffer[BufferIndex + i], 3); usb_Endpoints_FlushRxFIFO(); Speaker_Packet += 1; if (Speaker_Packet >= 10) { Speaker_Packet = 0; } Speaker_RxCount = Speaker_Packet * (gu32_PacketLengthSpeaker * 2); if (Speaker_Packet >= 5 && Speaker_Start == false) { Speaker_Start = true; } }break; default:break; } } } /* ENDPOINT_1 Tx */ if (TxStatus & 0x02) { /* Send microphone data to Host */ if (MIC_Start) { usb_selecet_endpoint(ENDPOINT_1); if (usb_Endpoints_GET_TxPktRdy() == false) { usb_write_fifo(ENDPOINT_1, (uint8_t *)&MIC_Buffer[MIC_TxCount], gu32_PacketLengthMic*2); usb_Endpoints_SET_TxPktRdy(); MIC_TxCount += gu32_PacketLengthMic; if (MIC_TxCount >= gu32_PacketLengthMic*10) { MIC_TxCount = 0; } } } } } void usb_Audio_InterfaceAlternateSet_callback(uint8_t Interface) { switch (Interface) { /* Speaker Interface */ case 1: { /* Change the data bit width */ if (usbdev_get_interface_alternate_num(1) == 1) gu32_BitWidthSpeaker = USB_AUDIO_DATA_WIDTH_16BIT; else if (usbdev_get_interface_alternate_num(1) == 2) gu32_BitWidthSpeaker = USB_AUDIO_DATA_WIDTH_24BIT; }break; default:break; } } void usb_Audio_ChangeSamplingRate_callback(uint8_t Index) { switch (Index) { /* Change the Speaker sampling rate */ case AUDIO_SET_SAMPLING_SPEAKER: { gu32_PacketLengthSpeaker = gu32_SamplingFreqSpeaker/1000; }break; /* Change the Mic sampling rate */ case AUDIO_SET_SAMPLING_MIC: { gu32_PacketLengthMic = gu32_SamplingFreqMic/1000; }break; default:break; } } uint32_t usb_Audio_get_Speaker_Packet_Length(void) { return gu32_PacketLengthSpeaker; } uint32_t usb_Audio_get_Mic_Packet_Length(void) { return gu32_PacketLengthMic; } uint32_t usb_Audio_get_Speaker_Bit_Width(void) { return gu32_BitWidthSpeaker; } uint32_t usb_Audio_get_Mic_Bit_Width(void) { return gu32_BitWidthMic; } uint32_t usb_Audio_get_Speaker_Mute_status(void) { return gu8_MuteSpeaker; } uint32_t usb_Audio_get_Mic_Mute_status(void) { return gu8_MuteMic; } uint32_t usb_Audio_get_Speaker_Volume(void) { return gu16_VolumeSpeaker; } uint32_t usb_Audio_get_Mic_Volume(void) { return gu16_VolumeMic; } uint32_t usb_Audio_get_Speaker_SamplingFreq(void) { return gu32_SamplingFreqSpeaker; } uint32_t usb_Audio_get_Mic_SamplingFreq(void) { return gu32_SamplingFreqMic; } /********************************************************************* * @fn usb_audio_init * * @brief audio device parameter initialization * * @param None. * @return None. */ void usb_audio_init(void) { /* Initialize the relevant pointer */ usbdev_get_dev_desc((uint8_t *)USB_Audio_DeviceDesc); usbdev_get_config_desc((uint8_t *)USB_Audio_ConfigurationDesc); usbdev_get_string_Manufacture((uint8_t *)USB_Audio_ManufactureDesc); usbdev_get_string_Product((uint8_t *)USB_Audio_ProductDesc); usbdev_get_string_SerialNumber((uint8_t *)USB_Audio_SerialNumberDesc); usbdev_get_string_LanuageID((uint8_t *)USB_Audio_LanuageIDDesc); Endpoint_0_StandardClassRequest_Handler = usb_hid_StandardClassRequest_Handler; Endpoint_0_ClassRequest_Handler = usb_Audio_ClassRequest_Handler; Endpoints_Handler = usb_Audio_Endpoints_Handler; USB_InterfaceAlternateSet_callback = usb_Audio_InterfaceAlternateSet_callback; USB_Reset_Handler = usb_audio_init; /* config data endpoint fifo */ usb_selecet_endpoint(ENDPOINT_1); usb_TxSyncEndpoint_enable(); usb_endpoint_Txfifo_config(64/8, 5); /* 256 Byte, 64 ~ 319 */ usb_TxMaxP_set(256/8); usb_selecet_endpoint(ENDPOINT_2); usb_RxSyncEndpoint_enable(); usb_endpoint_Rxfifo_config(320/8, 6); /* 512 Byte, 320 ~ 831 */ usb_RxMaxP_set(512/8); usb_endpoint_Txfifo_config(832/8, 1); /* 16 Byte, 832 ~ 464 */ usb_TxMaxP_set(16/8); usb_TxInt_Enable(ENDPOINT_1); usb_RxInt_Enable(ENDPOINT_2); }