1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-12-12 20:08:48 +01:00
LibrePilot/flight/Libraries/buffer.c
peabody124 4ca10e92c7 OP-121 OP-122 Flight: Improved USB HID communication.
1. Added reenumeration function and call it on USB init (device will appear after reprogramming now)
  2. Moved buffer.c to general flight/Libraries location
  3. Removed the 62 byte transmission limitation by adding a transmission buffer
  4. Sped up USB communication by increasing endpoint polling frequency

Note, that the nonblocking and blocking USB send functions are not blocking entirely correcting.  The blocking calls the nonblocking, and the nonblocking blocks until the last chunk has started tranmission if it's a big transmission.  The buffering I added would generalize to non-blocking nicely, but would require using the EP1(IN) callback to handle most of the tranmission.  This creates a lot of issues if one function is pushing data onto the buffer and the interrupt is sending.

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@1403 ebee16cc-31ac-478f-84a7-5cbb03baadba
2010-08-25 05:32:52 +00:00

245 lines
6.6 KiB
C

/**
******************************************************************************
*
* @addtogroup OpenPilotModules OpenPilot Modules
* @{
* @addtogroup Flight_Libraries Miscellaneous library functions
* @brief Miscellaneous library functions shared between PIOS / OpenPilot / AHRS
* @{
*
* @file buffer.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Simplies buffering data
* @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
*/
//*****************************************************************************
//
// File Name : 'buffer.c'
// Title : Multipurpose byte buffer structure and methods
// Author : Pascal Stang - Copyright (C) 2001-2002
// Created : 9/23/2001
// Revised : 9/23/2001
// Version : 1.0
// Target MCU : any
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#include "buffer.h"
/**
* @brief Initialize a cBuffer structure
* @param[in] buffer Points to the buffer structure
* @param[in] start Allocated memory to store data
* @param[in] size Maximum size of buffer
* @return None
*/
void bufferInit(cBuffer* buffer, uint8_t *start, uint32_t size)
{
// set start pointer of the buffer
buffer->dataptr = start;
buffer->size = size;
// initialize index and length
buffer->dataindex = 0;
buffer->datalength = 0;
}
/**
* @brief Return remaining space in buffer
* @param[in] buffer Pointer to buffer structure
* @return Amount of space remaining on buffer
*/
uint32_t bufferRemainingSpace(cBuffer* buffer)
{
return buffer->size - buffer->datalength;
}
/**
* @brief Return amount of data
* @param[in] buffer Pointer to buffer structure
* @return Amount of data queued in buffer
*/
uint32_t bufferBufferedData(cBuffer* buffer)
{
return buffer->datalength;
}
/**
* @brief Pop one element from buffer
* @param[in] buffer Pointer to the buffer structure
* @return None
*/
uint8_t bufferGetFromFront(cBuffer* buffer)
{
unsigned char data = 0;
// check to see if there's data in the buffer
if(buffer->datalength)
{
// get the first character from buffer
data = buffer->dataptr[buffer->dataindex];
// move index down and decrement length
buffer->dataindex++;
if(buffer->dataindex >= buffer->size)
{
buffer->dataindex %= buffer->size;
}
buffer->datalength--;
}
// return
return data;
}
/**
* @brief Copy number of elements into another buffer
* @param[in] buffer Pointer to the buffer structure
* @param[in] dest Point to destimation, must be allocated enough space for size
* @param[in] size Number of elements to get
* @return
* @arg -1 for success
* @arg 0 error
*/
uint8_t bufferGetChunkFromFront(cBuffer* buffer, uint8_t * dest, uint32_t size)
{
if(size > buffer->datalength)
return -1;
for(uint32_t i = 0; i < size; i++)
{
dest[i] = bufferGetFromFront(buffer);
}
return 0;
}
/**
* @brief Shift index to trash data from front of buffer
* @param[in] buffer Pointer to buffer structure
* @param[in] numbytes Number of bytes to drop
* @return None
*/
void bufferDumpFromFront(cBuffer* buffer, uint32_t numbytes)
{
// dump numbytes from the front of the buffer
// are we dumping less than the entire buffer?
if(numbytes < buffer->datalength)
{
// move index down by numbytes and decrement length by numbytes
buffer->dataindex += numbytes;
if(buffer->dataindex >= buffer->size)
{
buffer->dataindex %= buffer->size;
}
buffer->datalength -= numbytes;
}
else
{
// flush the whole buffer
buffer->datalength = 0;
}
}
/**
* @brief Get element indexed from the front of buffer
* @param[in] buffer Point to the buffer structure
* @param[in] index Index into the buffer relative to front
* @return None
*/
uint8_t bufferGetAtIndex(cBuffer* buffer, uint32_t index)
{
// return character at index in buffer
return buffer->dataptr[(buffer->dataindex+index)%(buffer->size)];
}
/**
* @brief Queue a character to end of buffer
* @param[in] buffer Point to the buffer structure
* @param[in] data Byte to add
* @return
* @arg -1 for success
* @arg 0 error
*/
uint8_t bufferAddToEnd(cBuffer* buffer, uint8_t data)
{
// make sure the buffer has room
if(buffer->datalength < buffer->size)
{
// save data byte at end of buffer
buffer->dataptr[(buffer->dataindex + buffer->datalength) % buffer->size] = data;
// increment the length
buffer->datalength++;
// return success
return -1;
}
else return 0;
}
/**
* @brief Queue a block of character to end of buffer
* @param[in] buffer Point to the buffer structure
* @param[in] data Pointer to data to add
* @param[in] size Number of bytes to add
* @return
* @arg -1 for success
* @arg 0 error
*/
uint8_t bufferAddChunkToEnd(cBuffer* buffer, const uint8_t * data, uint32_t size)
{
// TODO: replace with memcpy and logic, for now keeping it simple
for(uint32_t i = 0; i < size; i++)
{
if(bufferAddToEnd(buffer,data[i]) == 0)
return 0;
}
return -1;
}
/**
* @brief Check to see if the buffer has room
* @param[in] buffer Point to the buffer structure
* @return
* @arg True there is room available in buffer
* @arg False buffer is full
*/
unsigned char bufferIsNotFull(cBuffer* buffer)
{
return (buffer->datalength < buffer->size);
}
/**
* @brief Trash all data in buffer
* @param[in] buffer Point to the buffer structure
*/
void bufferFlush(cBuffer* buffer)
{
// flush contents of the buffer
buffer->datalength = 0;
}
/**
* @}
* @}
*/