fx2/firmware/include/setupdat.h

224 lines
6.6 KiB
C

// Copyright (C) 2009 Ubixum, Inc.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#ifndef SETUPDAT_H
#define SETUPDAT_H
#include "fx2regs.h"
#include "delay.h"
/** \file setupdat.h
Utilities for handling setup data and vendor commands.
\verbatim
This module needs initialized with a device descriptor.
NOTE that your descriptors need to be located in code memory
to use the SUDPTRH:L to auto transfer the data
and vendor commands handler. You have to provide callbacks.
DEVICE DESCRIPTORS
// copy the dscr_asm file from the lib dir to your
// own project directory, change it how
// you want, and link it against your project
VENDOR COMMANDS
0xA0 is handled by ez-usb firmware. (Upload/Download ram)
0xA1-0xAF is reserved for other ez-usb functions so don't use that
Any other value (Above 0x0C anyway) can be used for device specific
commands.
If you include this file, you need to define a function for vendor
commands even if you don't want to implement any vendor commands.
The function should return TRUE if you handled the command and FALSE
if you didn't. The handle_setup function calls
EP0CS |= bmHSNAK;
before returning so there is no reason to set that bit in your
vendor command handler. (You do need to Set EP0 data and
byte counts appropriately though.)
// return TRUE if you handle the command
// you can directly get SETUPDAT[0-7] for the data sent with the command
BOOL handle_vendorcommand(BYTE cmd) { return FALSE; }
// a note on vencor commands
// this from the usb spec for requesttype
D7 Data Phase Transfer Direction
0 = Host to Device
1 = Device to Host
D6..5 Type
0 = Standard
1 = Class
2 = Vendor
3 = Reserved
D4..0 Recipient
0 = Device
1 = Interface
2 = Endpoint
3 = Other
4..31 = Reserved
// if you want libusb to send data back to the host via ep0, you need to make
// sure the requesttype had 1 in bit 7. This is for libusb on linux anyway.
// set *alt_ifc to the current alt interface for ifc
BOOL handle_get_interface(BYTE ifc, BYTE* alt_ifc) { *ifc=0;*alt_ifc=0;}
// return TRUE if you set the interface requested
// NOTE this function should reconfigure and reset the endpoints
// according to the interface descriptors you provided.
BOOL handle_set_interface(BYTE ifc,BYTE alt_ifc) { return TRUE; }
// handle getting and setting the configuration
// 0 is the default. If you support more than one config
// keep track of the config number and return the correct number
// config numbers are set int the dscr file.
BYTE handle_get_configuration() { return 1; }
// return TRUE if you handle this request
// NOTE changing config requires the device to reset all the endpoints
BOOL handle_set_configuration(BYTE cfg) { return FALSE; }
// ep num (byte 7 is dir 1=IN,0=OUT)
// client needs to reset the endpoint to default state
void handle_reset_ep(BYTE ep) { }
\endverbatim
*/
#define SETUP_VALUE() MAKEWORD(SETUPDAT[3],SETUPDAT[2])
#define SETUP_INDEX() MAKEWORD(SETUPDAT[5],SETUPDAT[4])
#define SETUP_LENGTH() MAKEWORD(SETUPDAT[7],SETUPDAT[6])
#define SETUP_TYPE SETUPDAT[0]
/**
* self_powered is set to FALSE by default. It is
* used for GET_FEATURE requests. Firmware can set it to
* TRUE if the device is not powered by the USB bus.
**/
extern volatile BOOL self_powered;
/**
* remote_wakeup_allowed defaults to FALSE but can be
* set to TRUE with SET_FEATURE from the host. (firmware shouldn't
* set this.)
**/
extern volatile BOOL remote_wakeup_allowed;
//! see TRM 2-3
//! here are the usb setup data commands
//! these are the usb spec pretty much
typedef enum {
GET_STATUS,
CLEAR_FEATURE,
// 0x02 is reserved
SET_FEATURE = 0x03,
// 0x04 is reserved
SET_ADDRESS = 0x05, // this is handled by EZ-USB core unless RENUM=0
GET_DESCRIPTOR,
SET_DESCRIPTOR,
GET_CONFIGURATION,
SET_CONFIGURATION,
GET_INTERFACE,
SET_INTERFACE,
SYNC_FRAME
} SETUP_DATA;
/**
* returns the control/status register for an end point
* (bit 7=1 for IN, 0 for out
**/
__xdata BYTE *ep_addr(BYTE ep);
/*
You can call this function directly if you are polling
for setup data in your main loop.
You can also use the usbjt and enable the sudav isr
and call the function from withing the sudav isr routine
*/
void handle_setupdata();
/**
For devices to properly handle usb hispeed
(This is if your descriptor has high speed and full speed versions
and it should since the fx2lp is a high speed capable device
)
enable both USBRESET and HISPEED interrupts and
call this function to switch the descriptors. This function uses
a __critical section to switch the descriptors and is safe to call
from the hispeed or reset interrupt. See \ref fw.c
\param highspeed Call the function with highspeed = TRUE if
calling because the highspeed interrupt was received.
If calling from usbreset, call with highspeed=false
**/
void handle_hispeed(BOOL highspeed);
/* descriptor types */
#define DSCR_DEVICE_TYPE 1
#define DSCR_CONFIG_TYPE 2
#define DSCR_STRING_TYPE 3
#define DSCR_DEVQUAL_TYPE 6
#define DSCR_OTHERSPD_TYPE 7
/* usb spec 2 */
#define DSCR_BCD 2
/* device descriptor */
#define DSCR_DEVICE_LEN 18
typedef struct {
BYTE dsc_len; // descriptor length (18 for this )
BYTE dsc_type; // dscr type
WORD bcd; // bcd
BYTE dev_class; // device class
BYTE dev_subclass; // sub class
BYTE dev_protocol; // sub sub class
BYTE max_pkt; // max packet size
WORD vendor_id;
WORD product_id;
WORD dev_version; // product version id
BYTE idx_manstr; // manufacturer string index
BYTE idx_devstr; // product string index
BYTE idx_serstr; // serial number index
BYTE num_configs; // number of configurations
} DEVICE_DSCR;
/* config descriptor */
#define DSCR_CONFIG_LEN 9
typedef struct {
BYTE dsc_len; // 9 for this one
BYTE dsc_type; // dscr type
} CONFIG_DSCR;
/* string descriptor */
typedef struct {
BYTE dsc_len;
BYTE dsc_type;
BYTE pstr;
} STRING_DSCR;
#endif