VCOM_lib1.3
This commit is contained in:
parent
2aed667897
commit
99a520a442
6
VCOM_lib/intenable.c
Normal file
6
VCOM_lib/intenable.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include "LPC17xx.h"
|
||||
|
||||
void enable_USB_interrupts(void)
|
||||
{
|
||||
NVIC_EnableIRQ(USB_IRQn);
|
||||
}
|
68
VCOM_lib/lpcusb_type.h
Normal file
68
VCOM_lib/lpcusb_type.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
LPCUSB, an USB device driver for LPC microcontrollers
|
||||
Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
|
||||
|
||||
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. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*/
|
||||
/**
|
||||
@file
|
||||
primitive types used in the USB stack
|
||||
*/
|
||||
|
||||
// ***********************************************
|
||||
// Code Red Technologies - port to RDB1768 board
|
||||
// In order to avoid clashing with the NXP-produced type.h file, this
|
||||
// one has been renamed to lpcusb_type.h, the NXP-produced type.h has
|
||||
// been included, and the duplicate contents of this file commented out.
|
||||
// ***********************************************
|
||||
|
||||
|
||||
#ifndef _LPCUSB_TYPE_H_
|
||||
#define _LPCUSB_TYPE_H_
|
||||
|
||||
// CodeRed - include NXP-produced type.h file
|
||||
#include "type.h"
|
||||
|
||||
typedef unsigned char U8; /**< unsigned 8-bit */
|
||||
typedef unsigned short int U16; /**< unsigned 16-bit */
|
||||
typedef unsigned int U32; /**< unsigned 32-bit */
|
||||
|
||||
|
||||
// CodeRed - comment out defines duplicated in NXP type.h
|
||||
|
||||
//typedef int BOOL; /**< #TRUE or #FALSE */
|
||||
|
||||
//#define TRUE 1 /**< TRUE */
|
||||
//#define FALSE 0 /**< FALSE */
|
||||
|
||||
//#ifndef NULL
|
||||
//#define NULL ((void*)0) /**< NULL pointer */
|
||||
//#endif
|
||||
//#endif
|
||||
|
||||
/* some other useful macros */
|
||||
#define MIN(x,y) ((x)<(y)?(x):(y)) /**< MIN */
|
||||
#define MAX(x,y) ((x)>(y)?(x):(y)) /**< MAX */
|
||||
|
||||
#endif /* _LPCUSB_TYPE_H_ */
|
||||
|
87
VCOM_lib/serial_fifo.c
Normal file
87
VCOM_lib/serial_fifo.c
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
LPCUSB, an USB device driver for LPC microcontrollers
|
||||
Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
|
||||
|
||||
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. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
// CodeRed - LPCUSB type.h renamed
|
||||
//#include "type.h"
|
||||
#include "lpcusb_type.h"
|
||||
#include "serial_fifo.h"
|
||||
|
||||
void fifo_init(fifo_t *fifo, U8 *buf)
|
||||
{
|
||||
fifo->head = 0;
|
||||
fifo->tail = 0;
|
||||
fifo->buf = buf;
|
||||
}
|
||||
|
||||
|
||||
BOOL fifo_put(fifo_t *fifo, U8 c)
|
||||
{
|
||||
int next;
|
||||
|
||||
// check if FIFO has room
|
||||
next = (fifo->head + 1) % VCOM_FIFO_SIZE;
|
||||
if (next == fifo->tail) {
|
||||
// full
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fifo->buf[fifo->head] = c;
|
||||
fifo->head = next;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL fifo_get(fifo_t *fifo, U8 *pc)
|
||||
{
|
||||
int next;
|
||||
|
||||
// check if FIFO has data
|
||||
if (fifo->head == fifo->tail) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
next = (fifo->tail + 1) % VCOM_FIFO_SIZE;
|
||||
|
||||
*pc = fifo->buf[fifo->tail];
|
||||
fifo->tail = next;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
int fifo_avail(fifo_t *fifo)
|
||||
{
|
||||
return (VCOM_FIFO_SIZE + fifo->head - fifo->tail) % VCOM_FIFO_SIZE;
|
||||
}
|
||||
|
||||
|
||||
int fifo_free(fifo_t *fifo)
|
||||
{
|
||||
return (VCOM_FIFO_SIZE - 1 - fifo_avail(fifo));
|
||||
}
|
||||
|
42
VCOM_lib/serial_fifo.h
Normal file
42
VCOM_lib/serial_fifo.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
LPCUSB, an USB device driver for LPC microcontrollers
|
||||
Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
|
||||
|
||||
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. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
#include "lpcusb_type.h"
|
||||
|
||||
#define VCOM_FIFO_SIZE 512
|
||||
|
||||
typedef struct {
|
||||
int head;
|
||||
int tail;
|
||||
U8 *buf;
|
||||
} fifo_t;
|
||||
|
||||
void fifo_init(fifo_t *fifo, U8 *buf);
|
||||
BOOL fifo_put(fifo_t *fifo, U8 c);
|
||||
BOOL fifo_get(fifo_t *fifo, U8 *pc);
|
||||
int fifo_avail(fifo_t *fifo);
|
||||
int fifo_free(fifo_t *fifo);
|
628
VCOM_lib/usbSerial.c
Normal file
628
VCOM_lib/usbSerial.c
Normal file
@ -0,0 +1,628 @@
|
||||
//#define POLLED_USBSERIAL TRUE
|
||||
|
||||
|
||||
/*
|
||||
LPCUSB, an USB device driver for LPC microcontrollers
|
||||
Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
|
||||
|
||||
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. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Minimal implementation of a USB serial port, using the CDC class.
|
||||
This example application simply echoes everything it receives right back
|
||||
to the host.
|
||||
|
||||
Windows:
|
||||
Extract the usbser.sys file from .cab file in C:\WINDOWS\Driver Cache\i386
|
||||
and store it somewhere (C:\temp is a good place) along with the usbser.inf
|
||||
file. Then plug in the LPC176x and direct windows to the usbser driver.
|
||||
Windows then creates an extra COMx port that you can open in a terminal
|
||||
program, like hyperterminal.
|
||||
|
||||
Linux:
|
||||
The device should be recognised automatically by the cdc_acm driver,
|
||||
which creates a /dev/ttyACMx device file that acts just like a regular
|
||||
serial port.
|
||||
|
||||
*/
|
||||
|
||||
/* Modified by Sagar G V, Feb 2011
|
||||
Used the USB CDC example to create a library. Added the following functions
|
||||
|
||||
void VCOM_puts(const char* str); //writes a null terminated string.
|
||||
void VCOM_putc(char c); // writes a character.
|
||||
void VCOM_putHex(uint8_t hex); // writes 0x.. hex value on the terminal.
|
||||
char VCOM_getc(); // returns character entered in the terminal. blocking function
|
||||
void VCOM_gets(char* str); // returns a string. '\r' or '\n' will terminate character collection.
|
||||
char VCOM_getc_echo(); // returns character entered and echoes the same back.
|
||||
void VCOM_gets_echo(char *str); // gets string terminated in '\r' or '\n' and echoes back the same.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "usbSerial.h"
|
||||
|
||||
|
||||
|
||||
// data structure for GET_LINE_CODING / SET_LINE_CODING class requests
|
||||
typedef struct {
|
||||
U32 dwDTERate;
|
||||
U8 bCharFormat;
|
||||
U8 bParityType;
|
||||
U8 bDataBits;
|
||||
} TLineCoding;
|
||||
|
||||
static TLineCoding LineCoding = {115200, 0, 0, 8};
|
||||
static U8 abBulkBuf[64];
|
||||
static U8 abClassReqData[8];
|
||||
|
||||
static U8 txdata[VCOM_FIFO_SIZE];
|
||||
static U8 rxdata[VCOM_FIFO_SIZE];
|
||||
|
||||
static fifo_t txfifo;
|
||||
static fifo_t rxfifo;
|
||||
|
||||
// forward declaration of interrupt handler
|
||||
void USBIntHandler(void);
|
||||
|
||||
static const U8 abDescriptors[] = {
|
||||
|
||||
// device descriptor
|
||||
0x12,
|
||||
DESC_DEVICE,
|
||||
LE_WORD(0x0101), // bcdUSB
|
||||
0x02, // bDeviceClass
|
||||
0x00, // bDeviceSubClass
|
||||
0x00, // bDeviceProtocol
|
||||
MAX_PACKET_SIZE0, // bMaxPacketSize
|
||||
LE_WORD(0xFFFF), // idVendor
|
||||
LE_WORD(0x0005), // idProduct
|
||||
LE_WORD(0x0100), // bcdDevice
|
||||
0x01, // iManufacturer
|
||||
0x02, // iProduct
|
||||
0x03, // iSerialNumber
|
||||
0x01, // bNumConfigurations
|
||||
|
||||
// configuration descriptor
|
||||
0x09,
|
||||
DESC_CONFIGURATION,
|
||||
LE_WORD(67), // wTotalLength
|
||||
0x02, // bNumInterfaces
|
||||
0x01, // bConfigurationValue
|
||||
0x00, // iConfiguration
|
||||
0xC0, // bmAttributes
|
||||
0x32, // bMaxPower
|
||||
// control class interface
|
||||
0x09,
|
||||
DESC_INTERFACE,
|
||||
0x00, // bInterfaceNumber
|
||||
0x00, // bAlternateSetting
|
||||
0x01, // bNumEndPoints
|
||||
0x02, // bInterfaceClass
|
||||
0x02, // bInterfaceSubClass
|
||||
0x01, // bInterfaceProtocol, linux requires value of 1 for the cdc_acm module
|
||||
0x00, // iInterface
|
||||
// header functional descriptor
|
||||
0x05,
|
||||
CS_INTERFACE,
|
||||
0x00,
|
||||
LE_WORD(0x0110),
|
||||
// call management functional descriptor
|
||||
0x05,
|
||||
CS_INTERFACE,
|
||||
0x01,
|
||||
0x01, // bmCapabilities = device handles call management
|
||||
0x01, // bDataInterface
|
||||
// ACM functional descriptor
|
||||
0x04,
|
||||
CS_INTERFACE,
|
||||
0x02,
|
||||
0x02, // bmCapabilities
|
||||
// union functional descriptor
|
||||
0x05,
|
||||
CS_INTERFACE,
|
||||
0x06,
|
||||
0x00, // bMasterInterface
|
||||
0x01, // bSlaveInterface0
|
||||
// notification EP
|
||||
0x07,
|
||||
DESC_ENDPOINT,
|
||||
INT_IN_EP, // bEndpointAddress
|
||||
0x03, // bmAttributes = intr
|
||||
LE_WORD(8), // wMaxPacketSize
|
||||
0x0A, // bInterval
|
||||
// data class interface descriptor
|
||||
0x09,
|
||||
DESC_INTERFACE,
|
||||
0x01, // bInterfaceNumber
|
||||
0x00, // bAlternateSetting
|
||||
0x02, // bNumEndPoints
|
||||
0x0A, // bInterfaceClass = data
|
||||
0x00, // bInterfaceSubClass
|
||||
0x00, // bInterfaceProtocol
|
||||
0x00, // iInterface
|
||||
// data EP OUT
|
||||
0x07,
|
||||
DESC_ENDPOINT,
|
||||
BULK_OUT_EP, // bEndpointAddress
|
||||
0x02, // bmAttributes = bulk
|
||||
LE_WORD(MAX_PACKET_SIZE), // wMaxPacketSize
|
||||
0x00, // bInterval
|
||||
// data EP in
|
||||
0x07,
|
||||
DESC_ENDPOINT,
|
||||
BULK_IN_EP, // bEndpointAddress
|
||||
0x02, // bmAttributes = bulk
|
||||
LE_WORD(MAX_PACKET_SIZE), // wMaxPacketSize
|
||||
0x00, // bInterval
|
||||
|
||||
// string descriptors
|
||||
0x04,
|
||||
DESC_STRING,
|
||||
LE_WORD(0x0409),
|
||||
|
||||
0x0E,
|
||||
DESC_STRING,
|
||||
'L', 0, 'P', 0, 'C', 0, 'U', 0, 'S', 0, 'B', 0,
|
||||
|
||||
0x14,
|
||||
DESC_STRING,
|
||||
'U', 0, 'S', 0, 'B', 0, 'S', 0, 'e', 0, 'r', 0, 'i', 0, 'a', 0, 'l', 0,
|
||||
|
||||
0x12,
|
||||
DESC_STRING,
|
||||
'D', 0, 'E', 0, 'A', 0, 'D', 0, 'C', 0, '0', 0, 'D', 0, 'E', 0,
|
||||
|
||||
// terminating zero
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Local function to handle incoming bulk data
|
||||
|
||||
@param [in] bEP
|
||||
@param [in] bEPStatus
|
||||
*/
|
||||
static void BulkOut(U8 bEP, U8 bEPStatus)
|
||||
{
|
||||
int i, iLen;
|
||||
bEPStatus = bEPStatus;
|
||||
if (fifo_free(&rxfifo) < MAX_PACKET_SIZE) {
|
||||
// may not fit into fifo
|
||||
return;
|
||||
}
|
||||
|
||||
// get data from USB into intermediate buffer
|
||||
iLen = USBHwEPRead(bEP, abBulkBuf, sizeof(abBulkBuf));
|
||||
for (i = 0; i < iLen; i++) {
|
||||
// put into FIFO
|
||||
if (!fifo_put(&rxfifo, abBulkBuf[i])) {
|
||||
// overflow... :(
|
||||
ASSERT(FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Local function to handle outgoing bulk data
|
||||
|
||||
@param [in] bEP
|
||||
@param [in] bEPStatus
|
||||
*/
|
||||
static void BulkIn(U8 bEP, U8 bEPStatus)
|
||||
{
|
||||
int i, iLen;
|
||||
bEPStatus = bEPStatus;
|
||||
if (fifo_avail(&txfifo) == 0) {
|
||||
// no more data, disable further NAK interrupts until next USB frame
|
||||
USBHwNakIntEnable(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// get bytes from transmit FIFO into intermediate buffer
|
||||
for (i = 0; i < MAX_PACKET_SIZE; i++) {
|
||||
if (!fifo_get(&txfifo, &abBulkBuf[i])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
iLen = i;
|
||||
|
||||
// send over USB
|
||||
if (iLen > 0) {
|
||||
USBHwEPWrite(bEP, abBulkBuf, iLen);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Local function to handle the USB-CDC class requests
|
||||
|
||||
@param [in] pSetup
|
||||
@param [out] piLen
|
||||
@param [out] ppbData
|
||||
*/
|
||||
static BOOL HandleClassRequest(TSetupPacket *pSetup, int *piLen, U8 **ppbData)
|
||||
{
|
||||
int i;
|
||||
switch (pSetup->bRequest) {
|
||||
|
||||
// set line coding
|
||||
case SET_LINE_CODING:
|
||||
|
||||
//memcpy((U8 *)&LineCoding, *ppbData, 7);
|
||||
*piLen = 7;
|
||||
for(i=0;i<7;i++)
|
||||
((U8 *)&LineCoding)[i] = (*ppbData)[i];
|
||||
|
||||
break;
|
||||
|
||||
// get line coding
|
||||
case GET_LINE_CODING:
|
||||
|
||||
*ppbData = (U8 *)&LineCoding;
|
||||
*piLen = 7;
|
||||
break;
|
||||
|
||||
// set control line state
|
||||
case SET_CONTROL_LINE_STATE:
|
||||
// bit0 = DTR, bit = RTS
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Initialises the VCOM port.
|
||||
Call this function before using VCOM_puttchar or VCOM_getchar
|
||||
*/
|
||||
void VCOM_init(void)
|
||||
{
|
||||
fifo_init(&txfifo, txdata);
|
||||
fifo_init(&rxfifo, rxdata);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Writes one character to VCOM port
|
||||
|
||||
@param [in] c character to write
|
||||
@returns character written, or EOF if character could not be written
|
||||
*/
|
||||
int VCOM_putchar(int c)
|
||||
{
|
||||
return fifo_put(&txfifo, c) ? c : EOF;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Reads one character from VCOM port
|
||||
|
||||
@returns character read, or EOF if character could not be read
|
||||
*/
|
||||
int VCOM_getchar(void)
|
||||
{
|
||||
U8 c;
|
||||
|
||||
return fifo_get(&rxfifo, &c) ? c : EOF;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Interrupt handler
|
||||
|
||||
Simply calls the USB ISR
|
||||
*/
|
||||
//void USBIntHandler(void)
|
||||
void USB_IRQHandler(void)
|
||||
{
|
||||
USBHwISR();
|
||||
}
|
||||
|
||||
|
||||
static void USBFrameHandler(U16 wFrame)
|
||||
{
|
||||
wFrame = wFrame;
|
||||
if (fifo_avail(&txfifo) > 0) {
|
||||
// data available, enable NAK interrupt on bulk in
|
||||
USBHwNakIntEnable(INACK_BI);
|
||||
}
|
||||
}
|
||||
|
||||
void enable_USB_interrupts(void);
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
main
|
||||
====
|
||||
**************************************************************************/
|
||||
int usbSerialInit()
|
||||
{
|
||||
// initialise stack
|
||||
USBInit();
|
||||
|
||||
// register descriptors
|
||||
USBRegisterDescriptors(abDescriptors);
|
||||
|
||||
// register class request handler
|
||||
USBRegisterRequestHandler(REQTYPE_TYPE_CLASS, HandleClassRequest, abClassReqData);
|
||||
|
||||
// register endpoint handlers
|
||||
USBHwRegisterEPIntHandler(INT_IN_EP, NULL);
|
||||
USBHwRegisterEPIntHandler(BULK_IN_EP, BulkIn);
|
||||
USBHwRegisterEPIntHandler(BULK_OUT_EP, BulkOut);
|
||||
|
||||
// register frame handler
|
||||
USBHwRegisterFrameHandler(USBFrameHandler);
|
||||
|
||||
// enable bulk-in interrupts on NAKs
|
||||
USBHwNakIntEnable(INACK_BI);
|
||||
|
||||
// initialise VCOM
|
||||
VCOM_init();
|
||||
|
||||
|
||||
/* CodeRed - comment out original interrupt setup code
|
||||
// set up USB interrupt
|
||||
VICIntSelect &= ~(1<<22); // select IRQ for USB
|
||||
VICIntEnable |= (1<<22);
|
||||
|
||||
(*(&VICVectCntl0+INT_VECT_NUM)) = 0x20 | 22; // choose highest priority ISR slot
|
||||
(*(&VICVectAddr0+INT_VECT_NUM)) = (int)USBIntHandler;
|
||||
|
||||
enableIRQ();
|
||||
*/
|
||||
|
||||
// CodeRed - add in interrupt setup code for RDB1768
|
||||
|
||||
#ifndef POLLED_USBSERIAL
|
||||
//enable_USB_interrupts();
|
||||
NVIC_EnableIRQ(USB_IRQn);
|
||||
|
||||
#endif
|
||||
|
||||
// connect to bus
|
||||
|
||||
|
||||
USBHwConnect(TRUE);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
void VCOM_puts(const char* str)
|
||||
{
|
||||
while(*str != '\0')
|
||||
{
|
||||
VCOM_putchar(*str++);
|
||||
}
|
||||
}
|
||||
void VCOM_putc(char c)
|
||||
{
|
||||
while(VCOM_putchar(c) == EOF);
|
||||
}
|
||||
char VCOM_getc()
|
||||
{
|
||||
int c;
|
||||
c = EOF;
|
||||
while(c == EOF)
|
||||
{
|
||||
c = VCOM_getchar();
|
||||
}
|
||||
return (char)c;
|
||||
}
|
||||
void VCOM_putHex(uint8_t hex)
|
||||
{
|
||||
uint8_t temp;
|
||||
VCOM_puts("0x");
|
||||
|
||||
temp = ((hex >> 4) & 0x0F) + 0x30;// add 0x30 to get ASCII value
|
||||
if(temp > 0x39)
|
||||
temp += 7; // alphabet, not numeral
|
||||
VCOM_putc((char)temp);
|
||||
|
||||
temp = ((hex) & 0x0F) + 0x30;
|
||||
if(temp > 0x39)
|
||||
temp += 7;
|
||||
|
||||
VCOM_putc((char)temp);
|
||||
}
|
||||
void VCOM_gets(char* str)
|
||||
{
|
||||
char c;
|
||||
c = VCOM_getc();
|
||||
while((c != '\n') && (c != '\r'))
|
||||
{
|
||||
*str++ = c;
|
||||
c = VCOM_getc();
|
||||
}
|
||||
*str = '\0';
|
||||
}
|
||||
char VCOM_getc_echo()
|
||||
{
|
||||
char c;
|
||||
c = VCOM_getc();
|
||||
VCOM_putc(c);
|
||||
return c;
|
||||
}
|
||||
void VCOM_gets_echo(char *str)
|
||||
{
|
||||
char c;
|
||||
c = VCOM_getc_echo();
|
||||
while((c != '\n') && (c != '\r'))
|
||||
{
|
||||
*str++ = c;
|
||||
c = VCOM_getc_echo();
|
||||
}
|
||||
*str = '\0';
|
||||
}
|
||||
|
||||
/* Original code by ELM_ChaN. Modified by Martin Thomas */
|
||||
int xatoi (char **str, long *res)
|
||||
{
|
||||
uint32_t val;
|
||||
uint8_t c, radix, s = 0;
|
||||
|
||||
|
||||
while ((c = **str) == ' ') (*str)++;
|
||||
if (c == '-') {
|
||||
s = 1;
|
||||
c = *(++(*str));
|
||||
}
|
||||
if (c == '0') {
|
||||
c = *(++(*str));
|
||||
if (c <= ' ') {
|
||||
*res = 0; return 1;
|
||||
}
|
||||
if (c == 'x') {
|
||||
radix = 16;
|
||||
c = *(++(*str));
|
||||
} else {
|
||||
if (c == 'b') {
|
||||
radix = 2;
|
||||
c = *(++(*str));
|
||||
} else {
|
||||
if ((c >= '0')&&(c <= '9'))
|
||||
radix = 8;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((c < '1')||(c > '9'))
|
||||
return 0;
|
||||
radix = 10;
|
||||
}
|
||||
val = 0;
|
||||
while (c > ' ') {
|
||||
if (c >= 'a') c -= 0x20;
|
||||
c -= '0';
|
||||
if (c >= 17) {
|
||||
c -= 7;
|
||||
if (c <= 9) return 0;
|
||||
}
|
||||
if (c >= radix) return 0;
|
||||
val = val * radix + c;
|
||||
c = *(++(*str));
|
||||
}
|
||||
if (s) val = -val;
|
||||
*res = val;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void xitoa (long val, int radix, int len)
|
||||
{
|
||||
uint8_t c, r, sgn = 0, pad = ' ';
|
||||
uint8_t s[20], i = 0;
|
||||
uint32_t v;
|
||||
|
||||
|
||||
if (radix < 0) {
|
||||
radix = -radix;
|
||||
if (val < 0) {
|
||||
val = -val;
|
||||
sgn = '-';
|
||||
}
|
||||
}
|
||||
v = val;
|
||||
r = radix;
|
||||
if (len < 0) {
|
||||
len = -len;
|
||||
pad = '0';
|
||||
}
|
||||
if (len > 20) return;
|
||||
do {
|
||||
c = (uint8_t)(v % r);
|
||||
if (c >= 10) c += 7;
|
||||
c += '0';
|
||||
s[i++] = c;
|
||||
v /= r;
|
||||
} while (v);
|
||||
if (sgn) s[i++] = sgn;
|
||||
while (i < len)
|
||||
s[i++] = pad;
|
||||
do
|
||||
VCOM_putc(s[--i]);
|
||||
while (i);
|
||||
}
|
||||
|
||||
void VCOM_printf (const char* str, ...)
|
||||
{
|
||||
va_list arp;
|
||||
int d, r, w, s, l;
|
||||
|
||||
|
||||
va_start(arp, str);
|
||||
|
||||
while ((d = *str++) != 0) {
|
||||
if (d != '%') {
|
||||
VCOM_putc(d); continue;
|
||||
}
|
||||
d = *str++; w = r = s = l = 0;
|
||||
if (d == '0') {
|
||||
d = *str++; s = 1;
|
||||
}
|
||||
while ((d >= '0')&&(d <= '9')) {
|
||||
w += w * 10 + (d - '0');
|
||||
d = *str++;
|
||||
}
|
||||
if (s) w = -w;
|
||||
if (d == 'l') {
|
||||
l = 1;
|
||||
d = *str++;
|
||||
}
|
||||
if (!d) break;
|
||||
if (d == 's') {
|
||||
VCOM_puts(va_arg(arp, char*));
|
||||
continue;
|
||||
}
|
||||
if (d == 'c') {
|
||||
VCOM_putc((char)va_arg(arp, int));
|
||||
continue;
|
||||
}
|
||||
if (d == 'u') r = 10;
|
||||
if (d == 'd') r = -10;
|
||||
if (d == 'X' || d == 'x') r = 16; // 'x' added by mthomas in increase compatibility
|
||||
if (d == 'b') r = 2;
|
||||
if (!r) break;
|
||||
if (l) {
|
||||
xitoa((long)va_arg(arp, long), r, w);
|
||||
} else {
|
||||
if (r > 0)
|
||||
xitoa((unsigned long)va_arg(arp, int), r, w);
|
||||
else
|
||||
xitoa((long)va_arg(arp, int), r, w);
|
||||
}
|
||||
}
|
||||
|
||||
va_end(arp);
|
||||
}
|
129
VCOM_lib/usbSerial.h
Normal file
129
VCOM_lib/usbSerial.h
Normal file
@ -0,0 +1,129 @@
|
||||
//#define POLLED_USBSERIAL TRUE
|
||||
|
||||
|
||||
/*
|
||||
LPCUSB, an USB device driver for LPC microcontrollers
|
||||
Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
|
||||
|
||||
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. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Minimal implementation of a USB serial port, using the CDC class.
|
||||
This example application simply echoes everything it receives right back
|
||||
to the host.
|
||||
|
||||
Windows:
|
||||
Extract the usbser.sys file from .cab file in C:\WINDOWS\Driver Cache\i386
|
||||
and store it somewhere (C:\temp is a good place) along with the usbser.inf
|
||||
file. Then plug in the LPC176x and direct windows to the usbser driver.
|
||||
Windows then creates an extra COMx port that you can open in a terminal
|
||||
program, like hyperterminal.
|
||||
|
||||
Linux:
|
||||
The device should be recognised automatically by the cdc_acm driver,
|
||||
which creates a /dev/ttyACMx device file that acts just like a regular
|
||||
serial port.
|
||||
|
||||
*/
|
||||
|
||||
/* Modified by Sagar G V, Feb 2011
|
||||
Used the USB CDC example to create a library. Added the following functions
|
||||
|
||||
void VCOM_puts(const char* str); //writes a null terminated string.
|
||||
void VCOM_putc(char c); // writes a character.
|
||||
void VCOM_putHex(uint8_t hex); // writes 0x.. hex value on the terminal.
|
||||
char VCOM_getc(); // returns character entered in the terminal. blocking function
|
||||
void VCOM_gets(char* str); // returns a string. '\r' or '\n' will terminate character collection.
|
||||
char VCOM_getc_echo(); // returns character entered and echoes the same back.
|
||||
void VCOM_gets_echo(char *str); // gets string terminated in '\r' or '\n' and echoes back the same.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __USB_SERIAL_H__
|
||||
#define __USB_SERIAL_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "LPC17xx.h"
|
||||
|
||||
#include "usbapi.h"
|
||||
#include "usbdebug.h"
|
||||
|
||||
#define BAUD_RATE 115200
|
||||
|
||||
#define INT_IN_EP 0x81
|
||||
#define BULK_OUT_EP 0x05
|
||||
#define BULK_IN_EP 0x82
|
||||
|
||||
#define MAX_PACKET_SIZE 64
|
||||
|
||||
#define LE_WORD(x) ((x)&0xFF),((x)>>8)
|
||||
|
||||
// CDC definitions
|
||||
#define CS_INTERFACE 0x24
|
||||
#define CS_ENDPOINT 0x25
|
||||
|
||||
#define SET_LINE_CODING 0x20
|
||||
#define GET_LINE_CODING 0x21
|
||||
#define SET_CONTROL_LINE_STATE 0x22
|
||||
|
||||
|
||||
#include "serial_fifo.h"
|
||||
|
||||
int usbSerialInit(); // run once in main b4 main loop starts.
|
||||
|
||||
|
||||
/*
|
||||
Writes one character to VCOM port
|
||||
|
||||
@param [in] c character to write
|
||||
@returns character written, or EOF if character could not be written
|
||||
*/
|
||||
int VCOM_putchar(int c);
|
||||
|
||||
/**
|
||||
Reads one character from VCOM port
|
||||
|
||||
@returns character read, or EOF if character could not be read
|
||||
*/
|
||||
int VCOM_getchar(void);
|
||||
|
||||
void VCOM_puts(const char* str); //writes a null terminated string.
|
||||
void VCOM_putc(char c); // writes a character.
|
||||
void VCOM_putHex(uint8_t hex); // writes 0x.. hex value on the terminal.
|
||||
char VCOM_getc(); // returns character entered in the terminal. blocking function
|
||||
void VCOM_gets(char* str); // returns a string. '\r' or '\n' will terminate character collection.
|
||||
char VCOM_getc_echo(); // returns character entered and echoes the same back.
|
||||
void VCOM_gets_echo(char *str); // gets string terminated in '\r' or '\n' and echoes back the same.
|
||||
|
||||
void VCOM_printf(const char* str, ...); // Original code by Elm_CHaN. Modified by Martin Thomas
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
121
VCOM_lib/usbapi.h
Normal file
121
VCOM_lib/usbapi.h
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
LPCUSB, an USB device driver for LPC microcontrollers
|
||||
Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
|
||||
|
||||
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. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
@file
|
||||
*/
|
||||
|
||||
// CodeRed - include the LPCUSB type.h file rather than NXP one directly
|
||||
#include "lpcusb_type.h"
|
||||
|
||||
#include "usbstruct.h" // for TSetupPacket
|
||||
|
||||
/*************************************************************************
|
||||
USB configuration
|
||||
**************************************************************************/
|
||||
|
||||
#define MAX_PACKET_SIZE0 64 /**< maximum packet size for EP 0 */
|
||||
|
||||
/*************************************************************************
|
||||
USB hardware interface
|
||||
**************************************************************************/
|
||||
|
||||
// endpoint status sent through callback
|
||||
#define EP_STATUS_DATA (1<<0) /**< EP has data */
|
||||
#define EP_STATUS_STALLED (1<<1) /**< EP is stalled */
|
||||
#define EP_STATUS_SETUP (1<<2) /**< EP received setup packet */
|
||||
#define EP_STATUS_ERROR (1<<3) /**< EP data was overwritten by setup packet */
|
||||
#define EP_STATUS_NACKED (1<<4) /**< EP sent NAK */
|
||||
|
||||
// device status sent through callback
|
||||
#define DEV_STATUS_CONNECT (1<<0) /**< device just got connected */
|
||||
#define DEV_STATUS_SUSPEND (1<<2) /**< device entered suspend state */
|
||||
#define DEV_STATUS_RESET (1<<4) /**< device just got reset */
|
||||
|
||||
// interrupt bits for NACK events in USBHwNakIntEnable
|
||||
// (these bits conveniently coincide with the LPC176x USB controller bit)
|
||||
#define INACK_CI (1<<1) /**< interrupt on NACK for control in */
|
||||
#define INACK_CO (1<<2) /**< interrupt on NACK for control out */
|
||||
#define INACK_II (1<<3) /**< interrupt on NACK for interrupt in */
|
||||
#define INACK_IO (1<<4) /**< interrupt on NACK for interrupt out */
|
||||
#define INACK_BI (1<<5) /**< interrupt on NACK for bulk in */
|
||||
#define INACK_BO (1<<6) /**< interrupt on NACK for bulk out */
|
||||
|
||||
BOOL USBHwInit (void);
|
||||
void USBHwISR (void);
|
||||
|
||||
void USBHwNakIntEnable (U8 bIntBits);
|
||||
|
||||
void USBHwConnect (BOOL fConnect);
|
||||
|
||||
void USBHwSetAddress (U8 bAddr);
|
||||
void USBHwConfigDevice (BOOL fConfigured);
|
||||
|
||||
// endpoint operations
|
||||
void USBHwEPConfig (U8 bEP, U16 wMaxPacketSize);
|
||||
int USBHwEPRead (U8 bEP, U8 *pbBuf, int iMaxLen);
|
||||
int USBHwEPWrite (U8 bEP, U8 *pbBuf, int iLen);
|
||||
void USBHwEPStall (U8 bEP, BOOL fStall);
|
||||
U8 USBHwEPGetStatus (U8 bEP);
|
||||
|
||||
/** Endpoint interrupt handler callback */
|
||||
typedef void (TFnEPIntHandler) (U8 bEP, U8 bEPStatus);
|
||||
void USBHwRegisterEPIntHandler (U8 bEP, TFnEPIntHandler *pfnHandler);
|
||||
|
||||
/** Device status handler callback */
|
||||
typedef void (TFnDevIntHandler) (U8 bDevStatus);
|
||||
void USBHwRegisterDevIntHandler (TFnDevIntHandler *pfnHandler);
|
||||
|
||||
/** Frame event handler callback */
|
||||
typedef void (TFnFrameHandler)(U16 wFrame);
|
||||
void USBHwRegisterFrameHandler(TFnFrameHandler *pfnHandler);
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
USB application interface
|
||||
**************************************************************************/
|
||||
|
||||
// initialise the complete stack, including HW
|
||||
BOOL USBInit(void);
|
||||
|
||||
/** Request handler callback (standard, vendor, class) */
|
||||
typedef BOOL (TFnHandleRequest)(TSetupPacket *pSetup, int *piLen, U8 **ppbData);
|
||||
void USBRegisterRequestHandler(int iType, TFnHandleRequest *pfnHandler, U8 *pbDataStore);
|
||||
void USBRegisterCustomReqHandler(TFnHandleRequest *pfnHandler);
|
||||
|
||||
/** Descriptor handler callback */
|
||||
typedef BOOL (TFnGetDescriptor)(U16 wTypeIndex, U16 wLangID, int *piLen, U8 **ppbData);
|
||||
|
||||
/** Default standard request handler */
|
||||
BOOL USBHandleStandardRequest(TSetupPacket *pSetup, int *piLen, U8 **ppbData);
|
||||
|
||||
/** Default EP0 handler */
|
||||
void USBHandleControlTransfer(U8 bEP, U8 bEPStat);
|
||||
|
||||
/** Descriptor handling */
|
||||
void USBRegisterDescriptors(const U8 *pabDescriptors);
|
||||
BOOL USBGetDescriptor(U16 wTypeIndex, U16 wLangID, int *piLen, U8 **ppbData);
|
234
VCOM_lib/usbcontrol.c
Normal file
234
VCOM_lib/usbcontrol.c
Normal file
@ -0,0 +1,234 @@
|
||||
/*
|
||||
LPCUSB, an USB device driver for LPC microcontrollers
|
||||
Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
|
||||
|
||||
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. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
|
||||
/** @file
|
||||
Control transfer handler.
|
||||
|
||||
This module handles control transfers and is normally installed on the
|
||||
endpoint 0 callback.
|
||||
|
||||
Control transfers can be of the following type:
|
||||
0 Standard;
|
||||
1 Class;
|
||||
2 Vendor;
|
||||
3 Reserved.
|
||||
|
||||
A callback can be installed for each of these control transfers using
|
||||
USBRegisterRequestHandler.
|
||||
When an OUT request arrives, data is collected in the data store provided
|
||||
with the USBRegisterRequestHandler call. When the transfer is done, the
|
||||
callback is called.
|
||||
When an IN request arrives, the callback is called immediately to either
|
||||
put the control transfer data in the data store, or to get a pointer to
|
||||
control transfer data. The data is then packetised and sent to the host.
|
||||
*/
|
||||
|
||||
// CodeRed - include the LPCUSB type.h file rather than NXP one directly
|
||||
//#include "type.h"
|
||||
#include "lpcusb_type.h"
|
||||
|
||||
#include "usbdebug.h"
|
||||
|
||||
#include "usbstruct.h"
|
||||
#include "usbapi.h"
|
||||
|
||||
|
||||
|
||||
#define MAX_CONTROL_SIZE 128 /**< maximum total size of control transfer data */
|
||||
#define MAX_REQ_HANDLERS 4 /**< standard, class, vendor, reserved */
|
||||
|
||||
static TSetupPacket Setup; /**< setup packet */
|
||||
|
||||
static U8 *pbData; /**< pointer to data buffer */
|
||||
static int iResidue; /**< remaining bytes in buffer */
|
||||
static int iLen; /**< total length of control transfer */
|
||||
|
||||
/** Array of installed request handler callbacks */
|
||||
static TFnHandleRequest *apfnReqHandlers[4] = {NULL, NULL, NULL, NULL};
|
||||
/** Array of installed request data pointers */
|
||||
static U8 *apbDataStore[4] = {NULL, NULL, NULL, NULL};
|
||||
|
||||
/**
|
||||
Local function to handle a request by calling one of the installed
|
||||
request handlers.
|
||||
|
||||
In case of data going from host to device, the data is at *ppbData.
|
||||
In case of data going from device to host, the handler can either
|
||||
choose to write its data at *ppbData or update the data pointer.
|
||||
|
||||
@param [in] pSetup The setup packet
|
||||
@param [in,out] *piLen Pointer to data length
|
||||
@param [in,out] ppbData Data buffer.
|
||||
|
||||
@return TRUE if the request was handles successfully
|
||||
*/
|
||||
static BOOL _HandleRequest(TSetupPacket *pSetup, int *piLen, U8 **ppbData)
|
||||
{
|
||||
TFnHandleRequest *pfnHandler;
|
||||
int iType;
|
||||
|
||||
iType = REQTYPE_GET_TYPE(pSetup->bmRequestType);
|
||||
pfnHandler = apfnReqHandlers[iType];
|
||||
if (pfnHandler == NULL) {
|
||||
DBG("No handler for reqtype %d\n", iType);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return pfnHandler(pSetup, piLen, ppbData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Local function to stall the control endpoint
|
||||
|
||||
@param [in] bEPStat Endpoint status
|
||||
*/
|
||||
static void StallControlPipe(U8 bEPStat)
|
||||
{
|
||||
U8 *pb;
|
||||
int i;
|
||||
bEPStat = bEPStat;
|
||||
USBHwEPStall(0x80, TRUE);
|
||||
|
||||
// dump setup packet
|
||||
DBG("STALL on [");
|
||||
pb = (U8 *)&Setup;
|
||||
for (i = 0; i < 8; i++) {
|
||||
DBG(" %02x", *pb++);
|
||||
}
|
||||
DBG("] stat=%x\n", bEPStat);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Sends next chunk of data (possibly 0 bytes) to host
|
||||
*/
|
||||
static void DataIn(void)
|
||||
{
|
||||
int iChunk;
|
||||
|
||||
iChunk = MIN(MAX_PACKET_SIZE0, iResidue);
|
||||
USBHwEPWrite(0x80, pbData, iChunk);
|
||||
pbData += iChunk;
|
||||
iResidue -= iChunk;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles IN/OUT transfers on EP0
|
||||
*
|
||||
* @param [in] bEP Endpoint address
|
||||
* @param [in] bEPStat Endpoint status
|
||||
*/
|
||||
void USBHandleControlTransfer(U8 bEP, U8 bEPStat)
|
||||
{
|
||||
int iChunk, iType;
|
||||
|
||||
if (bEP == 0x00) {
|
||||
// OUT transfer
|
||||
if (bEPStat & EP_STATUS_SETUP) {
|
||||
// setup packet, reset request message state machine
|
||||
USBHwEPRead(0x00, (U8 *)&Setup, sizeof(Setup));
|
||||
DBG("S%x", Setup.bRequest);
|
||||
|
||||
// defaults for data pointer and residue
|
||||
iType = REQTYPE_GET_TYPE(Setup.bmRequestType);
|
||||
pbData = apbDataStore[iType];
|
||||
iResidue = Setup.wLength;
|
||||
iLen = Setup.wLength;
|
||||
|
||||
if ((Setup.wLength == 0) ||
|
||||
(REQTYPE_GET_DIR(Setup.bmRequestType) == REQTYPE_DIR_TO_HOST)) {
|
||||
// ask installed handler to process request
|
||||
if (!_HandleRequest(&Setup, &iLen, &pbData)) {
|
||||
DBG("_HandleRequest1 failed\n");
|
||||
StallControlPipe(bEPStat);
|
||||
return;
|
||||
}
|
||||
// send smallest of requested and offered length
|
||||
iResidue = MIN(iLen, Setup.wLength);
|
||||
// send first part (possibly a zero-length status message)
|
||||
DataIn();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (iResidue > 0) {
|
||||
// store data
|
||||
iChunk = USBHwEPRead(0x00, pbData, iResidue);
|
||||
if (iChunk < 0) {
|
||||
StallControlPipe(bEPStat);
|
||||
return;
|
||||
}
|
||||
pbData += iChunk;
|
||||
iResidue -= iChunk;
|
||||
if (iResidue == 0) {
|
||||
// received all, send data to handler
|
||||
iType = REQTYPE_GET_TYPE(Setup.bmRequestType);
|
||||
pbData = apbDataStore[iType];
|
||||
if (!_HandleRequest(&Setup, &iLen, &pbData)) {
|
||||
DBG("_HandleRequest2 failed\n");
|
||||
StallControlPipe(bEPStat);
|
||||
return;
|
||||
}
|
||||
// send status to host
|
||||
DataIn();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// absorb zero-length status message
|
||||
iChunk = USBHwEPRead(0x00, NULL, 0);
|
||||
DBG(iChunk > 0 ? "?" : "");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (bEP == 0x80) {
|
||||
// IN transfer
|
||||
// send more data if available (possibly a 0-length packet)
|
||||
DataIn();
|
||||
}
|
||||
else {
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Registers a callback for handling requests
|
||||
|
||||
@param [in] iType Type of request, e.g. REQTYPE_TYPE_STANDARD
|
||||
@param [in] *pfnHandler Callback function pointer
|
||||
@param [in] *pbDataStore Data storage area for this type of request
|
||||
*/
|
||||
void USBRegisterRequestHandler(int iType, TFnHandleRequest *pfnHandler, U8 *pbDataStore)
|
||||
{
|
||||
ASSERT(iType >= 0);
|
||||
ASSERT(iType < 4);
|
||||
apfnReqHandlers[iType] = pfnHandler;
|
||||
apbDataStore[iType] = pbDataStore;
|
||||
}
|
||||
|
44
VCOM_lib/usbdebug.h
Normal file
44
VCOM_lib/usbdebug.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
LPCUSB, an USB device driver for LPC microcontrollers
|
||||
Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
|
||||
|
||||
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. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
// CodeRed - comment out this printf, as will use real one from stdio.h
|
||||
// to implement output via semihosting
|
||||
|
||||
//int printf(const char *format, ...);
|
||||
# include <stdio.h>
|
||||
|
||||
// CodeRed - added DEBUG_MESSAGES, so still get output for Release builds
|
||||
//#define DEBUG_MESSAGES 1
|
||||
//#ifdef DEBUG
|
||||
#ifdef DEBUG_MESSAGES
|
||||
#define DBG printf
|
||||
#define ASSERT(x) if(!(x)){DBG("\nAssertion '%s' failed in %s:%s#%d!\n",#x,__FILE__,__FUNCTION__,__LINE__);while(1);}
|
||||
#else
|
||||
#define DBG(x ...)
|
||||
#define ASSERT(x)
|
||||
#endif
|
||||
|
627
VCOM_lib/usbhw_lpc.c
Normal file
627
VCOM_lib/usbhw_lpc.c
Normal file
@ -0,0 +1,627 @@
|
||||
/*
|
||||
LPCUSB, an USB device driver for LPC microcontrollers
|
||||
Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
|
||||
|
||||
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. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
|
||||
/** @file
|
||||
USB hardware layer
|
||||
*/
|
||||
|
||||
// CodeRed - include the LPCUSB type.h file rather than NXP one directly
|
||||
//#include "type.h"
|
||||
#include "lpcusb_type.h"
|
||||
|
||||
#include "usbdebug.h"
|
||||
#include "usbhw_lpc.h"
|
||||
#include "usbapi.h"
|
||||
// Configure LED pin functions
|
||||
//
|
||||
// LED pin functions
|
||||
//
|
||||
// Function Pin Port Bits Pin Select Register
|
||||
// ------------------- --- ----- ---- -------------------
|
||||
// P2.0 GPIO Port 2.0 xx P2.0 1:0 PINSEL4
|
||||
// P2.1 GPIO Port 2.1 xx P2.1 3:2 PINSEL4
|
||||
// P2.2 GPIO Port 2.2 xx P2.2 5:4 PINSEL4
|
||||
// P2.3 GPIO Port 2.3 xx P2.3 7:6 PINSEL4
|
||||
// P2.4 GPIO Port 2.4 xx P2.4 9:8 PINSEL4
|
||||
// P2.5 GPIO Port 2.5 xx P2.5 11:10 PINSEL4
|
||||
// P2.6 GPIO Port 2.6 xx P2.6 13:12 PINSEL4
|
||||
// P2.7 GPIO Port 2.7 xx P2.7 15:14 PINSEL4
|
||||
//
|
||||
// OFF - LED state 0
|
||||
// ON - LED state 1
|
||||
//
|
||||
// '*' as GPIO
|
||||
|
||||
#define NO_LEDS 8
|
||||
|
||||
#define LED_0 (1 << 0)
|
||||
#define LED_1 (1 << 1)
|
||||
#define LED_2 (1 << 2)
|
||||
#define LED_3 (1 << 3)
|
||||
#define LED_4 (1 << 4)
|
||||
#define LED_5 (1 << 5)
|
||||
#define LED_6 (1 << 6)
|
||||
#define LED_7 (1 << 7)
|
||||
|
||||
#ifdef DEBUG
|
||||
// comment out the following line if you don't want to use debug LEDs
|
||||
//#define DEBUG_LED
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_LED
|
||||
#define DEBUG_LED_ON(x) FIO2SET = (1 << x);
|
||||
#define DEBUG_LED_OFF(x) FIO2CLR = (1 << x);
|
||||
#define DEBUG_LED_INIT(x) PINSEL2 &= ~(0x3 << (2*x)); FIO2DIR |= (1 << x); DEBUG_LED_OFF(x);
|
||||
#else
|
||||
#define DEBUG_LED_INIT(x) /**< LED initialisation macro */
|
||||
#define DEBUG_LED_ON(x) /**< turn LED on */
|
||||
#define DEBUG_LED_OFF(x) /**< turn LED off */
|
||||
#endif
|
||||
|
||||
/** Installed device interrupt handler */
|
||||
static TFnDevIntHandler *_pfnDevIntHandler = NULL;
|
||||
/** Installed endpoint interrupt handlers */
|
||||
static TFnEPIntHandler *_apfnEPIntHandlers[16];
|
||||
/** Installed frame interrupt handlers */
|
||||
static TFnFrameHandler *_pfnFrameHandler = NULL;
|
||||
|
||||
/** convert from endpoint address to endpoint index */
|
||||
#define EP2IDX(bEP) ((((bEP)&0xF)<<1)|(((bEP)&0x80)>>7))
|
||||
/** convert from endpoint index to endpoint address */
|
||||
#define IDX2EP(idx) ((((idx)<<7)&0x80)|(((idx)>>1)&0xF))
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Local function to wait for a device interrupt (and clear it)
|
||||
|
||||
@param [in] dwIntr Bitmask of interrupts to wait for
|
||||
*/
|
||||
static void Wait4DevInt(U32 dwIntr)
|
||||
{
|
||||
// wait for specific interrupt
|
||||
while ((LPC_USB->USBDevIntSt & dwIntr) != dwIntr);
|
||||
// clear the interrupt bits
|
||||
LPC_USB->USBDevIntClr = dwIntr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Local function to send a command to the USB protocol engine
|
||||
|
||||
@param [in] bCmd Command to send
|
||||
*/
|
||||
static void USBHwCmd(U8 bCmd)
|
||||
{
|
||||
// clear CDFULL/CCEMTY
|
||||
LPC_USB->USBDevIntClr = CDFULL | CCEMTY;
|
||||
// write command code
|
||||
LPC_USB->USBCmdCode = 0x00000500 | (bCmd << 16);
|
||||
Wait4DevInt(CCEMTY);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Local function to send a command + data to the USB protocol engine
|
||||
|
||||
@param [in] bCmd Command to send
|
||||
@param [in] bData Data to send
|
||||
*/
|
||||
static void USBHwCmdWrite(U8 bCmd, U16 bData)
|
||||
{
|
||||
// write command code
|
||||
USBHwCmd(bCmd);
|
||||
|
||||
// write command data
|
||||
LPC_USB->USBCmdCode = 0x00000100 | (bData << 16);
|
||||
Wait4DevInt(CCEMTY);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Local function to send a command to the USB protocol engine and read data
|
||||
|
||||
@param [in] bCmd Command to send
|
||||
|
||||
@return the data
|
||||
*/
|
||||
static U8 USBHwCmdRead(U8 bCmd)
|
||||
{
|
||||
// write command code
|
||||
USBHwCmd(bCmd);
|
||||
|
||||
// get data
|
||||
LPC_USB->USBCmdCode = 0x00000200 | (bCmd << 16);
|
||||
Wait4DevInt(CDFULL);
|
||||
return LPC_USB->USBCmdData;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
'Realizes' an endpoint, meaning that buffer space is reserved for
|
||||
it. An endpoint needs to be realised before it can be used.
|
||||
|
||||
From experiments, it appears that a USB reset causes USBReEP to
|
||||
re-initialise to 3 (= just the control endpoints).
|
||||
However, a USB bus reset does not disturb the USBMaxPSize settings.
|
||||
|
||||
@param [in] idx Endpoint index
|
||||
@param [in] wMaxPSize Maximum packet size for this endpoint
|
||||
*/
|
||||
static void USBHwEPRealize(int idx, U16 wMaxPSize)
|
||||
{
|
||||
LPC_USB->USBReEP |= (1 << idx);
|
||||
LPC_USB->USBEpInd = idx;
|
||||
LPC_USB->USBMaxPSize = wMaxPSize;
|
||||
Wait4DevInt(EP_RLZED);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Enables or disables an endpoint
|
||||
|
||||
@param [in] idx Endpoint index
|
||||
@param [in] fEnable TRUE to enable, FALSE to disable
|
||||
*/
|
||||
static void USBHwEPEnable(int idx, BOOL fEnable)
|
||||
{
|
||||
USBHwCmdWrite(CMD_EP_SET_STATUS | idx, fEnable ? 0 : EP_DA);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Configures an endpoint and enables it
|
||||
|
||||
@param [in] bEP Endpoint number
|
||||
@param [in] wMaxPacketSize Maximum packet size for this EP
|
||||
*/
|
||||
void USBHwEPConfig(U8 bEP, U16 wMaxPacketSize)
|
||||
{
|
||||
int idx;
|
||||
|
||||
idx = EP2IDX(bEP);
|
||||
|
||||
// realise EP
|
||||
USBHwEPRealize(idx, wMaxPacketSize);
|
||||
|
||||
// enable EP
|
||||
USBHwEPEnable(idx, TRUE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Registers an endpoint event callback
|
||||
|
||||
@param [in] bEP Endpoint number
|
||||
@param [in] pfnHandler Callback function
|
||||
*/
|
||||
void USBHwRegisterEPIntHandler(U8 bEP, TFnEPIntHandler *pfnHandler)
|
||||
{
|
||||
int idx;
|
||||
|
||||
idx = EP2IDX(bEP);
|
||||
|
||||
ASSERT(idx<32);
|
||||
|
||||
/* add handler to list of EP handlers */
|
||||
_apfnEPIntHandlers[idx / 2] = pfnHandler;
|
||||
|
||||
/* enable EP interrupt */
|
||||
LPC_USB->USBEpIntEn |= (1 << idx);
|
||||
LPC_USB->USBDevIntEn |= EP_SLOW;
|
||||
|
||||
DBG("Registered handler for EP 0x%x\n", bEP);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Registers an device status callback
|
||||
|
||||
@param [in] pfnHandler Callback function
|
||||
*/
|
||||
void USBHwRegisterDevIntHandler(TFnDevIntHandler *pfnHandler)
|
||||
{
|
||||
_pfnDevIntHandler = pfnHandler;
|
||||
|
||||
// enable device interrupt
|
||||
LPC_USB->USBDevIntEn |= DEV_STAT;
|
||||
|
||||
DBG("Registered handler for device status\n");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Registers the frame callback
|
||||
|
||||
@param [in] pfnHandler Callback function
|
||||
*/
|
||||
void USBHwRegisterFrameHandler(TFnFrameHandler *pfnHandler)
|
||||
{
|
||||
_pfnFrameHandler = pfnHandler;
|
||||
|
||||
// enable device interrupt
|
||||
LPC_USB->USBDevIntEn |= FRAME;
|
||||
|
||||
DBG("Registered handler for frame\n");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Sets the USB address.
|
||||
|
||||
@param [in] bAddr Device address to set
|
||||
*/
|
||||
void USBHwSetAddress(U8 bAddr)
|
||||
{
|
||||
USBHwCmdWrite(CMD_DEV_SET_ADDRESS, DEV_EN | bAddr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Connects or disconnects from the USB bus
|
||||
|
||||
@param [in] fConnect If TRUE, connect, otherwise disconnect
|
||||
*/
|
||||
void USBHwConnect(BOOL fConnect)
|
||||
{
|
||||
USBHwCmdWrite(CMD_DEV_STATUS, fConnect ? CON : 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Enables interrupt on NAK condition
|
||||
|
||||
For IN endpoints a NAK is generated when the host wants to read data
|
||||
from the device, but none is available in the endpoint buffer.
|
||||
For OUT endpoints a NAK is generated when the host wants to write data
|
||||
to the device, but the endpoint buffer is still full.
|
||||
|
||||
The endpoint interrupt handlers can distinguish regular (ACK) interrupts
|
||||
from NAK interrupt by checking the bits in their bEPStatus argument.
|
||||
|
||||
@param [in] bIntBits Bitmap indicating which NAK interrupts to enable
|
||||
*/
|
||||
void USBHwNakIntEnable(U8 bIntBits)
|
||||
{
|
||||
USBHwCmdWrite(CMD_DEV_SET_MODE, bIntBits);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Gets the status from a specific endpoint.
|
||||
|
||||
@param [in] bEP Endpoint number
|
||||
@return Endpoint status byte (containing EP_STATUS_xxx bits)
|
||||
*/
|
||||
U8 USBHwEPGetStatus(U8 bEP)
|
||||
{
|
||||
int idx = EP2IDX(bEP);
|
||||
|
||||
return USBHwCmdRead(CMD_EP_SELECT | idx);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Sets the stalled property of an endpoint
|
||||
|
||||
@param [in] bEP Endpoint number
|
||||
@param [in] fStall TRUE to stall, FALSE to unstall
|
||||
*/
|
||||
void USBHwEPStall(U8 bEP, BOOL fStall)
|
||||
{
|
||||
int idx = EP2IDX(bEP);
|
||||
|
||||
USBHwCmdWrite(CMD_EP_SET_STATUS | idx, fStall ? EP_ST : 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Writes data to an endpoint buffer
|
||||
|
||||
@param [in] bEP Endpoint number
|
||||
@param [in] pbBuf Endpoint data
|
||||
@param [in] iLen Number of bytes to write
|
||||
|
||||
@return TRUE if the data was successfully written or <0 in case of error.
|
||||
*/
|
||||
int USBHwEPWrite(U8 bEP, U8 *pbBuf, int iLen)
|
||||
{
|
||||
int idx;
|
||||
|
||||
idx = EP2IDX(bEP);
|
||||
|
||||
// set write enable for specific endpoint
|
||||
LPC_USB->USBCtrl = WR_EN | ((bEP & 0xF) << 2);
|
||||
|
||||
// set packet length
|
||||
LPC_USB->USBTxPLen = iLen;
|
||||
|
||||
// write data
|
||||
while (LPC_USB->USBCtrl & WR_EN) {
|
||||
LPC_USB->USBTxData = (pbBuf[3] << 24) | (pbBuf[2] << 16) | (pbBuf[1] << 8) | pbBuf[0];
|
||||
pbBuf += 4;
|
||||
}
|
||||
|
||||
// select endpoint and validate buffer
|
||||
USBHwCmd(CMD_EP_SELECT | idx);
|
||||
USBHwCmd(CMD_EP_VALIDATE_BUFFER);
|
||||
|
||||
return iLen;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Reads data from an endpoint buffer
|
||||
|
||||
@param [in] bEP Endpoint number
|
||||
@param [in] pbBuf Endpoint data
|
||||
@param [in] iMaxLen Maximum number of bytes to read
|
||||
|
||||
@return the number of bytes available in the EP (possibly more than iMaxLen),
|
||||
or <0 in case of error.
|
||||
*/
|
||||
int USBHwEPRead(U8 bEP, U8 *pbBuf, int iMaxLen)
|
||||
{
|
||||
int i, idx;
|
||||
U32 dwData, dwLen;
|
||||
|
||||
idx = EP2IDX(bEP);
|
||||
|
||||
// set read enable bit for specific endpoint
|
||||
LPC_USB->USBCtrl = RD_EN | ((bEP & 0xF) << 2);
|
||||
|
||||
// wait for PKT_RDY
|
||||
do {
|
||||
dwLen = LPC_USB->USBRxPLen;
|
||||
} while ((dwLen & PKT_RDY) == 0);
|
||||
|
||||
// packet valid?
|
||||
if ((dwLen & DV) == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// get length
|
||||
dwLen &= PKT_LNGTH_MASK;
|
||||
|
||||
// get data
|
||||
dwData = 0;
|
||||
for (i = 0; i < (int)dwLen; i++) {
|
||||
if ((i % 4) == 0) {
|
||||
dwData = LPC_USB->USBRxData;
|
||||
}
|
||||
if ((pbBuf != NULL) && (i < iMaxLen)) {
|
||||
pbBuf[i] = dwData & 0xFF;
|
||||
}
|
||||
dwData >>= 8;
|
||||
}
|
||||
|
||||
// make sure RD_EN is clear
|
||||
LPC_USB->USBCtrl = 0;
|
||||
|
||||
// select endpoint and clear buffer
|
||||
USBHwCmd(CMD_EP_SELECT | idx);
|
||||
USBHwCmd(CMD_EP_CLEAR_BUFFER);
|
||||
|
||||
return dwLen;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Sets the 'configured' state.
|
||||
|
||||
All registered endpoints are 'realised' and enabled, and the
|
||||
'configured' bit is set in the device status register.
|
||||
|
||||
@param [in] fConfigured If TRUE, configure device, else unconfigure
|
||||
*/
|
||||
void USBHwConfigDevice(BOOL fConfigured)
|
||||
{
|
||||
// set configured bit
|
||||
USBHwCmdWrite(CMD_DEV_CONFIG, fConfigured ? CONF_DEVICE : 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
USB interrupt handler
|
||||
|
||||
@todo Get all 11 bits of frame number instead of just 8
|
||||
|
||||
Endpoint interrupts are mapped to the slow interrupt
|
||||
*/
|
||||
void USBHwISR(void)
|
||||
{
|
||||
U32 dwStatus;
|
||||
U32 dwIntBit;
|
||||
U8 bEPStat, bDevStat, bStat;
|
||||
int i;
|
||||
U16 wFrame;
|
||||
|
||||
// LED9 monitors total time in interrupt routine
|
||||
DEBUG_LED_ON(6);
|
||||
|
||||
// handle device interrupts
|
||||
dwStatus = LPC_USB->USBDevIntSt;
|
||||
|
||||
// frame interrupt
|
||||
if (dwStatus & FRAME) {
|
||||
// clear int
|
||||
LPC_USB->USBDevIntClr = FRAME;
|
||||
// call handler
|
||||
if (_pfnFrameHandler != NULL) {
|
||||
wFrame = USBHwCmdRead(CMD_DEV_READ_CUR_FRAME_NR);
|
||||
_pfnFrameHandler(wFrame);
|
||||
}
|
||||
}
|
||||
|
||||
// device status interrupt
|
||||
if (dwStatus & DEV_STAT) {
|
||||
/* Clear DEV_STAT interrupt before reading DEV_STAT register.
|
||||
This prevents corrupted device status reads, see
|
||||
LPC2148 User manual revision 2, 25 july 2006.
|
||||
*/
|
||||
LPC_USB->USBDevIntClr = DEV_STAT;
|
||||
bDevStat = USBHwCmdRead(CMD_DEV_STATUS);
|
||||
if (bDevStat & (CON_CH | SUS_CH | RST)) {
|
||||
// convert device status into something HW independent
|
||||
bStat = ((bDevStat & CON) ? DEV_STATUS_CONNECT : 0) |
|
||||
((bDevStat & SUS) ? DEV_STATUS_SUSPEND : 0) |
|
||||
((bDevStat & RST) ? DEV_STATUS_RESET : 0);
|
||||
// call handler
|
||||
if (_pfnDevIntHandler != NULL) {
|
||||
DEBUG_LED_ON(5);
|
||||
_pfnDevIntHandler(bStat);
|
||||
DEBUG_LED_OFF(5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// endpoint interrupt
|
||||
if (dwStatus & EP_SLOW) {
|
||||
// clear EP_SLOW
|
||||
LPC_USB->USBDevIntClr = EP_SLOW;
|
||||
// check all endpoints
|
||||
for (i = 0; i < 32; i++) {
|
||||
dwIntBit = (1 << i);
|
||||
if (LPC_USB->USBEpIntSt & dwIntBit) {
|
||||
// clear int (and retrieve status)
|
||||
LPC_USB->USBEpIntClr = dwIntBit;
|
||||
Wait4DevInt(CDFULL);
|
||||
bEPStat = LPC_USB->USBCmdData;
|
||||
// convert EP pipe stat into something HW independent
|
||||
bStat = ((bEPStat & EPSTAT_FE) ? EP_STATUS_DATA : 0) |
|
||||
((bEPStat & EPSTAT_ST) ? EP_STATUS_STALLED : 0) |
|
||||
((bEPStat & EPSTAT_STP) ? EP_STATUS_SETUP : 0) |
|
||||
((bEPStat & EPSTAT_EPN) ? EP_STATUS_NACKED : 0) |
|
||||
((bEPStat & EPSTAT_PO) ? EP_STATUS_ERROR : 0);
|
||||
// call handler
|
||||
if (_apfnEPIntHandlers[i / 2] != NULL) {
|
||||
DEBUG_LED_ON(7);
|
||||
_apfnEPIntHandlers[i / 2](IDX2EP(i), bStat);
|
||||
DEBUG_LED_OFF(7);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_LED_OFF(6);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Initialises the USB hardware
|
||||
|
||||
This function assumes that the hardware is connected as shown in
|
||||
section 10.1 of the LPC2148 data sheet:
|
||||
* P0.31 controls a switch to connect a 1.5k pull-up to D+ if low.
|
||||
* P0.23 is connected to USB VCC.
|
||||
|
||||
Embedded artists board: make sure to disconnect P0.23 LED as it
|
||||
acts as a pull-up and so prevents detection of USB disconnect.
|
||||
|
||||
@return TRUE if the hardware was successfully initialised
|
||||
*/
|
||||
BOOL USBHwInit(void)
|
||||
{
|
||||
/* CodeRed - comment out original code
|
||||
*
|
||||
// configure P0.23 for Vbus sense
|
||||
PINSEL1 = (PINSEL1 & ~(3 << 14)) | (1 << 14); // P0.23
|
||||
// configure P0.31 for CONNECT
|
||||
PINSEL1 = (PINSEL1 & ~(3 << 30)) | (2 << 30); // P0.31
|
||||
*/
|
||||
|
||||
// CodeRed - set up USB pins
|
||||
|
||||
// P2.9 -> USB_CONNECT
|
||||
LPC_PINCON->PINSEL4 &= ~0x000C0000;
|
||||
LPC_PINCON->PINSEL4 |= 0x00040000;
|
||||
|
||||
// P1.18 -> USB_UP_LED
|
||||
// P1.30 -> VBUS
|
||||
LPC_PINCON->PINSEL3 &= ~0x30000030;
|
||||
LPC_PINCON->PINSEL3 |= 0x20000010;
|
||||
|
||||
// P0.29 -> USB_D+
|
||||
// P0.30 -> USB_D-
|
||||
LPC_PINCON->PINSEL1 &= ~0x3C000000;
|
||||
LPC_PINCON->PINSEL1 |= 0x14000000;
|
||||
|
||||
|
||||
// enable PUSB
|
||||
LPC_SC->PCONP |= (1 << 31);
|
||||
|
||||
/* CodeRed - Comment out original PLL code
|
||||
* PLL now set up by NXP code in target.c within example projects
|
||||
*
|
||||
// initialise PLL
|
||||
PLL1CON = 1; // enable PLL
|
||||
PLL1CFG = (1 << 5) | 3; // P = 2, M = 4
|
||||
PLL1FEED = 0xAA;
|
||||
PLL1FEED = 0x55;
|
||||
while ((PLL1STAT & (1 << 10)) == 0);
|
||||
|
||||
PLL1CON = 3; // enable and connect
|
||||
PLL1FEED = 0xAA;
|
||||
PLL1FEED = 0x55;
|
||||
|
||||
*/
|
||||
|
||||
|
||||
// AWB added USB clock enable
|
||||
// These are actually the USBClkCtrl and USBClkSt registers
|
||||
// OTG_CLK_CTRL = 0x12; /* Dev clock, AHB clock enable */
|
||||
// while ((OTG_CLK_STAT & 0x12) != 0x12);
|
||||
|
||||
LPC_USB->USBClkCtrl = 0x1A; /* Dev clock, AHB clock enable */
|
||||
while ((LPC_USB->USBClkSt & 0x1A) != 0x1A);
|
||||
|
||||
|
||||
// disable/clear all interrupts for now
|
||||
LPC_USB->USBDevIntEn = 0;
|
||||
LPC_USB->USBDevIntClr = 0xFFFFFFFF;
|
||||
LPC_USB->USBDevIntPri = 0;
|
||||
|
||||
LPC_USB->USBEpIntEn = 0;
|
||||
LPC_USB->USBEpIntClr = 0xFFFFFFFF;
|
||||
LPC_USB->USBEpIntPri = 0;
|
||||
|
||||
// by default, only ACKs generate interrupts
|
||||
USBHwNakIntEnable(0);
|
||||
|
||||
// CodeRed - commented out LEDs - not used by current port
|
||||
// init debug leds
|
||||
/*
|
||||
DEBUG_LED_INIT(5);
|
||||
DEBUG_LED_INIT(6);
|
||||
DEBUG_LED_INIT(7);
|
||||
*/
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
148
VCOM_lib/usbhw_lpc.h
Normal file
148
VCOM_lib/usbhw_lpc.h
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
LPCUSB, an USB device driver for LPC microcontrollers
|
||||
Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
|
||||
|
||||
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. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
Hardware definitions for the LPC176x USB controller
|
||||
|
||||
These are private to the usbhw module
|
||||
*/
|
||||
|
||||
// CodeRed - pull in defines from NXP header file
|
||||
#include "LPC17xx.h"
|
||||
|
||||
|
||||
// CodeRed - these registers have been renamed on LPC176x
|
||||
#define USBReEP USBReEp
|
||||
#define OTG_CLK_CTRL USBClkCtrl
|
||||
#define OTG_CLK_STAT USBClkSt
|
||||
|
||||
/* USBIntSt bits */
|
||||
#define USB_INT_REQ_LP (1<<0)
|
||||
#define USB_INT_REQ_HP (1<<1)
|
||||
#define USB_INT_REQ_DMA (1<<2)
|
||||
#define USB_need_clock (1<<8)
|
||||
#define EN_USB_BITS (1<<31)
|
||||
|
||||
/* USBDevInt... bits */
|
||||
#define FRAME (1<<0)
|
||||
#define EP_FAST (1<<1)
|
||||
#define EP_SLOW (1<<2)
|
||||
#define DEV_STAT (1<<3)
|
||||
#define CCEMTY (1<<4)
|
||||
#define CDFULL (1<<5)
|
||||
#define RxENDPKT (1<<6)
|
||||
#define TxENDPKT (1<<7)
|
||||
#define EP_RLZED (1<<8)
|
||||
#define ERR_INT (1<<9)
|
||||
|
||||
/* USBRxPLen bits */
|
||||
#define PKT_LNGTH (1<<0)
|
||||
#define PKT_LNGTH_MASK 0x3FF
|
||||
#define DV (1<<10)
|
||||
#define PKT_RDY (1<<11)
|
||||
|
||||
/* USBCtrl bits */
|
||||
#define RD_EN (1<<0)
|
||||
#define WR_EN (1<<1)
|
||||
#define LOG_ENDPOINT (1<<2)
|
||||
|
||||
/* protocol engine command codes */
|
||||
/* device commands */
|
||||
#define CMD_DEV_SET_ADDRESS 0xD0
|
||||
#define CMD_DEV_CONFIG 0xD8
|
||||
#define CMD_DEV_SET_MODE 0xF3
|
||||
#define CMD_DEV_READ_CUR_FRAME_NR 0xF5
|
||||
#define CMD_DEV_READ_TEST_REG 0xFD
|
||||
#define CMD_DEV_STATUS 0xFE /* read/write */
|
||||
#define CMD_DEV_GET_ERROR_CODE 0xFF
|
||||
#define CMD_DEV_READ_ERROR_STATUS 0xFB
|
||||
/* endpoint commands */
|
||||
#define CMD_EP_SELECT 0x00
|
||||
#define CMD_EP_SELECT_CLEAR 0x40
|
||||
#define CMD_EP_SET_STATUS 0x40
|
||||
#define CMD_EP_CLEAR_BUFFER 0xF2
|
||||
#define CMD_EP_VALIDATE_BUFFER 0xFA
|
||||
|
||||
/* set address command */
|
||||
#define DEV_ADDR (1<<0)
|
||||
#define DEV_EN (1<<7)
|
||||
|
||||
/* configure device command */
|
||||
#define CONF_DEVICE (1<<0)
|
||||
|
||||
/* set mode command */
|
||||
#define AP_CLK (1<<0)
|
||||
#define INAK_CI (1<<1)
|
||||
#define INAK_CO (1<<2)
|
||||
#define INAK_II (1<<3)
|
||||
#define INAK_IO (1<<4)
|
||||
#define INAK_BI (1<<5)
|
||||
#define INAK_BO (1<<6)
|
||||
|
||||
/* set get device status command */
|
||||
#define CON (1<<0)
|
||||
#define CON_CH (1<<1)
|
||||
#define SUS (1<<2)
|
||||
#define SUS_CH (1<<3)
|
||||
#define RST (1<<4)
|
||||
|
||||
/* get error code command */
|
||||
// ...
|
||||
|
||||
/* Select Endpoint command read bits */
|
||||
#define EPSTAT_FE (1<<0)
|
||||
#define EPSTAT_ST (1<<1)
|
||||
#define EPSTAT_STP (1<<2)
|
||||
#define EPSTAT_PO (1<<3)
|
||||
#define EPSTAT_EPN (1<<4)
|
||||
#define EPSTAT_B1FULL (1<<5)
|
||||
#define EPSTAT_B2FULL (1<<6)
|
||||
|
||||
/* CMD_EP_SET_STATUS command */
|
||||
#define EP_ST (1<<0)
|
||||
#define EP_DA (1<<5)
|
||||
#define EP_RF_MO (1<<6)
|
||||
#define EP_CND_ST (1<<7)
|
||||
|
||||
/* read error status command */
|
||||
#define PID_ERR (1<<0)
|
||||
#define UEPKT (1<<1)
|
||||
#define DCRC (1<<2)
|
||||
#define TIMEOUT (1<<3)
|
||||
#define EOP (1<<4)
|
||||
#define B_OVRN (1<<5)
|
||||
#define BTSTF (1<<6)
|
||||
#define TGL_ERR (1<<7)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
85
VCOM_lib/usbinit.c
Normal file
85
VCOM_lib/usbinit.c
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
LPCUSB, an USB device driver for LPC microcontrollers
|
||||
Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
|
||||
|
||||
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. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
|
||||
/** @file
|
||||
USB stack initialisation
|
||||
*/
|
||||
|
||||
// CodeRed - include the LPCUSB type.h file rather than NXP one directly
|
||||
//#include "type.h"
|
||||
#include "lpcusb_type.h"
|
||||
|
||||
#include "usbdebug.h"
|
||||
#include "usbapi.h"
|
||||
|
||||
|
||||
/** data storage area for standard requests */
|
||||
static U8 abStdReqData[8];
|
||||
|
||||
|
||||
/**
|
||||
USB reset handler
|
||||
|
||||
@param [in] bDevStatus Device status
|
||||
*/
|
||||
static void HandleUsbReset(U8 bDevStatus)
|
||||
{
|
||||
if (bDevStatus & DEV_STATUS_RESET) {
|
||||
DBG("\n!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Initialises the USB hardware and sets up the USB stack by
|
||||
installing default callbacks.
|
||||
|
||||
@return TRUE if initialisation was successful
|
||||
*/
|
||||
BOOL USBInit(void)
|
||||
{
|
||||
// init hardware
|
||||
USBHwInit();
|
||||
|
||||
// register bus reset handler
|
||||
USBHwRegisterDevIntHandler(HandleUsbReset);
|
||||
|
||||
// register control transfer handler on EP0
|
||||
USBHwRegisterEPIntHandler(0x00, USBHandleControlTransfer);
|
||||
USBHwRegisterEPIntHandler(0x80, USBHandleControlTransfer);
|
||||
|
||||
// setup control endpoints
|
||||
USBHwEPConfig(0x00, MAX_PACKET_SIZE0);
|
||||
USBHwEPConfig(0x80, MAX_PACKET_SIZE0);
|
||||
|
||||
// register standard request handler
|
||||
USBRegisterRequestHandler(REQTYPE_TYPE_STANDARD, USBHandleStandardRequest, abStdReqData);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
32
VCOM_lib/usbser.inf
Normal file
32
VCOM_lib/usbser.inf
Normal file
@ -0,0 +1,32 @@
|
||||
[Version]
|
||||
Signature="$Windows NT$"
|
||||
Class=Ports
|
||||
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
|
||||
Provider=%CodeRed%
|
||||
DriverVer=05/20/2010,1.0.0.0
|
||||
|
||||
[MANUFACTURER]
|
||||
%ProviderName%=DeviceList, NTx86, NTamd64
|
||||
|
||||
[DeviceList.NTx86]
|
||||
%RDB1768CDC%=DriverInstall,USB\VID_FFFF&PID_0005
|
||||
|
||||
[DeviceList.NTamd64]
|
||||
%RDB1768CDC%=DriverInstall,USB\VID_FFFF&PID_0005
|
||||
|
||||
[DriverInstall]
|
||||
include=mdmcpq.inf
|
||||
CopyFiles=FakeModemCopyFileSection
|
||||
AddReg=LowerFilterAddReg,SerialPropPageAddReg
|
||||
|
||||
[DriverInstall.Services]
|
||||
include = mdmcpq.inf
|
||||
AddService = usbser, 0x00000002, LowerFilter_Service_Inst
|
||||
|
||||
; This adds the serial port property tab to the device properties dialog
|
||||
[SerialPropPageAddReg]
|
||||
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
|
||||
|
||||
[Strings]
|
||||
ProviderName = "CDC Driver"
|
||||
RDB1768CDC = "LPCUSB Virtual Com Port
|
434
VCOM_lib/usbstdreq.c
Normal file
434
VCOM_lib/usbstdreq.c
Normal file
@ -0,0 +1,434 @@
|
||||
/*
|
||||
LPCUSB, an USB device driver for LPC microcontrollers
|
||||
Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
|
||||
|
||||
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. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
|
||||
/** @file
|
||||
Standard request handler.
|
||||
|
||||
This modules handles the 'chapter 9' processing, specifically the
|
||||
standard device requests in table 9-3 from the universal serial bus
|
||||
specification revision 2.0
|
||||
|
||||
Specific types of devices may specify additional requests (for example
|
||||
HID devices add a GET_DESCRIPTOR request for interfaces), but they
|
||||
will not be part of this module.
|
||||
|
||||
@todo some requests have to return a request error if device not configured:
|
||||
@todo GET_INTERFACE, GET_STATUS, SET_INTERFACE, SYNCH_FRAME
|
||||
@todo this applies to the following if endpoint != 0:
|
||||
@todo SET_FEATURE, GET_FEATURE
|
||||
*/
|
||||
|
||||
// CodeRed - include the LPCUSB type.h file rather than NXP one directly
|
||||
//#include "type.h"
|
||||
#include "lpcusb_type.h"
|
||||
|
||||
#include "usbdebug.h"
|
||||
#include "usbstruct.h"
|
||||
#include "usbapi.h"
|
||||
|
||||
#define MAX_DESC_HANDLERS 4 /**< device, interface, endpoint, other */
|
||||
|
||||
|
||||
/* general descriptor field offsets */
|
||||
#define DESC_bLength 0 /**< length offset */
|
||||
#define DESC_bDescriptorType 1 /**< descriptor type offset */
|
||||
|
||||
/* config descriptor field offsets */
|
||||
#define CONF_DESC_wTotalLength 2 /**< total length offset */
|
||||
#define CONF_DESC_bConfigurationValue 5 /**< configuration value offset */
|
||||
#define CONF_DESC_bmAttributes 7 /**< configuration characteristics */
|
||||
|
||||
/* interface descriptor field offsets */
|
||||
#define INTF_DESC_bAlternateSetting 3 /**< alternate setting offset */
|
||||
|
||||
/* endpoint descriptor field offsets */
|
||||
#define ENDP_DESC_bEndpointAddress 2 /**< endpoint address offset */
|
||||
#define ENDP_DESC_wMaxPacketSize 4 /**< maximum packet size offset */
|
||||
|
||||
|
||||
/** Currently selected configuration */
|
||||
static U8 bConfiguration = 0;
|
||||
/** Installed custom request handler */
|
||||
static TFnHandleRequest *pfnHandleCustomReq = NULL;
|
||||
/** Pointer to registered descriptors */
|
||||
static const U8 *pabDescrip = NULL;
|
||||
|
||||
|
||||
/**
|
||||
Registers a pointer to a descriptor block containing all descriptors
|
||||
for the device.
|
||||
|
||||
@param [in] pabDescriptors The descriptor byte array
|
||||
*/
|
||||
void USBRegisterDescriptors(const U8 *pabDescriptors)
|
||||
{
|
||||
pabDescrip = pabDescriptors;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Parses the list of installed USB descriptors and attempts to find
|
||||
the specified USB descriptor.
|
||||
|
||||
@param [in] wTypeIndex Type and index of the descriptor
|
||||
@param [in] wLangID Language ID of the descriptor (currently unused)
|
||||
@param [out] *piLen Descriptor length
|
||||
@param [out] *ppbData Descriptor data
|
||||
|
||||
@return TRUE if the descriptor was found, FALSE otherwise
|
||||
*/
|
||||
BOOL USBGetDescriptor(U16 wTypeIndex, U16 wLangID, int *piLen, U8 **ppbData)
|
||||
{
|
||||
U8 bType, bIndex;
|
||||
U8 *pab;
|
||||
int iCurIndex;
|
||||
wLangID = wLangID;
|
||||
ASSERT(pabDescrip != NULL);
|
||||
|
||||
bType = GET_DESC_TYPE(wTypeIndex);
|
||||
bIndex = GET_DESC_INDEX(wTypeIndex);
|
||||
|
||||
pab = (U8 *)pabDescrip;
|
||||
iCurIndex = 0;
|
||||
|
||||
while (pab[DESC_bLength] != 0) {
|
||||
if (pab[DESC_bDescriptorType] == bType) {
|
||||
if (iCurIndex == bIndex) {
|
||||
// set data pointer
|
||||
*ppbData = pab;
|
||||
// get length from structure
|
||||
if (bType == DESC_CONFIGURATION) {
|
||||
// configuration descriptor is an exception, length is at offset 2 and 3
|
||||
*piLen = (pab[CONF_DESC_wTotalLength]) |
|
||||
(pab[CONF_DESC_wTotalLength + 1] << 8);
|
||||
}
|
||||
else {
|
||||
// normally length is at offset 0
|
||||
*piLen = pab[DESC_bLength];
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
iCurIndex++;
|
||||
}
|
||||
// skip to next descriptor
|
||||
pab += pab[DESC_bLength];
|
||||
}
|
||||
// nothing found
|
||||
DBG("Desc %x not found!\n", wTypeIndex);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Configures the device according to the specified configuration index and
|
||||
alternate setting by parsing the installed USB descriptor list.
|
||||
A configuration index of 0 unconfigures the device.
|
||||
|
||||
@param [in] bConfigIndex Configuration index
|
||||
@param [in] bAltSetting Alternate setting number
|
||||
|
||||
@todo function always returns TRUE, add stricter checking?
|
||||
|
||||
@return TRUE if successfully configured, FALSE otherwise
|
||||
*/
|
||||
static BOOL USBSetConfiguration(U8 bConfigIndex, U8 bAltSetting)
|
||||
{
|
||||
U8 *pab;
|
||||
U8 bCurConfig, bCurAltSetting;
|
||||
U8 bEP;
|
||||
U16 wMaxPktSize;
|
||||
|
||||
ASSERT(pabDescrip != NULL);
|
||||
|
||||
if (bConfigIndex == 0) {
|
||||
// unconfigure device
|
||||
USBHwConfigDevice(FALSE);
|
||||
}
|
||||
else {
|
||||
// configure endpoints for this configuration/altsetting
|
||||
pab = (U8 *)pabDescrip;
|
||||
bCurConfig = 0xFF;
|
||||
bCurAltSetting = 0xFF;
|
||||
|
||||
while (pab[DESC_bLength] != 0) {
|
||||
|
||||
switch (pab[DESC_bDescriptorType]) {
|
||||
|
||||
case DESC_CONFIGURATION:
|
||||
// remember current configuration index
|
||||
bCurConfig = pab[CONF_DESC_bConfigurationValue];
|
||||
break;
|
||||
|
||||
case DESC_INTERFACE:
|
||||
// remember current alternate setting
|
||||
bCurAltSetting = pab[INTF_DESC_bAlternateSetting];
|
||||
break;
|
||||
|
||||
case DESC_ENDPOINT:
|
||||
if ((bCurConfig == bConfigIndex) &&
|
||||
(bCurAltSetting == bAltSetting)) {
|
||||
// endpoint found for desired config and alternate setting
|
||||
bEP = pab[ENDP_DESC_bEndpointAddress];
|
||||
wMaxPktSize = (pab[ENDP_DESC_wMaxPacketSize]) |
|
||||
(pab[ENDP_DESC_wMaxPacketSize + 1] << 8);
|
||||
// configure endpoint
|
||||
USBHwEPConfig(bEP, wMaxPktSize);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// skip to next descriptor
|
||||
pab += pab[DESC_bLength];
|
||||
}
|
||||
|
||||
// configure device
|
||||
USBHwConfigDevice(TRUE);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Local function to handle a standard device request
|
||||
|
||||
@param [in] pSetup The setup packet
|
||||
@param [in,out] *piLen Pointer to data length
|
||||
@param [in,out] ppbData Data buffer.
|
||||
|
||||
@return TRUE if the request was handled successfully
|
||||
*/
|
||||
static BOOL HandleStdDeviceReq(TSetupPacket *pSetup, int *piLen, U8 **ppbData)
|
||||
{
|
||||
U8 *pbData = *ppbData;
|
||||
|
||||
switch (pSetup->bRequest) {
|
||||
|
||||
case REQ_GET_STATUS:
|
||||
// bit 0: self-powered
|
||||
// bit 1: remote wakeup = not supported
|
||||
pbData[0] = 0;
|
||||
pbData[1] = 0;
|
||||
*piLen = 2;
|
||||
break;
|
||||
|
||||
case REQ_SET_ADDRESS:
|
||||
USBHwSetAddress(pSetup->wValue);
|
||||
break;
|
||||
|
||||
case REQ_GET_DESCRIPTOR:
|
||||
DBG("D%x", pSetup->wValue);
|
||||
return USBGetDescriptor(pSetup->wValue, pSetup->wIndex, piLen, ppbData);
|
||||
|
||||
case REQ_GET_CONFIGURATION:
|
||||
// indicate if we are configured
|
||||
pbData[0] = bConfiguration;
|
||||
*piLen = 1;
|
||||
break;
|
||||
|
||||
case REQ_SET_CONFIGURATION:
|
||||
if (!USBSetConfiguration(pSetup->wValue & 0xFF, 0)) {
|
||||
DBG("USBSetConfiguration failed!\n");
|
||||
return FALSE;
|
||||
}
|
||||
// configuration successful, update current configuration
|
||||
bConfiguration = pSetup->wValue & 0xFF;
|
||||
break;
|
||||
|
||||
case REQ_CLEAR_FEATURE:
|
||||
case REQ_SET_FEATURE:
|
||||
if (pSetup->wValue == FEA_REMOTE_WAKEUP) {
|
||||
// put DEVICE_REMOTE_WAKEUP code here
|
||||
}
|
||||
if (pSetup->wValue == FEA_TEST_MODE) {
|
||||
// put TEST_MODE code here
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case REQ_SET_DESCRIPTOR:
|
||||
DBG("Device req %d not implemented\n", pSetup->bRequest);
|
||||
return FALSE;
|
||||
|
||||
default:
|
||||
DBG("Illegal device req %d\n", pSetup->bRequest);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Local function to handle a standard interface request
|
||||
|
||||
@param [in] pSetup The setup packet
|
||||
@param [in,out] *piLen Pointer to data length
|
||||
@param [in] ppbData Data buffer.
|
||||
|
||||
@return TRUE if the request was handled successfully
|
||||
*/
|
||||
static BOOL HandleStdInterfaceReq(TSetupPacket *pSetup, int *piLen, U8 **ppbData)
|
||||
{
|
||||
U8 *pbData = *ppbData;
|
||||
|
||||
switch (pSetup->bRequest) {
|
||||
|
||||
case REQ_GET_STATUS:
|
||||
// no bits specified
|
||||
pbData[0] = 0;
|
||||
pbData[1] = 0;
|
||||
*piLen = 2;
|
||||
break;
|
||||
|
||||
case REQ_CLEAR_FEATURE:
|
||||
case REQ_SET_FEATURE:
|
||||
// not defined for interface
|
||||
return FALSE;
|
||||
|
||||
case REQ_GET_INTERFACE: // TODO use bNumInterfaces
|
||||
// there is only one interface, return n-1 (= 0)
|
||||
pbData[0] = 0;
|
||||
*piLen = 1;
|
||||
break;
|
||||
|
||||
case REQ_SET_INTERFACE: // TODO use bNumInterfaces
|
||||
// there is only one interface (= 0)
|
||||
if (pSetup->wValue != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
*piLen = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
DBG("Illegal interface req %d\n", pSetup->bRequest);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Local function to handle a standard endpoint request
|
||||
|
||||
@param [in] pSetup The setup packet
|
||||
@param [in,out] *piLen Pointer to data length
|
||||
@param [in] ppbData Data buffer.
|
||||
|
||||
@return TRUE if the request was handled successfully
|
||||
*/
|
||||
static BOOL HandleStdEndPointReq(TSetupPacket *pSetup, int *piLen, U8 **ppbData)
|
||||
{
|
||||
U8 *pbData = *ppbData;
|
||||
|
||||
switch (pSetup->bRequest) {
|
||||
case REQ_GET_STATUS:
|
||||
// bit 0 = endpointed halted or not
|
||||
pbData[0] = (USBHwEPGetStatus(pSetup->wIndex) & EP_STATUS_STALLED) ? 1 : 0;
|
||||
pbData[1] = 0;
|
||||
*piLen = 2;
|
||||
break;
|
||||
|
||||
case REQ_CLEAR_FEATURE:
|
||||
if (pSetup->wValue == FEA_ENDPOINT_HALT) {
|
||||
// clear HALT by unstalling
|
||||
USBHwEPStall(pSetup->wIndex, FALSE);
|
||||
break;
|
||||
}
|
||||
// only ENDPOINT_HALT defined for endpoints
|
||||
return FALSE;
|
||||
|
||||
case REQ_SET_FEATURE:
|
||||
if (pSetup->wValue == FEA_ENDPOINT_HALT) {
|
||||
// set HALT by stalling
|
||||
USBHwEPStall(pSetup->wIndex, TRUE);
|
||||
break;
|
||||
}
|
||||
// only ENDPOINT_HALT defined for endpoints
|
||||
return FALSE;
|
||||
|
||||
case REQ_SYNCH_FRAME:
|
||||
DBG("EP req %d not implemented\n", pSetup->bRequest);
|
||||
return FALSE;
|
||||
|
||||
default:
|
||||
DBG("Illegal EP req %d\n", pSetup->bRequest);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Default handler for standard ('chapter 9') requests
|
||||
|
||||
If a custom request handler was installed, this handler is called first.
|
||||
|
||||
@param [in] pSetup The setup packet
|
||||
@param [in,out] *piLen Pointer to data length
|
||||
@param [in] ppbData Data buffer.
|
||||
|
||||
@return TRUE if the request was handled successfully
|
||||
*/
|
||||
BOOL USBHandleStandardRequest(TSetupPacket *pSetup, int *piLen, U8 **ppbData)
|
||||
{
|
||||
// try the custom request handler first
|
||||
if ((pfnHandleCustomReq != NULL) && pfnHandleCustomReq(pSetup, piLen, ppbData)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
switch (REQTYPE_GET_RECIP(pSetup->bmRequestType)) {
|
||||
case REQTYPE_RECIP_DEVICE: return HandleStdDeviceReq(pSetup, piLen, ppbData);
|
||||
case REQTYPE_RECIP_INTERFACE: return HandleStdInterfaceReq(pSetup, piLen, ppbData);
|
||||
case REQTYPE_RECIP_ENDPOINT: return HandleStdEndPointReq(pSetup, piLen, ppbData);
|
||||
default: return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Registers a callback for custom device requests
|
||||
|
||||
In USBHandleStandardRequest, the custom request handler gets a first
|
||||
chance at handling the request before it is handed over to the 'chapter 9'
|
||||
request handler.
|
||||
|
||||
This can be used for example in HID devices, where a REQ_GET_DESCRIPTOR
|
||||
request is sent to an interface, which is not covered by the 'chapter 9'
|
||||
specification.
|
||||
|
||||
@param [in] pfnHandler Callback function pointer
|
||||
*/
|
||||
void USBRegisterCustomReqHandler(TFnHandleRequest *pfnHandler)
|
||||
{
|
||||
pfnHandleCustomReq = pfnHandler;
|
||||
}
|
||||
|
121
VCOM_lib/usbstruct.h
Normal file
121
VCOM_lib/usbstruct.h
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
LPCUSB, an USB device driver for LPC microcontrollers
|
||||
Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
|
||||
|
||||
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. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
Definitions of structures of standard USB packets
|
||||
*/
|
||||
|
||||
#ifndef _USBSTRUCT_H_
|
||||
#define _USBSTRUCT_H_
|
||||
|
||||
// CodeRed - include the LPCUSB type.h file rather than NXP one directly
|
||||
//#include "type.h"
|
||||
#include "lpcusb_type.h"
|
||||
|
||||
|
||||
/** setup packet definitions */
|
||||
typedef struct {
|
||||
U8 bmRequestType; /**< characteristics of the specific request */
|
||||
U8 bRequest; /**< specific request */
|
||||
U16 wValue; /**< request specific parameter */
|
||||
U16 wIndex; /**< request specific parameter */
|
||||
U16 wLength; /**< length of data transfered in data phase */
|
||||
} TSetupPacket;
|
||||
|
||||
|
||||
#define REQTYPE_GET_DIR(x) (((x)>>7)&0x01)
|
||||
#define REQTYPE_GET_TYPE(x) (((x)>>5)&0x03)
|
||||
#define REQTYPE_GET_RECIP(x) ((x)&0x1F)
|
||||
|
||||
#define REQTYPE_DIR_TO_DEVICE 0
|
||||
#define REQTYPE_DIR_TO_HOST 1
|
||||
|
||||
#define REQTYPE_TYPE_STANDARD 0
|
||||
#define REQTYPE_TYPE_CLASS 1
|
||||
#define REQTYPE_TYPE_VENDOR 2
|
||||
#define REQTYPE_TYPE_RESERVED 3
|
||||
|
||||
#define REQTYPE_RECIP_DEVICE 0
|
||||
#define REQTYPE_RECIP_INTERFACE 1
|
||||
#define REQTYPE_RECIP_ENDPOINT 2
|
||||
#define REQTYPE_RECIP_OTHER 3
|
||||
|
||||
/* standard requests */
|
||||
#define REQ_GET_STATUS 0x00
|
||||
#define REQ_CLEAR_FEATURE 0x01
|
||||
#define REQ_SET_FEATURE 0x03
|
||||
#define REQ_SET_ADDRESS 0x05
|
||||
#define REQ_GET_DESCRIPTOR 0x06
|
||||
#define REQ_SET_DESCRIPTOR 0x07
|
||||
#define REQ_GET_CONFIGURATION 0x08
|
||||
#define REQ_SET_CONFIGURATION 0x09
|
||||
#define REQ_GET_INTERFACE 0x0A
|
||||
#define REQ_SET_INTERFACE 0x0B
|
||||
#define REQ_SYNCH_FRAME 0x0C
|
||||
|
||||
/* class requests HID */
|
||||
#define HID_GET_REPORT 0x01
|
||||
#define HID_GET_IDLE 0x02
|
||||
#define HID_GET_PROTOCOL 0x03
|
||||
#define HID_SET_REPORT 0x09
|
||||
#define HID_SET_IDLE 0x0A
|
||||
#define HID_SET_PROTOCOL 0x0B
|
||||
|
||||
/* feature selectors */
|
||||
#define FEA_ENDPOINT_HALT 0x00
|
||||
#define FEA_REMOTE_WAKEUP 0x01
|
||||
#define FEA_TEST_MODE 0x02
|
||||
|
||||
/*
|
||||
USB descriptors
|
||||
*/
|
||||
|
||||
/** USB descriptor header */
|
||||
typedef struct {
|
||||
U8 bLength; /**< descriptor length */
|
||||
U8 bDescriptorType; /**< descriptor type */
|
||||
} TUSBDescHeader;
|
||||
|
||||
#define DESC_DEVICE 1
|
||||
#define DESC_CONFIGURATION 2
|
||||
#define DESC_STRING 3
|
||||
#define DESC_INTERFACE 4
|
||||
#define DESC_ENDPOINT 5
|
||||
#define DESC_DEVICE_QUALIFIER 6
|
||||
#define DESC_OTHER_SPEED 7
|
||||
#define DESC_INTERFACE_POWER 8
|
||||
|
||||
#define DESC_HID_HID 0x21
|
||||
#define DESC_HID_REPORT 0x22
|
||||
#define DESC_HID_PHYSICAL 0x23
|
||||
|
||||
#define GET_DESC_TYPE(x) (((x)>>8)&0xFF)
|
||||
#define GET_DESC_INDEX(x) ((x)&0xFF)
|
||||
|
||||
#endif /* _USBSTRUCT_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user