LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
usbd_adcuser.c
Go to the documentation of this file.
1 /*
2  * @brief Audio device class ROM based application's specific functions supporting audio class layer
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2012
6  * All rights reserved.
7  *
8  * @par
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.
22  *
23  * @par
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
29  * this code.
30  */
31 
32 #define __INCLUDE_FROM_USB_DRIVER
33 #include "../../USBMode.h"
34 
35 #if defined(USB_CAN_BE_DEVICE)
36 
37 #if defined(USB_DEVICE_ROM_DRIVER) && !(defined(__LPC11U2X_3X__)||defined(__LPC13UXX__))
38 #include "../../../Class/AudioClass.h"
39 #include "usbd_adcuser.h"
40 
42 #define AUDIO_MAX_SAMPLE_FREQ 48000
43 
44 /* Volume definitions */
45 #define VOLUME_MIN 0x0000
46 #define VOLUME_MAX 0x003F
47 #define VOLUME_RES 0x0001
48 
49 uint32_t ISO_packet_size = 0;
50 
51 /* Device Transfer Descriptor used in Custom ROM mode */
52 DeviceTransferDescriptor Rom_dTD ATTR_ALIGNED(32);
53 /* external Audio Sample Frequency variable */
55 /* Current Volume */
56 uint32_t curr_vol;
57 static uint8_t ISOEndpointNumber;
58 static uint8_t StreamInterfaceNumber;
59 static uint8_t ControlInterfaceNumber;
60 static uint8_t USBPort;
61 
62 extern uint32_t sample_buffer_size;
63 
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);
67 
68 /* inline functions */
69 static INLINE DeviceQueueHead* Usbd_GetEpQH(USB_CORE_CTRL_T* pCtrl, uint8_t ep)
70 {
71  DeviceQueueHead* ep_QH = (DeviceQueueHead*)(*((uint32_t*)pCtrl->hw_data));
72  uint32_t ep_idx = (ep & 0x0F) << 1;
73 
74  if(ep & 0x80)
75  ep_idx++;
76 
77  return &ep_QH[ep_idx];
78 }
79 
81 static INLINE uint32_t Usbd_GetTransferSize(USB_CORE_CTRL_T *pCtrl, uint8_t ep)
82 {
83  DeviceQueueHead *ep_QH = Usbd_GetEpQH(pCtrl, ep);
84  return ep_QH->TransferCount - ep_QH->overlay.TotalBytes;
85 }
86 
87 static void UsbdDcdDataTransfer(uint8_t EPNum, uint8_t *pData, uint32_t length)
88 {
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);
94 
95  while ( USB_Reg->ENDPTSTAT & _BIT( EP_Physical2BitPosition(PhyEP) ) ) /* Endpoint is already primed */
96  {
97  }
98 
99  /* Zero out the device transfer descriptors */
100  memset((void*)pDTD, 0, sizeof(DeviceTransferDescriptor));
101 
102  if(((ENDPTCTRL_REG(USBPort, PhyEP/2)>>2)&EP_TYPE_MASK)==EP_TYPE_ISOCHRONOUS) // iso out endpoint
103  {
104  uint32_t mult = (USB_DATA_BUFFER_TEM_LENGTH + 1024) / 1024;
105  pDTD->NextTD = LINK_TERMINATE ;
106  ep_QH->Mult = mult;
107  }
108  else if(((ENDPTCTRL_REG(USBPort, PhyEP/2)>>18)&EP_TYPE_MASK)==EP_TYPE_ISOCHRONOUS)// iso in endpoint
109  {
110  uint32_t mult = (USB_DATA_BUFFER_TEM_LENGTH + 1024) / 1024;
111  pDTD->NextTD = LINK_TERMINATE;
112  ep_QH->Mult = mult;
113  }
114  else { // other endpoint types
115  pDTD->NextTD = LINK_TERMINATE; /* The next DTD pointer is INVALID */
116  }
117 
118  pDTD->TotalBytes = length;
119  pDTD->IntOnComplete = 1;
120  pDTD->Active = 1;
121  pDTD->MultiplierOverride = 1;
122 
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;
128 
129  ep_QH->Mult = 1;
130  ep_QH->MaxPacketSize = 512;
131  ep_QH->overlay.NextTD = (uint32_t) pDTD;
132  ep_QH->TransferCount = length;
133 
134  /* prime the endpoint for transmit */
135  USB_Reg->ENDPTPRIME |= _BIT( EP_Physical2BitPosition(PhyEP) ) ;
136 }
137 
139 void UsbdAdc_Init(USB_ClassInfo_Audio_Device_t* AudioInterface)
140 {
141  uint32_t ep_indx;
142  USBD_API->hw->ForceFullSpeed(UsbHandle,1);
143 
144  /* register ep0 handler */
145  USBD_API->core->RegisterClassHandler(UsbHandle, UsbdAdc_ep0_hdlr, NULL);
146 
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)
152  {
153  ISOEndpointNumber = AudioInterface->Config.DataOUTEndpointNumber;
154  ep_indx = ((ISOEndpointNumber & 0x0F) << 1);
155  USBD_API->core->RegisterEpHandler (UsbHandle, ep_indx, UsbdAdc_ISO_Hdlr, NULL);
156  }
157  else if(AudioInterface->Config.DataINEndpointNumber)
158  {
159  ISOEndpointNumber = AudioInterface->Config.DataINEndpointNumber;
160  ep_indx = ((ISOEndpointNumber & 0x0F) << 1) + 1;
161  USBD_API->core->RegisterEpHandler (UsbHandle, ep_indx, UsbdAdc_ISO_Hdlr, NULL);
162  }
163 
164 }
165 
170 ErrorCode_t ADC_IF_GetRequest (USB_CORE_CTRL_T* pCtrl)
171 {
172 
173  /*
174  Interface = SetupPacket.wIndex.WB.L;
175  EntityID = SetupPacket.wIndex.WB.H;
176  Request = SetupPacket.bRequest;
177  Value = SetupPacket.wValue.W;
178  ...
179  */
181 
182  if (pCtrl->SetupPacket.wIndex.W == 0x0200) {
183  /* Feature Unit: Interface = 0, ID = 2 */
184  if (pCtrl->SetupPacket.wValue.WB.L == 0) {
185  /* Master Channel */
186  switch (pCtrl->SetupPacket.wValue.WB.H) {
187  case AUDIO_MUTE_CONTROL:
188  if (pCtrl->SetupPacket.bRequest == AUDIO_REQUEST_GET_CUR) {
189  /*TODO: Get MUTE */
190  //pCtrl->EP0Buf[0] = (ADC_PLAY_MUTE)?1:0;
191  ret = LPC_OK;
192  }
193  break;
195  switch (pCtrl->SetupPacket.bRequest) {
197  *((uint16_t *)pCtrl->EP0Buf) = curr_vol;
198  ret = LPC_OK;
199  break;
201  *((uint16_t *)pCtrl->EP0Buf) = VOLUME_MIN;
202  ret = LPC_OK;
203  break;
205  *((uint16_t *)pCtrl->EP0Buf) = VOLUME_MAX;
206  ret = LPC_OK;
207  break;
209  *((uint16_t *)pCtrl->EP0Buf) = VOLUME_RES;
210  ret = LPC_OK;
211  break;
212  }
213  break;
214  }
215  }
216  }
217 
218  return (ret); /* Not Supported */
219 }
220 
221 
226 ErrorCode_t ADC_IF_SetRequest (USB_CORE_CTRL_T* pCtrl)
227 {
228 
229 /*
230  Interface = SetupPacket.wIndex.WB.L;
231  EntityID = SetupPacket.wIndex.WB.H;
232  Request = SetupPacket.bRequest;
233  Value = SetupPacket.wValue.W;
234  ...
235 */
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)) {
241  /* Master Channel */
242  switch (pCtrl->SetupPacket.wValue.WB.H) {
243  case AUDIO_MUTE_CONTROL:
244  if (pCtrl->EP0Buf[0])
245  { /*TODO: set MUTE here */
246  }else
247  { /*TODO: disable MUTE here */
248  }
249  ret = (LPC_OK);
250  break;
252  /*TODO: Set volume here */
253  curr_vol = *((uint16_t *)pCtrl->EP0Buf);
254  ret = (LPC_OK);
255  break;
256  }
257  }
258  }
259 
260  return ret; /* Not Supported */
261 }
262 
263 
268 ErrorCode_t ADC_EP_GetRequest (USB_CORE_CTRL_T* pCtrl)
269 {
270  /*
271  EndPoint = SetupPacket.wIndex.WB.L;
272  Request = SetupPacket.bRequest;
273  Value = SetupPacket.wValue.W;
274  ...
275  */
277 
278  if((pCtrl->SetupPacket.wIndex.W & 0x7F) == ISOEndpointNumber) {
279  /* Feature Unit: Interface = 0, ID = 2 */
280  if (pCtrl->SetupPacket.wValue.WB.L == 0) {
281  /* Master Channel */
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);
287  ret = (LPC_OK);
288  }
289  }
290  }
291  return ret; /* Not Supported */
292 }
293 
294 
299 ErrorCode_t ADC_EP_SetRequest (USB_CORE_CTRL_T* pCtrl)
300 {
301 
302  /*
303  EndPoint = SetupPacket.wIndex.WB.L;
304  Request = SetupPacket.bRequest;
305  Value = SetupPacket.wValue.W;
306  ...
307  */
308  uint32_t rate;
310 
311  if((pCtrl->SetupPacket.wIndex.W & 0x7F) == ISOEndpointNumber) {
312  /* Feature Unit: Interface = 0, ID = 2 */
313  if (pCtrl->SetupPacket.wValue.WB.L == 0) {
314  /* Master Channel */
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) {
320  {
322  ret = LPC_OK;
323  }
324  }
325  }
326  }
327  }
328  return (ret); /* Not Supported */
329 }
330 
335 {
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;
339 
340  /* write code to enable/disable audo playback when interface
341  ALT setting is changed */
342  if (wIndex == StreamInterfaceNumber) {
343  if((wValue == 0x0001)){
345  }else
346  {
348  }
349 
350  }
351 
352  return LPC_OK;
353 }
355 ErrorCode_t USB_Configure_Event (USBD_HANDLE_T hUsb)
356 {
357  return LPC_OK;
358 }
359 
360 #if defined(__ICCARM__)
361 /* Temp fix for IAR */
362 uint32_t TransferDelayidx=0;
363 volatile uint8_t Event_store[128];
364 #endif
365 
370 {
371  USB_CORE_CTRL_T* pCtrl = (USB_CORE_CTRL_T*)hUsb;
373 
374  #if defined(__ICCARM__)
375  /* Temp fix for IAR */
376  Event_store[TransferDelayidx] = event;
377  #endif
378 
379  if (pCtrl->SetupPacket.bmRequestType.BM.Type == REQUEST_CLASS) {
380  switch (event) {
381  case USB_EVT_SETUP:
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) {
390 
391  ret = ADC_IF_GetRequest(pCtrl);
392  if (ret == LPC_OK) {
393  pCtrl->EP0Data.pData = pCtrl->EP0Buf; /* point to data to be sent */
394  USBD_API->core->DataInStage(pCtrl); /* send requested data */
395  }
396  break;
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 */
402 
403  ret = LPC_OK;
404  break;
405  }
406  }
407  else if (pCtrl->SetupPacket.bmRequestType.BM.Recipient == REQUEST_TO_ENDPOINT) {
408  switch (pCtrl->SetupPacket.bRequest) {
413  ret = ADC_EP_GetRequest(pCtrl);
414  if (ret == LPC_OK) {
415  pCtrl->EP0Data.pData = pCtrl->EP0Buf; /* point to data to be sent */
416  USBD_API->core->DataInStage(pCtrl); /* send requested data */
417  }
418  break;
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 */
424  ret = LPC_OK;
425  break;
426  }
427  }
428  break;
429  case USB_EVT_OUT:
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) {
435  // case AUDIO_REQUEST_SET_MIN:
436  // case AUDIO_REQUEST_SET_MAX:
437  // case AUDIO_REQUEST_SET_RES:
438  ret = ADC_IF_SetRequest(pCtrl);
439  if (ret == LPC_OK) {
440  USBD_API->core->StatusInStage(pCtrl); /* send Acknowledge */
441  }
442  break;
443  }
444  } else if (pCtrl->SetupPacket.bmRequestType.BM.Recipient == REQUEST_TO_ENDPOINT) {
445  switch (pCtrl->SetupPacket.bRequest) {
447  // case AUDIO_REQUEST_SET_MIN:
448  // case AUDIO_REQUEST_SET_MAX:
449  // case AUDIO_REQUEST_SET_RES:
450  ret = ADC_EP_SetRequest(pCtrl);
451  if (ret == LPC_OK) {
452  USBD_API->core->StatusInStage(pCtrl); /* send Acknowledge */
453  }
454  break;
455  }
456  }
457  break;
458 
459  default:
460  break;
461  }
462  }
463  return ret;
464 }
465 
469 void UsbdAdc_start_xfr(void)
470 {
471  ISO_packet_size = 0;
472  uint32_t ISO_buffer_address;
473  /* reset audio 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);
478 
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);
482 }
483 
487 void UsbdAdc_stop_xfr(void)
488 {
489  ISO_packet_size = 0;
490  /* reset audio buffer */
492  USBD_API->hw->ResetEP(UsbHandle, ISOEndpointNumber);
493  USBD_API->hw->ResetEP(UsbHandle, USB_ENDPOINT_IN(ISOEndpointNumber));
494 }
495 
496 
500 ErrorCode_t UsbdAdc_ISO_Hdlr (USBD_HANDLE_T hUsb, void* data, uint32_t event)
501 {
502  uint32_t ISO_buffer_address;
503 
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;
508  }
509  /* Send DMA request */
510  ISO_buffer_address = CALLBACK_HAL_GetISOBufferAddress(ISOEndpointNumber, &ISO_packet_size);
511  UsbdDcdDataTransfer(ISOEndpointNumber, (uint8_t *) ISO_buffer_address, 512);
512  }
513 
514  if (event == USB_EVT_IN)
515  {
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);
519  }
520 
521  return LPC_OK;
522 }
523 
524 #endif
525 #endif