2 * @brief Audio device class ROM based application's specific functions supporting audio class layer
5 * Copyright(C) NXP Semiconductors, 2012
9 * Software that is described herein is for illustrative purposes only
10 * which provides customers with programming information regarding the
11 * LPC products. This software is supplied "AS IS" without any warranties of
12 * any kind, and NXP Semiconductors and its licensor disclaim any and
13 * all warranties, express or implied, including all implied warranties of
14 * merchantability, fitness for a particular purpose and non-infringement of
15 * intellectual property rights. NXP Semiconductors assumes no responsibility
16 * or liability for the use of the software, conveys no license or rights under any
17 * patent, copyright, mask work right, or any other intellectual property rights in
18 * or to any products. NXP Semiconductors reserves the right to make changes
19 * in the software without notification. NXP Semiconductors also makes no
20 * representation or warranty that such application will be suitable for the
21 * specified use without further testing or modification.
24 * Permission to use, copy, modify, and distribute this software and its
25 * documentation is hereby granted, under NXP Semiconductors' and its
26 * licensor's relevant copyrights in the software, without fee, provided that it
27 * is used in conjunction with NXP Semiconductors microcontrollers. This
28 * copyright, permission, and disclaimer notice must appear in all copies of
32 #define __INCLUDE_FROM_USB_DRIVER
33 #include "../../USBMode.h"
35 #if defined(USB_CAN_BE_DEVICE)
37 #if defined(USB_DEVICE_ROM_DRIVER) && !(defined(__LPC11U2X_3X__)||defined(__LPC13UXX__))
38 #include "../../../Class/AudioClass.h"
39 #include "usbd_adcuser.h"
41 /** Internal definition */
42 #define AUDIO_MAX_SAMPLE_FREQ 48000
44 /* Volume definitions */
45 #define VOLUME_MIN 0x0000
46 #define VOLUME_MAX 0x003F
47 #define VOLUME_RES 0x0001
49 uint32_t ISO_packet_size = 0;
51 /* Device Transfer Descriptor used in Custom ROM mode */
52 DeviceTransferDescriptor Rom_dTD ATTR_ALIGNED(32);
53 /* external Audio Sample Frequency variable */
54 extern uint32_t CurrentAudioSampleFrequency;
57 static uint8_t ISOEndpointNumber;
58 static uint8_t StreamInterfaceNumber;
59 static uint8_t ControlInterfaceNumber;
60 static uint8_t USBPort;
62 extern uint32_t sample_buffer_size;
64 extern uint32_t CALLBACK_HAL_GetISOBufferAddress(const uint32_t EPNum, uint32_t* last_packet_size);
65 extern void Audio_Reset_Data_Buffer(void);
66 extern void Audio_Init (uint32_t samplefreq);
68 /* inline functions */
69 static INLINE DeviceQueueHead* Usbd_GetEpQH(USB_CORE_CTRL_T* pCtrl, uint8_t ep)
71 DeviceQueueHead* ep_QH = (DeviceQueueHead*)(*((uint32_t*)pCtrl->hw_data));
72 uint32_t ep_idx = (ep & 0x0F) << 1;
77 return &ep_QH[ep_idx];
80 /** Get Transfer packet size */
81 static INLINE uint32_t Usbd_GetTransferSize(USB_CORE_CTRL_T *pCtrl, uint8_t ep)
83 DeviceQueueHead *ep_QH = Usbd_GetEpQH(pCtrl, ep);
84 return ep_QH->TransferCount - ep_QH->overlay.TotalBytes;
87 static void UsbdDcdDataTransfer(uint8_t EPNum, uint8_t *pData, uint32_t length)
89 uint8_t PhyEP = (EPNum<<1) | (EPNum>>7); /* Rotate left without carry */
90 DeviceQueueHead* ep_QH = Usbd_GetEpQH((USB_CORE_CTRL_T*) UsbHandle, EPNum);
91 DeviceTransferDescriptor* pDTD = (DeviceTransferDescriptor*) &Rom_dTD;
92 IP_USBHS_001_T * USB_Reg;
93 USB_Reg = USB_REG(USBPort);
95 while ( USB_Reg->ENDPTSTAT & _BIT( EP_Physical2BitPosition(PhyEP) ) ) /* Endpoint is already primed */
99 /* Zero out the device transfer descriptors */
100 memset((void*)pDTD, 0, sizeof(DeviceTransferDescriptor));
102 if(((ENDPTCTRL_REG(USBPort, PhyEP/2)>>2)&EP_TYPE_MASK)==EP_TYPE_ISOCHRONOUS) // iso out endpoint
104 uint32_t mult = (USB_DATA_BUFFER_TEM_LENGTH + 1024) / 1024;
105 pDTD->NextTD = LINK_TERMINATE ;
108 else if(((ENDPTCTRL_REG(USBPort, PhyEP/2)>>18)&EP_TYPE_MASK)==EP_TYPE_ISOCHRONOUS)// iso in endpoint
110 uint32_t mult = (USB_DATA_BUFFER_TEM_LENGTH + 1024) / 1024;
111 pDTD->NextTD = LINK_TERMINATE;
114 else { // other endpoint types
115 pDTD->NextTD = LINK_TERMINATE; /* The next DTD pointer is INVALID */
118 pDTD->TotalBytes = length;
119 pDTD->IntOnComplete = 1;
121 pDTD->MultiplierOverride = 1;
123 pDTD->BufferPage[0] = (uint32_t) pData;
124 pDTD->BufferPage[1] = ((uint32_t) pData + 0x1000) & 0xfffff000;
125 pDTD->BufferPage[2] = ((uint32_t) pData + 0x2000) & 0xfffff000;
126 pDTD->BufferPage[3] = ((uint32_t) pData + 0x3000) & 0xfffff000;
127 pDTD->BufferPage[4] = ((uint32_t) pData + 0x4000) & 0xfffff000;
130 ep_QH->MaxPacketSize = 512;
131 ep_QH->overlay.NextTD = (uint32_t) pDTD;
132 ep_QH->TransferCount = length;
134 /* prime the endpoint for transmit */
135 USB_Reg->ENDPTPRIME |= _BIT( EP_Physical2BitPosition(PhyEP) ) ;
138 /** Initialize USBD ADC driver */
139 void UsbdAdc_Init(USB_ClassInfo_Audio_Device_t* AudioInterface)
142 USBD_API->hw->ForceFullSpeed(UsbHandle,1);
144 /* register ep0 handler */
145 USBD_API->core->RegisterClassHandler(UsbHandle, UsbdAdc_ep0_hdlr, NULL);
147 StreamInterfaceNumber = AudioInterface->Config.StreamingInterfaceNumber;
148 ControlInterfaceNumber = AudioInterface->Config.ControlInterfaceNumber;
149 USBPort = AudioInterface->Config.PortNumber;
150 /* register ISO OUT endpoint interrupt handler */
151 if(AudioInterface->Config.DataOUTEndpointNumber)
153 ISOEndpointNumber = AudioInterface->Config.DataOUTEndpointNumber;
154 ep_indx = ((ISOEndpointNumber & 0x0F) << 1);
155 USBD_API->core->RegisterEpHandler (UsbHandle, ep_indx, UsbdAdc_ISO_Hdlr, NULL);
157 else if(AudioInterface->Config.DataINEndpointNumber)
159 ISOEndpointNumber = AudioInterface->Config.DataINEndpointNumber;
160 ep_indx = ((ISOEndpointNumber & 0x0F) << 1) + 1;
161 USBD_API->core->RegisterEpHandler (UsbHandle, ep_indx, UsbdAdc_ISO_Hdlr, NULL);
166 /**----------------------------------------------------------------------------
167 ADC_IF_GetRequest: Audio Device Class Interface Get Request Callback
168 Called automatically on ADC Interface Get Request
169 *----------------------------------------------------------------------------*/
170 ErrorCode_t ADC_IF_GetRequest (USB_CORE_CTRL_T* pCtrl)
174 Interface = SetupPacket.wIndex.WB.L;
175 EntityID = SetupPacket.wIndex.WB.H;
176 Request = SetupPacket.bRequest;
177 Value = SetupPacket.wValue.W;
180 ErrorCode_t ret = ERR_USBD_INVALID_REQ;
182 if (pCtrl->SetupPacket.wIndex.W == 0x0200) {
183 /* Feature Unit: Interface = 0, ID = 2 */
184 if (pCtrl->SetupPacket.wValue.WB.L == 0) {
186 switch (pCtrl->SetupPacket.wValue.WB.H) {
187 case AUDIO_MUTE_CONTROL:
188 if (pCtrl->SetupPacket.bRequest == AUDIO_REQUEST_GET_CUR) {
190 //pCtrl->EP0Buf[0] = (ADC_PLAY_MUTE)?1:0;
194 case AUDIO_VOLUME_CONTROL:
195 switch (pCtrl->SetupPacket.bRequest) {
196 case AUDIO_REQUEST_GET_CUR:
197 *((uint16_t *)pCtrl->EP0Buf) = curr_vol;
200 case AUDIO_REQUEST_GET_MIN:
201 *((uint16_t *)pCtrl->EP0Buf) = VOLUME_MIN;
204 case AUDIO_REQUEST_GET_MAX:
205 *((uint16_t *)pCtrl->EP0Buf) = VOLUME_MAX;
208 case AUDIO_REQUEST_GET_RES:
209 *((uint16_t *)pCtrl->EP0Buf) = VOLUME_RES;
218 return (ret); /* Not Supported */
222 /**----------------------------------------------------------------------------
223 ADC_IF_SetRequest: Audio Device Class Interface Set Request Callback
224 Called automatically on ADC Interface Set Request
225 *----------------------------------------------------------------------------*/
226 ErrorCode_t ADC_IF_SetRequest (USB_CORE_CTRL_T* pCtrl)
230 Interface = SetupPacket.wIndex.WB.L;
231 EntityID = SetupPacket.wIndex.WB.H;
232 Request = SetupPacket.bRequest;
233 Value = SetupPacket.wValue.W;
236 ErrorCode_t ret = ERR_USBD_INVALID_REQ;
237 if (pCtrl->SetupPacket.wIndex.W == 0x0200) {
238 /* Feature Unit: Interface = 0, ID = 2 */
239 if ((pCtrl->SetupPacket.wValue.WB.L == 0) &&
240 (pCtrl->SetupPacket.bRequest == AUDIO_REQUEST_SET_CUR)) {
242 switch (pCtrl->SetupPacket.wValue.WB.H) {
243 case AUDIO_MUTE_CONTROL:
244 if (pCtrl->EP0Buf[0])
245 { /*TODO: set MUTE here */
247 { /*TODO: disable MUTE here */
251 case AUDIO_VOLUME_CONTROL:
252 /*TODO: Set volume here */
253 curr_vol = *((uint16_t *)pCtrl->EP0Buf);
260 return ret; /* Not Supported */
264 /**----------------------------------------------------------------------------
265 ADC_EP_GetRequest: Audio Device Class EndPoint Get Request Callback
266 Called automatically on ADC EndPoint Get Request
267 *----------------------------------------------------------------------------*/
268 ErrorCode_t ADC_EP_GetRequest (USB_CORE_CTRL_T* pCtrl)
271 EndPoint = SetupPacket.wIndex.WB.L;
272 Request = SetupPacket.bRequest;
273 Value = SetupPacket.wValue.W;
276 ErrorCode_t ret = ERR_USBD_INVALID_REQ;
278 if((pCtrl->SetupPacket.wIndex.W & 0x7F) == ISOEndpointNumber) {
279 /* Feature Unit: Interface = 0, ID = 2 */
280 if (pCtrl->SetupPacket.wValue.WB.L == 0) {
282 if ((pCtrl->SetupPacket.wValue.WB.H == AUDIO_CONTROL_SAMPLING_FREQ) &&
283 (pCtrl->SetupPacket.bRequest == AUDIO_REQUEST_GET_CUR) ) {
284 pCtrl->EP0Buf[0] = (uint8_t)(CurrentAudioSampleFrequency & 0xFF);
285 pCtrl->EP0Buf[1] = (uint8_t)((CurrentAudioSampleFrequency >> 8) & 0xFF);
286 pCtrl->EP0Buf[2] = (uint8_t)((CurrentAudioSampleFrequency >> 16) & 0xFF);
291 return ret; /* Not Supported */
295 /**----------------------------------------------------------------------------
296 ADC_EP_SetRequest: Audio Device Class EndPoint Set Request Callback
297 Called automatically on ADC EndPoint Set Request
298 *----------------------------------------------------------------------------*/
299 ErrorCode_t ADC_EP_SetRequest (USB_CORE_CTRL_T* pCtrl)
303 EndPoint = SetupPacket.wIndex.WB.L;
304 Request = SetupPacket.bRequest;
305 Value = SetupPacket.wValue.W;
309 ErrorCode_t ret = ERR_USBD_INVALID_REQ;
311 if((pCtrl->SetupPacket.wIndex.W & 0x7F) == ISOEndpointNumber) {
312 /* Feature Unit: Interface = 0, ID = 2 */
313 if (pCtrl->SetupPacket.wValue.WB.L == 0) {
315 if (pCtrl->SetupPacket.wValue.WB.H == AUDIO_CONTROL_SAMPLING_FREQ) {
316 rate = pCtrl->EP0Buf[0] | (pCtrl->EP0Buf[1] << 8) | (pCtrl->EP0Buf[2] << 16);
317 if (pCtrl->SetupPacket.bRequest == AUDIO_REQUEST_SET_CUR) {
318 CurrentAudioSampleFrequency = rate;
319 if(CurrentAudioSampleFrequency <= AUDIO_MAX_SAMPLE_FREQ)
321 Audio_Init(CurrentAudioSampleFrequency);
328 return (ret); /* Not Supported */
331 /**----------------------------------------------------------------------------
332 Override standard Interface Event
333 *----------------------------------------------------------------------------*/
334 ErrorCode_t USB_Interface_Event (USBD_HANDLE_T hUsb)
336 USB_CORE_CTRL_T* pCtrl = (USB_CORE_CTRL_T*)hUsb;
337 uint16_t wIndex = pCtrl->SetupPacket.wIndex.W;
338 uint16_t wValue = pCtrl->SetupPacket.wValue.W;
340 /* write code to enable/disable audo playback when interface
341 ALT setting is changed */
342 if (wIndex == StreamInterfaceNumber) {
343 if((wValue == 0x0001)){
354 /** disable configure event in usbd_rom.c */
355 ErrorCode_t USB_Configure_Event (USBD_HANDLE_T hUsb)
360 #if defined(__ICCARM__)
361 /* Temp fix for IAR */
362 uint32_t TransferDelayidx=0;
363 volatile uint8_t Event_store[128];
366 /**----------------------------------------------------------------------------
368 *----------------------------------------------------------------------------*/
369 ErrorCode_t UsbdAdc_ep0_hdlr(USBD_HANDLE_T hUsb, void* data, uint32_t event)
371 USB_CORE_CTRL_T* pCtrl = (USB_CORE_CTRL_T*)hUsb;
372 ErrorCode_t ret = ERR_USBD_UNHANDLED;
374 #if defined(__ICCARM__)
375 /* Temp fix for IAR */
376 Event_store[TransferDelayidx] = event;
379 if (pCtrl->SetupPacket.bmRequestType.BM.Type == REQUEST_CLASS) {
382 if ((pCtrl->SetupPacket.bmRequestType.BM.Recipient == REQUEST_TO_INTERFACE) &&
383 ((pCtrl->SetupPacket.wIndex.WB.L == ControlInterfaceNumber) || /* IF number correct? */
384 (pCtrl->SetupPacket.wIndex.WB.L == StreamInterfaceNumber)) ) {
385 switch (pCtrl->SetupPacket.bRequest) {
386 case AUDIO_REQUEST_GET_CUR:
387 case AUDIO_REQUEST_GET_MIN:
388 case AUDIO_REQUEST_GET_MAX:
389 case AUDIO_REQUEST_GET_RES:
391 ret = ADC_IF_GetRequest(pCtrl);
393 pCtrl->EP0Data.pData = pCtrl->EP0Buf; /* point to data to be sent */
394 USBD_API->core->DataInStage(pCtrl); /* send requested data */
397 case AUDIO_REQUEST_SET_CUR:
398 // case AUDIO_REQUEST_SET_MIN:
399 // case AUDIO_REQUEST_SET_MAX:
400 // case AUDIO_REQUEST_SET_RES:
401 pCtrl->EP0Data.pData = pCtrl->EP0Buf; /* data to be received */
407 else if (pCtrl->SetupPacket.bmRequestType.BM.Recipient == REQUEST_TO_ENDPOINT) {
408 switch (pCtrl->SetupPacket.bRequest) {
409 case AUDIO_REQUEST_GET_CUR:
410 case AUDIO_REQUEST_GET_MIN:
411 case AUDIO_REQUEST_GET_MAX:
412 case AUDIO_REQUEST_GET_RES:
413 ret = ADC_EP_GetRequest(pCtrl);
415 pCtrl->EP0Data.pData = pCtrl->EP0Buf; /* point to data to be sent */
416 USBD_API->core->DataInStage(pCtrl); /* send requested data */
419 case AUDIO_REQUEST_SET_CUR:
420 // case AUDIO_REQUEST_SET_MIN:
421 // case AUDIO_REQUEST_SET_MAX:
422 // case AUDIO_REQUEST_SET_RES:
423 pCtrl->EP0Data.pData = pCtrl->EP0Buf; /* data to be received */
430 if ((pCtrl->SetupPacket.bmRequestType.BM.Recipient == REQUEST_TO_INTERFACE) &&
431 ((pCtrl->SetupPacket.wIndex.WB.L == ControlInterfaceNumber) || /* IF number correct? */
432 (pCtrl->SetupPacket.wIndex.WB.L == StreamInterfaceNumber)) ) {
433 switch (pCtrl->SetupPacket.bRequest) {
434 case AUDIO_REQUEST_SET_CUR:
435 // case AUDIO_REQUEST_SET_MIN:
436 // case AUDIO_REQUEST_SET_MAX:
437 // case AUDIO_REQUEST_SET_RES:
438 ret = ADC_IF_SetRequest(pCtrl);
440 USBD_API->core->StatusInStage(pCtrl); /* send Acknowledge */
444 } else if (pCtrl->SetupPacket.bmRequestType.BM.Recipient == REQUEST_TO_ENDPOINT) {
445 switch (pCtrl->SetupPacket.bRequest) {
446 case AUDIO_REQUEST_SET_CUR:
447 // case AUDIO_REQUEST_SET_MIN:
448 // case AUDIO_REQUEST_SET_MAX:
449 // case AUDIO_REQUEST_SET_RES:
450 ret = ADC_EP_SetRequest(pCtrl);
452 USBD_API->core->StatusInStage(pCtrl); /* send Acknowledge */
466 /**----------------------------------------------------------------------------
467 Audio Start Transfer Callback
468 *----------------------------------------------------------------------------*/
469 void UsbdAdc_start_xfr(void)
472 uint32_t ISO_buffer_address;
473 /* reset audio buffer */
474 Audio_Reset_Data_Buffer();
475 ISO_buffer_address = CALLBACK_HAL_GetISOBufferAddress(USB_ENDPOINT_IN(ISOEndpointNumber), &ISO_packet_size);
476 if(ISO_buffer_address != 0)
477 UsbdDcdDataTransfer(USB_ENDPOINT_IN(ISOEndpointNumber), (uint8_t*)ISO_buffer_address, ISO_packet_size);
479 ISO_buffer_address = CALLBACK_HAL_GetISOBufferAddress(ISOEndpointNumber, &ISO_packet_size);
480 if(ISO_buffer_address != 0)
481 UsbdDcdDataTransfer(ISOEndpointNumber, (uint8_t*)ISO_buffer_address, 512);
484 /**----------------------------------------------------------------------------
485 Audio Stop Transfer Callback
486 *----------------------------------------------------------------------------*/
487 void UsbdAdc_stop_xfr(void)
490 /* reset audio buffer */
491 Audio_Reset_Data_Buffer();
492 USBD_API->hw->ResetEP(UsbHandle, ISOEndpointNumber);
493 USBD_API->hw->ResetEP(UsbHandle, USB_ENDPOINT_IN(ISOEndpointNumber));
497 /**----------------------------------------------------------------------------
499 *----------------------------------------------------------------------------*/
500 ErrorCode_t UsbdAdc_ISO_Hdlr (USBD_HANDLE_T hUsb, void* data, uint32_t event)
502 uint32_t ISO_buffer_address;
504 if (event == USB_EVT_OUT) {
505 ISO_packet_size = Usbd_GetTransferSize((USB_CORE_CTRL_T *) hUsb, ISOEndpointNumber);
506 if (ISO_packet_size != 0) {
507 ISO_packet_size = ISO_packet_size;
509 /* Send DMA request */
510 ISO_buffer_address = CALLBACK_HAL_GetISOBufferAddress(ISOEndpointNumber, &ISO_packet_size);
511 UsbdDcdDataTransfer(ISOEndpointNumber, (uint8_t *) ISO_buffer_address, 512);
514 if (event == USB_EVT_IN)
516 /* Send DMA request */
517 ISO_buffer_address = CALLBACK_HAL_GetISOBufferAddress(USB_ENDPOINT_IN(ISOEndpointNumber), &ISO_packet_size);
518 UsbdDcdDataTransfer(USB_ENDPOINT_IN(ISOEndpointNumber), (uint8_t*)ISO_buffer_address, ISO_packet_size);