LP-551 Remove popup - Increase neutral diff levels for alarm
[librepilot.git] / flight / pios / stm32f30x / pios_usbhook.c
blob738eacd91f6e3fd0051b6c8ca349805a1a2f260e
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 "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,
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;
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 */
325 #else
326 case 0: /* HID Interface */
327 #endif
328 switch (RequestNo) {
329 case GET_DESCRIPTOR:
330 switch (pInformation->USBwValue1) {
331 case USB_DESC_TYPE_REPORT:
332 CopyInRoutine = PIOS_USBHOOK_GetReportDescriptor;
333 break;
334 case USB_DESC_TYPE_HID:
335 CopyInRoutine = PIOS_USBHOOK_GetHIDDescriptor;
336 break;
340 break;
342 case (CLASS_REQUEST | INTERFACE_RECIPIENT):
343 switch (pInformation->USBwIndex0) {
344 #if defined(PIOS_INCLUDE_USB_CDC)
345 case 2: /* HID Interface */
346 #else
347 case 0: /* HID Interface */
348 #endif
349 switch (RequestNo) {
350 case USB_HID_REQ_GET_PROTOCOL:
351 CopyInRoutine = PIOS_USBHOOK_GetProtocolValue;
352 break;
355 break;
356 #if defined(PIOS_INCLUDE_USB_CDC)
357 case 0: /* CDC Call Control Interface */
358 switch (RequestNo) {
359 case USB_CDC_REQ_SET_LINE_CODING:
360 CopyOutRoutine = PIOS_USB_CDC_SetLineCoding;
361 ep0_rxready_cb = PIOS_USB_CDC_SetLineCoding_Completed;
362 break;
363 case USB_CDC_REQ_GET_LINE_CODING:
364 CopyInRoutine = PIOS_USB_CDC_GetLineCoding;
365 break;
368 break;
370 case 1: /* CDC Data Interface */
371 switch (RequestNo) {
372 case 0:
373 break;
376 break;
377 #endif /* PIOS_INCLUDE_USB_CDC */
379 break;
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;
396 (*CopyInRoutine)(0);
397 } else if (CopyOutRoutine != NULL) {
398 pInformation->Ctrl_Info.CopyData = CopyOutRoutine;
399 pInformation->Ctrl_Info.Usb_rOffset = 0;
400 (*CopyOutRoutine)(0);
403 return USB_SUCCESS;
406 /*******************************************************************************
407 * Function Name : PIOS_USBHOOK_NoData_Setup
408 * Description : handle the no data class specific requests
409 * Input : Request Nb.
410 * Output : None.
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)
421 case 2: /* HID */
422 #else
423 case 0: /* HID */
424 #endif
425 switch (RequestNo) {
426 case USB_HID_REQ_SET_PROTOCOL:
427 return PIOS_USBHOOK_SetProtocol();
429 break;
432 break;
434 #if defined(PIOS_INCLUDE_USB_CDC)
435 case 0: /* CDC Call Control Interface */
436 switch (RequestNo) {
437 case USB_CDC_REQ_SET_CONTROL_LINE_STATE:
438 return PIOS_USB_CDC_SetControlLineState();
440 break;
443 break;
444 #endif /* PIOS_INCLUDE_USB_CDC */
447 break;
450 return USB_UNSUPPORT;
453 /*******************************************************************************
454 * Function Name : PIOS_USBHOOK_GetDeviceDescriptor.
455 * Description : Gets the device descriptor.
456 * Input : Length
457 * Output : None.
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.
468 * Input : Length
469 * Output : None.
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
480 * Input : Length
481 * Output : None.
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;
488 if (wValue0 > 4) {
489 return NULL;
490 } else {
491 return Standard_GetDescriptorData(Length, &String_Descriptor[wValue0]);
495 /*******************************************************************************
496 * Function Name : PIOS_USBHOOK_GetReportDescriptor.
497 * Description : Gets the HID report descriptor.
498 * Input : Length
499 * Output : None.
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.
510 * Input : Length
511 * Output : None.
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
522 * supported one.
523 * Input : - Interface : interface number.
524 * - AlternateSetting : Alternate Setting number.
525 * Output : None.
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;
535 return USB_SUCCESS;
538 /*******************************************************************************
539 * Function Name : PIOS_USBHOOK_SetProtocol
540 * Description : Set Protocol request routine.
541 * Input : None.
542 * Output : None.
543 * Return : USB SUCCESS.
544 *******************************************************************************/
545 static RESULT PIOS_USBHOOK_SetProtocol(void)
547 uint8_t wValue0 = pInformation->USBwValue0;
549 ProtocolValue = wValue0;
550 return USB_SUCCESS;
553 /*******************************************************************************
554 * Function Name : PIOS_USBHOOK_GetProtocolValue
555 * Description : get the protocol value
556 * Input : Length.
557 * Output : None.
558 * Return : address of the protcol value.
559 *******************************************************************************/
560 static const uint8_t *PIOS_USBHOOK_GetProtocolValue(uint16_t Length)
562 if (Length == 0) {
563 pInformation->Ctrl_Info.Usb_wLength = 1;
564 return NULL;
565 } else {
566 return (uint8_t *)(&ProtocolValue);
570 #endif /* PIOS_INCLUDE_USB */
572 /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/