2 ******************************************************************************
3 * @addtogroup PIOS PIOS Core hardware abstraction layer
5 * @addtogroup PIOS_USBHOOK USB glue code
6 * @brief Glue between PiOS and STM32 libs
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
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
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 */
45 static ONE_DESCRIPTOR Device_Descriptor
;
47 void PIOS_USBHOOK_RegisterDevice(const uint8_t *desc
, uint16_t desc_size
)
49 Device_Descriptor
.Descriptor
= desc
;
50 Device_Descriptor
.Descriptor_Size
= desc_size
;
53 static ONE_DESCRIPTOR Config_Descriptor
;
55 void PIOS_USBHOOK_RegisterConfig(__attribute__((unused
)) uint8_t config_id
, const uint8_t *desc
, uint16_t desc_size
)
57 Config_Descriptor
.Descriptor
= desc
;
58 Config_Descriptor
.Descriptor_Size
= desc_size
;
61 static ONE_DESCRIPTOR String_Descriptor
[4];
63 void PIOS_USBHOOK_RegisterString(enum usb_string_desc string_id
, const uint8_t *desc
, uint16_t desc_size
)
65 if (string_id
< NELEMENTS(String_Descriptor
)) {
66 String_Descriptor
[string_id
].Descriptor
= desc
;
67 String_Descriptor
[string_id
].Descriptor_Size
= desc_size
;
71 static ONE_DESCRIPTOR Hid_Descriptor
;
73 void PIOS_USB_HID_RegisterHidDescriptor(const uint8_t *desc
, uint16_t desc_size
)
75 Hid_Descriptor
.Descriptor
= desc
;
76 Hid_Descriptor
.Descriptor_Size
= desc_size
;
79 static ONE_DESCRIPTOR Hid_Report_Descriptor
;
81 void PIOS_USB_HID_RegisterHidReport(const uint8_t *desc
, uint16_t desc_size
)
83 Hid_Report_Descriptor
.Descriptor
= desc
;
84 Hid_Report_Descriptor
.Descriptor_Size
= desc_size
;
87 #include "stm32f10x.h" /* __IO */
88 __IO
uint8_t EXTI_Enable
;
90 uint32_t ProtocolValue
;
92 DEVICE Device_Table
= {
93 PIOS_USB_BOARD_EP_NUM
,
97 static void PIOS_USBHOOK_Init(void);
98 static void PIOS_USBHOOK_Reset(void);
99 static void PIOS_USBHOOK_Status_In(void);
100 static void PIOS_USBHOOK_Status_Out(void);
101 static RESULT
PIOS_USBHOOK_Data_Setup(uint8_t RequestNo
);
102 static RESULT
PIOS_USBHOOK_NoData_Setup(uint8_t RequestNo
);
103 static RESULT
PIOS_USBHOOK_Get_Interface_Setting(uint8_t Interface
, uint8_t AlternateSetting
);
104 static const uint8_t *PIOS_USBHOOK_GetDeviceDescriptor(uint16_t Length
);
105 static const uint8_t *PIOS_USBHOOK_GetConfigDescriptor(uint16_t Length
);
106 static const uint8_t *PIOS_USBHOOK_GetStringDescriptor(uint16_t Length
);
108 DEVICE_PROP Device_Property
= {
109 .Init
= PIOS_USBHOOK_Init
,
110 .Reset
= PIOS_USBHOOK_Reset
,
111 .Process_Status_IN
= PIOS_USBHOOK_Status_In
,
112 .Process_Status_OUT
= PIOS_USBHOOK_Status_Out
,
113 .Class_Data_Setup
= PIOS_USBHOOK_Data_Setup
,
114 .Class_NoData_Setup
= PIOS_USBHOOK_NoData_Setup
,
115 .Class_Get_Interface_Setting
= PIOS_USBHOOK_Get_Interface_Setting
,
116 .GetDeviceDescriptor
= PIOS_USBHOOK_GetDeviceDescriptor
,
117 .GetConfigDescriptor
= PIOS_USBHOOK_GetConfigDescriptor
,
118 .GetStringDescriptor
= PIOS_USBHOOK_GetStringDescriptor
,
120 .MaxPacketSize
= 0x40,
123 static void PIOS_USBHOOK_SetConfiguration(void);
124 static void PIOS_USBHOOK_SetDeviceAddress(void);
126 USER_STANDARD_REQUESTS User_Standard_Requests
= {
127 .User_GetConfiguration
= NOP_Process
,
128 .User_SetConfiguration
= PIOS_USBHOOK_SetConfiguration
,
129 .User_GetInterface
= NOP_Process
,
130 .User_SetInterface
= NOP_Process
,
131 .User_GetStatus
= NOP_Process
,
132 .User_ClearFeature
= NOP_Process
,
133 .User_SetEndPointFeature
= NOP_Process
,
134 .User_SetDeviceFeature
= NOP_Process
,
135 .User_SetDeviceAddress
= PIOS_USBHOOK_SetDeviceAddress
138 static RESULT
PIOS_USBHOOK_SetProtocol(void);
139 static const uint8_t *PIOS_USBHOOK_GetProtocolValue(uint16_t Length
);
140 static const uint8_t *PIOS_USBHOOK_GetReportDescriptor(uint16_t Length
);
141 static const uint8_t *PIOS_USBHOOK_GetHIDDescriptor(uint16_t Length
);
143 /*******************************************************************************
144 * Function Name : PIOS_USBHOOK_Init.
145 * Description : Custom HID init routine.
149 *******************************************************************************/
150 static void PIOS_USBHOOK_Init(void)
152 pInformation
->Current_Configuration
= 0;
154 /* Connect the device */
157 /* Perform basic device initialization operations */
160 bDeviceState
= UNCONNECTED
;
163 /*******************************************************************************
164 * Function Name : PIOS_USBHOOK_Reset.
165 * Description : Custom HID reset routine.
169 *******************************************************************************/
170 static void PIOS_USBHOOK_Reset(void)
172 /* Set DEVICE as not configured */
173 pInformation
->Current_Configuration
= 0;
174 pInformation
->Current_Interface
= 0; /*the default Interface */
176 /* Current Feature initialization */
177 pInformation
->Current_Feature
= 0;
180 /* EP0 is already configured in DFU_Init() by USB_SIL_Init() function */
182 /* Init EP1 IN as Interrupt endpoint */
183 OTG_DEV_EP_Init(EP1_IN
, OTG_DEV_EP_TYPE_INT
, 2);
185 /* Init EP1 OUT as Interrupt endpoint */
186 OTG_DEV_EP_Init(EP1_OUT
, OTG_DEV_EP_TYPE_INT
, 2);
188 SetBTABLE(BTABLE_ADDRESS
);
190 /* Initialize Endpoint 0 (Control) */
191 SetEPType(ENDP0
, EP_CONTROL
);
192 SetEPTxAddr(ENDP0
, ENDP0_TXADDR
);
193 SetEPTxStatus(ENDP0
, EP_TX_STALL
);
194 Clear_Status_Out(ENDP0
);
196 SetEPRxAddr(ENDP0
, ENDP0_RXADDR
);
197 SetEPRxCount(ENDP0
, Device_Property
.MaxPacketSize
);
200 #if defined(PIOS_INCLUDE_USB_HID)
201 /* Initialize Endpoint 1 (HID) */
202 SetEPType(ENDP1
, EP_INTERRUPT
);
203 SetEPTxAddr(ENDP1
, ENDP1_TXADDR
);
204 SetEPTxCount(ENDP1
, PIOS_USB_BOARD_HID_DATA_LENGTH
);
205 SetEPTxStatus(ENDP1
, EP_TX_NAK
);
207 SetEPRxAddr(ENDP1
, ENDP1_RXADDR
);
208 SetEPRxCount(ENDP1
, PIOS_USB_BOARD_HID_DATA_LENGTH
);
209 SetEPRxStatus(ENDP1
, EP_RX_VALID
);
210 #endif /* PIOS_INCLUDE_USB_HID */
212 #if defined(PIOS_INCLUDE_USB_CDC)
213 /* Initialize Endpoint 2 (CDC Call Control) */
214 SetEPType(ENDP2
, EP_INTERRUPT
);
215 SetEPTxAddr(ENDP2
, ENDP2_TXADDR
);
216 SetEPTxStatus(ENDP2
, EP_TX_NAK
);
218 SetEPRxAddr(ENDP2
, ENDP2_RXADDR
);
219 SetEPRxCount(ENDP2
, PIOS_USB_BOARD_CDC_MGMT_LENGTH
);
220 SetEPRxStatus(ENDP2
, EP_RX_DIS
);
222 /* Initialize Endpoint 3 (CDC Data) */
223 SetEPType(ENDP3
, EP_BULK
);
224 SetEPTxAddr(ENDP3
, ENDP3_TXADDR
);
225 SetEPTxStatus(ENDP3
, EP_TX_NAK
);
227 SetEPRxAddr(ENDP3
, ENDP3_RXADDR
);
228 SetEPRxCount(ENDP3
, PIOS_USB_BOARD_CDC_DATA_LENGTH
);
229 SetEPRxStatus(ENDP3
, EP_RX_VALID
);
231 #endif /* PIOS_INCLUDE_USB_CDC */
233 /* Set this device to response on default address */
235 #endif /* STM32F10X_CL */
237 bDeviceState
= ATTACHED
;
240 /*******************************************************************************
241 * Function Name : PIOS_USBHOOK_SetConfiguration.
242 * Description : Update the device state to configured
246 *******************************************************************************/
247 static void PIOS_USBHOOK_SetConfiguration(void)
249 if (pInformation
->Current_Configuration
!= 0) {
250 /* Device configured */
251 bDeviceState
= CONFIGURED
;
254 /* Enable transfers */
255 PIOS_USB_ChangeConnectionState(pInformation
->Current_Configuration
!= 0);
258 /*******************************************************************************
259 * Function Name : PIOS_USBHOOK_SetConfiguration.
260 * Description : Update the device state to addressed.
264 *******************************************************************************/
265 static void PIOS_USBHOOK_SetDeviceAddress(void)
267 bDeviceState
= ADDRESSED
;
270 /*******************************************************************************
271 * Function Name : PIOS_USBHOOK_Status_In.
272 * Description : status IN routine.
276 *******************************************************************************/
277 static void PIOS_USBHOOK_Status_In(void)
280 /*******************************************************************************
281 * Function Name : PIOS_USBHOOK_Status_Out
282 * Description : status OUT routine.
286 *******************************************************************************/
287 static void PIOS_USBHOOK_Status_Out(void)
290 /*******************************************************************************
291 * Function Name : PIOS_USBHOOK_Data_Setup
292 * Description : Handle the data class specific requests.
293 * Input : Request Nb.
295 * Return : USB_UNSUPPORT or USB_SUCCESS.
296 *******************************************************************************/
297 extern uint8_t *PIOS_USB_CDC_SetLineCoding(uint16_t Length
);
298 extern const uint8_t *PIOS_USB_CDC_GetLineCoding(uint16_t Length
);
300 static RESULT
PIOS_USBHOOK_Data_Setup(uint8_t RequestNo
)
302 uint8_t *(*CopyOutRoutine
)(uint16_t);
303 const uint8_t *(*CopyInRoutine
)(uint16_t);
305 CopyInRoutine
= NULL
;
306 CopyOutRoutine
= NULL
;
308 switch (Type_Recipient
) {
309 case (STANDARD_REQUEST
| INTERFACE_RECIPIENT
):
310 switch (pInformation
->USBwIndex0
) {
311 #if defined(PIOS_INCLUDE_USB_CDC)
312 case 2: /* HID Interface */
314 case 0: /* HID Interface */
318 switch (pInformation
->USBwValue1
) {
319 case USB_DESC_TYPE_REPORT
:
320 CopyInRoutine
= PIOS_USBHOOK_GetReportDescriptor
;
322 case USB_DESC_TYPE_HID
:
323 CopyInRoutine
= PIOS_USBHOOK_GetHIDDescriptor
;
330 case (CLASS_REQUEST
| INTERFACE_RECIPIENT
):
331 switch (pInformation
->USBwIndex0
) {
332 #if defined(PIOS_INCLUDE_USB_CDC)
333 case 2: /* HID Interface */
335 case 0: /* HID Interface */
338 case USB_HID_REQ_GET_PROTOCOL
:
339 CopyInRoutine
= PIOS_USBHOOK_GetProtocolValue
;
344 #if defined(PIOS_INCLUDE_USB_CDC)
345 case 0: /* CDC Call Control Interface */
347 case USB_CDC_REQ_SET_LINE_CODING
:
348 CopyOutRoutine
= PIOS_USB_CDC_SetLineCoding
;
350 case USB_CDC_REQ_GET_LINE_CODING
:
351 CopyInRoutine
= PIOS_USB_CDC_GetLineCoding
;
357 case 1: /* CDC Data Interface */
364 #endif /* PIOS_INCLUDE_USB_CDC */
369 /* No registered copy routine */
370 if ((CopyInRoutine
== NULL
) && (CopyOutRoutine
== NULL
)) {
371 return USB_UNSUPPORT
;
374 /* Registered copy in AND copy out routine */
375 if ((CopyInRoutine
!= NULL
) && (CopyOutRoutine
!= NULL
)) {
376 /* This should never happen */
377 return USB_UNSUPPORT
;
380 if (CopyInRoutine
!= NULL
) {
381 pInformation
->Ctrl_Info
.CopyDataIn
= CopyInRoutine
;
382 pInformation
->Ctrl_Info
.Usb_wOffset
= 0;
384 } else if (CopyOutRoutine
!= NULL
) {
385 pInformation
->Ctrl_Info
.CopyDataOut
= CopyOutRoutine
;
386 pInformation
->Ctrl_Info
.Usb_rOffset
= 0;
387 (*CopyOutRoutine
)(0);
393 /*******************************************************************************
394 * Function Name : PIOS_USBHOOK_NoData_Setup
395 * Description : handle the no data class specific requests
396 * Input : Request Nb.
398 * Return : USB_UNSUPPORT or USB_SUCCESS.
399 *******************************************************************************/
400 extern RESULT
PIOS_USB_CDC_SetControlLineState(void);
402 static RESULT
PIOS_USBHOOK_NoData_Setup(uint8_t RequestNo
)
404 switch (Type_Recipient
) {
405 case (CLASS_REQUEST
| INTERFACE_RECIPIENT
):
406 switch (pInformation
->USBwIndex0
) {
407 #if defined(PIOS_INCLUDE_USB_CDC)
413 case USB_HID_REQ_SET_PROTOCOL
:
414 return PIOS_USBHOOK_SetProtocol();
421 #if defined(PIOS_INCLUDE_USB_CDC)
422 case 0: /* CDC Call Control Interface */
424 case USB_CDC_REQ_SET_CONTROL_LINE_STATE
:
425 return PIOS_USB_CDC_SetControlLineState();
431 #endif /* PIOS_INCLUDE_USB_CDC */
437 return USB_UNSUPPORT
;
440 /*******************************************************************************
441 * Function Name : PIOS_USBHOOK_GetDeviceDescriptor.
442 * Description : Gets the device descriptor.
445 * Return : The address of the device descriptor.
446 *******************************************************************************/
447 static const uint8_t *PIOS_USBHOOK_GetDeviceDescriptor(uint16_t Length
)
449 return Standard_GetDescriptorData(Length
, &Device_Descriptor
);
452 /*******************************************************************************
453 * Function Name : PIOS_USBHOOK_GetConfigDescriptor.
454 * Description : Gets the configuration descriptor.
457 * Return : The address of the configuration descriptor.
458 *******************************************************************************/
459 static const uint8_t *PIOS_USBHOOK_GetConfigDescriptor(uint16_t Length
)
461 return Standard_GetDescriptorData(Length
, &Config_Descriptor
);
464 /*******************************************************************************
465 * Function Name : PIOS_USBHOOK_GetStringDescriptor
466 * Description : Gets the string descriptors according to the needed index
469 * Return : The address of the string descriptors.
470 *******************************************************************************/
471 static const uint8_t *PIOS_USBHOOK_GetStringDescriptor(uint16_t Length
)
473 uint8_t wValue0
= pInformation
->USBwValue0
;
478 return Standard_GetDescriptorData(Length
, &String_Descriptor
[wValue0
]);
482 /*******************************************************************************
483 * Function Name : PIOS_USBHOOK_GetReportDescriptor.
484 * Description : Gets the HID report descriptor.
487 * Return : The address of the configuration descriptor.
488 *******************************************************************************/
489 static const uint8_t *PIOS_USBHOOK_GetReportDescriptor(uint16_t Length
)
491 return Standard_GetDescriptorData(Length
, &Hid_Report_Descriptor
);
494 /*******************************************************************************
495 * Function Name : PIOS_USBHOOK_GetHIDDescriptor.
496 * Description : Gets the HID descriptor.
499 * Return : The address of the configuration descriptor.
500 *******************************************************************************/
501 static const uint8_t *PIOS_USBHOOK_GetHIDDescriptor(uint16_t Length
)
503 return Standard_GetDescriptorData(Length
, &Hid_Descriptor
);
506 /*******************************************************************************
507 * Function Name : PIOS_USBHOOK_Get_Interface_Setting.
508 * Description : tests the interface and the alternate setting according to the
510 * Input : - Interface : interface number.
511 * - AlternateSetting : Alternate Setting number.
513 * Return : USB_SUCCESS or USB_UNSUPPORT.
514 *******************************************************************************/
515 static RESULT
PIOS_USBHOOK_Get_Interface_Setting(uint8_t Interface
, uint8_t AlternateSetting
)
517 if (AlternateSetting
> 0) {
518 return USB_UNSUPPORT
;
519 } else if (Interface
> 0) {
520 return USB_UNSUPPORT
;
525 /*******************************************************************************
526 * Function Name : PIOS_USBHOOK_SetProtocol
527 * Description : Set Protocol request routine.
530 * Return : USB SUCCESS.
531 *******************************************************************************/
532 static RESULT
PIOS_USBHOOK_SetProtocol(void)
534 uint8_t wValue0
= pInformation
->USBwValue0
;
536 ProtocolValue
= wValue0
;
540 /*******************************************************************************
541 * Function Name : PIOS_USBHOOK_GetProtocolValue
542 * Description : get the protocol value
545 * Return : address of the protcol value.
546 *******************************************************************************/
547 static const uint8_t *PIOS_USBHOOK_GetProtocolValue(uint16_t Length
)
550 pInformation
->Ctrl_Info
.Usb_wLength
= 1;
553 return (uint8_t *)(&ProtocolValue
);
557 #endif /* PIOS_INCLUDE_USB */
559 /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/