mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-12-01 09:24:10 +01:00
USB HID now working and integrated into PIOS_COM.
You can now send and receive packets (up to 63 bytes) just like using the USART port with PIOS_COM. HID packet length will soon be increased to support maximum UAVTalk message length. git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@182 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
parent
7578f74e8c
commit
0a9be2dedd
@ -52,13 +52,14 @@ int32_t PIOS_COM_Init(void)
|
||||
|
||||
/* If any COM assignment: */
|
||||
PIOS_USART_Init();
|
||||
PIOS_USB_HID_Init(0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a package over given port
|
||||
* \param[in] port COM port (COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART)
|
||||
* \param[in] port COM port (COM_DEBUG_UART, COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART, COM_USB_HID)
|
||||
* \param[in] buffer character buffer
|
||||
* \param[in] len buffer length
|
||||
* \return -1 if port not available
|
||||
@ -70,26 +71,26 @@ int32_t PIOS_COM_SendBufferNonBlocking(COMPortTypeDef port, uint8_t *buffer, uin
|
||||
{
|
||||
/* Branch depending on selected port */
|
||||
switch(port) {
|
||||
case 0:
|
||||
case COM_DEBUG_UART:
|
||||
return PIOS_USART_TxBufferPutMoreNonBlocking(COM_DEBUG_PORT, buffer, len);
|
||||
case 1:
|
||||
case COM_GPS_UART:
|
||||
return PIOS_USART_TxBufferPutMoreNonBlocking(GPS, buffer, len);
|
||||
case 2:
|
||||
case COM_TELEM_UART:
|
||||
return PIOS_USART_TxBufferPutMoreNonBlocking(TELEM, buffer, len);
|
||||
case 3:
|
||||
case COM_AUX_UART:
|
||||
return PIOS_USART_TxBufferPutMoreNonBlocking(AUX, buffer, len);
|
||||
case COM_USB_HID:
|
||||
return PIOS_USB_HID_TxBufferPutMoreNonBlocking(buffer, len);
|
||||
default:
|
||||
/* Invalid port */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Sends a package over given port
|
||||
* (blocking function)
|
||||
* \param[in] port COM port (COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART)
|
||||
* \param[in] port COM port (COM_DEBUG_UART, COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART, COM_USB_HID)
|
||||
* \param[in] buffer character buffer
|
||||
* \param[in] len buffer length
|
||||
* \return -1 if port not available
|
||||
@ -99,24 +100,25 @@ int32_t PIOS_COM_SendBuffer(COMPortTypeDef port, uint8_t *buffer, uint16_t len)
|
||||
{
|
||||
/* Branch depending on selected port */
|
||||
switch(port) {
|
||||
case 0:
|
||||
case COM_DEBUG_UART:
|
||||
return PIOS_USART_TxBufferPutMore(COM_DEBUG_PORT, buffer, len);
|
||||
case 1:
|
||||
case COM_GPS_UART:
|
||||
return PIOS_USART_TxBufferPutMore(GPS, buffer, len);
|
||||
case 2:
|
||||
case COM_TELEM_UART:
|
||||
return PIOS_USART_TxBufferPutMore(TELEM, buffer, len);
|
||||
case 3:
|
||||
case COM_AUX_UART:
|
||||
return PIOS_USART_TxBufferPutMore(AUX, buffer, len);
|
||||
case COM_USB_HID:
|
||||
return PIOS_USB_HID_TxBufferPutMore(buffer, len);
|
||||
default:
|
||||
/* Invalid port */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends a single character over given port
|
||||
* \param[in] port COM port (COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART)
|
||||
* \param[in] port COM port (COM_DEBUG_UART, COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART, COM_USB_HID)
|
||||
* \param[in] c character
|
||||
* \return -1 if port not available
|
||||
* \return -2 buffer is full
|
||||
@ -128,11 +130,10 @@ int32_t PIOS_COM_SendCharNonBlocking(COMPortTypeDef port, char c)
|
||||
return PIOS_COM_SendBufferNonBlocking(port, (uint8_t *)&c, 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends a single character over given port
|
||||
* (blocking function)
|
||||
* \param[in] port COM port (COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART)
|
||||
* \param[in] port COM port (COM_DEBUG_UART, COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART, COM_USB_HID)
|
||||
* \param[in] c character
|
||||
* \return -1 if port not available
|
||||
* \return 0 on success
|
||||
@ -142,10 +143,9 @@ int32_t PIOS_COM_SendChar(COMPortTypeDef port, char c)
|
||||
return PIOS_COM_SendBuffer(port, (uint8_t *)&c, 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends a string over given port
|
||||
* \param[in] port COM port (COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART)
|
||||
* \param[in] port COM port (COM_DEBUG_UART, COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART, COM_USB_HID)
|
||||
* \param[in] str zero-terminated string
|
||||
* \return -1 if port not available
|
||||
* \return -2 buffer is full
|
||||
@ -157,11 +157,10 @@ int32_t PIOS_COM_SendStringNonBlocking(COMPortTypeDef port, char *str)
|
||||
return PIOS_COM_SendBufferNonBlocking(port, (uint8_t *)str, (uint16_t)strlen(str));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends a string over given port
|
||||
* (blocking function)
|
||||
* \param[in] port COM port (COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART)
|
||||
* \param[in] port COM port (COM_DEBUG_UART, COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART, COM_USB_HID)
|
||||
* \param[in] str zero-terminated string
|
||||
* \return -1 if port not available
|
||||
* \return 0 on success
|
||||
@ -171,10 +170,9 @@ int32_t PIOS_COM_SendString(COMPortTypeDef port, char *str)
|
||||
return PIOS_COM_SendBuffer(port, (uint8_t *)str, strlen(str));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends a formatted string (-> printf) over given port
|
||||
* \param[in] port COM port (COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART)
|
||||
* \param[in] port COM port (COM_DEBUG_UART, COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART, COM_USB_HID)
|
||||
* \param[in] *format zero-terminated format string - 128 characters supported maximum!
|
||||
* \param[in] ... optional arguments,
|
||||
* 128 characters supported maximum!
|
||||
@ -193,11 +191,10 @@ int32_t PIOS_COM_SendFormattedStringNonBlocking(COMPortTypeDef port, char *forma
|
||||
return PIOS_COM_SendBufferNonBlocking(port, buffer, (uint16_t)strlen((char *)buffer));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends a formatted string (-> printf) over given port
|
||||
* (blocking function)
|
||||
* \param[in] port COM port (COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART)
|
||||
* \param[in] port COM port (COM_DEBUG_UART, COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART, COM_USB_HID)
|
||||
* \param[in] *format zero-terminated format string - 128 characters supported maximum!
|
||||
* \param[in] ... optional arguments,
|
||||
* \return -1 if port not available
|
||||
@ -213,8 +210,6 @@ int32_t PIOS_COM_SendFormattedString(COMPortTypeDef port, char *format, ...)
|
||||
return PIOS_COM_SendBuffer(port, buffer, (uint16_t)strlen((char *)buffer));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Checks for incoming COM messages, calls the callback function which has
|
||||
* been installed via PIOS_COM_ReceiveCallbackInit()
|
||||
@ -238,28 +233,44 @@ int32_t PIOS_COM_ReceiveHandler(void)
|
||||
uint8_t again = 1;
|
||||
|
||||
do {
|
||||
// Round Robin
|
||||
// TODO: maybe a list based approach would be better
|
||||
// it would allow to add/remove interfaces dynamically
|
||||
// this would also allow to give certain ports a higher priority (to add them multiple times to the list)
|
||||
// it would also improve this spagetthi code ;)
|
||||
/* Round Robin */
|
||||
/* TODO: maybe a list based approach would be better */
|
||||
/* it would allow to add/remove interfaces dynamically */
|
||||
/* this would also allow to give certain ports a higher priority (to add them multiple times to the list) */
|
||||
/* it would also improve this spagetthi code ;) */
|
||||
int32_t status = -1;
|
||||
switch( intf++ ) {
|
||||
case 0: status = PIOS_USART_RxBufferGet(COM_DEBUG_PORT); port = COM_DEBUG_UART; break;
|
||||
case 1: status = PIOS_USART_RxBufferGet(GPS); port = COM_GPS_UART; break;
|
||||
case 2: status = PIOS_USART_RxBufferGet(TELEM); port = COM_TELEM_UART; break;
|
||||
case 3: status = PIOS_USART_RxBufferGet(AUX); port = COM_AUX_UART; break;
|
||||
switch(intf++) {
|
||||
case COM_DEBUG_UART:
|
||||
status = PIOS_USART_RxBufferGet(COM_DEBUG_PORT);
|
||||
port = COM_DEBUG_UART;
|
||||
break;
|
||||
case COM_GPS_UART:
|
||||
status = PIOS_USART_RxBufferGet(GPS);
|
||||
port = COM_GPS_UART;
|
||||
break;
|
||||
case COM_TELEM_UART:
|
||||
status = PIOS_USART_RxBufferGet(TELEM);
|
||||
port = COM_TELEM_UART;
|
||||
break;
|
||||
case COM_AUX_UART:
|
||||
status = PIOS_USART_RxBufferGet(AUX);
|
||||
port = COM_AUX_UART;
|
||||
break;
|
||||
case COM_USB_HID:
|
||||
status = PIOS_USB_HID_RxBufferGet();
|
||||
port = COM_USB_HID;
|
||||
break;
|
||||
default:
|
||||
// allow 64 forwards maximum to yield some CPU time for other tasks
|
||||
/* Allow 64 forwards maximum to yield some CPU time for other tasks */
|
||||
if(bytes_forwarded && total_bytes_forwarded < 64) {
|
||||
intf = 0; // restart with USB
|
||||
bytes_forwarded = 0; // for checking, if bytes still have been forwarded in next round
|
||||
intf = 0; /* Restart at start */
|
||||
bytes_forwarded = 0; /* Ror checking, if bytes still have been forwarded in next round */
|
||||
} else {
|
||||
again = 0; // no more interfaces to be processed
|
||||
again = 0; /* No more interfaces to be processed */
|
||||
}
|
||||
status = -1; // empty round - no message
|
||||
status = -1; /* Empty round - no message */
|
||||
}
|
||||
|
||||
|
||||
/* Message received? */
|
||||
if(status >= 0) {
|
||||
/* Notify that a package has been forwarded */
|
||||
@ -275,7 +286,6 @@ int32_t PIOS_COM_ReceiveHandler(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Installs the callback function which is executed on incoming characters
|
||||
* from a COM interface.
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
/* Project Includes */
|
||||
#include "pios.h"
|
||||
#include <string.h>
|
||||
//#include <string.h>
|
||||
|
||||
|
||||
/* Local definitions */
|
||||
@ -42,7 +42,6 @@
|
||||
|
||||
/* ISTR events */
|
||||
/* mask defining which events has to be handled by the device application software */
|
||||
/* Unused; #define IMR_MSK (CNTR_CTRM | CNTR_WKUPM | CNTR_SUSPM | CNTR_ERRM | CNTR_SOFM | CNTR_ESOFM | CNTR_RESETM) */
|
||||
#define IMR_MSK (CNTR_RESETM | CNTR_SOFM | CNTR_CTRM)
|
||||
|
||||
/* Local types */
|
||||
@ -160,7 +159,7 @@ static const uint8_t PIOS_USB_ConfigDescriptor[PIOS_USB_SIZ_CONFIG_DESC] = {
|
||||
|
||||
0x81, /* bEndpointAddress: Endpoint Address (IN) */
|
||||
0x03, /* bmAttributes: Interrupt endpoint */
|
||||
64,//0x02, /* wMaxPacketSize: 2 Bytes max */
|
||||
(PIOS_USB_HID_DATA_LENGTH + 1), /* wMaxPacketSize: 2 Bytes max */
|
||||
0x00, 2,//0x20, /* bInterval: Polling Interval (2 ms) */
|
||||
/* 34 */
|
||||
|
||||
@ -170,7 +169,7 @@ static const uint8_t PIOS_USB_ConfigDescriptor[PIOS_USB_SIZ_CONFIG_DESC] = {
|
||||
0x01, /* bEndpointAddress: */
|
||||
/* Endpoint Address (OUT) */
|
||||
0x03, /* bmAttributes: Interrupt endpoint */
|
||||
64,//0x02, /* wMaxPacketSize: 2 Bytes max */
|
||||
(PIOS_USB_HID_DATA_LENGTH + 1), /* wMaxPacketSize: 2 Bytes max */
|
||||
0x00, 8,//0x20, /* bInterval: Polling Interval (8 ms) */
|
||||
/* 41 */
|
||||
};
|
||||
@ -255,7 +254,7 @@ int32_t PIOS_USB_Init(uint32_t mode)
|
||||
if(mode != 2) {
|
||||
/* Note: usually no need to duplicate this for external drivers */
|
||||
pInformation = &My_Device_Info;
|
||||
pInformation->Ctrl_Info.Usb_wLength = 64; /* TODO: Is this required? */
|
||||
pInformation->Ctrl_Info.Usb_wLength = (PIOS_USB_HID_DATA_LENGTH + 1); /* TODO: Is this required? */
|
||||
|
||||
/* Following hooks/pointers should be replaced by external drivers */
|
||||
memcpy(&Device_Table, (DEVICE *) &My_Device_Table, sizeof(Device_Table));
|
||||
@ -417,19 +416,17 @@ static void PIOS_USB_CB_Reset(void)
|
||||
SetEPRxCount(ENDP0, pProperty->MaxPacketSize);
|
||||
SetEPRxValid(ENDP0);
|
||||
|
||||
#ifndef DISABLE_HID
|
||||
/* Initialise Endpoint 1 */
|
||||
SetEPType(ENDP1, EP_INTERRUPT);
|
||||
SetEPTxAddr(ENDP1, PIOS_USB_ENDP1_TXADDR);
|
||||
SetEPRxAddr(ENDP1, PIOS_USB_ENDP1_RXADDR);
|
||||
SetEPTxCount(ENDP1, 2);
|
||||
SetEPRxCount(ENDP1, 2);
|
||||
SetEPTxCount(ENDP1, (PIOS_USB_HID_DATA_LENGTH + 1));
|
||||
SetEPRxCount(ENDP1, (PIOS_USB_HID_DATA_LENGTH + 1));
|
||||
SetEPTxStatus(ENDP1, EP_TX_NAK);
|
||||
SetEPRxStatus(ENDP1, EP_RX_VALID);
|
||||
|
||||
/* Propagate connection state to USB HID driver */
|
||||
PIOS_USB_HID_ChangeConnectionState(0);
|
||||
#endif
|
||||
|
||||
/* Set this device to response on default address */
|
||||
SetDeviceAddress(0);
|
||||
|
@ -42,7 +42,7 @@ typedef enum _HID_REQUESTS {
|
||||
} HID_REQUESTS;
|
||||
|
||||
/* Local Variables */
|
||||
uint32_t ProtocolValue;
|
||||
static uint32_t ProtocolValue;
|
||||
|
||||
/* Local Functions */
|
||||
static uint8_t *PIOS_USB_HID_GetHIDDescriptor(uint16_t Length);
|
||||
@ -50,192 +50,181 @@ static uint8_t *PIOS_USB_HID_GetReportDescriptor(uint16_t Length);
|
||||
static uint8_t *PIOS_USB_HID_GetProtocolValue(uint16_t Length);
|
||||
|
||||
static const uint8_t PIOS_USB_HID_ReportDescriptor[PIOS_USB_HID_SIZ_REPORT_DESC] = {
|
||||
#if 0
|
||||
0x05, 0x8c, /* USAGE_PAGE (ST Page) */
|
||||
0x09, 0x01, /* USAGE (Demo Kit) */
|
||||
0xa1, 0x01, /* COLLECTION (Application) */
|
||||
/* 6 */
|
||||
#endif
|
||||
#if 0
|
||||
/* Led 1 */
|
||||
0x85, 0x01, /* REPORT_ID (1) */
|
||||
0x09, 0x01, /* USAGE (LED 1) */
|
||||
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
|
||||
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
|
||||
0x75, 0x08, /* REPORT_SIZE (8) */
|
||||
0x95, 0x01, /* REPORT_COUNT (1) */
|
||||
0xB1, 0x82, /* FEATURE (Data,Var,Abs,Vol) */
|
||||
0x06, 0x9c, 0xff, /* Usage Page (Vendor Defined) */
|
||||
0x09, 0x01, /* Usage (Vendor Defined) */
|
||||
0xa1, 0x01, /* Collection (Vendor Defined) */
|
||||
|
||||
0x85, 0x01, /* REPORT_ID (1) */
|
||||
0x09, 0x01, /* USAGE (LED 1) */
|
||||
0x91, 0x82, /* OUTPUT (Data,Var,Abs,Vol) */
|
||||
/* 26 */
|
||||
0x09, 0x02, /* Usage (Vendor Defined) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x95, (PIOS_USB_HID_DATA_LENGTH), /* Report Count (64) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0xff, /* Logical Maximum (255) */
|
||||
0x81, 0x02, /* Input (Data, Variable, Absolute) */
|
||||
|
||||
/* Led 2 */
|
||||
0x85, 0x02, /* REPORT_ID 2 */
|
||||
0x09, 0x02, /* USAGE (LED 2) */
|
||||
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
|
||||
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
|
||||
0x75, 0x08, /* REPORT_SIZE (8) */
|
||||
0x95, 0x01, /* REPORT_COUNT (1) */
|
||||
0xB1, 0x82, /* FEATURE (Data,Var,Abs,Vol) */
|
||||
0x09, 0x03, /* Usage (Vendor Defined) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x95, (PIOS_USB_HID_DATA_LENGTH), /* Report Count (64) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0xff, /* Logical Maximum (255) */
|
||||
0x91, 0x02, /* Output (Data, Variable, Absolute) */
|
||||
|
||||
0x85, 0x02, /* REPORT_ID (2) */
|
||||
0x09, 0x02, /* USAGE (LED 2) */
|
||||
0x91, 0x82, /* OUTPUT (Data,Var,Abs,Vol) */
|
||||
/* 46 */
|
||||
|
||||
/* key Push Button */
|
||||
0x85, 0x05, /* REPORT_ID (5) */
|
||||
0x09, 0x05, /* USAGE (Push Button) */
|
||||
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
|
||||
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
|
||||
0x75, 0x01, /* REPORT_SIZE (1) */
|
||||
0x81, 0x82, /* INPUT (Data,Var,Abs,Vol) */
|
||||
|
||||
0x09, 0x05, /* USAGE (Push Button) */
|
||||
0x75, 0x01, /* REPORT_SIZE (1) */
|
||||
0xb1, 0x82, /* FEATURE (Data,Var,Abs,Vol) */
|
||||
|
||||
0x75, 0x07, /* REPORT_SIZE (7) */
|
||||
0x81, 0x83, /* INPUT (Cnst,Var,Abs,Vol) */
|
||||
0x85, 0x05, /* REPORT_ID (2) */
|
||||
|
||||
0x75, 0x07, /* REPORT_SIZE (7) */
|
||||
0xb1, 0x83, /* FEATURE (Cnst,Var,Abs,Vol) */
|
||||
/* 74 */
|
||||
|
||||
/* Tamper Push Button */
|
||||
0x85, 0x06, /* REPORT_ID (6) */
|
||||
0x09, 0x06, /* USAGE (Tamper Push Button) */
|
||||
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
|
||||
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
|
||||
0x75, 0x01, /* REPORT_SIZE (1) */
|
||||
0x81, 0x82, /* INPUT (Data,Var,Abs,Vol) */
|
||||
|
||||
0x09, 0x06, /* USAGE (Tamper Push Button) */
|
||||
0x75, 0x01, /* REPORT_SIZE (1) */
|
||||
0xb1, 0x82, /* FEATURE (Data,Var,Abs,Vol) */
|
||||
|
||||
0x75, 0x07, /* REPORT_SIZE (7) */
|
||||
0x81, 0x83, /* INPUT (Cnst,Var,Abs,Vol) */
|
||||
0x85, 0x06, /* REPORT_ID (6) */
|
||||
|
||||
0x75, 0x07, /* REPORT_SIZE (7) */
|
||||
0xb1, 0x83, /* FEATURE (Cnst,Var,Abs,Vol) */
|
||||
/* 102 */
|
||||
|
||||
/* ADC IN */
|
||||
0x85, 0x07, /* REPORT_ID (7) */
|
||||
0x09, 0x07, /* USAGE (ADC IN) */
|
||||
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
|
||||
0x26, 0xff, 0x00, /* LOGICAL_MAXIMUM (255) */
|
||||
0x75, 0x08, /* REPORT_SIZE (8) */
|
||||
0x81, 0x82, /* INPUT (Data,Var,Abs,Vol) */
|
||||
|
||||
0x85, 0x07, /* REPORT_ID (7) */
|
||||
0x09, 0x07, /* USAGE (ADC in) */
|
||||
0xb1, 0x82, /* FEATURE (Data,Var,Abs,Vol) */
|
||||
/* 121 */
|
||||
#endif
|
||||
#if 0
|
||||
/* In Control */
|
||||
0x85, 0x06, // Report ID (6)
|
||||
0x95, 0x02, // REPORT_COUNT (2)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x09, 0x01, // USAGE (Vendor Usage 1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
/*21*/
|
||||
|
||||
/* Out Control */
|
||||
0x85, 0x07, // Report ID (7)
|
||||
0x95, 0x02, // REPORT_COUNT (2)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x09, 0x01, // USAGE (Vendor Usage 1)
|
||||
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
||||
/*36*/
|
||||
|
||||
/* In Data */
|
||||
0x85, 0x01, // Report ID (1)
|
||||
0x95, 0x40, // REPORT_COUNT (64)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x09, 0x01, // USAGE (Vendor Usage 1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
/*51*/
|
||||
|
||||
/* Out Data */
|
||||
0x85, 0x02, // Report ID (2)
|
||||
0x95, 0x40, // REPORT_COUNT (64)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x09, 0x02, // USAGE (Vendor Usage 1)
|
||||
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
||||
/*66*/
|
||||
#endif
|
||||
#if 0
|
||||
0x75, 0x08, // report size = 8 bits
|
||||
0x15, 0x00, // logical minimum = 0
|
||||
0x26, 0xff, 0x00, // logical maximum = 255
|
||||
|
||||
/* In Data */
|
||||
0x95, 64, // report count (64 bytes)
|
||||
0x09, 0x01, // usage
|
||||
0x81, 0x02, // Input (array)
|
||||
|
||||
/* Out Data */
|
||||
0x95, 64, // report count (64 bytes)
|
||||
0x09, 0x02, // usage
|
||||
0x91, 0x02, // Output (array)
|
||||
/*25*/
|
||||
#endif
|
||||
|
||||
0x06, 0x9c, 0xff, /* Usage Page (Vendor Defined) */
|
||||
0x09, 0x01, /* Usage (Vendor Defined) */
|
||||
0xa1, 0x01, /* Collection (Vendor Defined) */
|
||||
|
||||
0x09, 0x02, /* Usage (Vendor Defined) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x95, 64, /* Report Count (64) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0xff, /* Logical Maximum (255) */
|
||||
0x81, 0x02, /* Input (Data, Variable, Absolute) */
|
||||
|
||||
0x09, 0x03, /* Usage (Vendor Defined) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x95, 64, /* Report Count (64) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0xff, /* Logical Maximum (255) */
|
||||
0x91, 0x02, /* Output (Data, Variable, Absolute) */
|
||||
|
||||
0xc0 /* End Collection */
|
||||
0xc0 /* End Collection */
|
||||
};
|
||||
static ONE_DESCRIPTOR PIOS_USB_HID_Report_Descriptor = {(uint8_t *) PIOS_USB_HID_ReportDescriptor, PIOS_USB_HID_SIZ_REPORT_DESC};
|
||||
static ONE_DESCRIPTOR PIOS_USB_HID_Hid_Descriptor = {(uint8_t*) PIOS_USB_HID_ReportDescriptor + PIOS_USB_HID_OFF_HID_DESC, PIOS_USB_HID_SIZ_HID_DESC};
|
||||
|
||||
/* Rx/Tx status */
|
||||
static volatile uint8_t rx_buffer_new_data_ctr = 0;
|
||||
static volatile uint8_t rx_buffer_ix;
|
||||
static uint8_t transfer_possible = 0;
|
||||
|
||||
static uint8_t rx_buffer[PIOS_USB_HID_DATA_LENGTH];
|
||||
|
||||
/**
|
||||
* Initialises USB COM layer
|
||||
* \param[in] mode currently only mode 0 supported
|
||||
* \return < 0 if initialisation failed
|
||||
* \note Applications shouldn't call this function directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
int32_t PIOS_USB_HID_Init(uint32_t mode)
|
||||
{
|
||||
/* Currently only mode 0 supported */
|
||||
if(mode != 0) {
|
||||
/* Unsupported mode */
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0; /* No error */
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called by the USB driver on cable connection/disconnection
|
||||
* \param[in] connected connection status (1 if connected)
|
||||
* \return < 0 on errors
|
||||
* \note Applications shouldn't call this function directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
uint32_t PIOS_USB_HID_ChangeConnectionState(uint32_t Connected)
|
||||
int32_t PIOS_USB_HID_ChangeConnectionState(uint32_t Connected)
|
||||
{
|
||||
/* In all cases: re-initialise USB HID driver */
|
||||
if(Connected) {
|
||||
transfer_possible = 1;
|
||||
//TODO: Check SetEPRxValid(ENDP1);
|
||||
} else {
|
||||
/* Cable disconnected: disable transfers */
|
||||
transfer_possible = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the connection status of the USB COM interface
|
||||
* \return 1: interface available
|
||||
* \return 0: interface not available
|
||||
* \note Applications shouldn't call this function directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
int32_t PIOS_USB_HID_CheckAvailable(void)
|
||||
{
|
||||
return transfer_possible ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts more than one byte onto the transmit buffer (used for atomic sends)
|
||||
* \param[in] *buffer pointer to buffer which should be transmitted
|
||||
* \param[in] len number of bytes which should be transmitted
|
||||
* \return 0 if no error
|
||||
* \return -1 if too many bytes to be send
|
||||
* \note Applications shouldn't call this function directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
int32_t PIOS_USB_HID_TxBufferPutMoreNonBlocking(uint8_t *buffer, uint16_t len)
|
||||
{
|
||||
if(len > PIOS_USB_HID_DATA_LENGTH) {
|
||||
/* Cannot get all requested bytes */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Copy bytes to be transmitted into transmit buffer */
|
||||
UserToPMABufferCopy((uint8_t*) buffer, GetEPTxAddr(EP1_IN & 0x7F), (PIOS_USB_HID_DATA_LENGTH + 1));
|
||||
SetEPTxCount(ENDP1, (PIOS_USB_HID_DATA_LENGTH + 1));
|
||||
|
||||
/* Send Buffer */
|
||||
SetEPTxValid(ENDP1);
|
||||
|
||||
/* No error */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts more than one byte onto the transmit buffer (used for atomic sends)<br>
|
||||
* (Blocking Function)
|
||||
* \param[in] *buffer pointer to buffer which should be transmitted
|
||||
* \param[in] len number of bytes which should be transmitted
|
||||
* \return 0 if no error
|
||||
* \return -1 if too many bytes to be send
|
||||
* \note Applications shouldn't call this function directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
int32_t PIOS_USB_HID_TxBufferPutMore(uint8_t *buffer, uint16_t len)
|
||||
{
|
||||
int32_t error;
|
||||
|
||||
while((error = PIOS_USB_HID_TxBufferPutMoreNonBlocking(buffer, len)) == -2);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a byte from the receive buffer
|
||||
* \param[in] usb_com USB_COM number (not supported yet, should always be 0)
|
||||
* \return -1 if no new byte available
|
||||
* \return >= 0: received byte
|
||||
* \note Applications shouldn't call this function directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
int32_t PIOS_USB_HID_RxBufferGet(void)
|
||||
{
|
||||
if(!rx_buffer_new_data_ctr) {
|
||||
/* Nothing new in buffer */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get byte - this operation should be atomic! */
|
||||
//PIOS_IRQ_Disable();
|
||||
// TODO: Access buffer directly, so that we don't need to copy into temporary buffer
|
||||
//uint8_t buffer_out[PIOS_USB_HID_DATA_LENGTH];
|
||||
//PMAToUserBufferCopy(buffer_out, GetEPRxAddr(ENDP1 & 0x7F), GetEPRxCount(ENDP1));
|
||||
|
||||
/* This stops returning bytes after the first ocurance of '\0' */
|
||||
/* We don't need to do this but it does optimize things quite a bit */
|
||||
if(rx_buffer[rx_buffer_ix] == 0) {
|
||||
/* TODO: Evaluate if this is really needed */
|
||||
/* Clean the buffer */
|
||||
for(uint8_t i = 0; i < PIOS_USB_HID_DATA_LENGTH; i++) {
|
||||
rx_buffer[i] = 0;
|
||||
}
|
||||
|
||||
rx_buffer_new_data_ctr = 0;
|
||||
rx_buffer_ix = 0;
|
||||
SetEPRxStatus(ENDP1, EP_RX_VALID);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* There is still data in the buffer */
|
||||
uint8_t b = rx_buffer[rx_buffer_ix++];
|
||||
if(!--rx_buffer_new_data_ctr) {
|
||||
rx_buffer_ix = 0;
|
||||
SetEPRxStatus(ENDP1, EP_RX_VALID);
|
||||
}
|
||||
//PIOS_IRQ_Enable();
|
||||
|
||||
/* Return received byte */
|
||||
return b;
|
||||
}
|
||||
|
||||
int32_t PIOS_USB_HID_CB_Data_Setup(uint8_t RequestNo)
|
||||
{
|
||||
uint8_t *(*CopyRoutine)( uint16_t) = NULL;
|
||||
|
||||
CopyRoutine = NULL;
|
||||
|
||||
/* GET_DESCRIPTOR */
|
||||
if((RequestNo == GET_DESCRIPTOR) && (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) && (pInformation->USBwIndex0 == 0)) {
|
||||
|
||||
if(pInformation->USBwValue1 == PIOS_USB_HID_REPORT_DESCRIPTOR) {
|
||||
@ -245,7 +234,6 @@ int32_t PIOS_USB_HID_CB_Data_Setup(uint8_t RequestNo)
|
||||
}
|
||||
|
||||
}
|
||||
/* End of GET_DESCRIPTOR */
|
||||
|
||||
/* GET_PROTOCOL */
|
||||
else if((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) && RequestNo == GET_PROTOCOL) {
|
||||
@ -274,9 +262,6 @@ int32_t PIOS_USB_HID_CB_NoData_Setup(uint8_t RequestNo)
|
||||
else {
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
// TODO:Unsure
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -319,14 +304,26 @@ static uint8_t *PIOS_USB_HID_GetProtocolValue(uint16_t Length)
|
||||
*/
|
||||
void PIOS_USB_HID_EP1_OUT_Callback(void)
|
||||
{
|
||||
const char *buff = "\rACK\r";
|
||||
PIOS_COM_SendBuffer(GPS, (uint8_t *)buff, sizeof(buff));
|
||||
#if 1
|
||||
uint32_t DataLength = 0;
|
||||
|
||||
uint8_t Receive_Buffer[64];
|
||||
/* Get the number of received data on the selected Endpoint */
|
||||
DataLength = GetEPRxCount(ENDP1 & 0x7F);
|
||||
|
||||
/* Use the memory interface function to write to the selected endpoint */
|
||||
PMAToUserBufferCopy((uint8_t *) rx_buffer, GetEPRxAddr(ENDP1 & 0x7F), DataLength);
|
||||
|
||||
/* We now have data waiting */
|
||||
rx_buffer_new_data_ctr = PIOS_USB_HID_DATA_LENGTH;
|
||||
|
||||
#else
|
||||
// FOR DEBUGGING USE ONLY
|
||||
|
||||
uint8_t Receive_Buffer[PIOS_USB_HID_DATA_LENGTH];
|
||||
//uint32_t DataLength = 0;
|
||||
|
||||
/* Read received data (64 bytes) */
|
||||
//USB_SIL_Read(EP1_OUT, Receive_Buffer);
|
||||
/* Read received data (63 bytes) */
|
||||
USB_SIL_Read(EP1_OUT, Receive_Buffer);
|
||||
|
||||
/* Get the number of received data on the selected Endpoint */
|
||||
//DataLength = GetEPRxCount(ENDP1 & 0x7F);
|
||||
@ -334,9 +331,11 @@ void PIOS_USB_HID_EP1_OUT_Callback(void)
|
||||
/* Use the memory interface function to write to the selected endpoint */
|
||||
//PMAToUserBufferCopy((uint8_t *) Receive_Buffer, GetEPRxAddr(ENDP1 & 0x7F), DataLength);
|
||||
|
||||
/* Do stuff here */
|
||||
//PIOS_COM_SendBuffer(GPS, Receive_Buffer, sizeof(Receive_Buffer));
|
||||
/* Send it back */
|
||||
PIOS_COM_SendBuffer(GPS, Receive_Buffer, sizeof(Receive_Buffer));
|
||||
PIOS_COM_SendBuffer(GPS, "\r", 1);
|
||||
|
||||
SetEPRxStatus(ENDP1, EP_RX_VALID);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -27,12 +27,13 @@
|
||||
#ifndef PIOS_COM_H
|
||||
#define PIOS_COM_H
|
||||
|
||||
/* GLobal Types */
|
||||
/* Global Types */
|
||||
typedef enum {
|
||||
COM_DEBUG_UART = 0,
|
||||
COM_GPS_UART = 1,
|
||||
COM_TELEM_UART = 2,
|
||||
COM_AUX_UART = 3
|
||||
COM_AUX_UART = 3,
|
||||
COM_USB_HID = 4
|
||||
} COMPortTypeDef;
|
||||
|
||||
/* Public Functions */
|
||||
|
@ -28,21 +28,23 @@
|
||||
#define PIOS_USB_HID_H
|
||||
|
||||
/* Global Definitions */
|
||||
//#define PIOS_USB_HID_SIZ_REPORT_DESC 26
|
||||
//#define PIOS_USB_HID_SIZ_REPORT_DESC 67
|
||||
//#define PIOS_USB_HID_SIZ_REPORT_DESC 122
|
||||
#define PIOS_USB_HID_SIZ_REPORT_DESC 32
|
||||
|
||||
#define PIOS_USB_HID_REPORT_DESCRIPTOR 0x22
|
||||
#define PIOS_USB_HID_HID_DESCRIPTOR_TYPE 0x21
|
||||
#define PIOS_USB_HID_OFF_HID_DESC 0x12
|
||||
#define PIOS_USB_HID_SIZ_HID_DESC 0x09
|
||||
|
||||
#define PIOS_USB_HID_DATA_LENGTH 63
|
||||
|
||||
/* Global Variables */
|
||||
extern uint32_t ProtocolValue;
|
||||
|
||||
/* Global functions */
|
||||
extern uint32_t PIOS_USB_HID_ChangeConnectionState(uint32_t Connected);
|
||||
extern int32_t PIOS_USB_HID_Init(uint32_t mode);
|
||||
extern int32_t PIOS_USB_HID_ChangeConnectionState(uint32_t Connected);
|
||||
extern int32_t PIOS_USB_HID_CheckAvailable(void);
|
||||
extern int32_t PIOS_USB_HID_TxBufferPutMoreNonBlocking(uint8_t *buffer, uint16_t len);
|
||||
extern int32_t PIOS_USB_HID_TxBufferPutMore(uint8_t *buffer, uint16_t len);
|
||||
extern int32_t PIOS_USB_HID_RxBufferGet(void);
|
||||
extern int32_t PIOS_USB_HID_CB_Data_Setup(uint8_t RequestNo);
|
||||
extern int32_t PIOS_USB_HID_CB_NoData_Setup(uint8_t RequestNo);
|
||||
extern void PIOS_USB_HID_EP1_OUT_Callback(void);
|
||||
|
@ -109,9 +109,9 @@ int main()
|
||||
|
||||
/* Create a FreeRTOS task */
|
||||
xTaskCreate(TaskTick, (signed portCHAR *)"Test", configMINIMAL_STACK_SIZE , NULL, 1, NULL);
|
||||
xTaskCreate(TaskHIDTest, (signed portCHAR *)"HIDTest", configMINIMAL_STACK_SIZE , NULL, 4, NULL);
|
||||
//xTaskCreate(TaskHIDTest, (signed portCHAR *)"HIDTest", configMINIMAL_STACK_SIZE , NULL, 4, NULL);
|
||||
//xTaskCreate(TaskServos, (signed portCHAR *)"Servos", configMINIMAL_STACK_SIZE , NULL, 4, NULL);
|
||||
//xTaskCreate(TaskHooks, (signed portCHAR *)"Hooks", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_HOOKS, NULL);
|
||||
xTaskCreate(TaskHooks, (signed portCHAR *)"Hooks", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_HOOKS, NULL);
|
||||
//xTaskCreate(TaskSDCard, (signed portCHAR *)"SDCard", configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY + 2), NULL);
|
||||
|
||||
/* Start the FreeRTOS scheduler */
|
||||
@ -124,10 +124,16 @@ int main()
|
||||
|
||||
int32_t CONSOLE_Parse(COMPortTypeDef port, char c)
|
||||
{
|
||||
if(port == COM_USB_HID) {
|
||||
PIOS_COM_SendChar(COM_DEBUG_UART, c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(c == '\r') {
|
||||
/* Ignore */
|
||||
} else if(c == '\n') {
|
||||
PIOS_COM_SendFormattedString(GPS, "String: %s\n", line_buffer);
|
||||
PIOS_COM_SendFormattedString(COM_DEBUG_UART, "String: %s\n", line_buffer);
|
||||
line_ix = 0;
|
||||
} else if(line_ix < (STRING_MAX - 1)) {
|
||||
line_buffer[line_ix++] = c;
|
||||
@ -170,12 +176,13 @@ static void TaskTick(void *pvParameters)
|
||||
|
||||
static void TaskHIDTest(void *pvParameters)
|
||||
{
|
||||
portTickType xDelay = 250 / portTICK_RATE_MS;;
|
||||
portTickType xDelay = 1000 / portTICK_RATE_MS;;
|
||||
|
||||
__IO uint8_t Send_Buffer[64];
|
||||
__IO uint8_t Send_Buffer[63];
|
||||
|
||||
for(;;)
|
||||
{
|
||||
|
||||
Send_Buffer[0] = 'H';
|
||||
Send_Buffer[1] = 'e';
|
||||
Send_Buffer[2] = 'l';
|
||||
@ -191,10 +198,12 @@ static void TaskHIDTest(void *pvParameters)
|
||||
Send_Buffer[12] = 0;
|
||||
|
||||
/* Write the data to the pipe */
|
||||
UserToPMABufferCopy((uint8_t*) Send_Buffer, GetEPTxAddr(EP1_IN & 0x7F), 64);
|
||||
SetEPTxCount(ENDP1, 64);
|
||||
//UserToPMABufferCopy((uint8_t*) Send_Buffer, GetEPTxAddr(EP1_IN & 0x7F), 64);
|
||||
//SetEPTxCount(ENDP1, 64);
|
||||
|
||||
SetEPTxValid(ENDP1);
|
||||
//SetEPTxValid(ENDP1);
|
||||
|
||||
PIOS_COM_SendBufferNonBlocking(COM_USB_HID, Send_Buffer, 63);
|
||||
|
||||
vTaskDelay(xDelay);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user