update credits
[librepilot.git] / flight / pios / stm32f10x / pios_usbhook.c
blob210256f73f3a444663d69cb4aeafbbbaf8866687
1 /**
2 ******************************************************************************
3 * @addtogroup PIOS PIOS Core hardware abstraction layer
4 * @{
5 * @addtogroup PIOS_USBHOOK USB glue code
6 * @brief Glue between PiOS and STM32 libs
7 * @{
9 * @file pios_usbhook.c
10 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
11 * @brief Glue between PiOS and STM32 libs
12 * @see The GNU Public License (GPL) Version 3
14 *****************************************************************************/
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful, but
22 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 * for more details.
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include "pios.h"
33 #ifdef PIOS_INCLUDE_USB
35 #include "pios_usb.h" /* PIOS_USB_* */
36 #include "pios_usbhook.h"
37 #include "pios_usb_defs.h" /* struct usb_* */
38 #include "pios_usb_hid_pwr.h"
39 #include "pios_usb_cdc_priv.h" /* PIOS_USB_CDC_* */
40 #include "pios_usb_board_data.h" /* PIOS_USB_BOARD_* */
42 /* STM32 USB Library Definitions */
43 #include "usb_lib.h"
45 static void (*ep0_rxready_cb)(void) = 0;
47 static ONE_DESCRIPTOR Device_Descriptor;
49 void PIOS_USBHOOK_RegisterDevice(const uint8_t *desc, uint16_t desc_size)
51 Device_Descriptor.Descriptor = desc;
52 Device_Descriptor.Descriptor_Size = desc_size;
55 static ONE_DESCRIPTOR Config_Descriptor;
57 void PIOS_USBHOOK_RegisterConfig(__attribute__((unused)) uint8_t config_id, const uint8_t *desc, uint16_t desc_size)
59 Config_Descriptor.Descriptor = desc;
60 Config_Descriptor.Descriptor_Size = desc_size;
63 static ONE_DESCRIPTOR String_Descriptor[4];
65 void PIOS_USBHOOK_RegisterString(enum usb_string_desc string_id, const uint8_t *desc, uint16_t desc_size)
67 if (string_id < NELEMENTS(String_Descriptor)) {
68 String_Descriptor[string_id].Descriptor = desc;
69 String_Descriptor[string_id].Descriptor_Size = desc_size;
73 static ONE_DESCRIPTOR Hid_Descriptor;
75 void PIOS_USB_HID_RegisterHidDescriptor(const uint8_t *desc, uint16_t desc_size)
77 Hid_Descriptor.Descriptor = desc;
78 Hid_Descriptor.Descriptor_Size = desc_size;
81 static ONE_DESCRIPTOR Hid_Report_Descriptor;
83 void PIOS_USB_HID_RegisterHidReport(const uint8_t *desc, uint16_t desc_size)
85 Hid_Report_Descriptor.Descriptor = desc;
86 Hid_Report_Descriptor.Descriptor_Size = desc_size;
89 void PIOS_USBHOOK_Deactivate(void)
92 #include "stm32f10x.h" /* __IO */
93 __IO uint8_t EXTI_Enable;
95 uint32_t ProtocolValue;
97 DEVICE Device_Table = {
98 PIOS_USB_BOARD_EP_NUM,
102 static void PIOS_USBHOOK_Init(void);
103 static void PIOS_USBHOOK_Reset(void);
104 static void PIOS_USBHOOK_Status_In(void);
105 static void PIOS_USBHOOK_Status_Out(void);
106 static RESULT PIOS_USBHOOK_Data_Setup(uint8_t RequestNo);
107 static RESULT PIOS_USBHOOK_NoData_Setup(uint8_t RequestNo);
108 static RESULT PIOS_USBHOOK_Get_Interface_Setting(uint8_t Interface, uint8_t AlternateSetting);
109 static const uint8_t *PIOS_USBHOOK_GetDeviceDescriptor(uint16_t Length);
110 static const uint8_t *PIOS_USBHOOK_GetConfigDescriptor(uint16_t Length);
111 static const uint8_t *PIOS_USBHOOK_GetStringDescriptor(uint16_t Length);
113 DEVICE_PROP Device_Property = {
114 .Init = PIOS_USBHOOK_Init,
115 .Reset = PIOS_USBHOOK_Reset,
116 .Process_Status_IN = PIOS_USBHOOK_Status_In,
117 .Process_Status_OUT = PIOS_USBHOOK_Status_Out,
118 .Class_Data_Setup = PIOS_USBHOOK_Data_Setup,
119 .Class_NoData_Setup = PIOS_USBHOOK_NoData_Setup,
120 .Class_Get_Interface_Setting = PIOS_USBHOOK_Get_Interface_Setting,
121 .GetDeviceDescriptor = PIOS_USBHOOK_GetDeviceDescriptor,
122 .GetConfigDescriptor = PIOS_USBHOOK_GetConfigDescriptor,
123 .GetStringDescriptor = PIOS_USBHOOK_GetStringDescriptor,
124 .RxEP_buffer = 0,
125 .MaxPacketSize = 0x40,
128 static void PIOS_USBHOOK_SetConfiguration(void);
129 static void PIOS_USBHOOK_SetDeviceAddress(void);
131 USER_STANDARD_REQUESTS User_Standard_Requests = {
132 .User_GetConfiguration = NOP_Process,
133 .User_SetConfiguration = PIOS_USBHOOK_SetConfiguration,
134 .User_GetInterface = NOP_Process,
135 .User_SetInterface = NOP_Process,
136 .User_GetStatus = NOP_Process,
137 .User_ClearFeature = NOP_Process,
138 .User_SetEndPointFeature = NOP_Process,
139 .User_SetDeviceFeature = NOP_Process,
140 .User_SetDeviceAddress = PIOS_USBHOOK_SetDeviceAddress
143 static RESULT PIOS_USBHOOK_SetProtocol(void);
144 static const uint8_t *PIOS_USBHOOK_GetProtocolValue(uint16_t Length);
145 static const uint8_t *PIOS_USBHOOK_GetReportDescriptor(uint16_t Length);
146 static const uint8_t *PIOS_USBHOOK_GetHIDDescriptor(uint16_t Length);
148 /*******************************************************************************
149 * Function Name : PIOS_USBHOOK_Init.
150 * Description : Custom HID init routine.
151 * Input : None.
152 * Output : None.
153 * Return : None.
154 *******************************************************************************/
155 static void PIOS_USBHOOK_Init(void)
157 pInformation->Current_Configuration = 0;
159 /* Connect the device */
160 PowerOn();
162 /* Perform basic device initialization operations */
163 USB_SIL_Init();
165 bDeviceState = UNCONNECTED;
168 /*******************************************************************************
169 * Function Name : PIOS_USBHOOK_Reset.
170 * Description : Custom HID reset routine.
171 * Input : None.
172 * Output : None.
173 * Return : None.
174 *******************************************************************************/
175 static void PIOS_USBHOOK_Reset(void)
177 /* Set DEVICE as not configured */
178 pInformation->Current_Configuration = 0;
179 pInformation->Current_Interface = 0; /*the default Interface */
181 /* Current Feature initialization */
182 pInformation->Current_Feature = 0;
184 #ifdef STM32F10X_CL
185 /* EP0 is already configured in DFU_Init() by USB_SIL_Init() function */
187 /* Init EP1 IN as Interrupt endpoint */
188 OTG_DEV_EP_Init(EP1_IN, OTG_DEV_EP_TYPE_INT, 2);
190 /* Init EP1 OUT as Interrupt endpoint */
191 OTG_DEV_EP_Init(EP1_OUT, OTG_DEV_EP_TYPE_INT, 2);
192 #else
193 SetBTABLE(BTABLE_ADDRESS);
195 /* Initialize Endpoint 0 (Control) */
196 SetEPType(ENDP0, EP_CONTROL);
197 SetEPTxAddr(ENDP0, ENDP0_TXADDR);
198 SetEPTxStatus(ENDP0, EP_TX_STALL);
199 Clear_Status_Out(ENDP0);
201 SetEPRxAddr(ENDP0, ENDP0_RXADDR);
202 SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
203 SetEPRxValid(ENDP0);
205 #if defined(PIOS_INCLUDE_USB_HID)
206 /* Initialize Endpoint 1 (HID) */
207 SetEPType(ENDP1, EP_INTERRUPT);
208 SetEPTxAddr(ENDP1, ENDP1_TXADDR);
209 SetEPTxCount(ENDP1, PIOS_USB_BOARD_HID_DATA_LENGTH);
210 SetEPTxStatus(ENDP1, EP_TX_NAK);
212 SetEPRxAddr(ENDP1, ENDP1_RXADDR);
213 SetEPRxCount(ENDP1, PIOS_USB_BOARD_HID_DATA_LENGTH);
214 SetEPRxStatus(ENDP1, EP_RX_VALID);
215 #endif /* PIOS_INCLUDE_USB_HID */
217 #if defined(PIOS_INCLUDE_USB_CDC)
218 /* Initialize Endpoint 2 (CDC Call Control) */
219 SetEPType(ENDP2, EP_INTERRUPT);
220 SetEPTxAddr(ENDP2, ENDP2_TXADDR);
221 SetEPTxStatus(ENDP2, EP_TX_NAK);
223 SetEPRxAddr(ENDP2, ENDP2_RXADDR);
224 SetEPRxCount(ENDP2, PIOS_USB_BOARD_CDC_MGMT_LENGTH);
225 SetEPRxStatus(ENDP2, EP_RX_DIS);
227 /* Initialize Endpoint 3 (CDC Data) */
228 SetEPType(ENDP3, EP_BULK);
229 SetEPTxAddr(ENDP3, ENDP3_TXADDR);
230 SetEPTxStatus(ENDP3, EP_TX_NAK);
232 SetEPRxAddr(ENDP3, ENDP3_RXADDR);
233 SetEPRxCount(ENDP3, PIOS_USB_BOARD_CDC_DATA_LENGTH);
234 SetEPRxStatus(ENDP3, EP_RX_VALID);
236 #endif /* PIOS_INCLUDE_USB_CDC */
238 /* Set this device to response on default address */
239 SetDeviceAddress(0);
240 #endif /* STM32F10X_CL */
242 bDeviceState = ATTACHED;
245 /*******************************************************************************
246 * Function Name : PIOS_USBHOOK_SetConfiguration.
247 * Description : Update the device state to configured
248 * Input : None.
249 * Output : None.
250 * Return : None.
251 *******************************************************************************/
252 static void PIOS_USBHOOK_SetConfiguration(void)
254 if (pInformation->Current_Configuration != 0) {
255 /* Device configured */
256 bDeviceState = CONFIGURED;
259 /* Enable transfers */
260 PIOS_USB_ChangeConnectionState(pInformation->Current_Configuration != 0);
263 /*******************************************************************************
264 * Function Name : PIOS_USBHOOK_SetConfiguration.
265 * Description : Update the device state to addressed.
266 * Input : None.
267 * Output : None.
268 * Return : None.
269 *******************************************************************************/
270 static void PIOS_USBHOOK_SetDeviceAddress(void)
272 bDeviceState = ADDRESSED;
275 /*******************************************************************************
276 * Function Name : PIOS_USBHOOK_Status_In.
277 * Description : status IN routine.
278 * Input : None.
279 * Output : None.
280 * Return : None.
281 *******************************************************************************/
282 static void PIOS_USBHOOK_Status_In(void)
284 /* this callback gets executed after sending ZLP and doing In0_Process(), to ack */
285 if (ep0_rxready_cb) {
286 ep0_rxready_cb();
287 ep0_rxready_cb = 0;
291 /*******************************************************************************
292 * Function Name : PIOS_USBHOOK_Status_Out
293 * Description : status OUT routine.
294 * Input : None.
295 * Output : None.
296 * Return : None.
297 *******************************************************************************/
298 static void PIOS_USBHOOK_Status_Out(void)
301 /*******************************************************************************
302 * Function Name : PIOS_USBHOOK_Data_Setup
303 * Description : Handle the data class specific requests.
304 * Input : Request Nb.
305 * Output : None.
306 * Return : USB_UNSUPPORT or USB_SUCCESS.
307 *******************************************************************************/
308 extern uint8_t *PIOS_USB_CDC_SetLineCoding(uint16_t Length);
309 extern const uint8_t *PIOS_USB_CDC_GetLineCoding(uint16_t Length);
310 extern void PIOS_USB_CDC_SetLineCoding_Completed();
312 static RESULT PIOS_USBHOOK_Data_Setup(uint8_t RequestNo)
314 uint8_t *(*CopyOutRoutine)(uint16_t);
315 const uint8_t *(*CopyInRoutine)(uint16_t);
317 CopyInRoutine = NULL;
318 CopyOutRoutine = NULL;
321 switch (Type_Recipient) {
322 case (STANDARD_REQUEST | INTERFACE_RECIPIENT):
323 switch (pInformation->USBwIndex0) {
324 #if defined(PIOS_INCLUDE_USB_CDC)
325 case 2: /* HID Interface */
326 #else
327 case 0: /* HID Interface */
328 #endif
329 switch (RequestNo) {
330 case GET_DESCRIPTOR:
331 switch (pInformation->USBwValue1) {
332 case USB_DESC_TYPE_REPORT:
333 CopyInRoutine = PIOS_USBHOOK_GetReportDescriptor;
334 break;
335 case USB_DESC_TYPE_HID:
336 CopyInRoutine = PIOS_USBHOOK_GetHIDDescriptor;
337 break;
341 break;
343 case (CLASS_REQUEST | INTERFACE_RECIPIENT):
344 switch (pInformation->USBwIndex0) {
345 #if defined(PIOS_INCLUDE_USB_CDC)
346 case 2: /* HID Interface */
347 #else
348 case 0: /* HID Interface */
349 #endif
350 switch (RequestNo) {
351 case USB_HID_REQ_GET_PROTOCOL:
352 CopyInRoutine = PIOS_USBHOOK_GetProtocolValue;
353 break;
356 break;
357 #if defined(PIOS_INCLUDE_USB_CDC)
358 case 0: /* CDC Call Control Interface */
359 switch (RequestNo) {
360 case USB_CDC_REQ_SET_LINE_CODING:
361 CopyOutRoutine = PIOS_USB_CDC_SetLineCoding;
362 ep0_rxready_cb = PIOS_USB_CDC_SetLineCoding_Completed;
363 break;
364 case USB_CDC_REQ_GET_LINE_CODING:
365 CopyInRoutine = PIOS_USB_CDC_GetLineCoding;
366 break;
369 break;
371 case 1: /* CDC Data Interface */
372 switch (RequestNo) {
373 case 0:
374 break;
377 break;
378 #endif /* PIOS_INCLUDE_USB_CDC */
380 break;
383 /* No registered copy routine */
384 if ((CopyInRoutine == NULL) && (CopyOutRoutine == NULL)) {
385 return USB_UNSUPPORT;
388 /* Registered copy in AND copy out routine */
389 if ((CopyInRoutine != NULL) && (CopyOutRoutine != NULL)) {
390 /* This should never happen */
391 return USB_UNSUPPORT;
394 if (CopyInRoutine != NULL) {
395 pInformation->Ctrl_Info.CopyDataIn = CopyInRoutine;
396 pInformation->Ctrl_Info.Usb_wOffset = 0;
397 (*CopyInRoutine)(0);
398 } else if (CopyOutRoutine != NULL) {
399 pInformation->Ctrl_Info.CopyDataOut = CopyOutRoutine;
400 pInformation->Ctrl_Info.Usb_rOffset = 0;
401 (*CopyOutRoutine)(0);
404 return USB_SUCCESS;
407 /*******************************************************************************
408 * Function Name : PIOS_USBHOOK_NoData_Setup
409 * Description : handle the no data class specific requests
410 * Input : Request Nb.
411 * Output : None.
412 * Return : USB_UNSUPPORT or USB_SUCCESS.
413 *******************************************************************************/
414 extern RESULT PIOS_USB_CDC_SetControlLineState(void);
416 static RESULT PIOS_USBHOOK_NoData_Setup(uint8_t RequestNo)
418 switch (Type_Recipient) {
419 case (CLASS_REQUEST | INTERFACE_RECIPIENT):
420 switch (pInformation->USBwIndex0) {
421 #if defined(PIOS_INCLUDE_USB_CDC)
422 case 2: /* HID */
423 #else
424 case 0: /* HID */
425 #endif
426 switch (RequestNo) {
427 case USB_HID_REQ_SET_PROTOCOL:
428 return PIOS_USBHOOK_SetProtocol();
430 break;
433 break;
435 #if defined(PIOS_INCLUDE_USB_CDC)
436 case 0: /* CDC Call Control Interface */
437 switch (RequestNo) {
438 case USB_CDC_REQ_SET_CONTROL_LINE_STATE:
439 return PIOS_USB_CDC_SetControlLineState();
441 break;
444 break;
445 #endif /* PIOS_INCLUDE_USB_CDC */
448 break;
451 return USB_UNSUPPORT;
454 /*******************************************************************************
455 * Function Name : PIOS_USBHOOK_GetDeviceDescriptor.
456 * Description : Gets the device descriptor.
457 * Input : Length
458 * Output : None.
459 * Return : The address of the device descriptor.
460 *******************************************************************************/
461 static const uint8_t *PIOS_USBHOOK_GetDeviceDescriptor(uint16_t Length)
463 return Standard_GetDescriptorData(Length, &Device_Descriptor);
466 /*******************************************************************************
467 * Function Name : PIOS_USBHOOK_GetConfigDescriptor.
468 * Description : Gets the configuration descriptor.
469 * Input : Length
470 * Output : None.
471 * Return : The address of the configuration descriptor.
472 *******************************************************************************/
473 static const uint8_t *PIOS_USBHOOK_GetConfigDescriptor(uint16_t Length)
475 return Standard_GetDescriptorData(Length, &Config_Descriptor);
478 /*******************************************************************************
479 * Function Name : PIOS_USBHOOK_GetStringDescriptor
480 * Description : Gets the string descriptors according to the needed index
481 * Input : Length
482 * Output : None.
483 * Return : The address of the string descriptors.
484 *******************************************************************************/
485 static const uint8_t *PIOS_USBHOOK_GetStringDescriptor(uint16_t Length)
487 uint8_t wValue0 = pInformation->USBwValue0;
489 if (wValue0 > 4) {
490 return NULL;
491 } else {
492 return Standard_GetDescriptorData(Length, &String_Descriptor[wValue0]);
496 /*******************************************************************************
497 * Function Name : PIOS_USBHOOK_GetReportDescriptor.
498 * Description : Gets the HID report descriptor.
499 * Input : Length
500 * Output : None.
501 * Return : The address of the configuration descriptor.
502 *******************************************************************************/
503 static const uint8_t *PIOS_USBHOOK_GetReportDescriptor(uint16_t Length)
505 return Standard_GetDescriptorData(Length, &Hid_Report_Descriptor);
508 /*******************************************************************************
509 * Function Name : PIOS_USBHOOK_GetHIDDescriptor.
510 * Description : Gets the HID descriptor.
511 * Input : Length
512 * Output : None.
513 * Return : The address of the configuration descriptor.
514 *******************************************************************************/
515 static const uint8_t *PIOS_USBHOOK_GetHIDDescriptor(uint16_t Length)
517 return Standard_GetDescriptorData(Length, &Hid_Descriptor);
520 /*******************************************************************************
521 * Function Name : PIOS_USBHOOK_Get_Interface_Setting.
522 * Description : tests the interface and the alternate setting according to the
523 * supported one.
524 * Input : - Interface : interface number.
525 * - AlternateSetting : Alternate Setting number.
526 * Output : None.
527 * Return : USB_SUCCESS or USB_UNSUPPORT.
528 *******************************************************************************/
529 static RESULT PIOS_USBHOOK_Get_Interface_Setting(uint8_t Interface, uint8_t AlternateSetting)
531 if (AlternateSetting > 0) {
532 return USB_UNSUPPORT;
533 } else if (Interface > 0) {
534 return USB_UNSUPPORT;
536 return USB_SUCCESS;
539 /*******************************************************************************
540 * Function Name : PIOS_USBHOOK_SetProtocol
541 * Description : Set Protocol request routine.
542 * Input : None.
543 * Output : None.
544 * Return : USB SUCCESS.
545 *******************************************************************************/
546 static RESULT PIOS_USBHOOK_SetProtocol(void)
548 uint8_t wValue0 = pInformation->USBwValue0;
550 ProtocolValue = wValue0;
551 return USB_SUCCESS;
554 /*******************************************************************************
555 * Function Name : PIOS_USBHOOK_GetProtocolValue
556 * Description : get the protocol value
557 * Input : Length.
558 * Output : None.
559 * Return : address of the protcol value.
560 *******************************************************************************/
561 static const uint8_t *PIOS_USBHOOK_GetProtocolValue(uint16_t Length)
563 if (Length == 0) {
564 pInformation->Ctrl_Info.Usb_wLength = 1;
565 return NULL;
566 } else {
567 return (uint8_t *)(&ProtocolValue);
571 #endif /* PIOS_INCLUDE_USB */
573 /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/