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 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 "stm32f30x.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
,
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.
154 *******************************************************************************/
155 static void PIOS_USBHOOK_Init(void)
157 pInformation
->Current_Configuration
= 0;
159 /* Connect the device */
162 /* Perform basic device initialization operations */
165 bDeviceState
= UNCONNECTED
;
168 /*******************************************************************************
169 * Function Name : PIOS_USBHOOK_Reset.
170 * Description : Custom HID reset routine.
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;
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);
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
);
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 */
240 #endif /* STM32F10X_CL */
242 bDeviceState
= ATTACHED
;
245 /*******************************************************************************
246 * Function Name : PIOS_USBHOOK_SetConfiguration.
247 * Description : Update the device state to configured
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.
269 *******************************************************************************/
270 static void PIOS_USBHOOK_SetDeviceAddress(void)
272 bDeviceState
= ADDRESSED
;
275 /*******************************************************************************
276 * Function Name : PIOS_USBHOOK_Status_In.
277 * Description : status IN routine.
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
) {
291 /*******************************************************************************
292 * Function Name : PIOS_USBHOOK_Status_Out
293 * Description : status OUT routine.
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.
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
;
320 switch (Type_Recipient
) {
321 case (STANDARD_REQUEST
| INTERFACE_RECIPIENT
):
322 switch (pInformation
->USBwIndex0
) {
323 #if defined(PIOS_INCLUDE_USB_CDC)
324 case 2: /* HID Interface */
326 case 0: /* HID Interface */
330 switch (pInformation
->USBwValue1
) {
331 case USB_DESC_TYPE_REPORT
:
332 CopyInRoutine
= PIOS_USBHOOK_GetReportDescriptor
;
334 case USB_DESC_TYPE_HID
:
335 CopyInRoutine
= PIOS_USBHOOK_GetHIDDescriptor
;
342 case (CLASS_REQUEST
| INTERFACE_RECIPIENT
):
343 switch (pInformation
->USBwIndex0
) {
344 #if defined(PIOS_INCLUDE_USB_CDC)
345 case 2: /* HID Interface */
347 case 0: /* HID Interface */
350 case USB_HID_REQ_GET_PROTOCOL
:
351 CopyInRoutine
= PIOS_USBHOOK_GetProtocolValue
;
356 #if defined(PIOS_INCLUDE_USB_CDC)
357 case 0: /* CDC Call Control Interface */
359 case USB_CDC_REQ_SET_LINE_CODING
:
360 CopyOutRoutine
= PIOS_USB_CDC_SetLineCoding
;
361 ep0_rxready_cb
= PIOS_USB_CDC_SetLineCoding_Completed
;
363 case USB_CDC_REQ_GET_LINE_CODING
:
364 CopyInRoutine
= PIOS_USB_CDC_GetLineCoding
;
370 case 1: /* CDC Data Interface */
377 #endif /* PIOS_INCLUDE_USB_CDC */
382 /* No registered copy routine */
383 if ((CopyInRoutine
== NULL
) && (CopyOutRoutine
== NULL
)) {
384 return USB_UNSUPPORT
;
387 /* Registered copy in AND copy out routine */
388 if ((CopyInRoutine
!= NULL
) && (CopyOutRoutine
!= NULL
)) {
389 /* This should never happen */
390 return USB_UNSUPPORT
;
393 if (CopyInRoutine
!= NULL
) {
394 pInformation
->Ctrl_Info
.CopyData
= (typeof(pInformation
->Ctrl_Info
.CopyData
))CopyInRoutine
;
395 pInformation
->Ctrl_Info
.Usb_wOffset
= 0;
397 } else if (CopyOutRoutine
!= NULL
) {
398 pInformation
->Ctrl_Info
.CopyData
= CopyOutRoutine
;
399 pInformation
->Ctrl_Info
.Usb_rOffset
= 0;
400 (*CopyOutRoutine
)(0);
406 /*******************************************************************************
407 * Function Name : PIOS_USBHOOK_NoData_Setup
408 * Description : handle the no data class specific requests
409 * Input : Request Nb.
411 * Return : USB_UNSUPPORT or USB_SUCCESS.
412 *******************************************************************************/
413 extern RESULT
PIOS_USB_CDC_SetControlLineState(void);
415 static RESULT
PIOS_USBHOOK_NoData_Setup(uint8_t RequestNo
)
417 switch (Type_Recipient
) {
418 case (CLASS_REQUEST
| INTERFACE_RECIPIENT
):
419 switch (pInformation
->USBwIndex0
) {
420 #if defined(PIOS_INCLUDE_USB_CDC)
426 case USB_HID_REQ_SET_PROTOCOL
:
427 return PIOS_USBHOOK_SetProtocol();
434 #if defined(PIOS_INCLUDE_USB_CDC)
435 case 0: /* CDC Call Control Interface */
437 case USB_CDC_REQ_SET_CONTROL_LINE_STATE
:
438 return PIOS_USB_CDC_SetControlLineState();
444 #endif /* PIOS_INCLUDE_USB_CDC */
450 return USB_UNSUPPORT
;
453 /*******************************************************************************
454 * Function Name : PIOS_USBHOOK_GetDeviceDescriptor.
455 * Description : Gets the device descriptor.
458 * Return : The address of the device descriptor.
459 *******************************************************************************/
460 static const uint8_t *PIOS_USBHOOK_GetDeviceDescriptor(uint16_t Length
)
462 return Standard_GetDescriptorData(Length
, &Device_Descriptor
);
465 /*******************************************************************************
466 * Function Name : PIOS_USBHOOK_GetConfigDescriptor.
467 * Description : Gets the configuration descriptor.
470 * Return : The address of the configuration descriptor.
471 *******************************************************************************/
472 static const uint8_t *PIOS_USBHOOK_GetConfigDescriptor(uint16_t Length
)
474 return Standard_GetDescriptorData(Length
, &Config_Descriptor
);
477 /*******************************************************************************
478 * Function Name : PIOS_USBHOOK_GetStringDescriptor
479 * Description : Gets the string descriptors according to the needed index
482 * Return : The address of the string descriptors.
483 *******************************************************************************/
484 static const uint8_t *PIOS_USBHOOK_GetStringDescriptor(uint16_t Length
)
486 uint8_t wValue0
= pInformation
->USBwValue0
;
491 return Standard_GetDescriptorData(Length
, &String_Descriptor
[wValue0
]);
495 /*******************************************************************************
496 * Function Name : PIOS_USBHOOK_GetReportDescriptor.
497 * Description : Gets the HID report descriptor.
500 * Return : The address of the configuration descriptor.
501 *******************************************************************************/
502 static const uint8_t *PIOS_USBHOOK_GetReportDescriptor(uint16_t Length
)
504 return Standard_GetDescriptorData(Length
, &Hid_Report_Descriptor
);
507 /*******************************************************************************
508 * Function Name : PIOS_USBHOOK_GetHIDDescriptor.
509 * Description : Gets the HID descriptor.
512 * Return : The address of the configuration descriptor.
513 *******************************************************************************/
514 static const uint8_t *PIOS_USBHOOK_GetHIDDescriptor(uint16_t Length
)
516 return Standard_GetDescriptorData(Length
, &Hid_Descriptor
);
519 /*******************************************************************************
520 * Function Name : PIOS_USBHOOK_Get_Interface_Setting.
521 * Description : tests the interface and the alternate setting according to the
523 * Input : - Interface : interface number.
524 * - AlternateSetting : Alternate Setting number.
526 * Return : USB_SUCCESS or USB_UNSUPPORT.
527 *******************************************************************************/
528 static RESULT
PIOS_USBHOOK_Get_Interface_Setting(uint8_t Interface
, uint8_t AlternateSetting
)
530 if (AlternateSetting
> 0) {
531 return USB_UNSUPPORT
;
532 } else if (Interface
> 0) {
533 return USB_UNSUPPORT
;
538 /*******************************************************************************
539 * Function Name : PIOS_USBHOOK_SetProtocol
540 * Description : Set Protocol request routine.
543 * Return : USB SUCCESS.
544 *******************************************************************************/
545 static RESULT
PIOS_USBHOOK_SetProtocol(void)
547 uint8_t wValue0
= pInformation
->USBwValue0
;
549 ProtocolValue
= wValue0
;
553 /*******************************************************************************
554 * Function Name : PIOS_USBHOOK_GetProtocolValue
555 * Description : get the protocol value
558 * Return : address of the protcol value.
559 *******************************************************************************/
560 static const uint8_t *PIOS_USBHOOK_GetProtocolValue(uint16_t Length
)
563 pInformation
->Ctrl_Info
.Usb_wLength
= 1;
566 return (uint8_t *)(&ProtocolValue
);
570 #endif /* PIOS_INCLUDE_USB */
572 /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/