mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-12-01 09:24:10 +01:00
Improvement OP-3; Implemented buffer based receiving functions, untested.
git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@254 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
parent
95122faa40
commit
d406232eb1
@ -35,11 +35,11 @@
|
||||
#include <op_config.h>
|
||||
#include <op_logging.h>
|
||||
|
||||
|
||||
/* FreeRTOS Includes */
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
#include <queue.h>
|
||||
#include <semphr.h>
|
||||
|
||||
/* Global Functions */
|
||||
extern void OpenPilotInit(void);
|
||||
|
@ -32,15 +32,16 @@
|
||||
|
||||
#if !defined(PIOS_DONT_USE_COM)
|
||||
|
||||
/* Private Function Prototypes */
|
||||
|
||||
/* Global Variables */
|
||||
xSemaphoreHandle PIOS_HID_Buffer;
|
||||
|
||||
/* Local Variables */
|
||||
static int32_t (*receive_callback_func)(COMPortTypeDef port, char c);
|
||||
|
||||
|
||||
/**
|
||||
* Initializes COM layer
|
||||
* Initialises COM layer
|
||||
* \param[in] mode currently only mode 0 supported
|
||||
* \return < 0 if initialisation failed
|
||||
*/
|
||||
@ -60,7 +61,7 @@ int32_t PIOS_COM_Init(void)
|
||||
|
||||
/**
|
||||
* Sends a package over given port
|
||||
* \param[in] port COM port (COM_DEBUG_UART, COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART, COM_USB_HID)
|
||||
* \param[in] port COM port
|
||||
* \param[in] buffer character buffer
|
||||
* \param[in] len buffer length
|
||||
* \return -1 if port not available
|
||||
@ -91,7 +92,7 @@ int32_t PIOS_COM_SendBufferNonBlocking(COMPortTypeDef port, uint8_t *buffer, uin
|
||||
/**
|
||||
* Sends a package over given port
|
||||
* (blocking function)
|
||||
* \param[in] port COM port (COM_DEBUG_UART, COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART, COM_USB_HID)
|
||||
* \param[in] port COM port
|
||||
* \param[in] buffer character buffer
|
||||
* \param[in] len buffer length
|
||||
* \return -1 if port not available
|
||||
@ -119,7 +120,7 @@ int32_t PIOS_COM_SendBuffer(COMPortTypeDef port, uint8_t *buffer, uint16_t len)
|
||||
|
||||
/**
|
||||
* Sends a single character over given port
|
||||
* \param[in] port COM port (COM_DEBUG_UART, COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART, COM_USB_HID)
|
||||
* \param[in] port COM port
|
||||
* \param[in] c character
|
||||
* \return -1 if port not available
|
||||
* \return -2 buffer is full
|
||||
@ -134,7 +135,7 @@ int32_t PIOS_COM_SendCharNonBlocking(COMPortTypeDef port, char c)
|
||||
/**
|
||||
* Sends a single character over given port
|
||||
* (blocking function)
|
||||
* \param[in] port COM port (COM_DEBUG_UART, COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART, COM_USB_HID)
|
||||
* \param[in] port COM port
|
||||
* \param[in] c character
|
||||
* \return -1 if port not available
|
||||
* \return 0 on success
|
||||
@ -146,7 +147,7 @@ int32_t PIOS_COM_SendChar(COMPortTypeDef port, char c)
|
||||
|
||||
/**
|
||||
* Sends a string over given port
|
||||
* \param[in] port COM port (COM_DEBUG_UART, COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART, COM_USB_HID)
|
||||
* \param[in] port COM port
|
||||
* \param[in] str zero-terminated string
|
||||
* \return -1 if port not available
|
||||
* \return -2 buffer is full
|
||||
@ -161,7 +162,7 @@ int32_t PIOS_COM_SendStringNonBlocking(COMPortTypeDef port, char *str)
|
||||
/**
|
||||
* Sends a string over given port
|
||||
* (blocking function)
|
||||
* \param[in] port COM port (COM_DEBUG_UART, COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART, COM_USB_HID)
|
||||
* \param[in] port COM port
|
||||
* \param[in] str zero-terminated string
|
||||
* \return -1 if port not available
|
||||
* \return 0 on success
|
||||
@ -173,7 +174,7 @@ int32_t PIOS_COM_SendString(COMPortTypeDef port, char *str)
|
||||
|
||||
/**
|
||||
* Sends a formatted string (-> printf) over given port
|
||||
* \param[in] port COM port (COM_DEBUG_UART, COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART, COM_USB_HID)
|
||||
* \param[in] port COM port
|
||||
* \param[in] *format zero-terminated format string - 128 characters supported maximum!
|
||||
* \param[in] ... optional arguments,
|
||||
* 128 characters supported maximum!
|
||||
@ -195,7 +196,7 @@ int32_t PIOS_COM_SendFormattedStringNonBlocking(COMPortTypeDef port, char *forma
|
||||
/**
|
||||
* Sends a formatted string (-> printf) over given port
|
||||
* (blocking function)
|
||||
* \param[in] port COM port (COM_DEBUG_UART, COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART, COM_USB_HID)
|
||||
* \param[in] port COM port
|
||||
* \param[in] *format zero-terminated format string - 128 characters supported maximum!
|
||||
* \param[in] ... optional arguments,
|
||||
* \return -1 if port not available
|
||||
@ -212,108 +213,47 @@ int32_t PIOS_COM_SendFormattedString(COMPortTypeDef port, char *format, ...)
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for incoming COM messages, calls the callback function which has
|
||||
* been installed via PIOS_COM_ReceiveCallbackInit()
|
||||
*
|
||||
* Not for use in an application - this function is called by
|
||||
* by a task in the programming model!
|
||||
*
|
||||
* \return < 0 on errors
|
||||
* Transfer bytes from port buffers into another buffer
|
||||
* \param[in] port COM port
|
||||
* \returns Byte from buffer
|
||||
*/
|
||||
int32_t PIOS_COM_ReceiveHandler(void)
|
||||
uint8_t PIOS_COM_ReceiveBuffer(COMPortTypeDef port)
|
||||
{
|
||||
uint8_t port;
|
||||
|
||||
/* Interface to be checked */
|
||||
uint8_t intf = 0;
|
||||
|
||||
/* Number of forwards - stop after 10 forwards to yield some CPU time for other tasks */
|
||||
uint8_t total_bytes_forwarded = 0;
|
||||
|
||||
uint8_t bytes_forwarded = 0;
|
||||
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 ;) */
|
||||
int32_t status = -1;
|
||||
switch(intf++) {
|
||||
case COM_DEBUG_USART:
|
||||
status = PIOS_USART_RxBufferGet(PIOS_COM_DEBUG_PORT);
|
||||
port = COM_DEBUG_USART;
|
||||
break;
|
||||
case COM_USART1:
|
||||
status = PIOS_USART_RxBufferGet(USART_1);
|
||||
port = COM_USART1;
|
||||
break;
|
||||
case COM_USART2:
|
||||
status = PIOS_USART_RxBufferGet(USART_2);
|
||||
port = COM_USART2;
|
||||
break;
|
||||
case COM_USART3:
|
||||
status = PIOS_USART_RxBufferGet(USART_3);
|
||||
port = COM_USART3;
|
||||
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 */
|
||||
if(bytes_forwarded && total_bytes_forwarded < 64) {
|
||||
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 */
|
||||
}
|
||||
status = -1; /* Empty round - no message */
|
||||
}
|
||||
|
||||
/* Message received? */
|
||||
if(status >= 0) {
|
||||
/* Notify that a package has been forwarded */
|
||||
++bytes_forwarded;
|
||||
++total_bytes_forwarded;
|
||||
|
||||
/* Call function */
|
||||
if(receive_callback_func != NULL)
|
||||
receive_callback_func(port, (uint8_t)status);
|
||||
}
|
||||
} while(again);
|
||||
|
||||
return 0;
|
||||
switch(port) {
|
||||
case COM_USART1:
|
||||
return PIOS_USART_RxBufferGet(USART_1);
|
||||
case COM_USART2:
|
||||
return PIOS_USART_RxBufferGet(USART_2);
|
||||
case COM_USART3:
|
||||
return PIOS_USART_RxBufferGet(USART_3);
|
||||
case COM_USB_HID:
|
||||
return PIOS_USB_HID_RxBufferGet();
|
||||
/* To suppress warnings */
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs the callback function which is executed on incoming characters
|
||||
* from a COM interface.
|
||||
*
|
||||
* Example:
|
||||
* \code
|
||||
* int32_t CONSOLE_Parse(COMPortTypeDef port, char c)
|
||||
* {
|
||||
* // Do Parsing here
|
||||
*
|
||||
* return 0; // no error
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* The callback function has been installed in an Init() function with:
|
||||
* \code
|
||||
* PIOS_COM_ReceiveCallbackInit(CONSOLE_Parse);
|
||||
* \endcode
|
||||
* \param[in] callback_debug_command the callback function (NULL disables the callback)
|
||||
* \return < 0 on errors
|
||||
* Get the number of bytes waiting in the buffer
|
||||
* \param[in] port COM port
|
||||
* \return Number of bytes used in buffer
|
||||
*/
|
||||
int32_t PIOS_COM_ReceiveCallbackInit(void *callback_receive)
|
||||
int32_t PIOS_COM_ReceiveBufferUsed(COMPortTypeDef port)
|
||||
{
|
||||
receive_callback_func = callback_receive;
|
||||
|
||||
/* No error */
|
||||
return 0;
|
||||
switch(port) {
|
||||
case COM_USART1:
|
||||
return PIOS_USART_RxBufferUsed(USART_1);
|
||||
case COM_USART2:
|
||||
return PIOS_USART_RxBufferUsed(USART_2);
|
||||
case COM_USART3:
|
||||
return PIOS_USART_RxBufferUsed(USART_3);
|
||||
case COM_USB_HID:
|
||||
return PIOS_USB_HID_DATA_LENGTH;
|
||||
/* To suppress warnings */
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -35,6 +35,9 @@
|
||||
|
||||
/* Global Variables */
|
||||
extern SettingsTypeDef Settings;
|
||||
xSemaphoreHandle PIOS_USART1_Buffer;
|
||||
xSemaphoreHandle PIOS_USART2_Buffer;
|
||||
xSemaphoreHandle PIOS_USART3_Buffer;
|
||||
|
||||
/* Local Variables */
|
||||
static uint8_t rx_buffer[PIOS_USART_NUM][PIOS_USART_RX_BUFFER_SIZE];
|
||||
@ -47,6 +50,8 @@ static volatile uint8_t tx_buffer_tail[PIOS_USART_NUM];
|
||||
static volatile uint8_t tx_buffer_head[PIOS_USART_NUM];
|
||||
static volatile uint8_t tx_buffer_size[PIOS_USART_NUM];
|
||||
|
||||
static portBASE_TYPE xHigherPriorityTaskWoken;
|
||||
|
||||
|
||||
/**
|
||||
* Initialise the GPS and TELEM onboard USARTs
|
||||
@ -174,6 +179,10 @@ void PIOS_USART_Init(void)
|
||||
/* Enable USART */
|
||||
USART_Cmd(PIOS_USART3_USART, ENABLE);
|
||||
#endif
|
||||
|
||||
vSemaphoreCreateBinary(PIOS_USART1_Buffer);
|
||||
vSemaphoreCreateBinary(PIOS_USART2_Buffer);
|
||||
vSemaphoreCreateBinary(PIOS_USART3_Buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -335,12 +344,24 @@ int32_t PIOS_USART_RxBufferPut(USARTNumTypeDef usart, uint8_t b)
|
||||
}
|
||||
++rx_buffer_size[usart];
|
||||
PIOS_IRQ_Enable();
|
||||
|
||||
|
||||
|
||||
switch(usart) {
|
||||
case USART_1:
|
||||
xSemaphoreGiveFromISR(PIOS_USART1_Buffer, &xHigherPriorityTaskWoken);
|
||||
break;
|
||||
case USART_2:
|
||||
xSemaphoreGiveFromISR(PIOS_USART2_Buffer, &xHigherPriorityTaskWoken);
|
||||
break;
|
||||
case USART_3:
|
||||
xSemaphoreGiveFromISR(PIOS_USART3_Buffer, &xHigherPriorityTaskWoken);
|
||||
break;
|
||||
}
|
||||
|
||||
/* No error */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* returns number of free bytes in transmit buffer
|
||||
* \param[in] USART USART name
|
||||
|
@ -44,8 +44,12 @@ typedef enum _HID_REQUESTS {
|
||||
SET_PROTOCOL
|
||||
} HID_REQUESTS;
|
||||
|
||||
/* Global Variables */
|
||||
xSemaphoreHandle PIOS_HID_Buffer;
|
||||
|
||||
/* Local Variables */
|
||||
static uint32_t ProtocolValue;
|
||||
static portBASE_TYPE xHigherPriorityTaskWoken;
|
||||
|
||||
/* Local Functions */
|
||||
static uint8_t *PIOS_USB_HID_GetHIDDescriptor(uint16_t Length);
|
||||
@ -176,7 +180,6 @@ int32_t PIOS_USB_HID_TxBufferPutMore(uint8_t *buffer, uint16_t len)
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -188,14 +191,8 @@ int32_t PIOS_USB_HID_RxBufferGet(void)
|
||||
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 */
|
||||
/* This stops returning bytes after the first occurrence of '\0' */
|
||||
/* We don't need to do this but it does optimise things quite a bit */
|
||||
if(rx_buffer[rx_buffer_ix] == 0) {
|
||||
/* TODO: Evaluate if this is really needed */
|
||||
/* Clean the buffer */
|
||||
@ -215,7 +212,6 @@ int32_t PIOS_USB_HID_RxBufferGet(void)
|
||||
rx_buffer_ix = 0;
|
||||
SetEPRxStatus(ENDP1, EP_RX_VALID);
|
||||
}
|
||||
//PIOS_IRQ_Enable();
|
||||
|
||||
/* Return received byte */
|
||||
return b;
|
||||
@ -290,7 +286,7 @@ static uint8_t *PIOS_USB_HID_GetReportDescriptor(uint16_t Length)
|
||||
/**
|
||||
* Gets the protocol value
|
||||
* \param[in] Length
|
||||
* \return address of the protcol value.
|
||||
* \return address of the protocol value.
|
||||
*/
|
||||
static uint8_t *PIOS_USB_HID_GetProtocolValue(uint16_t Length)
|
||||
{
|
||||
@ -318,6 +314,7 @@ void PIOS_USB_HID_EP1_OUT_Callback(void)
|
||||
|
||||
/* We now have data waiting */
|
||||
rx_buffer_new_data_ctr = PIOS_USB_HID_DATA_LENGTH;
|
||||
xSemaphoreGiveFromISR(PIOS_HID_Buffer, &xHigherPriorityTaskWoken);
|
||||
|
||||
#else
|
||||
// FOR DEBUGGING USE ONLY
|
||||
|
@ -47,8 +47,9 @@ extern int32_t PIOS_COM_SendStringNonBlocking(COMPortTypeDef port, char *str);
|
||||
extern int32_t PIOS_COM_SendString(COMPortTypeDef port, char *str);
|
||||
extern int32_t PIOS_COM_SendFormattedStringNonBlocking(COMPortTypeDef port, char *format, ...);
|
||||
extern int32_t PIOS_COM_SendFormattedString(COMPortTypeDef port, char *format, ...);
|
||||
extern uint8_t PIOS_COM_ReceiveBuffer(COMPortTypeDef port);
|
||||
extern int32_t PIOS_COM_ReceiveBufferUsed(COMPortTypeDef port);
|
||||
|
||||
extern int32_t PIOS_COM_ReceiveHandler(void);
|
||||
extern int32_t PIOS_COM_ReceiveCallbackInit(void *callback_receive);
|
||||
|
||||
#endif /* PIOS_COM_H */
|
||||
|
@ -29,8 +29,12 @@
|
||||
|
||||
|
||||
/* Global Types */
|
||||
typedef enum {USART_1 = 0, USART_2 = 1, USART_3 = 2} USARTNumTypeDef; //TODO: Make this non-application specific
|
||||
typedef enum {USART_1 = 0, USART_2 = 1, USART_3 = 2} USARTNumTypeDef;
|
||||
|
||||
/* Global Variables */
|
||||
extern xSemaphoreHandle PIOS_USART1_Buffer;
|
||||
extern xSemaphoreHandle PIOS_USART2_Buffer;
|
||||
extern xSemaphoreHandle PIOS_USART3_Buffer;
|
||||
|
||||
/* Public Functions */
|
||||
extern void PIOS_USART_Init(void);
|
||||
|
@ -37,6 +37,7 @@
|
||||
#define PIOS_USB_HID_DATA_LENGTH 63
|
||||
|
||||
/* Global Variables */
|
||||
extern xSemaphoreHandle PIOS_HID_Buffer;
|
||||
|
||||
/* Global functions */
|
||||
extern int32_t PIOS_USB_HID_Init(uint32_t mode);
|
||||
|
@ -33,6 +33,12 @@
|
||||
#include "pios_config.h"
|
||||
#include "pios_board.h"
|
||||
|
||||
/* FreeRTOS Includes */
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
#include <queue.h>
|
||||
#include <semphr.h>
|
||||
|
||||
/* C Lib Includes */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -77,8 +83,6 @@
|
||||
#include <pios_com.h>
|
||||
#include <pios_bmp085.h>
|
||||
|
||||
/* More added here as they get written */
|
||||
|
||||
#if !defined(PIOS_DONT_USE_USB)
|
||||
/* USB Libs */
|
||||
#include <usb_lib.h>
|
||||
|
Loading…
Reference in New Issue
Block a user