speed up for cdc

This commit is contained in:
schneider 2011-12-10 21:39:32 +01:00
parent 5704ce08cb
commit 2edc933ce0
6 changed files with 86 additions and 246 deletions

View File

@ -4,7 +4,6 @@
OBJS = OBJS =
OBJS += cdcuser.o OBJS += cdcuser.o
OBJS += cdc_buf.o
OBJS += usbcore.o OBJS += usbcore.o
OBJS += usbdesc.o OBJS += usbdesc.o
OBJS += usbhw.o OBJS += usbhw.o

View File

@ -1,161 +0,0 @@
/*******************************************************************
Copyright (C) 2009 FreakLabs
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
Originally written by Christopher Wang aka Akiba.
Please post support questions to the FreakLabs forum.
*******************************************************************/
/**************************************************************************/
/*!
@file cdc_buf.c
@author Christopher Wang (Freaklabs)
Modified by: K. Townsend (microBuilder.eu)
@date 19 May 2010
Original code taken from the FreakUSB Open Source USB Device Stack
http://freaklabs.org/index.php/FreakUSB-Open-Source-USB-Device-Stack.html
If it works well, you can thank Akiba at Freaklabs. If it fails
miserably, you can blame me (since parts of it it were rather
ungraciously modified). :-)
*/
/**************************************************************************/
#include "cdc_buf.h"
static cdc_buffer_t cdcfifo;
/**************************************************************************/
/*!
Gets a pointer to the fifo buffer
*/
/**************************************************************************/
cdc_buffer_t *cdcGetBuffer()
{
return &cdcfifo;
}
/**************************************************************************/
/*!
Initialises the RX FIFO buffer
*/
/**************************************************************************/
void cdcBufferInit()
{
cdcfifo.len = 0;
}
/**************************************************************************/
/*!
Read one byte out of the RX buffer. This function will return the byte
located at the array index of the read pointer, and then increment the
read pointer index. If the read pointer exceeds the maximum buffer
size, it will roll over to zero.
*/
/**************************************************************************/
uint8_t cdcBufferRead()
{
uint8_t data;
data = cdcfifo.buf[cdcfifo.rd_ptr];
cdcfifo.rd_ptr = (cdcfifo.rd_ptr + 1) % CFG_USBCDC_BUFFERSIZE;
cdcfifo.len--;
return data;
}
/**************************************************************************/
/*!
Reads x bytes from cdc buffer
*/
/**************************************************************************/
uint32_t cdcBufferReadLen(uint8_t* buf, uint32_t len)
{
uint32_t counter, actual;
counter = actual = 0;
while(counter != len)
{
// Make sure we don't exceed buffer limits
if (cdcfifo.len > 0)
{
buf[counter] = cdcBufferRead();
actual++;
counter++;
}
else
{
return actual;
}
}
return actual;
}
/**************************************************************************/
/*!
Write one byte into the RX buffer. This function will write one
byte into the array index specified by the write pointer and increment
the write index. If the write index exceeds the max buffer size, then it
will roll over to zero.
*/
/**************************************************************************/
void cdcBufferWrite(uint8_t data)
{
cdcfifo.buf[cdcfifo.wr_ptr] = data;
cdcfifo.wr_ptr = (cdcfifo.wr_ptr + 1) % CFG_USBCDC_BUFFERSIZE;
cdcfifo.len++;
}
/**************************************************************************/
/*!
Clear the fifo read and write pointers and set the length to zero.
*/
/**************************************************************************/
void cdcBufferClearFIFO()
{
cdcfifo.rd_ptr = 0;
cdcfifo.wr_ptr = 0;
cdcfifo.len = 0;
}
/**************************************************************************/
/*!
Check whether there is any data pending on the RX buffer.
*/
/**************************************************************************/
uint8_t cdcBufferDataPending()
{
if (cdcfifo.len != 0)
{
return 1;
}
return 0;
}

View File

@ -1,29 +0,0 @@
/*----------------------------------------------------------------------------
* Name: cdc_buf.h
* Purpose: usb cdc buffer handling
* Version: V1.00
*---------------------------------------------------------------------------*/
#ifndef __CDC_BUF_H__
#define __CDC_BUF_H__
#include "projectconfig.h"
// Buffer used for circular fifo
typedef struct _cdc_buffer_t
{
volatile uint8_t len;
volatile uint8_t wr_ptr;
volatile uint8_t rd_ptr;
uint8_t buf[CFG_USBCDC_BUFFERSIZE];
} cdc_buffer_t;
cdc_buffer_t * cdcGetBuffer();
void cdcBufferInit();
uint8_t cdcBufferRead();
uint32_t cdcBufferReadLen(uint8_t* buf, uint32_t len);
void cdcBufferWrite(uint8_t data);
void cdcBufferClearFIFO();
uint8_t cdcBufferDataPending();
#endif

View File

@ -1,4 +1,4 @@
/*---------------------------------------------------------------------------- /*----------/BulkBufOut------------------------------------------------------------------
* U S B - K e r n e l * U S B - K e r n e l
*---------------------------------------------------------------------------- *----------------------------------------------------------------------------
* Name: cdcuser.c * Name: cdcuser.c
@ -17,6 +17,7 @@
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/
#include "projectconfig.h" #include "projectconfig.h"
#include "basic/basic.h"
#include "usb.h" #include "usb.h"
#include "usbhw.h" #include "usbhw.h"
@ -24,15 +25,14 @@
#include "usbcore.h" #include "usbcore.h"
#include "cdc.h" #include "cdc.h"
#include "cdcuser.h" #include "cdcuser.h"
#include "cdc_buf.h"
// unsigned char BulkBufIn [64]; // Buffer to store USB IN packet unsigned char BulkBufIn [64]; // Buffer to store USB IN packet
unsigned char BulkBufOut [64]; // Buffer to store USB OUT packet unsigned char BulkBufOut [64]; // Buffer to store USB OUT packet
unsigned char NotificationBuf [10]; unsigned char NotificationBuf [10];
CDC_LINE_CODING CDC_LineCoding = {CFG_USBCDC_BAUDRATE, 0, 0, 8}; CDC_LINE_CODING CDC_LineCoding = {CFG_USBCDC_BAUDRATE, 0, 0, 8};
unsigned short CDC_SerialState = 0x0000; unsigned short CDC_SerialState = 0x0000;
unsigned short CDC_DepInEmpty = 1; // Data IN EP is empty volatile unsigned char CDC_DepInEmpty = 1; // Data IN EP is empty
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
We need a buffer for incoming data on USB port because USB receives We need a buffer for incoming data on USB port because USB receives
@ -61,6 +61,7 @@ typedef struct __CDC_BUF_T
} CDC_BUF_T; } CDC_BUF_T;
CDC_BUF_T CDC_OutBuf; // buffer for all CDC Out data CDC_BUF_T CDC_OutBuf; // buffer for all CDC Out data
CDC_BUF_T CDC_InBuf; // buffer for all CDC Out data
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
read data from CDC_OutBuf read data from CDC_OutBuf
@ -116,6 +117,67 @@ int CDC_OutBufAvailChar (int *availChar)
} }
/* end Buffer handling */ /* end Buffer handling */
/*----------------------------------------------------------------------------
read data from CDC_InBuf
*---------------------------------------------------------------------------*/
int CDC_RdInBuf (char *buffer, const int *length)
{
int bytesToRead, bytesRead;
/* Read *length bytes, block if *bytes are not avaialable */
bytesToRead = *length;
//bytesToRead = (bytesToRead < (*length)) ? bytesToRead : (*length);
bytesRead = bytesToRead;
// ... add code to check for underrun
while (bytesToRead--) {
*buffer++ = CDC_BUF_RD(CDC_InBuf);
}
return (bytesRead);
}
/*----------------------------------------------------------------------------
write data to CDC_InBuf
*---------------------------------------------------------------------------*/
int CDC_WrInBuf (const char *buffer, int *length)
{
int bytesToWrite, bytesWritten;
// Write *length bytes
bytesToWrite = *length;
bytesWritten = bytesToWrite;
//Just block if we can't write all at once
while( CDC_BUF_SIZE - CDC_BUF_COUNT(CDC_InBuf) < bytesToWrite );
//uint8_t flush = CDC_DepInEmpty;
while (bytesToWrite--) {
CDC_BUF_WR(CDC_InBuf, *buffer++); // Copy Data to buffer
}
//if( flush == 1 ){
if( CDC_DepInEmpty && CDC_BUF_COUNT(CDC_InBuf) ){
CDC_DepInEmpty = 0;
gpioSetValue (RB_LED2, 0);
CDC_BulkIn();
}
return (bytesWritten);
}
/*----------------------------------------------------------------------------
check if character(s) are available at CDC_OutBuf
*---------------------------------------------------------------------------*/
int CDC_InBufAvailChar (int *availChar)
{
*availChar = CDC_BUF_COUNT(CDC_InBuf);
return (0);
}
/* end Buffer handling */
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
CDC Initialisation CDC Initialisation
@ -129,12 +191,8 @@ void CDC_Init (void)
CDC_SerialState = CDC_GetSerialState(); CDC_SerialState = CDC_GetSerialState();
CDC_BUF_RESET(CDC_OutBuf); CDC_BUF_RESET(CDC_OutBuf);
CDC_BUF_RESET(CDC_InBuf);
// Initialise the CDC buffer. This is required to buffer outgoing
// data (MCU to PC) since data can only be sent 64 bytes per frame
// with at least 1ms between frames. To see how the buffer is used,
// see 'puts' in systeminit.c
cdcBufferInit();
} }
@ -277,25 +335,19 @@ uint32_t CDC_SendBreak (unsigned short wDurationOfBreak) {
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/
void CDC_BulkIn(void) void CDC_BulkIn(void)
{ {
// int numBytesRead, numBytesAvail; int numBytesRead, numBytesAvail;
// CDC_InBufAvailChar(&numBytesAvail);
// // ToDo: Modify BulkIn to send incoming data to USB numBytesRead = CDC_RdInBuf(&BulkBufIn[0], &numBytesAvail);
// // send over USB
// ser_AvailChar (&numBytesAvail); if (numBytesRead > 0) {
// //gpioSetValue (RB_LED0, 1);
// // ... add code to check for overwrite USB_WriteEP (CDC_DEP_IN, &BulkBufIn[0], numBytesRead);
// //gpioSetValue (RB_LED0, 0);
// numBytesRead = ser_Read ((char *)&BulkBufIn[0], &numBytesAvail); } else {
// //USB_WriteEP (CDC_DEP_IN, "test\r\n", 6);
// // send over USB CDC_DepInEmpty = 1;
// if (numBytesRead > 0) { //gpioSetValue (RB_LED2, 1);
// USB_WriteEP (CDC_DEP_IN, &BulkBufIn[0], numBytesRead); }
// }
// else {
// CDC_DepInEmpty = 1;
// }
//
//
} }

View File

@ -57,7 +57,7 @@ extern void CDC_Init (void);
extern unsigned short CDC_GetSerialState (void); extern unsigned short CDC_GetSerialState (void);
/* flow control */ /* flow control */
extern unsigned short CDC_DepInEmpty; // DataEndPoint IN empty extern volatile unsigned char CDC_DepInEmpty; // DataEndPoint IN empty
#endif /* __CDCUSER_H__ */ #endif /* __CDCUSER_H__ */

View File

@ -17,29 +17,8 @@ int puts(const char * str){
if(!USB_Configuration) if(!USB_Configuration)
return -1; return -1;
while(*str) int len = strlen(str);
cdcBufferWrite(*str++); CDC_WrInBuf(str, &len);
//XXX: This assumes systick is 1ms, which it isn't for us.
// this makes usbserial unnecessary slow. Ah well....
// Check if we can flush the buffer now or if we need to wait
unsigned int currentTick = systickGetTicks();
if (currentTick != lastTick){
uint8_t frame[64];
uint32_t bytesRead = 0;
char repeat=0;
while (cdcBufferDataPending()){
// Read up to 64 bytes as long as possible
bytesRead = cdcBufferReadLen(frame, 64);
USB_WriteEP (CDC_DEP_IN, frame, bytesRead);
if(repeat)
systickDelay(1);
else
repeat=1;
}
lastTick = currentTick;
}
return 0; return 0;
} }
@ -47,8 +26,8 @@ int puts_plus(const char * str){
if(!USB_Configuration) if(!USB_Configuration)
return -1; return -1;
while(*str) int len = strlen(str);
cdcBufferWrite(*str++); CDC_WrInBuf(str, &len);
return 0; return 0;
} }