ARMEBS4  revision-26.06.2015
usbh_adk_core.c
1 #include "heivs/config.h"
2 #if (USE_STM32_USB_HOST_MODE || USE_STM32_USB_USE_DEVICE_MODE || USE_STM32_USB_OTG_MODE)
3 /**
4  ******************************************************************************
5  * @file usbh_adk_core.c
6  * @author Yuuichi Akagawa
7  * @version V1.0.0
8  * @date 2012/03/05
9  * @brief Android Open Accessory implementation
10  ******************************************************************************
11  * @attention
12  *
13  * Licensed under the Apache License, Version 2.0 (the "License");
14  * you may not use this file except in compliance with the License.
15  * You may obtain a copy of the License at
16  *
17  * http://www.apache.org/licenses/LICENSE-2.0
18  *
19  * Unless required by applicable law or agreed to in writing, software
20  * distributed under the License is distributed on an "AS IS" BASIS,
21  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22  * See the License for the specific language governing permissions and
23  * limitations under the License.
24  * <h2><center>&copy; COPYRIGHT (C)2012 Yuuichi Akagawa</center></h2>
25  *
26  ******************************************************************************
27  */
28 
29 /* Includes ------------------------------------------------------------------*/
30 #include "config/usb_conf.h"
31 #if defined(USE_HOST_MODE)
32 
34 #include "stm32/usb/usbh_core.h"
35 #include "heivs/time.h"
36 #include <stdio.h>
37 #include <string.h>
38 #include <inttypes.h>
39 #define DEBUG
40 
41 //AOA 1.0
42 #define USB_ACCESSORY_VENDOR_ID 0x18D1
43 #define USB_ACCESSORY_PRODUCT_ID 0x2D00
44 #define USB_ACCESSORY_ADB_PRODUCT_ID 0x2D01
45 //AOA 2.0
46 #define USB_AUDIO_PRODUCT_ID 0x2D02
47 #define USB_AUDIO_ADB_PRODUCT_ID 0x2D03
48 #define USB_ACCESSORY_AUDIO_PRODUCT_ID 0x2D04
49 #define USB_ACCESSORY_AUDIO_ADB_PRODUCT_ID 0x2D05
50 
51 #define ACCESSORY_STRING_MANUFACTURER 0
52 #define ACCESSORY_STRING_MODEL 1
53 #define ACCESSORY_STRING_DESCRIPTION 2
54 #define ACCESSORY_STRING_VERSION 3
55 #define ACCESSORY_STRING_URI 4
56 #define ACCESSORY_STRING_SERIAL 5
57 
58 //AOA 1.0
59 #define ACCESSORY_GET_PROTOCOL 51
60 #define ACCESSORY_SEND_STRING 52
61 #define ACCESSORY_START 53
62 
63 //AOA 2.0
64 #define ACCESSORY_REGISTER_HID 54
65 #define ACCESSORY_UNREGISTER_HID 55
66 #define ACCESSORY_SET_HID_REPORT_DESC 56
67 #define ACCESSORY_SEND_HID_EVENT 57
68 #define ACCESSORY_SET_AUDIO_MODE 58
69 
70 #define USBH_ADK_DATA_SIZE 64
71 #define USBH_ADK_NAK_RETRY_LIMIT 1
72 
73 /* States for ADK Initialize State Machine */
74 enum adk_init_state_e
75 {
76  ADK_INIT_SETUP = 0,
77  ADK_INIT_GET_PROTOCOL,
78  ADK_INIT_SEND_MANUFACTURER,
79  ADK_INIT_SEND_MODEL,
80  ADK_INIT_SEND_DESCRIPTION,
81  ADK_INIT_SEND_VERSION,
82  ADK_INIT_SEND_URI,
83  ADK_INIT_SEND_SERIAL,
84  ADK_INIT_SWITCHING,
85  ADK_INIT_GET_DEVDESC,
86  ADK_INIT_CONFIGURE_ANDROID,
87  ADK_INIT_DONE,
88  ADK_INIT_FAILED,
89 };
90 
91 /* States for ADK State Machine */
92 enum adk_state_e
93 {
94  ADK_DISCONNECTED = 0,
95  ADK_ERROR = 1,
96  ADK_INITIALIZING = 2,
97  ADK_IDLE = 3,
98 };
99 
100 enum adk_tx_state_e
101 {
102  ADK_TX_IDLE,
103  ADK_TX_START,
104  ADK_TX_BUSY,
105  ADK_TX_ERROR,
106 };
107 
108 /* Structure for ADK process */
109 struct adk_t
110 {
111  uint16_t pid;
112  uint8_t hc_num_in;
113  uint8_t hc_num_out;
114  uint8_t BulkOutEp;
115  uint8_t BulkInEp;
116  uint16_t BulkInEpSize;
117  uint16_t BulkOutEpSize;
118  uint32_t inbuff[(USBH_ADK_DATA_SIZE+sizeof(uint32_t)-1)/sizeof(uint32_t)];
119  uint32_t outbuff[(USBH_ADK_DATA_SIZE+sizeof(uint32_t)-1)/sizeof(uint32_t)];
120  uint16_t inSize;
121  uint16_t outSize;
122  enum adk_init_state_e initstate;
123  enum adk_state_e state;
124  enum adk_tx_state_e tx_state;
125  const char *acc_manufacturer;
126  const char *acc_model;
127  const char *acc_description;
128  const char *acc_version;
129  const char *acc_uri;
130  const char *acc_serial;
131  uint16_t protocol;
132  timeout_t timeout;
133  uint32_t nakretry;
134 };
135 
136 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
137  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
138  #pragma data_alignment=4
139  #endif
140 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
141 static __ALIGN_BEGIN struct adk_t sAdk __ALIGN_END;
142 
143 static USBH_Status USBH_ADK_getProtocol ( USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost)
144 {
145  phost->Control.setup.b.bmRequestType = USB_D2H | USB_REQ_TYPE_VENDOR | USB_REQ_RECIPIENT_DEVICE;
146  phost->Control.setup.b.bRequest = ACCESSORY_GET_PROTOCOL;
147  phost->Control.setup.b.wValue.w = 0;
148  phost->Control.setup.b.wIndex.w = 0;
149  phost->Control.setup.b.wLength.w = 2;
150 
151  /* Control Request */
152  return USBH_CtlReq(pdev, phost, (uint8_t*)&sAdk.protocol , 2 );
153 }
154 
155 /**
156  * @brief USBH_ADK_sendString
157  * Send identifying string information to the Android device.
158  * @param pdev: Selected device
159  * @param hdev: Selected device property
160  * @param index: String ID
161  * @param buff: Identifying string
162  * @retval USBH_Status
163  */
164 static USBH_Status USBH_ADK_sendString ( USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost, uint16_t index, const char* buff)
165 {
166  uint16_t length;
167  length = (uint16_t)strlen(buff)+1;
168 
169  phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_TYPE_VENDOR | USB_REQ_RECIPIENT_DEVICE;
170  phost->Control.setup.b.bRequest = ACCESSORY_SEND_STRING;
171  phost->Control.setup.b.wValue.w = 0;
172  phost->Control.setup.b.wIndex.w = index;
173  phost->Control.setup.b.wLength.w = length;
174 
175  /* Control Request */
176  return USBH_CtlReq(pdev, phost, (uint8_t*)buff , length );
177 }
178 /**
179  * @brief USBH_ADK_switch
180  * Request the Android device start up in accessory mode.
181  * @param pdev: Selected device
182  * @param hdev: Selected device property
183  * @retval USBH_Status
184  */
185 static USBH_Status USBH_ADK_switch ( USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost)
186 {
187  phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_TYPE_VENDOR | USB_REQ_RECIPIENT_DEVICE;
188  phost->Control.setup.b.bRequest = ACCESSORY_START;
189  phost->Control.setup.b.wValue.w = 0;
190  phost->Control.setup.b.wIndex.w = 0;
191  phost->Control.setup.b.wLength.w = 0;
192 
193  /* Control Request */
194  return USBH_CtlReq(pdev, phost, 0 , 0);
195 }
196 
197 /**
198  * @brief USBH_ADK_configAndroid
199  * Setup bulk transfer endpoint and open channel.
200  * @param pdev: Selected device
201  * @param hdev: Selected device property
202  * @retval USBH_Status
203  */
204 static USBH_Status USBH_ADK_configAndroid ( USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost)
205 {
206  USBH_HOST *pphost = phost;
207 #ifdef DEBUG
208  iprintf("ADK:configure bulk endpoint\n");
209 #endif
210  if(pphost->device_prop.Ep_Desc[0][0].bEndpointAddress & 0x80)
211  {
212  sAdk.BulkInEp = (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress);
213  sAdk.BulkInEpSize = pphost->device_prop.Ep_Desc[0][0].wMaxPacketSize;
214  }
215  else
216  {
217  sAdk.BulkOutEp = (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress);
218  sAdk.BulkOutEpSize = pphost->device_prop.Ep_Desc[0] [0].wMaxPacketSize;
219  }
220 
221  if(pphost->device_prop.Ep_Desc[0][1].bEndpointAddress & 0x80)
222  {
223  sAdk.BulkInEp = (pphost->device_prop.Ep_Desc[0][1].bEndpointAddress);
224  sAdk.BulkInEpSize = pphost->device_prop.Ep_Desc[0][1].wMaxPacketSize;
225  }
226  else
227  {
228  sAdk.BulkOutEp = (pphost->device_prop.Ep_Desc[0][1].bEndpointAddress);
229  sAdk.BulkOutEpSize = pphost->device_prop.Ep_Desc[0][1].wMaxPacketSize;
230  }
231 
232  sAdk.hc_num_out = USBH_Alloc_Channel(pdev, sAdk.BulkOutEp);
233  sAdk.hc_num_in = USBH_Alloc_Channel(pdev, sAdk.BulkInEp);
234 
235  /* Open the new channels */
236  USBH_Open_Channel (pdev,
237  sAdk.hc_num_out,
238  pphost->device_prop.address,
239  pphost->device_prop.speed,
240  EP_TYPE_BULK,
241  sAdk.BulkOutEpSize);
242 
243  USBH_Open_Channel (pdev,
244  sAdk.hc_num_in,
245  pphost->device_prop.address,
246  pphost->device_prop.speed,
247  EP_TYPE_BULK,
248  sAdk.BulkInEpSize);
249 
250  return USBH_OK;
251 }
252 /**
253  * @brief USBH_ADK_InterfaceInit
254  * Interface initialization for ADK class.
255  * @param pdev: Selected device
256  * @param hdev: Selected device property
257  * @retval USBH_Status : Status of class request handled.
258  */
259 static USBH_Status USBH_ADK_InterfaceInit ( USB_OTG_CORE_HANDLE *pdev, void *phost)
260 {
261  USBH_Status status = USBH_OK; //USBH_OK ;
262 
263  sAdk.state = ADK_INITIALIZING;
264  sAdk.inSize = 0;
265 
266 #ifdef DEBUG
267  iprintf("> USB_ADK_Init\n");
268 #endif
269  return status ;
270 }
271 
272 /**
273  * @brief USBH_ADK_InterfaceDeInit
274  * De-Initialize interface by freeing host channels allocated to interface
275  * @param pdev: Selected device
276  * @param hdev: Selected device property
277  * @retval None
278  */
279 void USBH_ADK_InterfaceDeInit ( USB_OTG_CORE_HANDLE *pdev, void *phost)
280 {
281 #ifdef DEBUG
282  iprintf("> USB_ADK_DeInit\n");
283 #endif
284  sAdk.state = ADK_INITIALIZING;
285  sAdk.initstate = ADK_INIT_SETUP;
286 
287  /* Switch to accessory mode, Re-enumeration */
288 // if(ADK_Machine.state == ADK_INITIALIZING)
289 // {
290 // pdev->host.ConnSts = 1;
291 // }
292 
293  /* close bulk transfer pipe */
294  if ( sAdk.hc_num_out)
295  {
296  USB_OTG_HC_Halt(pdev, sAdk.hc_num_out);
297  USBH_Free_Channel (pdev, sAdk.hc_num_out);
298  sAdk.hc_num_out = 0; /* Reset the Channel as Free */
299  }
300  if ( sAdk.hc_num_in)
301  {
302  USB_OTG_HC_Halt(pdev, sAdk.hc_num_in);
303  USBH_Free_Channel (pdev, sAdk.hc_num_in);
304  sAdk.hc_num_in = 0; /* Reset the Channel as Free */
305  }
306 
307  //restore NAK retry limit to default value
308 // pdev->host.NakRetryLimit = USB_NAK_RETRY_ATTEMPTS;
309 }
310 
311 /**
312  * @brief USBH_ADK_ClassRequest
313  * This function will only initialize the ADK state machine
314  * @param pdev: Selected device
315  * @param hdev: Selected device property
316  * @retval USBH_Status : Status of class request handled.
317  */
318 static USBH_Status USBH_ADK_ClassRequest(USB_OTG_CORE_HANDLE *pdev, void *phost)
319 {
320  USBH_HOST *pphost = phost;
321  USBH_Status status = USBH_BUSY ;
322 
323  switch (sAdk.initstate)
324  {
325  case ADK_INIT_SETUP:
326 #ifdef DEBUG
327  iprintf("> USB_ADK_ClassRequest\n");
328 #endif
329  // minimize NAK retry limit
330 // pdev->host.NakRetryLimit = USBH_ADK_NAK_RETRY_LIMIT;
331 
332  //check vaild device
333  if(pphost->device_prop.Dev_Desc.idVendor == USB_ACCESSORY_VENDOR_ID &&
334  (pphost->device_prop.Dev_Desc.idProduct == USB_ACCESSORY_PRODUCT_ID ||
335  pphost->device_prop.Dev_Desc.idProduct == USB_ACCESSORY_ADB_PRODUCT_ID)
336  ){
337  sAdk.initstate = ADK_INIT_CONFIGURE_ANDROID;
338  }else{
339  sAdk.initstate = ADK_INIT_GET_PROTOCOL;
340  sAdk.protocol = -1;
341  }
342  break;
343 
344  case ADK_INIT_GET_PROTOCOL:
345  if ( USBH_ADK_getProtocol ( pdev, phost ) == USBH_OK ){
346  if (sAdk.protocol >= 1) {
347  sAdk.initstate = ADK_INIT_SEND_MANUFACTURER;
348 #ifdef DEBUG
349  iprintf("ADK:device supports protocol 1\n");
350 #endif
351  } else {
352  sAdk.initstate = ADK_INIT_FAILED;
353  #ifdef DEBUG
354  iprintf("ADK:could not read device protocol version\n");
355  #endif
356  }
357  }
358  break;
359  case ADK_INIT_SEND_MANUFACTURER:
360  if( USBH_ADK_sendString ( pdev, phost, ACCESSORY_STRING_MANUFACTURER, sAdk.acc_manufacturer)== USBH_OK ){
361  sAdk.initstate = ADK_INIT_SEND_MODEL;
362 #ifdef DEBUG
363  iprintf("ADK:SEND_MANUFACTURER\n");
364 #endif
365  }
366  break;
367  case ADK_INIT_SEND_MODEL:
368  if( USBH_ADK_sendString ( pdev, phost, ACCESSORY_STRING_MODEL, sAdk.acc_model)== USBH_OK ){
369  sAdk.initstate = ADK_INIT_SEND_DESCRIPTION;
370 #ifdef DEBUG
371  iprintf("ADK:SEND_MODEL\n");
372 #endif
373  }
374  break;
375  case ADK_INIT_SEND_DESCRIPTION:
376  if( USBH_ADK_sendString ( pdev, phost, ACCESSORY_STRING_DESCRIPTION, sAdk.acc_description)== USBH_OK ){
377  sAdk.initstate = ADK_INIT_SEND_VERSION;
378 #ifdef DEBUG
379  iprintf("ADK:SEND_DESCRIPTION\n");
380 #endif
381  }
382  break;
383  case ADK_INIT_SEND_VERSION:
384  if( USBH_ADK_sendString ( pdev, phost, ACCESSORY_STRING_VERSION, sAdk.acc_version)== USBH_OK ){
385  sAdk.initstate = ADK_INIT_SEND_URI;
386 #ifdef DEBUG
387  iprintf("ADK:SEND_VERSION\n");
388 #endif
389  }
390  break;
391  case ADK_INIT_SEND_URI:
392  if( USBH_ADK_sendString ( pdev, phost, ACCESSORY_STRING_URI, sAdk.acc_uri)== USBH_OK ){
393  sAdk.initstate = ADK_INIT_SEND_SERIAL;
394 #ifdef DEBUG
395  iprintf("ADK:SEND_URI\n");
396 #endif
397  }
398  break;
399  case ADK_INIT_SEND_SERIAL:
400  if( USBH_ADK_sendString ( pdev, phost, ACCESSORY_STRING_SERIAL, sAdk.acc_serial)== USBH_OK ){
401  sAdk.initstate = ADK_INIT_SWITCHING;
402 #ifdef DEBUG
403  iprintf("ADK:SEND_SERIAL\n");
404 #endif
405  }
406  break;
407  case ADK_INIT_SWITCHING:
408  if( USBH_ADK_switch ( pdev, phost)== USBH_OK ){
409  sAdk.initstate = ADK_INIT_GET_DEVDESC;
410 #ifdef DEBUG
411  iprintf("ADK:switch to accessory mode\n");
412 #endif
413  }
414  break;
415 
416  case ADK_INIT_GET_DEVDESC:
417  if( USBH_Get_DevDesc(pdev , phost, USB_DEVICE_DESC_SIZE)== USBH_OK ){
418  sAdk.initstate = ADK_INIT_DONE;
419  sAdk.pid = pphost->device_prop.Dev_Desc.idProduct;
420  //check vaild device
421  if(pphost->device_prop.Dev_Desc.idVendor == USB_ACCESSORY_VENDOR_ID &&
422  (pphost->device_prop.Dev_Desc.idProduct == USB_ACCESSORY_PRODUCT_ID ||
423  pphost->device_prop.Dev_Desc.idProduct == USB_ACCESSORY_ADB_PRODUCT_ID)
424  ){
425  sAdk.initstate = ADK_INIT_CONFIGURE_ANDROID;
426  }else{
427  sAdk.initstate = ADK_INIT_FAILED;
428  }
429  }
430  break;
431 
432  case ADK_INIT_CONFIGURE_ANDROID:
433  USBH_ADK_configAndroid(pdev, phost);
434  sAdk.initstate = ADK_INIT_DONE;
435  break;
436 
437  case ADK_INIT_DONE:
438  status = USBH_OK;
439 #ifdef DEBUG
440  iprintf("ADK:configuration complete.\n");
441 #endif
442  break;
443 
444  case ADK_INIT_FAILED:
445  status = USBH_UNRECOVERED_ERROR;
446  break;
447 
448  default:
449  break;
450  }
451 
452  return status;
453 }
454 
455 /**
456  * @brief USBH_ADK_Handle
457  * ADK state machine handler
458  * @param pdev: Selected device
459  * @param hdev: Selected device property
460  * @retval USBH_Status
461  */
462 static USBH_Status USBH_ADK_Handle(USB_OTG_CORE_HANDLE *pdev, void *phost)
463 {
464  uint32_t HCD_GXferCnt = HCD_GetXferCnt(pdev , sAdk.hc_num_in);
465  HC_STATUS HCD_Status = HCD_GetHCState(pdev , sAdk.hc_num_in);
466  URB_STATE URB_Status;
467 
468  if (HCD_GXferCnt)
469  {
470  sAdk.inSize = HCD_GXferCnt;
471  }
472 
473  if (HCD_Status == HC_XFRC && time_elapsed(sAdk.timeout))
474  {
475  sAdk.timeout = time_set_timeout_ms(1);
476  USBH_BulkReceiveData(pdev, (uint8_t*)sAdk.inbuff, USBH_ADK_DATA_SIZE, sAdk.hc_num_in);
477  }
478 
479  switch (sAdk.state)
480  {
481  case ADK_INITIALIZING:
482  USBH_BulkReceiveData(pdev, (uint8_t*)sAdk.inbuff, USBH_ADK_DATA_SIZE, sAdk.hc_num_in);
483  sAdk.state = ADK_IDLE;
484  break;
485  case ADK_IDLE:
486  default:
487  break;
488  }
489 
490  /**
491  * Manage output
492  */
493  URB_Status = HCD_GetURB_State(pdev , sAdk.hc_num_out);
494  HCD_Status = HCD_GetHCState(pdev , sAdk.hc_num_out);
495 
496  switch (sAdk.tx_state)
497  {
498  case ADK_TX_IDLE:
499  break;
500 
501  case ADK_TX_START:
502  USBH_BulkSendData(pdev, (uint8_t*)sAdk.outbuff, sAdk.outSize, sAdk.hc_num_out);
503  sAdk.tx_state = ADK_TX_BUSY;
504  break;
505 
506  case ADK_TX_BUSY:
507 
508  switch (URB_Status)
509  {
510  case URB_DONE:
511  sAdk.tx_state = ADK_TX_IDLE;
512  if (sAdk.nakretry)
513  {
514  //iprintf("nakretry was %"PRIu32"\n", sAdk.nakretry);
515  sAdk.nakretry = 0;
516  }
517  break;
518 
519  case URB_IDLE:
520  /* URB_IDLE means sending !*/
521  break;
522 
523  case URB_NOTREADY:
524  sAdk.nakretry++;
525  if (sAdk.nakretry++ < 500)
526  {
527  USBH_BulkSendData(pdev, (uint8_t*)sAdk.outbuff, sAdk.outSize, sAdk.hc_num_out);
528  }
529  else
530  {
531  sAdk.nakretry = 0;
532  sAdk.tx_state = ADK_TX_IDLE;
533  iprintf("nakretry\n");
534  }
535  break;
536 
537  case URB_ERROR:
538  case URB_STALL:
539  iprintf("USBH_ADK_ReInit called from USBH_ADK_Handle\n");
540  USBH_ADK_ReInit();
541  break;
542  }
543  break;
544 
545  case ADK_TX_ERROR:
546  default:
547  break;
548  }
549 
550  return USBH_OK;
551 }
552 
553 USBH_Class_cb_TypeDef USBH_ADK_cb =
554 {
555  USBH_ADK_InterfaceInit,
556  USBH_ADK_InterfaceDeInit,
557  USBH_ADK_ClassRequest,
558  USBH_ADK_Handle,
559 };
560 /**
561 * @}
562 */
563 
564 static void disconnected(void)
565 {
566 #ifdef DEBUG
567  printf("> Device Disconnected\n");
568 #endif
569  /* Re-init ADK for the next connection */
570  USBH_ADK_ReInit();
571 }
572 
573 static void do_nothing(void){}
574 static void do_nothing_uint8_t(uint8_t unused){}
575 static void do_nothing_voidptr(void *unused){}
576 static void do_nothing_desc(USBH_CfgDesc_TypeDef *a, USBH_InterfaceDesc_TypeDef *b, USBH_EpDesc_TypeDef *c){}
577 
578 static USBH_USR_Status do_nothing_ret_ok(){return USBH_USR_RESP_OK;}
579 static int do_nothing_ret_int(){return 0;}
580 
581 static USBH_Usr_cb_TypeDef USR_Callbacks =
582 {
583  .Init = do_nothing,
584  .DeInit = do_nothing,
585  .DeviceAttached = do_nothing,
586  .ResetDevice = do_nothing,
587  .DeviceDisconnected = disconnected,
588  .OverCurrentDetected = do_nothing,
589  .DeviceSpeedDetected = do_nothing_uint8_t,
590  .DeviceDescAvailable = do_nothing_voidptr,
591  .DeviceAddressAssigned = do_nothing,
592  .ConfigurationDescAvailable = do_nothing_desc,
593  .ManufacturerString = do_nothing_voidptr,
594  .ProductString = do_nothing_voidptr,
595  .SerialNumString = do_nothing_voidptr,
596  .EnumerationDone = do_nothing,
597  .UserInput = do_nothing_ret_ok,
598  .UserApplication = do_nothing_ret_int,
599  .DeviceNotSupported = do_nothing,
600  .UnrecoveredError = do_nothing,
601 };
602 
603 status_e USBH_ADK_ReInit(void)
604 {
605  sAdk.initstate = ADK_INIT_SETUP;
606  sAdk.state = ADK_INITIALIZING;
607  sAdk.tx_state = ADK_TX_IDLE;
608  sAdk.timeout = time_set_timeout_ms(1);
609  sAdk.nakretry = 0;
610 
611  /* Init Host Library */
612  USBH_Init(&USB_OTG_Core, USB_OTG_FS_CORE_ID, &USB_Host, &USBH_ADK_cb, &USR_Callbacks);
613 
614  return NO_ERROR;
615 }
616 
617 /**
618  * @brief USBH_ADK_Init
619  * Initialization for ADK class.
620  * @param manufacture: manufacturer name string(max 63 chars)
621  * @param model: model name string (max 63 chars)
622  * @param description: description string (max 63 chars)
623  * @param version: version string (max 63 chars)
624  * @param uri: URI string (max 63 chars)
625  * @param serial: serial number string (max 63 chars)
626  * @retval None
627  */
628 status_e USBH_ADK_Init(const char* manufacture, const char* model, const char* description, const char* version, const char* uri, const char* serial)
629 {
630  const size_t max_size = 255; /* from aoa 1.0 */
631  if (strlen(manufacture) > max_size)
632  {
633  return ERROR_BAD_PARAM;
634  }
635  sAdk.acc_manufacturer = manufacture;
636 
637  if (strlen(model) > max_size)
638  {
639  return ERROR_BAD_PARAM;
640  }
641  sAdk.acc_model = model;
642 
643  if (strlen(description) > max_size)
644  {
645  return ERROR_BAD_PARAM;
646  }
647  sAdk.acc_description = description;
648 
649  if (strlen(version) > max_size)
650  {
651  return ERROR_BAD_PARAM;
652  }
653  sAdk.acc_version = version;
654 
655  if (strlen(uri) > max_size)
656  {
657  return ERROR_BAD_PARAM;
658  }
659  sAdk.acc_uri = uri;
660 
661  if (strlen(serial) > max_size)
662  {
663  return ERROR_BAD_PARAM;
664  }
665  sAdk.acc_serial = serial;
666 
667  return USBH_ADK_ReInit();
668 }
669 
670 /**
671  * @brief USBH_ADK_write
672  * Send data to Android device.
673  * @param pdev: Selected device
674  * @param buff: send data
675  * @param len : send data length
676  * @retval USBH_Status
677  */
678 status_e USBH_ADK_write(USB_OTG_CORE_HANDLE *pdev, const uint8_t *buff, size_t len)
679 {
680  timeout_t timeout = time_set_timeout_ms(100);
681 
682  while (sAdk.tx_state != ADK_TX_IDLE)
683  {
684  USBH_Process(&USB_OTG_Core , &USB_Host);
685 
686  if (time_elapsed(timeout))
687  {
688  iprintf("%s:timeout", __FUNCTION__);
689  return ERROR_TIMEOUT;
690  }
691  }
692 
693  if (len > sizeof(sAdk.outbuff))
694  {
695  return ERROR_BAD_PARAM;
696  }
697 
698  memcpy(&sAdk.outbuff[0], buff, len);
699  sAdk.outSize = len;
700  sAdk.tx_state = ADK_TX_START;
701 
702  return NO_ERROR;
703 }
704 
705 /**
706  * @brief USBH_ADK_read
707  * Receive data from Android device.
708  * @param pdev: Selected device
709  * @param buff: receive data
710  * @param len : receive data buffer length
711  * @retval received data length
712  */
713 status_e USBH_ADK_read(USB_OTG_CORE_HANDLE *pdev, uint8_t *buff, size_t len, size_t *rlen)
714 {
715  uint32_t xfercount = sAdk.inSize;
716  if (!xfercount)
717  {
718  *rlen = 0;
719  return NO_ERROR;
720  }
721 
722  sAdk.inSize = 0;
723  *rlen = min(xfercount, len);
724  memcpy(buff, sAdk.inbuff, *rlen);
725  memset(sAdk.inbuff, 0x00, sizeof(sAdk.inbuff));
726 
727  return NO_ERROR;
728 }
729 
730 /**
731  * \return !0 when connected and idle
732  */
733 uint32_t USBH_ADK_Connected(void)
734 {
735  return sAdk.state == ADK_IDLE;
736 }
737 
738 #endif
739 #endif /* (USE_STM32_USB_HOST_MODE || USE_STM32_USB_USE_DEVICE_MODE || USE_STM32_USB_OTG_MODE) */
No comment.
Definition: error.h:64
simple time abstraction
void * memcpy(void *dest, const void *src, size_t n)
void * memset(void *dest, int n, size_t n)
libheivs configuration file
This file contains all the prototypes for the usbh_adk_core.c.
static uint32_t time_elapsed(timeout_t timeout)
Is this time passed?
Definition: time.h:71
int printf(const char *fmt,...)
printf
Parameter unsupported.
Definition: error.h:56
Timeout structure.
Definition: time.h:34
timeout_t time_set_timeout_ms(uint32_t ms)
Set an obscure time at least ms milliseconds in the future.
Definition: time.c:15
status_e
Known errors.
Definition: error.h:21
int iprintf(const char *fmt,...)
iprintf Integer-only version of printf
No error.
Definition: error.h:28
size_t strlen(const char *str)