1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-18 08:54:15 +01:00

Added PIOS_COM Module. Still needs a bit of reworking.

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@29 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
gussy 2009-11-30 16:03:37 +00:00 committed by gussy
parent a855efb86c
commit 47c8bc5a78
8 changed files with 409 additions and 46 deletions

View File

@ -85,6 +85,7 @@ SRC += $(SYSDIR)/pios_settings.c
SRC += $(SYSDIR)/pios_led.c
SRC += $(SYSDIR)/pios_uart.c
SRC += $(SYSDIR)/pios_irq.c
SRC += $(SYSDIR)/pios_com.c
## CMSIS for STM32
SRC += $(CMSISDIR)/core_cm3.c

View File

@ -51,9 +51,7 @@
#include "pios_led.h"
#include "pios_uart.h"
#include "pios_irq.h"
//#include "pios_spi.h"
//#include "pios_uart.h"
#include "pios_com.h"
/* More added here as they get written */

View File

@ -120,8 +120,9 @@
// USART Serial Ports
//-------------------------
#define UART_NUM 3
#define UART_RX_BUFFER_SIZE 128
#define UART_TX_BUFFER_SIZE 128
#define UART_RX_BUFFER_SIZE 1024
#define UART_TX_BUFFER_SIZE 256
#define COM_DEBUG_PORT TELEM
//-------------------------
// Receiver PWM inputs

322
flight/sys/pios_com.c Normal file
View File

@ -0,0 +1,322 @@
/**
******************************************************************************
*
* @file pios_com.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2009.
* @brief COM layer functions
* @see The GNU Public License (GPL) Version 3
* @defgroup PIOS_COM COM layer functions
* @{
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Project Includes */
#include "pios.h"
/* Private Function Prototypes */
/* Local Variables */
static int32_t (*receive_callback_func)(COMPortTypeDef port, char c);
/**
* Initializes COM layer
* \param[in] mode currently only mode 0 supported
* \return < 0 if initialisation failed
*/
int32_t COMInit(void)
{
int32_t ret = 0;
/* Disable callback by default */
receive_callback_func = NULL;
/* If any COM assignment: */
UARTInit();
return -ret;
}
/**
* This function checks the availability of a COM port
* \param[in] port COM port (COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART)
* \return 1: port available
* \return 0: port not available
* \note Deprecated since our hardware is a constant
*/
int32_t COMCheckAvailable(COMPortTypeDef port)
{
/* Deprecated since our hardware is a constant */
}
/**
* Sends a package over given port
* \param[in] port COM port (COM_GPS_UART, COM_TELEM_UART, COM_AUX_UART)
* \param[in] buffer character buffer
* \param[in] len buffer length
* \return -1 if port not available
* \return -2 if non-blocking mode activated: buffer is full
* caller should retry until buffer is free again
* \return 0 on success
*/
int32_t COMSendBufferNonBlocking(COMPortTypeDef port, uint8_t *buffer, uint16_t len)
{
/* Branch depending on selected port */
switch(port) {
case 0:
return UARTTxBufferPutMoreNonBlocking(COM_DEBUG_PORT, buffer, len);
case 1:
return UARTTxBufferPutMoreNonBlocking(GPS, buffer, len);
case 2:
return UARTTxBufferPutMoreNonBlocking(TELEM, buffer, len);
case 3:
return UARTTxBufferPutMoreNonBlocking(AUX, 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] buffer character buffer
* \param[in] len buffer length
* \return -1 if port not available
* \return 0 on success
*/
int32_t COMSendBuffer(COMPortTypeDef port, uint8_t *buffer, uint16_t len)
{
/* Branch depending on selected port */
switch(port) {
case 0:
return UARTTxBufferPutMore(COM_DEBUG_PORT, buffer, len);
case 1:
return UARTTxBufferPutMore(GPS, buffer, len);
case 2:
return UARTTxBufferPutMore(TELEM, buffer, len);
case 3:
return UARTTxBufferPutMore(AUX, 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] c character
* \return -1 if port not available
* \return -2 buffer is full
* caller should retry until buffer is free again
* \return 0 on success
*/
int32_t COMSendCharNonBlocking(COMPortTypeDef port, char c)
{
return COMSendBufferNonBlocking(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] c character
* \return -1 if port not available
* \return 0 on success
*/
int32_t COMSendChar(COMPortTypeDef port, char c)
{
return COMSendBuffer(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] str zero-terminated string
* \return -1 if port not available
* \return -2 buffer is full
* caller should retry until buffer is free again
* \return 0 on success
*/
int32_t COMSendString_NonBlocking(COMPortTypeDef port, char *str)
{
return COMSendBufferNonBlocking(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] str zero-terminated string
* \return -1 if port not available
* \return 0 on success
*/
int32_t MIOS32_COM_SendString(COMPortTypeDef port, char *str)
{
/* return COMSendBuffer(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] *format zero-terminated format string - 128 characters supported maximum!
* \param[in] ... optional arguments,
* 128 characters supported maximum!
* \return -2 if non-blocking mode activated: buffer is full
* caller should retry until buffer is free again
* \return 0 on success
*/
int32_t MIOS32_COM_SendFormattedStringNonBlocking(COMPortTypeDef port, char *format, ...)
{
uint8_t buffer[128]; // TODO: tmp!!! Provide a streamed COM method later!
/*
va_list args;
va_start(args, format);
vsprintf((char *)buffer, format, args);
return COMSendBufferNonBlocking(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] *format zero-terminated format string - 128 characters supported maximum!
* \param[in] ... optional arguments,
* \return -1 if port not available
* \return 0 on success
*/
int32_t MIOS32_COM_SendFormattedString(COMPortTypeDef port, char *format, ...)
{
uint8_t buffer[128]; // TODO: tmp!!! Provide a streamed COM method later!
/*
va_list args;
va_start(args, format);
vsprintf((char *)buffer, format, args);
return COMSendBuffer(port, buffer, (uint16_t)strlen((char *)buffer));
*/
}
/**
* Checks for incoming COM messages, calls the callback function which has
* been installed via COMReceiveCallbackInit()
*
* Not for use in an application - this function is called by
* by a task in the programming model!
*
* \return < 0 on errors
*/
int32_t COMReceiveHandler(void)
{
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 0: status = UARTRxBufferGet(COM_DEBUG_PORT); port = COM_DEBUG_UART; break;
case 1: status = UARTRxBufferGet(GPS); port = COM_GPS_UART; break;
case 2: status = UARTRxBufferGet(TELEM); port = COM_TELEM_UART; break;
case 3: status = UARTRxBufferGet(AUX); port = COM_AUX_UART; break;
default:
// 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
} 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;
}
/**
* 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
* COMReceiveCallbackInit(CONSOLE_Parse);
* \endcode
* \param[in] callback_debug_command the callback function (NULL disables the callback)
* \return < 0 on errors
*/
int32_t COMReceiveCallbackInit(void *callback_receive)
{
receive_callback_func = callback_receive;
/* No error */
return 0;
}

54
flight/sys/pios_com.h Normal file
View File

@ -0,0 +1,54 @@
/**
******************************************************************************
*
* @file pios_com.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2009.
* @brief COM layer functions header
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef PIOS_COM_H
#define PIOS_COM_H
/* GLobal Types */
typedef enum {
COM_DEBUG_UART = 0,
COM_GPS_UART = 1,
COM_TELEM_UART = 2,
COM_AUX_UART = 3
} COMPortTypeDef;
/* Public Functions */
extern int32_t COMInit(void);
extern int32_t COMCheckAvailable(COMPortTypeDef port);
extern int32_t COMSendChar_NonBlocking(COMPortTypeDef port, char c);
extern int32_t COMSendChar(COMPortTypeDef port, char c);
extern int32_t COMSendBuffer_NonBlocking(COMPortTypeDef port, uint8_t *buffer, uint16_t len);
extern int32_t COMSendBuffer(COMPortTypeDef port, uint8_t *buffer, uint16_t len);
extern int32_t COMSendStringNonBlocking(COMPortTypeDef port, char *str);
extern int32_t COMSendString(COMPortTypeDef port, char *str);
extern int32_t COMSendFormattedStringNonBlocking(COMPortTypeDef port, char *format, ...);
extern int32_t COMSendFormattedString(COMPortTypeDef port, char *format, ...);
extern int32_t COMReceiveHandler(void);
extern int32_t COMReceiveCallback_Init(void *callback_receive);
#endif /* PIOS_COM_H */

View File

@ -27,14 +27,6 @@
#define PIOS_IRQ_H
/* Public Functions */
extern void UARTInit(void);
extern void EnableAuxUART(void);
extern void DisableAuxUART(void);
extern void UARTChangeBaud(USART_TypeDef* USARTx, uint32_t Baud);
/*----------------------------------------------------------------------------------*/
/* WORK IN PROGRESS BELOW */
/*----------------------------------------------------------------------------------*/
extern int IRQDisable(void);
extern int IRQEnable(void);

View File

@ -34,15 +34,15 @@
/* Local Variables */
static u8 rx_buffer[UART_NUM][UART_RX_BUFFER_SIZE];
static volatile u8 rx_buffer_tail[UART_NUM];
static volatile u8 rx_buffer_head[UART_NUM];
static volatile u8 rx_buffer_size[UART_NUM];
static uint8_t rx_buffer[UART_NUM][UART_RX_BUFFER_SIZE];
static volatile uint8_t rx_buffer_tail[UART_NUM];
static volatile uint8_t rx_buffer_head[UART_NUM];
static volatile uint8_t rx_buffer_size[UART_NUM];
static u8 tx_buffer[UART_NUM][UART_TX_BUFFER_SIZE];
static volatile u8 tx_buffer_tail[UART_NUM];
static volatile u8 tx_buffer_head[UART_NUM];
static volatile u8 tx_buffer_size[UART_NUM];
static uint8_t tx_buffer[UART_NUM][UART_TX_BUFFER_SIZE];
static volatile uint8_t tx_buffer_tail[UART_NUM];
static volatile uint8_t tx_buffer_head[UART_NUM];
static volatile uint8_t tx_buffer_size[UART_NUM];
/**
@ -192,11 +192,6 @@ void UARTChangeBaud(USART_TypeDef* USARTx, uint32_t Baud)
USARTx->BRR = (uint16_t)TmpReg;
}
/*----------------------------------------------------------------------------------*/
/* WORK IN PROGRESS BELOW */
/*----------------------------------------------------------------------------------*/
/**
* Returns number of free bytes in receive buffer
* \param[in] uart UART name (GPS, TELEM, AUX)
@ -218,7 +213,7 @@ int UARTRxBufferFree(UARTNumTypeDef uart)
* \param[in] uart UART name (GPS, TELEM, AUX)
* \return > 0: number of used bytes
* \return 0 if uart not available
* \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
* \note Applications shouldn't call these functions directly, instead please use \ref PIOS_COM layer functions
*/
int UARTRxBufferUsed(UARTNumTypeDef uart)
{
@ -235,7 +230,7 @@ int UARTRxBufferUsed(UARTNumTypeDef uart)
* \return -1 if UART not available
* \return -2 if no new byte available
* \return >= 0: number of received bytes
* \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
* \note Applications shouldn't call these functions directly, instead please use \ref PIOS_COM layer functions
*/
int UARTRxBufferGet(UARTNumTypeDef uart)
{
@ -267,7 +262,7 @@ int UARTRxBufferGet(UARTNumTypeDef uart)
* \return -1 if UART not available
* \return -2 if no new byte available
* \return >= 0: number of received bytes
* \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
* \note Applications shouldn't call these functions directly, instead please use \ref PIOS_COM layer functions
*/
int UARTRxBufferPeek(UARTNumTypeDef uart)
{
@ -297,7 +292,7 @@ int UARTRxBufferPeek(UARTNumTypeDef uart)
* \return 0 if no error
* \return -1 if UART not available
* \return -2 if buffer full (retry)
* \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
* \note Applications shouldn't call these functions directly, instead please use \ref PIOS_COM layer functions
*/
int UARTRxBufferPut(UARTNumTypeDef uart, uint8_t b)
{
@ -331,7 +326,7 @@ int UARTRxBufferPut(UARTNumTypeDef uart, uint8_t b)
* \param[in] uart UART name (GPS, TELEM, AUX)
* \return number of free bytes
* \return 0 if uart not available
* \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
* \note Applications shouldn't call these functions directly, instead please use \ref PIOS_COM layer functions
*/
int UARTTxBufferFree(UARTNumTypeDef uart)
{
@ -347,7 +342,7 @@ int UARTTxBufferFree(UARTNumTypeDef uart)
* \param[in] uart UART name (GPS, TELEM, AUX)
* \return number of used bytes
* \return 0 if uart not available
* \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
* \note Applications shouldn't call these functions directly, instead please use \ref PIOS_COM layer functions
*/
int UARTTxBufferUsed(UARTNumTypeDef uart)
{
@ -364,7 +359,7 @@ int UARTTxBufferUsed(UARTNumTypeDef uart)
* \return -1 if UART not available
* \return -2 if no new byte available
* \return >= 0: transmitted byte
* \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
* \note Applications shouldn't call these functions directly, instead please use \ref PIOS_COM layer functions
*/
int UARTTxBufferGet(UARTNumTypeDef uart)
{
@ -400,9 +395,9 @@ int UARTTxBufferGet(UARTNumTypeDef uart)
* \return -1 if UART not available
* \return -2 if buffer full or cannot get all requested bytes (retry)
* \return -3 if UART not supported by MIOS32_UART_TxBufferPut Routine
* \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
* \note Applications shouldn't call these functions directly, instead please use \ref PIOS_COM layer functions
*/
int UARTTxBufferPutMore_NonBlocking(UARTNumTypeDef uart, uint8_t *buffer, uint16_t len)
int UARTTxBufferPutMoreNonBlocking(UARTNumTypeDef uart, uint8_t *buffer, uint16_t len)
{
if(uart >= UART_NUM) {
/* UART not available */
@ -456,13 +451,13 @@ int UARTTxBufferPutMore_NonBlocking(UARTNumTypeDef uart, uint8_t *buffer, uint16
* \return 0 if no error
* \return -1 if UART not available
* \return -3 if UART not supported by MIOS32_UART_TxBufferPut Routine
* \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
* \note Applications shouldn't call these functions directly, instead please use \ref PIOS_COM layer functions
*/
int UARTTxBufferPutMore(UARTNumTypeDef uart, uint8_t *buffer, uint16_t len)
{
int error;
while((error = UARTTxBufferPutMore_NonBlocking(uart, buffer, len)) == -2);
while((error = UARTTxBufferPutMoreNonBlocking(uart, buffer, len)) == -2);
return error;
}
@ -475,7 +470,7 @@ int UARTTxBufferPutMore(UARTNumTypeDef uart, uint8_t *buffer, uint16_t len)
* \return -1 if UART not available
* \return -2 if buffer full (retry)
* \return -3 if UART not supported by MIOS32_UART_TxBufferPut Routine
* \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
* \note Applications shouldn't call these functions directly, instead please use \ref PIOS_COM layer functions
*/
int UARTTxBufferPut_NonBlocking(UARTNumTypeDef uart, uint8_t b)
{
@ -492,7 +487,7 @@ int UARTTxBufferPut_NonBlocking(UARTNumTypeDef uart, uint8_t b)
* \return 0 if no error
* \return -1 if UART not available
* \return -3 if UART not supported by MIOS32_UART_TxBufferPut Routine
* \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
* \note Applications shouldn't call these functions directly, instead please use \ref PIOS_COM layer functions
*/
int UARTTxBufferPut(UARTNumTypeDef uart, uint8_t b)
{

View File

@ -26,17 +26,17 @@
#ifndef PIOS_UART_H
#define PIOS_UART_H
/* Global Types */
typedef enum {GPS = 0, TELEM = 1, AUX = 2} UARTNumTypeDef;
/* Public Functions */
extern void UARTInit(void);
extern void EnableAuxUART(void);
extern void DisableAuxUART(void);
extern void UARTChangeBaud(USART_TypeDef* USARTx, uint32_t Baud);
/*----------------------------------------------------------------------------------*/
/* WORK IN PROGRESS BELOW */
/*----------------------------------------------------------------------------------*/
typedef enum {GPS = 0, TELEM = 1, AUX = 2} UARTNumTypeDef;
extern int UARTRxBufferFree(UARTNumTypeDef uart);
extern int UARTRxBufferUsed(UARTNumTypeDef uart);
extern int UARTRxBufferGet(UARTNumTypeDef uart);
@ -45,9 +45,9 @@ extern int UARTRxBufferPut(UARTNumTypeDef uart, uint8_t b);
extern int UARTTxBufferFree(UARTNumTypeDef uart);
extern int UARTTxBufferGet(UARTNumTypeDef uart);
extern int UARTTxBufferPutMore_NonBlocking(UARTNumTypeDef uart, uint8_t *buffer, uint16_t len);
extern int UARTTxBufferPutMoreNonBlocking(UARTNumTypeDef uart, uint8_t *buffer, uint16_t len);
extern int UARTTxBufferPutMore(UARTNumTypeDef uart, uint8_t *buffer, uint16_t len);
extern int UARTTxBufferPut_NonBlocking(uint8_t uart, uint8_t b);
extern int UARTTxBufferPutNonBlocking(uint8_t uart, uint8_t b);
extern int UARTTxBufferPut(UARTNumTypeDef uart, uint8_t b);
#endif /* PIOS_UART_H */