Addition of USB files
This commit is contained in:
parent
a520fe4646
commit
219846f408
36 changed files with 11046 additions and 0 deletions
125
cpu/avr/dev/usb/INF/AtmelRNDIS.inf
Normal file
125
cpu/avr/dev/usb/INF/AtmelRNDIS.inf
Normal file
|
@ -0,0 +1,125 @@
|
|||
;
|
||||
; Template INF for a USB Remote NDIS Device
|
||||
; Copyright (c) Microsoft Corporation
|
||||
;
|
||||
|
||||
[Version]
|
||||
Signature = "$Windows NT$"
|
||||
Class = Net
|
||||
ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318}
|
||||
Provider = %Atmel%
|
||||
DriverVer = 06/20/2008,0.0.0.3
|
||||
;CatalogFile = Atmel.cat
|
||||
|
||||
[Manufacturer]
|
||||
%Atmel% = AtmelDevices,NT.5.1
|
||||
|
||||
[AtmelDevices]
|
||||
%AtmelDevice% = RNDIS, USB\VID_03EB&PID_2019
|
||||
|
||||
[AtmelDevices.NT.5.1]
|
||||
%AtmelDevice% = RNDIS.NT.5.1, USB\VID_03EB&PID_2019
|
||||
|
||||
[ControlFlags]
|
||||
ExcludeFromSelect=*
|
||||
|
||||
; Windows 2000 specific sections ---------------------------------
|
||||
|
||||
[RNDIS.NT]
|
||||
Characteristics = 0x84 ; NCF_PHYSICAL + NCF_HAS_UI
|
||||
BusType = 15
|
||||
DriverVer = 06/20/2008,0.0.0.2
|
||||
AddReg = RNDIS_AddReg_NT, RNDIS_AddReg_WIN2K,RNDIS_AddReg_Vista
|
||||
CopyFiles = RNDIS_CopyFiles_NT
|
||||
|
||||
; DO NOT MODIFY THE SERVICE NAME
|
||||
[RNDIS.NT.Services]
|
||||
AddService = USB_RNDISY, 2, RNDIS_ServiceInst_NT, RNDIS_EventLog
|
||||
|
||||
[RNDIS_CopyFiles_NT]
|
||||
; no rename of files on Windows 2000, use the 'y' names as is
|
||||
usb8023y.sys, , , 0
|
||||
rndismpy.sys, , , 0
|
||||
|
||||
[RNDIS_ServiceInst_NT]
|
||||
DisplayName = %ServiceDisplayName%
|
||||
ServiceType = 1
|
||||
StartType = 3
|
||||
ErrorControl = 1
|
||||
ServiceBinary = %12%\usb8023y.sys
|
||||
LoadOrderGroup = NDIS
|
||||
AddReg = RNDIS_WMI_AddReg_NT
|
||||
|
||||
[RNDIS_WMI_AddReg_NT]
|
||||
HKR, , MofImagePath, 0x00020000, "System32\drivers\rndismpy.sys"
|
||||
|
||||
; Windows XP specific sections -----------------------------------
|
||||
|
||||
[RNDIS.NT.5.1]
|
||||
Characteristics = 0x84 ; NCF_PHYSICAL + NCF_HAS_UI
|
||||
BusType = 15
|
||||
DriverVer = 06/20/2008,0.0.0.2
|
||||
AddReg = RNDIS_AddReg_XP
|
||||
include = netrndis.inf
|
||||
needs = Usb_Rndis.ndi
|
||||
|
||||
; no copyfiles - the files are already in place
|
||||
|
||||
[RNDIS.NT.5.1.Services]
|
||||
include = netrndis.inf
|
||||
needs = Usb_Rndis.ndi.Services
|
||||
|
||||
; Windows 2000 sections
|
||||
|
||||
; DO NOT MODIFY ServiceName
|
||||
[RNDIS_AddReg_NT]
|
||||
HKR, Ndi, Service, 0, "USB_RNDISY"
|
||||
HKR, Ndi\Interfaces, UpperRange, 0, "ndis5"
|
||||
HKR, Ndi\Interfaces, LowerRange, 0, "ethernet"
|
||||
|
||||
[RNDIS_AddReg_WIN2K]
|
||||
HKR, , ReclaimRecv, 0x00010001, 1
|
||||
HKR, NDI\params\NetworkAddress, ParamDesc, 0, %NetworkAddress%
|
||||
HKR, NDI\params\NetworkAddress, type, 0, "edit"
|
||||
HKR, NDI\params\NetworkAddress, LimitText, 0, "12"
|
||||
HKR, NDI\params\NetworkAddress, UpperCase, 0, "1"
|
||||
HKR, NDI\params\NetworkAddress, default, 0, " "
|
||||
HKR, NDI\params\NetworkAddress, optional, 0, "1"
|
||||
|
||||
[RNDIS_EventLog]
|
||||
AddReg = RNDIS_EventLog_AddReg
|
||||
|
||||
[RNDIS_EventLog_AddReg]
|
||||
HKR, , EventMessageFile, 0x00020000, "%%SystemRoot%%\System32\netevent.dll"
|
||||
HKR, , TypesSupported, 0x00010001, 7
|
||||
|
||||
|
||||
[RNDIS_AddReg_XP]
|
||||
HKR, NDI\params\rawmode, ParamDesc, 0, %RAWMODE%
|
||||
HKR, NDI\params\rawmode, base, 0, "10"
|
||||
HKR, NDI\params\rawmode, type, 0, "enum"
|
||||
HKR, NDI\params\rawmode, default, 0, "0"
|
||||
HKR, NDI\params\rawmode\enum, "0", 0, "Off"
|
||||
HKR, NDI\params\rawmode\enum, "1", 0, "On"
|
||||
|
||||
|
||||
|
||||
[SourceDisksNames]
|
||||
1=%SourceDisk%,,1
|
||||
|
||||
[SourceDisksFiles]
|
||||
usb8023y.sys=1
|
||||
rndismpy.sys=1
|
||||
|
||||
[DestinationDirs]
|
||||
RNDIS_CopyFiles_NT = 12
|
||||
|
||||
; DO NOT CHANGE ServiceDisplayName
|
||||
[Strings]
|
||||
ServiceDisplayName = "USB Remote NDIS Y Network Device Driver"
|
||||
NetworkAddress = "Network Address"
|
||||
Atmel = "Atmel Corporation"
|
||||
AtmelDevice = "Atmel RAVEN USB Stick"
|
||||
SourceDisk = "Atmel USB Network Driver Install Disk"
|
||||
RAWMODE = "Raw 802.15.4 Mode"
|
||||
|
124
cpu/avr/dev/usb/INF/CompositeAtmelRNDIS.inf
Normal file
124
cpu/avr/dev/usb/INF/CompositeAtmelRNDIS.inf
Normal file
|
@ -0,0 +1,124 @@
|
|||
;
|
||||
; Template INF for a USB Remote NDIS Device
|
||||
; Copyright (c) Microsoft Corporation
|
||||
;
|
||||
|
||||
[Version]
|
||||
Signature = "$Windows NT$"
|
||||
Class = Net
|
||||
ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318}
|
||||
Provider = %Atmel%
|
||||
DriverVer = 06/20/2008,0.0.0.3
|
||||
;CatalogFile = Atmel.cat
|
||||
|
||||
[Manufacturer]
|
||||
%Atmel% = AtmelDevices,NT.5.1
|
||||
|
||||
[AtmelDevices]
|
||||
%AtmelDevice% = RNDIS, USB\VID_03EB&PID_2021&MI_00
|
||||
|
||||
[AtmelDevices.NT.5.1]
|
||||
%AtmelDevice% = RNDIS.NT.5.1, USB\VID_03EB&PID_2021&MI_00
|
||||
|
||||
[ControlFlags]
|
||||
ExcludeFromSelect=*
|
||||
|
||||
; Windows 2000 specific sections ---------------------------------
|
||||
|
||||
[RNDIS.NT]
|
||||
Characteristics = 0x84 ; NCF_PHYSICAL + NCF_HAS_UI
|
||||
BusType = 15
|
||||
DriverVer = 06/20/2008,0.0.0.2
|
||||
AddReg = RNDIS_AddReg_NT, RNDIS_AddReg_WIN2K,RNDIS_AddReg_Vista
|
||||
CopyFiles = RNDIS_CopyFiles_NT
|
||||
|
||||
; DO NOT MODIFY THE SERVICE NAME
|
||||
[RNDIS.NT.Services]
|
||||
AddService = USB_RNDISY, 2, RNDIS_ServiceInst_NT, RNDIS_EventLog
|
||||
|
||||
[RNDIS_CopyFiles_NT]
|
||||
; no rename of files on Windows 2000, use the 'y' names as is
|
||||
usb8023y.sys, , , 0
|
||||
rndismpy.sys, , , 0
|
||||
|
||||
[RNDIS_ServiceInst_NT]
|
||||
DisplayName = %ServiceDisplayName%
|
||||
ServiceType = 1
|
||||
StartType = 3
|
||||
ErrorControl = 1
|
||||
ServiceBinary = %12%\usb8023y.sys
|
||||
LoadOrderGroup = NDIS
|
||||
AddReg = RNDIS_WMI_AddReg_NT
|
||||
|
||||
[RNDIS_WMI_AddReg_NT]
|
||||
HKR, , MofImagePath, 0x00020000, "System32\drivers\rndismpy.sys"
|
||||
|
||||
; Windows XP specific sections -----------------------------------
|
||||
|
||||
[RNDIS.NT.5.1]
|
||||
Characteristics = 0x84 ; NCF_PHYSICAL + NCF_HAS_UI
|
||||
BusType = 15
|
||||
DriverVer = 06/20/2008,0.0.0.2
|
||||
AddReg = RNDIS_AddReg_XP
|
||||
include = netrndis.inf
|
||||
needs = Usb_Rndis.ndi
|
||||
|
||||
; no copyfiles - the files are already in place
|
||||
|
||||
[RNDIS.NT.5.1.Services]
|
||||
include = netrndis.inf
|
||||
needs = Usb_Rndis.ndi.Services
|
||||
|
||||
; Windows 2000 sections
|
||||
|
||||
; DO NOT MODIFY ServiceName
|
||||
[RNDIS_AddReg_NT]
|
||||
HKR, Ndi, Service, 0, "USB_RNDISY"
|
||||
HKR, Ndi\Interfaces, UpperRange, 0, "ndis5"
|
||||
HKR, Ndi\Interfaces, LowerRange, 0, "ethernet"
|
||||
|
||||
[RNDIS_AddReg_WIN2K]
|
||||
HKR, , ReclaimRecv, 0x00010001, 1
|
||||
HKR, NDI\params\NetworkAddress, ParamDesc, 0, %NetworkAddress%
|
||||
HKR, NDI\params\NetworkAddress, type, 0, "edit"
|
||||
HKR, NDI\params\NetworkAddress, LimitText, 0, "12"
|
||||
HKR, NDI\params\NetworkAddress, UpperCase, 0, "1"
|
||||
HKR, NDI\params\NetworkAddress, default, 0, " "
|
||||
HKR, NDI\params\NetworkAddress, optional, 0, "1"
|
||||
|
||||
[RNDIS_EventLog]
|
||||
AddReg = RNDIS_EventLog_AddReg
|
||||
|
||||
[RNDIS_EventLog_AddReg]
|
||||
HKR, , EventMessageFile, 0x00020000, "%%SystemRoot%%\System32\netevent.dll"
|
||||
HKR, , TypesSupported, 0x00010001, 7
|
||||
|
||||
|
||||
[RNDIS_AddReg_XP]
|
||||
[RNDIS_AddReg_XP]
|
||||
HKR, NDI\params\rawmode, ParamDesc, 0, %RAWMODE%
|
||||
HKR, NDI\params\rawmode, base, 0, "10"
|
||||
HKR, NDI\params\rawmode, type, 0, "enum"
|
||||
HKR, NDI\params\rawmode, default, 0, "0"
|
||||
HKR, NDI\params\rawmode\enum, "0", 0, "Off"
|
||||
HKR, NDI\params\rawmode\enum, "1", 0, "On"
|
||||
|
||||
|
||||
[SourceDisksNames]
|
||||
1=%SourceDisk%,,1
|
||||
|
||||
[SourceDisksFiles]
|
||||
usb8023y.sys=1
|
||||
rndismpy.sys=1
|
||||
|
||||
[DestinationDirs]
|
||||
RNDIS_CopyFiles_NT = 12
|
||||
|
||||
; DO NOT CHANGE ServiceDisplayName
|
||||
[Strings]
|
||||
ServiceDisplayName = "USB Remote NDIS Y Network Device Driver"
|
||||
NetworkAddress = "Network Address"
|
||||
Atmel = "Atmel Corporation"
|
||||
AtmelDevice = "Atmel RAVEN USB Stick"
|
||||
SourceDisk = "Atmel USB Network Driver Install Disk"
|
||||
RAWMODE = "Raw 802.15.4 Mode"
|
53
cpu/avr/dev/usb/INF/CompositeAtmelVCP.inf
Normal file
53
cpu/avr/dev/usb/INF/CompositeAtmelVCP.inf
Normal file
|
@ -0,0 +1,53 @@
|
|||
; Windows 2000 and XP setup File for AT89C5131 demo
|
||||
|
||||
[Version]
|
||||
Signature="$Windows NT$"
|
||||
Class=Ports
|
||||
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
|
||||
|
||||
Provider=%ATMEL%
|
||||
LayoutFile=layout.inf
|
||||
DriverVer=10/15/1999,5.0.2153.1
|
||||
|
||||
[Manufacturer]
|
||||
%ATMEL%=ATMEL
|
||||
|
||||
[ATMEL]
|
||||
%ATMEL_CDC%=Reader, USB\VID_03EB&PID_2021&MI_02
|
||||
|
||||
|
||||
[Reader_Install.NTx86]
|
||||
;Windows2000
|
||||
|
||||
[DestinationDirs]
|
||||
DefaultDestDir=12
|
||||
Reader.NT.Copy=12
|
||||
|
||||
[Reader.NT]
|
||||
CopyFiles=Reader.NT.Copy
|
||||
AddReg=Reader.NT.AddReg
|
||||
|
||||
[Reader.NT.Copy]
|
||||
usbser.sys
|
||||
|
||||
[Reader.NT.AddReg]
|
||||
HKR,,DevLoader,,*ntkern
|
||||
HKR,,NTMPDriver,,usbser.sys
|
||||
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
|
||||
|
||||
[Reader.NT.Services]
|
||||
AddService = usbser, 0x00000002, Service_Inst
|
||||
|
||||
[Service_Inst]
|
||||
DisplayName = %Serial.SvcDesc%
|
||||
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
|
||||
StartType = 3 ; SERVICE_DEMAND_START
|
||||
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
|
||||
ServiceBinary = %12%\usbser.sys
|
||||
LoadOrderGroup = Base
|
||||
|
||||
[Strings]
|
||||
ATMEL = "ATMEL, Inc."
|
||||
ATMEL_CDC = "Atmel Raven USB Debug Port"
|
||||
Serial.SvcDesc = "USB Serial emulation driver"
|
||||
|
351
cpu/avr/dev/usb/compiler.h
Normal file
351
cpu/avr/dev/usb/compiler.h
Normal file
|
@ -0,0 +1,351 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file *********************************************************************
|
||||
*
|
||||
* \brief This file includes the correct compiler definitions for the different
|
||||
* architectures.
|
||||
*
|
||||
* \par Documentation
|
||||
* For comprehensive code documentation, supported compilers, compiler
|
||||
* settings and supported devices see readme.html
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
*
|
||||
* $Name: $
|
||||
* $Revision: 1.1 $
|
||||
* $RCSfile: compiler.h,v $
|
||||
* $Date: 2008/10/14 20:16:36 $ \n
|
||||
*
|
||||
* Copyright (c) 2008, Atmel Corporation All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of ATMEL may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL ``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 EXPRESSLY AND
|
||||
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _COMPILER_H_
|
||||
#define _COMPILER_H_
|
||||
|
||||
/*_____ I N C L U D E S ____________________________________________________*/
|
||||
|
||||
|
||||
/*_____ D E C L A R A T I O N S ____________________________________________*/
|
||||
#define LITTLE_ENDIAN
|
||||
|
||||
#ifndef ASM_INCLUDE // define ASM_INCLUDE in your a51 source code before include of .h file
|
||||
typedef float Float16;
|
||||
|
||||
typedef unsigned char U8 ;
|
||||
typedef unsigned short U16;
|
||||
typedef unsigned long U32;
|
||||
typedef signed char S8 ;
|
||||
typedef signed short S16;
|
||||
typedef long S32;
|
||||
#if (defined __C51__)
|
||||
typedef bit Bool; // Shall be used with _MEM_TYPE_BIT_ to optimize the memory.
|
||||
#else
|
||||
typedef unsigned char Bool;
|
||||
#endif
|
||||
|
||||
typedef U8 Status;
|
||||
typedef Bool Status_bool;
|
||||
#define PASS 0
|
||||
#define FAIL 1
|
||||
|
||||
|
||||
|
||||
#if (defined __C51__)
|
||||
# define _MEM_TYPE_BIT_ bdata // Used for bit accesses
|
||||
# define _MEM_TYPE_FAST_ data
|
||||
# define _MEM_TYPE_MEDFAST_ idata
|
||||
# define _MEM_TYPE_MEDSLOW_ pdata
|
||||
# define _MEM_TYPE_SLOW_ xdata
|
||||
#else
|
||||
# define _MEM_TYPE_BIT_
|
||||
# define _MEM_TYPE_FAST_
|
||||
# define _MEM_TYPE_MEDFAST_
|
||||
# define _MEM_TYPE_MEDSLOW_
|
||||
# define _MEM_TYPE_SLOW_
|
||||
#endif
|
||||
|
||||
typedef unsigned char Uchar;
|
||||
|
||||
|
||||
typedef unsigned char Uint8;
|
||||
typedef unsigned int Uint16;
|
||||
typedef unsigned long int Uint32;
|
||||
|
||||
typedef char Int8;
|
||||
typedef int Int16;
|
||||
typedef long int Int32;
|
||||
|
||||
typedef unsigned char Byte;
|
||||
typedef unsigned int Word;
|
||||
typedef unsigned long int DWord;
|
||||
|
||||
typedef union
|
||||
{
|
||||
Uint32 dw; // l changed in dw (double word) because l is used for signed long...
|
||||
Uint16 w[2];
|
||||
Uint8 b[4];
|
||||
} Union32;
|
||||
|
||||
typedef union
|
||||
{
|
||||
Uint16 w;
|
||||
Uint8 b[2];
|
||||
} Union16;
|
||||
|
||||
#ifdef __IAR_SYSTEMS_ICC__
|
||||
typedef char bit;
|
||||
typedef int p_uart_ptchar;
|
||||
typedef int r_uart_ptchar;
|
||||
#endif
|
||||
#ifdef __CODEVISIONAVR__
|
||||
typedef char bit;
|
||||
typedef int p_uart_ptchar;
|
||||
typedef char r_uart_ptchar;
|
||||
#endif
|
||||
#if !defined(__IAR_SYSTEMS_ICC__) && !defined(___ICC__)
|
||||
typedef char p_uart_ptchar;
|
||||
typedef char r_uart_ptchar;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/**********************************************************************************/
|
||||
/* codevision COMPILER (__CODEVISIONAVR__) */
|
||||
/**********************************************************************************/
|
||||
#ifdef __ICC__
|
||||
#define _ConstType_ lit
|
||||
#define _MemType_
|
||||
#define _GenericType_ __generic
|
||||
#define FLASH lit
|
||||
#define XDATA
|
||||
#define IDATA
|
||||
#define DATA
|
||||
#endif
|
||||
/**********************************************************************************/
|
||||
/* IAR COMPILER (__IAR_SYSTEMS_ICC__) */
|
||||
/**********************************************************************************/
|
||||
#ifdef __IAR_SYSTEMS_ICC__
|
||||
#include "inavr.h"
|
||||
#define _ConstType_ __flash
|
||||
#define _MemType_
|
||||
#define _GenericType_ __generic
|
||||
#define FLASH __flash
|
||||
#define FARFLASH __farflash
|
||||
#define XDATA
|
||||
#define IDATA
|
||||
#define DATA
|
||||
#define At(x) @ x
|
||||
#define PDATA
|
||||
#define BDATA
|
||||
// Memory Type Location
|
||||
#ifndef _CONST_TYPE_
|
||||
# define _CONST_TYPE_ code
|
||||
#endif
|
||||
|
||||
#define Enable_interrupt() __enable_interrupt()
|
||||
#define Disable_interrupt() __disable_interrupt()
|
||||
|
||||
#include <iomacro.h>
|
||||
#define SFR_W_EXT(a,b) SFR_W_R(b,a)
|
||||
#endif
|
||||
|
||||
|
||||
/* General purpose defines */
|
||||
/*#define _ConstType_ __farflash
|
||||
#define _MemType_
|
||||
#define _GenericType_ __generic
|
||||
#define code __farflash
|
||||
#define xdata
|
||||
#define idata
|
||||
#define data*/
|
||||
|
||||
|
||||
|
||||
|
||||
/*_____ M A C R O S ________________________________________________________*/
|
||||
/* little-big endian management */
|
||||
#define INTEL_ALIGNMENT LITTLE_ENDIAN
|
||||
#define MOTOROLA_ALIGNMENT BIG_ENDIAN
|
||||
|
||||
// U16/U32 endian handlers
|
||||
#ifdef LITTLE_ENDIAN // => 16bit: (LSB,MSB), 32bit: (LSW,MSW) or (LSB0,LSB1,LSB2,LSB3) or (MSB3,MSB2,MSB1,MSB0)
|
||||
# define MSB(u16) (((U8* )&u16)[1])
|
||||
# define LSB(u16) (((U8* )&u16)[0])
|
||||
# define MSW(u32) (((U16*)&u32)[1])
|
||||
# define LSW(u32) (((U16*)&u32)[0])
|
||||
# define MSB0(u32) (((U8* )&u32)[3])
|
||||
# define MSB1(u32) (((U8* )&u32)[2])
|
||||
# define MSB2(u32) (((U8* )&u32)[1])
|
||||
# define MSB3(u32) (((U8* )&u32)[0])
|
||||
# define LSB0(u32) MSB3(u32)
|
||||
# define LSB1(u32) MSB2(u32)
|
||||
# define LSB2(u32) MSB1(u32)
|
||||
# define LSB3(u32) MSB0(u32)
|
||||
#else // BIG_ENDIAN => 16bit: (MSB,LSB), 32bit: (MSW,LSW) or (LSB3,LSB2,LSB1,LSB0) or (MSB0,MSB1,MSB2,MSB3)
|
||||
# define MSB(u16) (((U8* )&u16)[0])
|
||||
# define LSB(u16) (((U8* )&u16)[1])
|
||||
# define MSW(u32) (((U16*)&u32)[0])
|
||||
# define LSW(u32) (((U16*)&u32)[1])
|
||||
# define MSB0(u32) (((U8* )&u32)[0])
|
||||
# define MSB1(u32) (((U8* )&u32)[1])
|
||||
# define MSB2(u32) (((U8* )&u32)[2])
|
||||
# define MSB3(u32) (((U8* )&u32)[3])
|
||||
# define LSB0(u32) MSB3(u32)
|
||||
# define LSB1(u32) MSB2(u32)
|
||||
# define LSB2(u32) MSB1(u32)
|
||||
# define LSB3(u32) MSB0(u32)
|
||||
#endif
|
||||
|
||||
// Endian converters
|
||||
#define Le16(b) \
|
||||
( ((U16)( (b) & 0xFF) << 8) \
|
||||
| ( ((U16)(b) & 0xFF00) >> 8) \
|
||||
)
|
||||
#define Le32(b) \
|
||||
( ((U32)( (b) & 0xFF) << 24) \
|
||||
| ((U32)((U16)(b) & 0xFF00) << 8) \
|
||||
| ( ((U32)(b) & 0xFF0000) >> 8) \
|
||||
| ( ((U32)(b) & 0xFF000000) >> 24) \
|
||||
)
|
||||
|
||||
// host to network conversion: used for Intel HEX format, TCP/IP, ...
|
||||
// Convert a 16-bit value from host-byte order to network-byte order
|
||||
// Standard Unix, POSIX 1003.1g (draft)
|
||||
|
||||
/*
|
||||
#ifdef LITTLE_ENDIAN
|
||||
# define htons(a) Le16(a)
|
||||
#define ntohs(a) htons(a)
|
||||
# define htonl(a) Le32(a)
|
||||
#define ntohl(a) htonl(a)
|
||||
#else
|
||||
#define htons(a) (a)
|
||||
#define ntohs(a) (a)
|
||||
#define htonl(a) (a)
|
||||
#define ntohl(a) (a)
|
||||
#endif
|
||||
*/
|
||||
|
||||
// Constants
|
||||
#define ENABLE 1
|
||||
#define ENABLED 1
|
||||
#define DISABLED 0
|
||||
#define DISABLE 0
|
||||
#define FALSE (0==1)
|
||||
#define TRUE (1==1)
|
||||
|
||||
#define KO 0
|
||||
#define OK 1
|
||||
#define OFF 0
|
||||
#define ON 1
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
#ifndef ASM_INCLUDE // define ASM_INCLUDE in your a51 source code before include of .h file
|
||||
#define CLR 0
|
||||
#define SET 1
|
||||
#endif
|
||||
|
||||
/* Bit and bytes manipulations */
|
||||
#define LOW(U16) ((Uchar)U16)
|
||||
#define HIGH(U16) ((Uchar)(U16>>8))
|
||||
#define TST_BIT_X(addrx,mask) (*addrx & mask)
|
||||
#define SET_BIT_X(addrx,mask) (*addrx = (*addrx | mask))
|
||||
#define CLR_BIT_X(addrx,mask) (*addrx = (*addrx & ~mask))
|
||||
#define OUT_X(addrx,value) (*addrx = value)
|
||||
#define IN_X(addrx) (*addrx)
|
||||
|
||||
# define Max(a, b) ( (a)>(b) ? (a) : (b) ) // Take the max between a and b
|
||||
# define Min(a, b) ( (a)<(b) ? (a) : (b) ) // Take the min between a and b
|
||||
|
||||
// Align on the upper value <val> on a <n> boundary
|
||||
// i.e. Upper(0, 4)= 4
|
||||
// Upper(1, 4)= 4
|
||||
// Upper(2, 4)= 4
|
||||
// Upper(3, 4)= 4
|
||||
// Upper(4, 4)= 8
|
||||
// ../..
|
||||
# define Upper(val, n) ( ((val)+(n)) & ~((n)-1) )
|
||||
|
||||
// Align up <val> on a <n> boundary
|
||||
// i.e. Align_up(0, 4)= 0
|
||||
// Align_up(1, 4)= 4
|
||||
// Align_up(2, 4)= 4
|
||||
// Align_up(3, 4)= 4
|
||||
// Align_up(4, 4)= 4
|
||||
// ../..
|
||||
# define Align_up(val, n) ( ((val)+(n)-1) & ~((n)-1) )
|
||||
|
||||
// Align down <val> on a <n> boundary
|
||||
// i.e. Align_down(0, 4)= 0
|
||||
// Align_down(1, 4)= 0
|
||||
// Align_down(2, 4)= 0
|
||||
// Align_down(3, 4)= 0
|
||||
// Align_down(4, 4)= 4
|
||||
// ../..
|
||||
# define Align_down(val, n) ( (val) & ~((n)-1) )
|
||||
|
||||
/* {For Langdoc} */
|
||||
|
||||
/***********************************************************
|
||||
SET_SFR_BIT macro
|
||||
parameters
|
||||
sfr_reg : defined value in include file for sfr register
|
||||
bit_pos : defined value B_XX in include file for particular
|
||||
bit of sfr register
|
||||
bit_val : CLR / SET
|
||||
************************************************************/
|
||||
#define SET_SFR_BIT(sfr_reg, bit_pos, bit_val) { sfr_reg &= ~(1<<(bit_pos)); sfr_reg |= ((bit_val)<<(bit_pos));}
|
||||
|
||||
#define TID_GUARD(proc) ((__TID__ & 0x7FF0) != ((90 << 8) | ((proc) << 4)))
|
||||
|
||||
/******************************************************************************/
|
||||
/* GCC COMPILER */
|
||||
/******************************************************************************/
|
||||
#ifdef AVRGCC
|
||||
#define _CONST_TYPE_
|
||||
#define _ConstType_ __flash
|
||||
#define _MemType_
|
||||
#define _GenericType_ __generic
|
||||
#define FLASH PROGMEM
|
||||
#define XDATA
|
||||
#define IDATA
|
||||
#define DATA
|
||||
#define At(x) @ x
|
||||
#define PDATA
|
||||
#define BDATA
|
||||
#define bit U8
|
||||
//#include <avr/sfr_defs.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#define Enable_interrupt() sei()
|
||||
#define Disable_interrupt() cli()
|
||||
|
||||
#endif
|
||||
#endif /* _COMPILER_H_ */
|
||||
|
148
cpu/avr/dev/usb/conf_usb.h
Normal file
148
cpu/avr/dev/usb/conf_usb.h
Normal file
|
@ -0,0 +1,148 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file conf_usb.h **********************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file contains the possible external configuration of the USB.
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _CONF_USB_H_
|
||||
#define _CONF_USB_H_
|
||||
|
||||
|
||||
|
||||
/**
|
||||
\ingroup usbstick
|
||||
\defgroup usbconf USB Configuration
|
||||
@{
|
||||
*/
|
||||
|
||||
|
||||
// _________________ USB MODE CONFIGURATION ____________________________
|
||||
//! @ingroup usbconf
|
||||
//! @defgroup USB_op_mode USB operating modes configuration
|
||||
//! defines to enable device or host usb operating modes
|
||||
//! supported by the application
|
||||
//! @{
|
||||
|
||||
//! @brief ENABLE to activate the host software library support
|
||||
//!
|
||||
//! Possible values ENABLE or DISABLE
|
||||
#define USB_HOST_FEATURE DISABLED
|
||||
|
||||
//! @brief ENABLE to activate the device software library support
|
||||
//!
|
||||
//! Possible values ENABLE or DISABLE
|
||||
#define USB_DEVICE_FEATURE ENABLED
|
||||
|
||||
//! @}
|
||||
|
||||
// _________________ USB REGULATOR CONFIGURATION _______________________
|
||||
//! @ingroup usbconf
|
||||
//! @defgroup USB_reg_mode USB regulator configuration
|
||||
//! @{
|
||||
|
||||
//! @brief Enable the internal regulator for USB pads
|
||||
//!
|
||||
//! When the application voltage is lower than 3.5V, to optimize power consumption
|
||||
//! the internal USB pads regulatr can be disabled.
|
||||
#ifndef USE_USB_PADS_REGULATOR
|
||||
#define USE_USB_PADS_REGULATOR ENABLE // Possible values ENABLE or DISABLE
|
||||
#endif
|
||||
//! @}
|
||||
|
||||
// _________________ DEVICE MODE CONFIGURATION __________________________
|
||||
|
||||
//! @ingroup usbconf
|
||||
//! @defgroup USB_device_mode_cfg USB device operating mode configuration
|
||||
//!
|
||||
//! @{
|
||||
|
||||
/** USB RNDIS / Virtual com port setup **/
|
||||
|
||||
#define NB_ENDPOINTS 7 //! number of endpoints in the application including control endpoint
|
||||
#define VCP_RX_EP 0x06
|
||||
#define VCP_TX_EP 0x05
|
||||
#define VCP_INT_EP 0x04
|
||||
#define TX_EP 0x02
|
||||
#define RX_EP 0x03
|
||||
#define INT_EP 0x01
|
||||
|
||||
/** USB Mass Storage Setup **/
|
||||
|
||||
#define NB_ENDPOINTS_MS 3 //! number of endpoints in the application including control endpoint
|
||||
#define MS_IN_EP 0x01
|
||||
#define MS_OUT_EP 0x02
|
||||
|
||||
#define USB_LOW_SPEED_DEVICE DISABLE
|
||||
|
||||
|
||||
#define Usb_unicode(a) ((U16)(a))
|
||||
|
||||
//! @ingroup usbconf
|
||||
//! @defgroup device_cst_actions USB device custom actions
|
||||
//!
|
||||
//! @{
|
||||
// write here the action to associate to each USB event
|
||||
// be carefull not to waste time in order not disturbing the functions
|
||||
#define Usb_sof_action() /* sof_action(); */
|
||||
#define Usb_wake_up_action()
|
||||
#define Usb_resume_action()
|
||||
#define Usb_suspend_action() suspend_action();
|
||||
#define Usb_reset_action()
|
||||
#define Usb_vbus_on_action()
|
||||
#define Usb_vbus_off_action()
|
||||
#define Usb_set_configuration_action()
|
||||
|
||||
|
||||
// write here the action to associate to each SCSI event
|
||||
// be carefull not to waste time in order not disturbing the functions
|
||||
#define Scsi_start_read_action() Led1_on()
|
||||
#define Scsi_stop_read_action() Led1_off()
|
||||
#define Scsi_start_write_action() Led2_on()
|
||||
#define Scsi_stop_write_action() Led2_off()
|
||||
|
||||
//! @}
|
||||
|
||||
extern void sof_action(void);
|
||||
extern void suspend_action(void);
|
||||
//! @}
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif // _CONF_USB_H_
|
114
cpu/avr/dev/usb/config.h
Normal file
114
cpu/avr/dev/usb/config.h
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file *********************************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file contains the system configuration definition.
|
||||
*
|
||||
* \par Application note:
|
||||
* AVR280: USB Host CDC Demonstration
|
||||
*
|
||||
* \par Documentation
|
||||
* For comprehensive code documentation, supported compilers, compiler
|
||||
* settings and supported devices see readme.html
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
*
|
||||
* $Name: $
|
||||
* $Revision: 1.1 $
|
||||
* $RCSfile: config.h,v $
|
||||
* $Date: 2008/10/14 20:16:36 $ \n
|
||||
* $Id: config.h,v 1.1 2008/10/14 20:16:36 c_oflynn Exp $
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _CONFIG_H_
|
||||
#define _CONFIG_H_
|
||||
|
||||
/**
|
||||
@addtogroup usb
|
||||
@{
|
||||
*/
|
||||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
|
||||
#include "compiler.h" //!< Compiler definitions
|
||||
|
||||
#include "contiki-raven.h"
|
||||
|
||||
#ifdef AVRGCC
|
||||
#define __AVR_AT90USBxxx__
|
||||
#include <avr/io.h>
|
||||
#else
|
||||
#include "lib_mcu/mcu.h" //!< Register declaration
|
||||
#endif
|
||||
|
||||
//#include "conf_scheduler.h" //!< Scheduler tasks declaration
|
||||
|
||||
//! Enable or not the ADC usage
|
||||
#undef USE_ADC
|
||||
|
||||
//! CPU core frequency in kHz
|
||||
#define FOSC 8000
|
||||
|
||||
|
||||
// -------- END Generic Configuration -------------------------------------
|
||||
|
||||
// UART Sample configuration, if we have one ... __________________________
|
||||
|
||||
#ifndef AVRGCC
|
||||
#define uart_usb_putchar putchar
|
||||
#endif
|
||||
#define r_uart_ptchar int
|
||||
#define p_uart_ptchar int
|
||||
|
||||
#define NB_MS_BEFORE_FLUSH 50
|
||||
#define REPEAT_KEY_PRESSED 100
|
||||
|
||||
// ADC Sample configuration, if we have one ... ___________________________
|
||||
|
||||
//! ADC Prescaler value
|
||||
#define ADC_PRESCALER 64
|
||||
//! Right adjust
|
||||
#define ADC_RIGHT_ADJUST_RESULT 1
|
||||
//! AVCC As reference voltage (See adc_drv.h)
|
||||
#define ADC_INTERNAL_VREF 2
|
||||
|
||||
//!--------- Device Mass Storage Identifiers Signature -----------------------
|
||||
#define SBC_VENDOR_ID {'A','T','M','E','L',' ',' ',' '} // 8 Bytes only
|
||||
#define SBC_PRODUCT_ID {'R','Z','R','A','V','E','N','U','S','B',' ','D','O','C','S',' '} // 16 Bytes only
|
||||
#define SBC_REVISION_ID {'0','.','0','0'} // 4 Bytes only
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif // _CONFIG_H_
|
||||
|
124
cpu/avr/dev/usb/pll_drv.h
Normal file
124
cpu/avr/dev/usb/pll_drv.h
Normal file
|
@ -0,0 +1,124 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file *********************************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file contains the low level macros and definition for the USB PLL.
|
||||
*
|
||||
* \par Application note:
|
||||
* AVR280: USB Host CDC Demonstration
|
||||
*
|
||||
* \par Documentation
|
||||
* For comprehensive code documentation, supported compilers, compiler
|
||||
* settings and supported devices see readme.html
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
*
|
||||
* $Name: $
|
||||
* $Revision: 1.1 $
|
||||
* $RCSfile: pll_drv.h,v $
|
||||
* $Date: 2008/10/14 20:16:36 $ \n
|
||||
* $Id: pll_drv.h,v 1.1 2008/10/14 20:16:36 c_oflynn Exp $
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef PLL_DRV_H
|
||||
#define PLL_DRV_H
|
||||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
/**
|
||||
@addtogroup usb
|
||||
@{
|
||||
*/
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
//! @defgroup PLL_macros PLL Macros
|
||||
//! These functions allow to control the PLL
|
||||
//! @{
|
||||
#define PLLx24 ( (0<<PLLP2) | (0<<PLLP1) | (0<<PLLP0) )
|
||||
#define PLLx12 ( (0<<PLLP2) | (0<<PLLP1) | (1<<PLLP0) )
|
||||
#define PLLx08 ( (0<<PLLP2) | (1<<PLLP1) | (0<<PLLP0) )
|
||||
#define PLLx06 ( (0<<PLLP2) | (1<<PLLP1) | (1<<PLLP0) )
|
||||
#define PLLx04 ( (1<<PLLP2) | (0<<PLLP1) | (0<<PLLP0) )
|
||||
#define PLLx03 ( (1<<PLLP2) | (0<<PLLP1) | (1<<PLLP0) )
|
||||
#define PLLx04_8 ( (1<<PLLP2) | (1<<PLLP1) | (0<<PLLP0) )
|
||||
#define PLLx02 ( (1<<PLLP2) | (1<<PLLP1) | (1<<PLLP0) )
|
||||
|
||||
|
||||
//! @brief Start the PLL at only 48 MHz, regarding CPU frequency
|
||||
//! Start the USB PLL with clockfactor
|
||||
//! clockfactor can be PLLx24, PLLx12, PLLx08
|
||||
//! PLLx06, PLLx04, PLLx03
|
||||
#define Start_pll(clockfactor) \
|
||||
(PLLCSR = ( clockfactor | (1<<PLLE) ))
|
||||
|
||||
//! return 1 when PLL locked
|
||||
#define Is_pll_ready() (PLLCSR & (1<<PLOCK) )
|
||||
|
||||
//! Test PLL lock bit and wait until lock is set
|
||||
#define Wait_pll_ready() while (!(PLLCSR & (1<<PLOCK)))
|
||||
|
||||
//! Stop the PLL
|
||||
#define Stop_pll() (PLLCSR &= (~(1<<PLLE)) )
|
||||
|
||||
// Start the PLL in autofactor mode
|
||||
// regarding FOSC define
|
||||
#if (FOSC==2000)
|
||||
//! Start the PLL in autofactor mode
|
||||
//! regarding FOSC define
|
||||
#define Pll_start_auto() Start_pll(PLLx24)
|
||||
#elif (FOSC==4000)
|
||||
#define Pll_start_auto() Start_pll(PLLx12)
|
||||
#elif (FOSC==6000)
|
||||
#define Pll_start_auto() Start_pll(PLLx08)
|
||||
#elif (FOSC==8000)
|
||||
//! Start the PLL in autofactor mode
|
||||
//! regarding FOSC define
|
||||
#define Pll_start_auto() Start_pll(PLLx06)
|
||||
#elif (FOSC==12000)
|
||||
#define Pll_start_auto() Start_pll(PLLx04)
|
||||
#elif (FOSC==16000)
|
||||
#define Pll_start_auto() Start_pll(PLLx03)
|
||||
#elif (FOSC==20000)
|
||||
#define Pll_start_auto() Start_pll(PLLx04_8)
|
||||
#elif (FOSC==24000)
|
||||
#define Pll_start_auto() Start_pll(PLLx02)
|
||||
#else
|
||||
#error "FOSC should be defined in config.h"
|
||||
#endif
|
||||
|
||||
//! @}
|
||||
|
||||
//! @}
|
||||
#endif // PLL_DRV_H
|
||||
|
||||
|
266
cpu/avr/dev/usb/rndis/ndis.h
Normal file
266
cpu/avr/dev/usb/rndis/ndis.h
Normal file
|
@ -0,0 +1,266 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file ndis.h ***************************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file contains the possible external configuration of the USB.
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
\ingroup usbstick
|
||||
\defgroup RNDIS RNDIS Support
|
||||
@{
|
||||
*/
|
||||
|
||||
/*
|
||||
* ndis.h
|
||||
*
|
||||
* Modified by Colin O'Flynn <coflynn@newae.com>
|
||||
* ntddndis.h modified by Benedikt Spranger <b.spranger@pengutronix.de>
|
||||
*
|
||||
* Thanks to the cygwin development team,
|
||||
* espacially to Casper S. Hornstrup <chorns@users.sourceforge.net>
|
||||
*
|
||||
* THIS SOFTWARE IS NOT COPYRIGHTED
|
||||
*
|
||||
* This source code is offered for use in the public domain. You may
|
||||
* use, modify or distribute it freely.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful but
|
||||
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
|
||||
* DISCLAIMED. This includes but is not limited to warranties of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_NDIS_H
|
||||
#define _LINUX_NDIS_H
|
||||
|
||||
|
||||
#define NDIS_STATUS_MULTICAST_FULL 0xC0010009
|
||||
#define NDIS_STATUS_MULTICAST_EXISTS 0xC001000A
|
||||
#define NDIS_STATUS_MULTICAST_NOT_FOUND 0xC001000B
|
||||
|
||||
/* from drivers/net/sk98lin/h/skgepnmi.h */
|
||||
#define OID_PNP_CAPABILITIES 0xFD010100
|
||||
#define OID_PNP_SET_POWER 0xFD010101
|
||||
#define OID_PNP_QUERY_POWER 0xFD010102
|
||||
#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103
|
||||
#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104
|
||||
#define OID_PNP_ENABLE_WAKE_UP 0xFD010106
|
||||
|
||||
enum NDIS_DEVICE_POWER_STATE {
|
||||
NdisDeviceStateUnspecified = 0,
|
||||
NdisDeviceStateD0,
|
||||
NdisDeviceStateD1,
|
||||
NdisDeviceStateD2,
|
||||
NdisDeviceStateD3,
|
||||
NdisDeviceStateMaximum
|
||||
};
|
||||
|
||||
struct NDIS_PM_WAKE_UP_CAPABILITIES {
|
||||
enum NDIS_DEVICE_POWER_STATE MinMagicPacketWakeUp;
|
||||
enum NDIS_DEVICE_POWER_STATE MinPatternWakeUp;
|
||||
enum NDIS_DEVICE_POWER_STATE MinLinkChangeWakeUp;
|
||||
};
|
||||
|
||||
/* NDIS_PNP_CAPABILITIES.Flags constants */
|
||||
#define NDIS_DEVICE_WAKE_UP_ENABLE 0x00000001
|
||||
#define NDIS_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002
|
||||
#define NDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004
|
||||
|
||||
/*
|
||||
struct NDIS_PNP_CAPABILITIES {
|
||||
__le32 Flags;
|
||||
struct NDIS_PM_WAKE_UP_CAPABILITIES WakeUpCapabilities;
|
||||
};
|
||||
|
||||
struct NDIS_PM_PACKET_PATTERN {
|
||||
__le32 Priority;
|
||||
__le32 Reserved;
|
||||
__le32 MaskSize;
|
||||
__le32 PatternOffset;
|
||||
__le32 PatternSize;
|
||||
__le32 PatternFlags;
|
||||
};
|
||||
*/
|
||||
|
||||
/* Required Object IDs (OIDs) */
|
||||
#define OID_GEN_SUPPORTED_LIST 0x00010101
|
||||
#define OID_GEN_HARDWARE_STATUS 0x00010102
|
||||
#define OID_GEN_MEDIA_SUPPORTED 0x00010103
|
||||
#define OID_GEN_MEDIA_IN_USE 0x00010104
|
||||
#define OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105
|
||||
#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106
|
||||
#define OID_GEN_LINK_SPEED 0x00010107
|
||||
#define OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108
|
||||
#define OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109
|
||||
#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A
|
||||
#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B
|
||||
#define OID_GEN_VENDOR_ID 0x0001010C
|
||||
#define OID_GEN_VENDOR_DESCRIPTION 0x0001010D
|
||||
#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010E
|
||||
#define OID_GEN_CURRENT_LOOKAHEAD 0x0001010F
|
||||
#define OID_GEN_DRIVER_VERSION 0x00010110
|
||||
#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111
|
||||
#define OID_GEN_PROTOCOL_OPTIONS 0x00010112
|
||||
#define OID_GEN_MAC_OPTIONS 0x00010113
|
||||
#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114
|
||||
#define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115
|
||||
#define OID_GEN_VENDOR_DRIVER_VERSION 0x00010116
|
||||
#define OID_GEN_SUPPORTED_GUIDS 0x00010117
|
||||
#define OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118
|
||||
#define OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119
|
||||
#define OID_GEN_MACHINE_NAME 0x0001021A
|
||||
#define OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B
|
||||
#define OID_GEN_VLAN_ID 0x0001021C
|
||||
|
||||
/* Optional OIDs */
|
||||
#define OID_GEN_MEDIA_CAPABILITIES 0x00010201
|
||||
#define OID_GEN_PHYSICAL_MEDIUM 0x00010202
|
||||
|
||||
/* Required statistics OIDs */
|
||||
#define OID_GEN_XMIT_OK 0x00020101
|
||||
#define OID_GEN_RCV_OK 0x00020102
|
||||
#define OID_GEN_XMIT_ERROR 0x00020103
|
||||
#define OID_GEN_RCV_ERROR 0x00020104
|
||||
#define OID_GEN_RCV_NO_BUFFER 0x00020105
|
||||
|
||||
/* Optional statistics OIDs */
|
||||
#define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201
|
||||
#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202
|
||||
#define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203
|
||||
#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204
|
||||
#define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205
|
||||
#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206
|
||||
#define OID_GEN_DIRECTED_BYTES_RCV 0x00020207
|
||||
#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208
|
||||
#define OID_GEN_MULTICAST_BYTES_RCV 0x00020209
|
||||
#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A
|
||||
#define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B
|
||||
#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C
|
||||
#define OID_GEN_RCV_CRC_ERROR 0x0002020D
|
||||
#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E
|
||||
#define OID_GEN_GET_TIME_CAPS 0x0002020F
|
||||
#define OID_GEN_GET_NETCARD_TIME 0x00020210
|
||||
#define OID_GEN_NETCARD_LOAD 0x00020211
|
||||
#define OID_GEN_DEVICE_PROFILE 0x00020212
|
||||
#define OID_GEN_INIT_TIME_MS 0x00020213
|
||||
#define OID_GEN_RESET_COUNTS 0x00020214
|
||||
#define OID_GEN_MEDIA_SENSE_COUNTS 0x00020215
|
||||
#define OID_GEN_FRIENDLY_NAME 0x00020216
|
||||
#define OID_GEN_MINIPORT_INFO 0x00020217
|
||||
#define OID_GEN_RESET_VERIFY_PARAMETERS 0x00020218
|
||||
|
||||
/* IEEE 802.3 (Ethernet) OIDs */
|
||||
#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001
|
||||
|
||||
#define OID_802_3_PERMANENT_ADDRESS 0x01010101
|
||||
#define OID_802_3_CURRENT_ADDRESS 0x01010102
|
||||
#define OID_802_3_MULTICAST_LIST 0x01010103
|
||||
#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104
|
||||
#define OID_802_3_MAC_OPTIONS 0x01010105
|
||||
#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101
|
||||
#define OID_802_3_XMIT_ONE_COLLISION 0x01020102
|
||||
#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103
|
||||
#define OID_802_3_XMIT_DEFERRED 0x01020201
|
||||
#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202
|
||||
#define OID_802_3_RCV_OVERRUN 0x01020203
|
||||
#define OID_802_3_XMIT_UNDERRUN 0x01020204
|
||||
#define OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205
|
||||
#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206
|
||||
#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207
|
||||
|
||||
/* Wireless LAN OIDs */
|
||||
//Mandatory
|
||||
#define OID_802_11_BSSID 0x0D010101 /* Q S */
|
||||
#define OID_802_11_SSID 0x0D010102 /* Q S */
|
||||
#define OID_802_11_NETWORK_TYPE_IN_USE 0x0D010204 /* Q S */
|
||||
#define OID_802_11_RSSI 0x0D010206 /* Q I */
|
||||
#define OID_802_11_BSSID_LIST 0x0D010217 /* Q */
|
||||
#define OID_802_11_BSSID_LIST_SCAN 0x0D01011A /* S */
|
||||
#define OID_802_11_INFRASTRUCTURE_MODE 0x0D010108 /* Q S */
|
||||
#define OID_802_11_SUPPORTED_RATES 0x0D01020E /* Q */
|
||||
#define OID_802_11_CONFIGURATION 0x0D010211 /* Q S */
|
||||
#define OID_802_11_ADD_WEP 0x0D010113 /* S */
|
||||
#define OID_802_11_WEP_STATUS 0x0D01011B /* Q S */
|
||||
#define OID_802_11_REMOVE_WEP 0x0D010114 /* S */
|
||||
#define OID_802_11_DISASSOCIATE 0x0D010115 /* S */
|
||||
#define OID_802_11_AUTHENTICATION_MODE 0x0D010118 /* Q S */
|
||||
#define OID_802_11_RELOAD_DEFAULTS 0x0D01011C /* S */
|
||||
|
||||
|
||||
|
||||
/* OID_GEN_MINIPORT_INFO constants */
|
||||
#define NDIS_MINIPORT_BUS_MASTER 0x00000001
|
||||
#define NDIS_MINIPORT_WDM_DRIVER 0x00000002
|
||||
#define NDIS_MINIPORT_SG_LIST 0x00000004
|
||||
#define NDIS_MINIPORT_SUPPORTS_MEDIA_QUERY 0x00000008
|
||||
#define NDIS_MINIPORT_INDICATES_PACKETS 0x00000010
|
||||
#define NDIS_MINIPORT_IGNORE_PACKET_QUEUE 0x00000020
|
||||
#define NDIS_MINIPORT_IGNORE_REQUEST_QUEUE 0x00000040
|
||||
#define NDIS_MINIPORT_IGNORE_TOKEN_RING_ERRORS 0x00000080
|
||||
#define NDIS_MINIPORT_INTERMEDIATE_DRIVER 0x00000100
|
||||
#define NDIS_MINIPORT_IS_NDIS_5 0x00000200
|
||||
#define NDIS_MINIPORT_IS_CO 0x00000400
|
||||
#define NDIS_MINIPORT_DESERIALIZE 0x00000800
|
||||
#define NDIS_MINIPORT_REQUIRES_MEDIA_POLLING 0x00001000
|
||||
#define NDIS_MINIPORT_SUPPORTS_MEDIA_SENSE 0x00002000
|
||||
#define NDIS_MINIPORT_NETBOOT_CARD 0x00004000
|
||||
#define NDIS_MINIPORT_PM_SUPPORTED 0x00008000
|
||||
#define NDIS_MINIPORT_SUPPORTS_MAC_ADDRESS_OVERWRITE 0x00010000
|
||||
#define NDIS_MINIPORT_USES_SAFE_BUFFER_APIS 0x00020000
|
||||
#define NDIS_MINIPORT_HIDDEN 0x00040000
|
||||
#define NDIS_MINIPORT_SWENUM 0x00080000
|
||||
#define NDIS_MINIPORT_SURPRISE_REMOVE_OK 0x00100000
|
||||
#define NDIS_MINIPORT_NO_HALT_ON_SUSPEND 0x00200000
|
||||
#define NDIS_MINIPORT_HARDWARE_DEVICE 0x00400000
|
||||
#define NDIS_MINIPORT_SUPPORTS_CANCEL_SEND_PACKETS 0x00800000
|
||||
#define NDIS_MINIPORT_64BITS_DMA 0x01000000
|
||||
|
||||
#define NDIS_MEDIUM_802_3 0x00000000
|
||||
#define NDIS_MEDIUM_802_5 0x00000001
|
||||
#define NDIS_MEDIUM_FDDI 0x00000002
|
||||
#define NDIS_MEDIUM_WAN 0x00000003
|
||||
#define NDIS_MEDIUM_LOCAL_TALK 0x00000004
|
||||
#define NDIS_MEDIUM_DIX 0x00000005
|
||||
#define NDIS_MEDIUM_ARCENT_RAW 0x00000006
|
||||
#define NDIS_MEDIUM_ARCENT_878_2 0x00000007
|
||||
#define NDIS_MEDIUM_ATM 0x00000008
|
||||
#define NDIS_MEDIUM_WIRELESS_LAN 0x00000009
|
||||
#define NDIS_MEDIUM_IRDA 0x0000000A
|
||||
#define NDIS_MEDIUM_BPC 0x0000000B
|
||||
#define NDIS_MEDIUM_CO_WAN 0x0000000C
|
||||
#define NDIS_MEDIUM_1394 0x0000000D
|
||||
|
||||
#define NDIS_PACKET_TYPE_DIRECTED 0x00000001
|
||||
#define NDIS_PACKET_TYPE_MULTICAST 0x00000002
|
||||
#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004
|
||||
#define NDIS_PACKET_TYPE_BROADCAST 0x00000008
|
||||
#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010
|
||||
#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020
|
||||
#define NDIS_PACKET_TYPE_SMT 0x00000040
|
||||
#define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080
|
||||
#define NDIS_PACKET_TYPE_GROUP 0x00000100
|
||||
#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00000200
|
||||
#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00000400
|
||||
#define NDIS_PACKET_TYPE_MAC_FRAME 0x00000800
|
||||
|
||||
#define NDIS_MEDIA_STATE_CONNECTED 0x00000000
|
||||
#define NDIS_MEDIA_STATE_DISCONNECTED 0x00000001
|
||||
|
||||
#define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA 0x00000001
|
||||
#define NDIS_MAC_OPTION_RECEIVE_SERIALIZED 0x00000002
|
||||
#define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND 0x00000004
|
||||
#define NDIS_MAC_OPTION_NO_LOOPBACK 0x00000008
|
||||
#define NDIS_MAC_OPTION_FULL_DUPLEX 0x00000010
|
||||
#define NDIS_MAC_OPTION_EOTX_INDICATION 0x00000020
|
||||
#define NDIS_MAC_OPTION_8021P_PRIORITY 0x00000040
|
||||
#define NDIS_MAC_OPTION_RESERVED 0x80000000
|
||||
|
||||
#endif /* _LINUX_NDIS_H */
|
||||
|
||||
/** @} */
|
842
cpu/avr/dev/usb/rndis/rndis.c
Normal file
842
cpu/avr/dev/usb/rndis/rndis.c
Normal file
|
@ -0,0 +1,842 @@
|
|||
/**
|
||||
* \file rndis.c
|
||||
* RNDIS Functions for mounting USB device as network interface
|
||||
*
|
||||
* \author
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*/
|
||||
/* Copyright (c) 2008 Colin O'Flynn
|
||||
|
||||
The CDC code which this is based on is Copyright (c) Atmel Corporation 2008
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
RNDIS Status Information:
|
||||
|
||||
802.3 Support:
|
||||
More or less working
|
||||
|
||||
802.11 Support:
|
||||
Incomplete, would just error out if you tried probably
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup RNDIS
|
||||
@{
|
||||
*/
|
||||
|
||||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
#include "radio.h"
|
||||
#include "contiki.h"
|
||||
#include "config.h"
|
||||
#include "usb_drv.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "usb_specific_request.h"
|
||||
#include "rndis/rndis_protocol.h"
|
||||
#include "uip.h"
|
||||
#include "serial/uart_usb_lib.h"
|
||||
#include "sicslow_ethernet.h"
|
||||
#include <avr/pgmspace.h>
|
||||
#include <string.h>
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
//_____ D E F I N I T I O N ________________________________________________
|
||||
|
||||
//_____ P R I V A T E D E C L A R A T I O N ______________________________
|
||||
|
||||
extern PGM_VOID_P pbuffer;
|
||||
extern U8 data_to_transfer;
|
||||
|
||||
//NB: If you change the OID list be sure to update this!!!
|
||||
//#define OID_LIST_LENGTH 50
|
||||
#define OID_LIST_LENGTH 35
|
||||
|
||||
/**
|
||||
* \brief List of supported RNDIS OID's
|
||||
*/
|
||||
prog_uint32_t OIDSupportedList[OID_LIST_LENGTH] = {
|
||||
/* Required General */
|
||||
OID_GEN_SUPPORTED_LIST ,
|
||||
OID_GEN_HARDWARE_STATUS ,
|
||||
OID_GEN_MEDIA_SUPPORTED ,
|
||||
OID_GEN_MEDIA_IN_USE ,
|
||||
OID_GEN_MAXIMUM_FRAME_SIZE ,
|
||||
OID_GEN_LINK_SPEED ,
|
||||
OID_GEN_TRANSMIT_BLOCK_SIZE ,
|
||||
OID_GEN_RECEIVE_BLOCK_SIZE ,
|
||||
OID_GEN_VENDOR_ID ,
|
||||
OID_GEN_VENDOR_DESCRIPTION ,
|
||||
OID_GEN_CURRENT_PACKET_FILTER ,
|
||||
OID_GEN_MAXIMUM_TOTAL_SIZE ,
|
||||
OID_GEN_MEDIA_CONNECT_STATUS ,
|
||||
OID_GEN_VENDOR_DRIVER_VERSION ,
|
||||
OID_GEN_PHYSICAL_MEDIUM ,
|
||||
|
||||
/* Required Statistical */
|
||||
OID_GEN_XMIT_OK ,
|
||||
OID_GEN_RCV_OK ,
|
||||
OID_GEN_XMIT_ERROR ,
|
||||
OID_GEN_RCV_ERROR ,
|
||||
OID_GEN_RCV_NO_BUFFER ,
|
||||
|
||||
/* Please configure us */
|
||||
OID_GEN_RNDIS_CONFIG_PARAMETER ,
|
||||
|
||||
|
||||
/* IEEE 802.3 (Ethernet) OIDs */
|
||||
OID_802_3_PERMANENT_ADDRESS ,
|
||||
OID_802_3_CURRENT_ADDRESS ,
|
||||
OID_802_3_MULTICAST_LIST ,
|
||||
OID_802_3_MAXIMUM_LIST_SIZE ,
|
||||
OID_802_3_MAC_OPTIONS ,
|
||||
OID_802_3_RCV_ERROR_ALIGNMENT ,
|
||||
OID_802_3_XMIT_ONE_COLLISION ,
|
||||
OID_802_3_XMIT_MORE_COLLISIONS ,
|
||||
|
||||
/*802.11 OID's not fully implemented yet. Hence do not say we
|
||||
support them */
|
||||
#ifdef DONOTEVERDEFINETHISORBADSTUFFHAPPENS
|
||||
/* 802.11 OIDs */
|
||||
OID_802_11_BSSID ,
|
||||
OID_802_11_SSID ,
|
||||
OID_802_11_NETWORK_TYPE_IN_USE ,
|
||||
OID_802_11_RSSI ,
|
||||
OID_802_11_BSSID_LIST ,
|
||||
OID_802_11_BSSID_LIST_SCAN ,
|
||||
OID_802_11_INFRASTRUCTURE_MODE ,
|
||||
OID_802_11_SUPPORTED_RATES ,
|
||||
OID_802_11_CONFIGURATION ,
|
||||
OID_802_11_ADD_WEP ,
|
||||
OID_802_11_WEP_STATUS ,
|
||||
OID_802_11_REMOVE_WEP ,
|
||||
OID_802_11_DISASSOCIATE ,
|
||||
OID_802_11_AUTHENTICATION_MODE ,
|
||||
OID_802_11_RELOAD_DEFAULTS ,
|
||||
#endif
|
||||
|
||||
/* Minimum power managment needed for USB */
|
||||
|
||||
OID_PNP_CAPABILITIES ,
|
||||
OID_PNP_QUERY_POWER ,
|
||||
OID_PNP_SET_POWER ,
|
||||
|
||||
OID_PNP_ENABLE_WAKE_UP ,
|
||||
OID_PNP_ADD_WAKE_UP_PATTERN ,
|
||||
OID_PNP_REMOVE_WAKE_UP_PATTERN
|
||||
|
||||
};
|
||||
|
||||
|
||||
rndis_state_t rndis_state;
|
||||
|
||||
rndis_stat_t rndis_stat;
|
||||
|
||||
uint8_t schedule_interrupt = 0;
|
||||
|
||||
uint64_t rndis_ethernet_addr = 0x203478928323UL;
|
||||
|
||||
//_____ D E C L A R A T I O N ______________________________________________
|
||||
|
||||
|
||||
void rndis_packetFilter(uint32_t newfilter);
|
||||
|
||||
/******** RNDIS ********/
|
||||
|
||||
#define ENC_BUF_SIZE (4*OID_LIST_LENGTH + 32)
|
||||
|
||||
// Command buffer
|
||||
U8 encapsulated_buffer[ENC_BUF_SIZE];
|
||||
|
||||
//Do we have data to send back?
|
||||
U8 data_to_send = 0x00;
|
||||
|
||||
/**
|
||||
* \brief Handles a "SEND ENCAPSULATED COMMAND" message.
|
||||
*
|
||||
* \return True on success, false on failure.
|
||||
*/
|
||||
uint8_t send_encapsulated_command(uint16_t wLength)
|
||||
{
|
||||
U8 i = 0;
|
||||
|
||||
//Received setup message OK
|
||||
Usb_ack_receive_setup();
|
||||
|
||||
|
||||
//Crude bounds check
|
||||
if (wLength > ENC_BUF_SIZE)
|
||||
wLength = ENC_BUF_SIZE;
|
||||
|
||||
//For debugging: this shouldn't happen, just checked it didn't
|
||||
//if (data_to_send) {
|
||||
// while(1);
|
||||
//}
|
||||
|
||||
|
||||
//Read in all the bytes...
|
||||
|
||||
uint8_t nb_counter;
|
||||
|
||||
|
||||
while (wLength) {
|
||||
nb_counter = EP_CONTROL_LENGTH;
|
||||
|
||||
//Wait for data to come in
|
||||
while (!(Is_usb_receive_out()));
|
||||
|
||||
while(nb_counter && wLength) {
|
||||
encapsulated_buffer[i] = Usb_read_byte();
|
||||
i++;
|
||||
wLength--;
|
||||
nb_counter--;
|
||||
}
|
||||
|
||||
Usb_ack_receive_out();
|
||||
|
||||
}
|
||||
|
||||
Usb_send_control_in();
|
||||
|
||||
|
||||
switch(((rndis_generic_msg_t *)encapsulated_buffer)->MessageType)
|
||||
{
|
||||
/* Requests remote intilization. Respond with complete,
|
||||
eventually should probably do something */
|
||||
case REMOTE_NDIS_INITIALIZE_MSG:
|
||||
{
|
||||
rndis_initialize_cmplt_t * m;
|
||||
m = ((rndis_initialize_cmplt_t *)encapsulated_buffer);
|
||||
|
||||
//m->MessageID is same as before
|
||||
m->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT;
|
||||
m->MessageLength = sizeof(rndis_initialize_cmplt_t);
|
||||
m->MajorVersion = RNDIS_MAJOR_VERSION;
|
||||
m->MinorVersion = RNDIS_MAJOR_VERSION;
|
||||
m->Status = RNDIS_STATUS_SUCCESS;
|
||||
m->DeviceFlags = RNDIS_DF_CONNECTIONLESS;
|
||||
m->Medium = RNDIS_MEDIUM_802_3;
|
||||
m->MaxPacketsPerTransfer = 1;
|
||||
m->MaxTransferSize = 1338; /* Space for 1280 IP buffer, Ethernet Header,
|
||||
RNDIS messages */
|
||||
m->PacketAlignmentFactor = 3;
|
||||
m->AfListOffset = 0;
|
||||
m->AfListSize = 0;
|
||||
|
||||
rndis_state = rndis_initialized;
|
||||
|
||||
data_to_send = m->MessageLength;
|
||||
}
|
||||
break;
|
||||
case REMOTE_NDIS_HALT_MSG:
|
||||
|
||||
Led0_on();
|
||||
Led1_on();
|
||||
Led2_on();
|
||||
Led3_on();
|
||||
|
||||
|
||||
Usb_send_control_in();
|
||||
|
||||
while(1);
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case REMOTE_NDIS_QUERY_MSG:
|
||||
rndis_query_process();
|
||||
break;
|
||||
|
||||
case REMOTE_NDIS_SET_MSG:
|
||||
{
|
||||
rndis_set_process();
|
||||
}
|
||||
break;
|
||||
|
||||
case REMOTE_NDIS_RESET_MSG:
|
||||
{
|
||||
rndis_reset_cmplt_t * m;
|
||||
m = ((rndis_reset_cmplt_t *)encapsulated_buffer);
|
||||
|
||||
rndis_state = rndis_uninitialized;
|
||||
|
||||
m->MessageType = REMOTE_NDIS_RESET_CMPLT;
|
||||
m->MessageLength = sizeof(rndis_reset_cmplt_t);
|
||||
m->Status = RNDIS_STATUS_SUCCESS;
|
||||
m->AddressingReset = 1; /* Make it look like we did something */
|
||||
// m->AddressingReset = 0; //Windows halts if set to 1 for some reason
|
||||
data_to_send = m->MessageLength;
|
||||
}
|
||||
break;
|
||||
|
||||
case REMOTE_NDIS_KEEPALIVE_MSG:
|
||||
{
|
||||
rndis_keepalive_cmplt_t * m;
|
||||
m = (rndis_keepalive_cmplt_t *)encapsulated_buffer;
|
||||
m->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT;
|
||||
m->MessageLength = sizeof(rndis_keepalive_cmplt_t);
|
||||
m->Status = RNDIS_STATUS_SUCCESS;
|
||||
|
||||
//We have data to send back
|
||||
data_to_send = m->MessageLength;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Led2_on();
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
while(!(Is_usb_read_control_enabled()));
|
||||
|
||||
if (Is_usb_receive_out()) Usb_ack_receive_out();
|
||||
|
||||
rndis_send_interrupt();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Send an interrupt over the interrupt endpoint to the host.
|
||||
*/
|
||||
void rndis_send_interrupt(void)
|
||||
{
|
||||
|
||||
//Schedule the interrupt to take place next
|
||||
//time USB task is run
|
||||
schedule_interrupt = 1;
|
||||
}
|
||||
|
||||
#define INFBUF ((uint32_t *)(encapsulated_buffer + sizeof(rndis_query_cmplt_t)))
|
||||
|
||||
uint32_t oid_packet_filter = 0x0000000;
|
||||
|
||||
uint16_t panid = 0xbaad;
|
||||
|
||||
/**
|
||||
* \brief Function to handle a RNDIS "QUERY" command in the encapsulated_buffer
|
||||
*/
|
||||
void rndis_query_process(void)
|
||||
{
|
||||
rndis_query_msg_t * m;
|
||||
rndis_query_cmplt_t * c;
|
||||
rndis_Status_t status = RNDIS_STATUS_SUCCESS;
|
||||
|
||||
m = (rndis_query_msg_t *)encapsulated_buffer;
|
||||
c = (rndis_query_cmplt_t *)encapsulated_buffer;
|
||||
|
||||
/* We set up packet for sending one 4-byte response, which a lot of
|
||||
these will do. If you need more or less just change the defaults in
|
||||
the specific case */
|
||||
|
||||
c->MessageType = REMOTE_NDIS_QUERY_CMPLT;
|
||||
//c->Status DO NOT SET YET - as m->Oid resides in this space. We still need it...
|
||||
c->InformationBufferLength = 4;
|
||||
c->InformationBufferOffset = 16;
|
||||
|
||||
switch (m->Oid) {
|
||||
|
||||
/**** GENERAL ****/
|
||||
case OID_GEN_SUPPORTED_LIST:
|
||||
c->InformationBufferLength = 4 * OID_LIST_LENGTH;
|
||||
|
||||
//Copy data to SRAM
|
||||
memcpy_P(INFBUF, OIDSupportedList, 4*OID_LIST_LENGTH);
|
||||
break;
|
||||
|
||||
case OID_GEN_HARDWARE_STATUS:
|
||||
*INFBUF = 0x00000000; /* Ready and Willing */
|
||||
break;
|
||||
|
||||
case OID_GEN_MEDIA_SUPPORTED:
|
||||
case OID_GEN_MEDIA_IN_USE:
|
||||
*INFBUF = NDIS_MEDIUM_802_3; /* NDIS_MEDIUM_WIRELESS_LAN instead? */
|
||||
break;
|
||||
|
||||
case OID_GEN_MAXIMUM_FRAME_SIZE:
|
||||
*INFBUF = (uint32_t) 1280; //1280 //102; /* Assume 25 octet header on 15.4 */
|
||||
break;
|
||||
|
||||
case OID_GEN_LINK_SPEED:
|
||||
*INFBUF = (uint32_t) 100; /* in 100 bytes/sec units.. this is kinda a lie */
|
||||
break;
|
||||
|
||||
case OID_GEN_TRANSMIT_BLOCK_SIZE:
|
||||
case OID_GEN_RECEIVE_BLOCK_SIZE:
|
||||
*INFBUF = (uint32_t) 102;
|
||||
break;
|
||||
|
||||
case OID_GEN_VENDOR_ID:
|
||||
*INFBUF = 0xFFFFFF; /* No vendor ID ! */
|
||||
break;
|
||||
|
||||
case OID_GEN_VENDOR_DESCRIPTION:
|
||||
c->InformationBufferLength = 8;
|
||||
memcpy_P(INFBUF, PSTR("Atmel\0\0\0\0"), 8);
|
||||
break;
|
||||
|
||||
case OID_GEN_CURRENT_PACKET_FILTER:
|
||||
*INFBUF = oid_packet_filter;
|
||||
break;
|
||||
|
||||
case OID_GEN_MAXIMUM_TOTAL_SIZE:
|
||||
*INFBUF = (uint32_t) 1300; //127;
|
||||
break;
|
||||
|
||||
case OID_GEN_MEDIA_CONNECT_STATUS:
|
||||
*INFBUF = NDIS_MEDIA_STATE_CONNECTED;
|
||||
break;
|
||||
|
||||
case OID_GEN_VENDOR_DRIVER_VERSION:
|
||||
*INFBUF = 0x00001000;
|
||||
break;
|
||||
|
||||
case OID_GEN_PHYSICAL_MEDIUM:
|
||||
*INFBUF = NDIS_MEDIUM_802_3; /*NDIS_MEDIUM_WIRELESS_LAN;*/
|
||||
break;
|
||||
|
||||
case OID_GEN_CURRENT_LOOKAHEAD:
|
||||
*INFBUF = (uint32_t) 1280; //102;
|
||||
|
||||
/******* 802.3 (Ethernet) *******/
|
||||
|
||||
/*The address of the NIC encoded in the hardware.*/
|
||||
case OID_802_3_PERMANENT_ADDRESS:
|
||||
|
||||
//Clear unused bytes
|
||||
*(INFBUF + 1) = 0;
|
||||
|
||||
//Set address
|
||||
*((uint8_t *)INFBUF + 0) = *(((uint8_t * ) &rndis_ethernet_addr) + 5);
|
||||
*((uint8_t *)INFBUF + 1) = *(((uint8_t * ) &rndis_ethernet_addr) + 4);
|
||||
*((uint8_t *)INFBUF + 2) = *(((uint8_t * ) &rndis_ethernet_addr) + 3);
|
||||
*((uint8_t *)INFBUF + 3) = *(((uint8_t * ) &rndis_ethernet_addr) + 2);
|
||||
*((uint8_t *)INFBUF + 4) = *(((uint8_t * ) &rndis_ethernet_addr) + 1);
|
||||
*((uint8_t *)INFBUF + 5) = *(((uint8_t * ) &rndis_ethernet_addr) + 0);
|
||||
|
||||
|
||||
/*4+2 = 6 Bytes of eth address */
|
||||
c->InformationBufferLength += 2;
|
||||
break;
|
||||
|
||||
/*The address the NIC is currently using.*/
|
||||
case OID_802_3_CURRENT_ADDRESS:
|
||||
//Clear unused bytes
|
||||
*(INFBUF + 1) = 0;
|
||||
|
||||
//Set address
|
||||
*((uint8_t *)INFBUF + 0) = *(((uint8_t * ) &rndis_ethernet_addr) + 5);
|
||||
*((uint8_t *)INFBUF + 1) = *(((uint8_t * ) &rndis_ethernet_addr) + 4);
|
||||
*((uint8_t *)INFBUF + 2) = *(((uint8_t * ) &rndis_ethernet_addr) + 3);
|
||||
*((uint8_t *)INFBUF + 3) = *(((uint8_t * ) &rndis_ethernet_addr) + 2);
|
||||
*((uint8_t *)INFBUF + 4) = *(((uint8_t * ) &rndis_ethernet_addr) + 1);
|
||||
*((uint8_t *)INFBUF + 5) = *(((uint8_t * ) &rndis_ethernet_addr) + 0);
|
||||
|
||||
/*4+2 = 6 Bytes of eth address */
|
||||
c->InformationBufferLength += 2;
|
||||
break;
|
||||
|
||||
/* The multicast address list on the NIC enabled for packet reception. */
|
||||
case OID_802_3_MULTICAST_LIST:
|
||||
*INFBUF = 0xE000000;
|
||||
break;
|
||||
|
||||
/* The maximum number of multicast addresses the NIC driver can manage. */
|
||||
case OID_802_3_MAXIMUM_LIST_SIZE:
|
||||
*INFBUF = 1;
|
||||
break;
|
||||
|
||||
/* Features supported by the underlying driver, which could be emulating Ethernet. */
|
||||
case OID_802_3_MAC_OPTIONS:
|
||||
*INFBUF = 0;
|
||||
break;
|
||||
|
||||
/* Frames received with alignment error */
|
||||
case OID_802_3_RCV_ERROR_ALIGNMENT:
|
||||
*INFBUF = 0;
|
||||
break;
|
||||
|
||||
/* Frames transmitted with one collision */
|
||||
case OID_802_3_XMIT_ONE_COLLISION:
|
||||
*INFBUF = 0;
|
||||
break;
|
||||
|
||||
/* Frames transmitted with more than one collision */
|
||||
case OID_802_3_XMIT_MORE_COLLISIONS:
|
||||
*INFBUF = 0;
|
||||
break;
|
||||
|
||||
|
||||
/*** 802.11 OIDs ***/
|
||||
case OID_802_11_BSSID:
|
||||
*INFBUF = (uint32_t)panid;
|
||||
*(INFBUF + 1) = 0;
|
||||
|
||||
/*4+2 = 6 Bytes of eth address */
|
||||
c->InformationBufferLength += 2;
|
||||
break;
|
||||
|
||||
case OID_802_11_SSID:
|
||||
/* Our SSID is *always* "PANID: 0xXXXX", length = 13 */
|
||||
*INFBUF = 13;
|
||||
|
||||
strncpy_P((char*)(INFBUF + 1), PSTR("PANID: 0xBAAD"), 13);
|
||||
break;
|
||||
|
||||
case OID_802_11_NETWORK_TYPE_IN_USE:
|
||||
*INFBUF = 0; /* Ndis802_11FH - it's all lies anyway */
|
||||
break;
|
||||
|
||||
case OID_802_11_RSSI:
|
||||
*((int32_t *) INFBUF) = -20; //-20 dBm
|
||||
break;
|
||||
|
||||
case OID_802_11_BSSID_LIST:
|
||||
break;
|
||||
|
||||
/* todo: */
|
||||
case OID_802_11_INFRASTRUCTURE_MODE:
|
||||
case OID_802_11_SUPPORTED_RATES:
|
||||
case OID_802_11_CONFIGURATION:
|
||||
case OID_802_11_WEP_STATUS:
|
||||
case OID_802_11_AUTHENTICATION_MODE:
|
||||
break;
|
||||
|
||||
/*** Statistical ***/
|
||||
|
||||
/* Frames transmitted without errors */
|
||||
case OID_GEN_XMIT_OK:
|
||||
*INFBUF = rndis_stat.txok;
|
||||
break;
|
||||
|
||||
/* Frames received without errors */
|
||||
case OID_GEN_RCV_OK:
|
||||
*INFBUF = rndis_stat.rxok;
|
||||
break;
|
||||
|
||||
/* Frames received with errors */
|
||||
case OID_GEN_RCV_ERROR:
|
||||
*INFBUF = rndis_stat.rxbad;
|
||||
break;
|
||||
|
||||
/* Frames transmitted with errors */
|
||||
case OID_GEN_XMIT_ERROR:
|
||||
*INFBUF = rndis_stat.txbad;
|
||||
break;
|
||||
|
||||
/* Frames dropped due to lack of buffer space */
|
||||
case OID_GEN_RCV_NO_BUFFER:
|
||||
|
||||
*INFBUF = 0; /* Lies! */
|
||||
break;
|
||||
|
||||
/*** Power Managment ***/
|
||||
case OID_PNP_CAPABILITIES:
|
||||
c->InformationBufferLength = sizeof(struct NDIS_PM_WAKE_UP_CAPABILITIES);
|
||||
|
||||
//Sorry, I don't play ball. Power managment is for hippies
|
||||
memset((char *)INFBUF, 0, sizeof(struct NDIS_PM_WAKE_UP_CAPABILITIES));
|
||||
break;
|
||||
|
||||
case OID_PNP_QUERY_POWER:
|
||||
c->InformationBufferLength = 0;
|
||||
break;
|
||||
|
||||
case OID_PNP_ENABLE_WAKE_UP:
|
||||
*INFBUF = 0; /* Nothing Supported */
|
||||
break;
|
||||
|
||||
default:
|
||||
status = RNDIS_STATUS_FAILURE;
|
||||
c->InformationBufferLength = 0;
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
//Set Status now that we are done with Oid
|
||||
c->Status = status;
|
||||
|
||||
//Calculate message size
|
||||
c->MessageLength = sizeof (rndis_query_cmplt_t) + c->InformationBufferLength;
|
||||
|
||||
//Check if we are sending no information buffer
|
||||
if (c->InformationBufferLength == 0) {
|
||||
c->InformationBufferOffset = 0;
|
||||
}
|
||||
|
||||
//Set it up
|
||||
data_to_send = c->MessageLength;
|
||||
}
|
||||
|
||||
|
||||
#undef INFBUF
|
||||
#define INFBUF ((uint32_t *)((uint8_t *)&(m->RequestId) + m->InformationBufferOffset))
|
||||
#define CFGBUF ((rndis_config_parameter_t *) INFBUF)
|
||||
#define PARMNAME ((uint8_t *)CFGBUF + CFGBUF->ParameterNameOffset)
|
||||
#define PARMVALUE ((uint8_t *)CFGBUF + CFGBUF->ParameterValueOffset)
|
||||
|
||||
#define PARM_NAME_LENGTH 25 /* Maximum parameter name length */
|
||||
|
||||
/**
|
||||
* \brief Function to deal with a RNDIS "SET" command present in the
|
||||
* encapsulated_buffer
|
||||
*/
|
||||
void rndis_set_process(void)
|
||||
{
|
||||
rndis_set_cmplt_t * c;
|
||||
rndis_set_msg_t * m;
|
||||
|
||||
c = ((rndis_set_cmplt_t *)encapsulated_buffer);
|
||||
m = ((rndis_set_msg_t *)encapsulated_buffer);
|
||||
|
||||
//Never have longer parameter names than PARM_NAME_LENGTH
|
||||
char parmname[PARM_NAME_LENGTH];
|
||||
|
||||
uint8_t i;
|
||||
int8_t parmlength;
|
||||
|
||||
/* The parameter name seems to be transmitted in uint16_t, but
|
||||
we want this in uint8_t. Hence have to throw out some info... */
|
||||
if (CFGBUF->ParameterNameLength > (PARM_NAME_LENGTH*2)) {
|
||||
parmlength = PARM_NAME_LENGTH * 2;
|
||||
} else {
|
||||
parmlength = CFGBUF->ParameterNameLength;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while(parmlength > 0) {
|
||||
//Convert from uint16_t to char array.
|
||||
parmname[i] = (char)*(PARMNAME + 2*i);
|
||||
parmlength -= 2;
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
switch(m->Oid) {
|
||||
|
||||
/* Parameters set up in 'Advanced' tab */
|
||||
case OID_GEN_RNDIS_CONFIG_PARAMETER:
|
||||
/* Parameter name: rawmode
|
||||
Parameter desc: Enables or disable raw capture of 802.15.4 Packets
|
||||
Parameter type: single octet
|
||||
Parameter values: '0' = disabled, '1' = enabled
|
||||
*/
|
||||
if (strncmp_P(parmname, PSTR("rawmode"), 7) == 0) {
|
||||
if (*PARMVALUE == '0') {
|
||||
usbstick_mode.raw = 0;
|
||||
} else {
|
||||
usbstick_mode.raw = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
|
||||
/* Mandatory general OIDs */
|
||||
case OID_GEN_CURRENT_PACKET_FILTER:
|
||||
oid_packet_filter = *INFBUF;
|
||||
|
||||
if (oid_packet_filter) {
|
||||
|
||||
rndis_packetFilter(oid_packet_filter);
|
||||
|
||||
rndis_state = rndis_data_initialized;
|
||||
} else {
|
||||
rndis_state = rndis_initialized;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case OID_GEN_CURRENT_LOOKAHEAD:
|
||||
break;
|
||||
|
||||
case OID_GEN_PROTOCOL_OPTIONS:
|
||||
break;
|
||||
|
||||
/* Mandatory 802_3 OIDs */
|
||||
case OID_802_3_MULTICAST_LIST:
|
||||
break;
|
||||
|
||||
/* Mandatory 802.11 OIDs */
|
||||
case OID_802_11_BSSID:
|
||||
panid = *INFBUF;
|
||||
break;
|
||||
|
||||
case OID_802_11_SSID:
|
||||
break;
|
||||
//TODO: rest of 802.11
|
||||
|
||||
/* Power Managment: fails for now */
|
||||
case OID_PNP_ADD_WAKE_UP_PATTERN:
|
||||
case OID_PNP_REMOVE_WAKE_UP_PATTERN:
|
||||
case OID_PNP_ENABLE_WAKE_UP:
|
||||
|
||||
default:
|
||||
//c->MessageID is same as before
|
||||
c->MessageType = REMOTE_NDIS_SET_CMPLT;
|
||||
c->MessageLength = sizeof(rndis_set_cmplt_t);
|
||||
c->Status = RNDIS_STATUS_FAILURE;
|
||||
data_to_send = c->MessageLength;
|
||||
return;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//c->MessageID is same as before
|
||||
c->MessageType = REMOTE_NDIS_SET_CMPLT;
|
||||
c->MessageLength = sizeof(rndis_set_cmplt_t);
|
||||
c->Status = RNDIS_STATUS_SUCCESS;
|
||||
data_to_send = c->MessageLength;
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Handle "GET ENCAPSULATED COMMAND"
|
||||
*
|
||||
* \return True on success, false on failure.
|
||||
*
|
||||
* This function assumes the message has already set up in
|
||||
* the "encapsulated_buffer" variable. This will be done by
|
||||
* the "SEND ENCAPSULATED COMMAND" message, which will trigger
|
||||
* and interrupt on the host so it knows data is ready.
|
||||
*/
|
||||
uint8_t get_encapsulated_command(void)
|
||||
{
|
||||
U8 nb_byte, zlp, i;
|
||||
|
||||
//We assume this is already set up...
|
||||
|
||||
//Received setup message OK
|
||||
Usb_ack_receive_setup();
|
||||
|
||||
if ((data_to_send % EP_CONTROL_LENGTH) == 0) { zlp = TRUE; }
|
||||
else { zlp = FALSE; } //!< no need of zero length packet
|
||||
|
||||
|
||||
i = 0;
|
||||
while((data_to_send != 0) && (!Is_usb_receive_out()))
|
||||
{
|
||||
while(!Is_usb_read_control_enabled());
|
||||
|
||||
nb_byte=0;
|
||||
while(data_to_send != 0) //!< Send data until necessary
|
||||
{
|
||||
if(nb_byte++==EP_CONTROL_LENGTH) //!< Check endpoint 0 size
|
||||
{
|
||||
break;
|
||||
}
|
||||
Usb_write_byte(encapsulated_buffer[i]);
|
||||
i++;
|
||||
data_to_send--;
|
||||
|
||||
}
|
||||
Usb_send_control_in();
|
||||
}
|
||||
|
||||
if(Is_usb_receive_out()) { Usb_ack_receive_out(); return TRUE; } //!< abort from Host
|
||||
|
||||
if(zlp == TRUE)
|
||||
{
|
||||
while(!Is_usb_read_control_enabled());
|
||||
Usb_send_control_in();
|
||||
}
|
||||
|
||||
while(!Is_usb_receive_out());
|
||||
Usb_ack_receive_out();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Send a status packet back to the host
|
||||
*
|
||||
* \return Sucess or Failure
|
||||
* \retval 1 Success
|
||||
* \retval 0 Failure
|
||||
*/
|
||||
uint8_t rndis_send_status(rndis_Status_t stat)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
if(Is_usb_read_control_enabled() && !data_to_send) {
|
||||
|
||||
rndis_indicate_status_t * m;
|
||||
m = (rndis_indicate_status_t *)encapsulated_buffer;
|
||||
|
||||
m->MessageType = REMOTE_NDIS_INDICATE_STATUS_MSG;
|
||||
m->MessageLength = sizeof(rndis_indicate_status_t);
|
||||
m->Status = stat;
|
||||
|
||||
for(i = 0; i < sizeof(rndis_indicate_status_t); i++) {
|
||||
Usb_write_byte(encapsulated_buffer[i]);
|
||||
}
|
||||
|
||||
Usb_send_control_in();
|
||||
while(!(Is_usb_read_control_enabled()));
|
||||
|
||||
while(!Is_usb_receive_out());
|
||||
Usb_ack_receive_out();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************** Radio Interface ****************/
|
||||
|
||||
/**
|
||||
* \brief Set the packet filter - currently distinguishes
|
||||
* between promiscuous mode and normal mode
|
||||
*/
|
||||
void rndis_packetFilter(uint32_t newfilter)
|
||||
{
|
||||
|
||||
if (newfilter & NDIS_PACKET_TYPE_PROMISCUOUS) {
|
||||
rxMode = RX_ON;
|
||||
radio_set_trx_state(RX_ON);
|
||||
} else {
|
||||
rxMode = RX_AACK_ON;
|
||||
radio_set_trx_state(RX_AACK_ON);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** @} */
|
325
cpu/avr/dev/usb/rndis/rndis_protocol.h
Normal file
325
cpu/avr/dev/usb/rndis/rndis_protocol.h
Normal file
|
@ -0,0 +1,325 @@
|
|||
/**
|
||||
* \file rndis_protocol.h
|
||||
* RNDIS Defines
|
||||
*
|
||||
* \author
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*/
|
||||
|
||||
/* Copyright (c) 2008 Colin O'Flynn
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _RNDIS_H
|
||||
#define _RNDIS_H
|
||||
|
||||
/**
|
||||
\addtogroup RNDIS
|
||||
@{
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define RNDIS_MAJOR_VERSION 1
|
||||
#define RNDIS_MINOR_VERSION 0
|
||||
|
||||
#define RNDIS_STATUS_SUCCESS 0X00000000
|
||||
#define RNDIS_STATUS_FAILURE 0XC0000001
|
||||
#define RNDIS_STATUS_INVALID_DATA 0XC0010015
|
||||
#define RNDIS_STATUS_NOT_SUPPORTED 0XC00000BB
|
||||
#define RNDIS_STATUS_MEDIA_CONNECT 0X4001000B
|
||||
#define RNDIS_STATUS_MEDIA_DISCONNECT 0X4001000C
|
||||
|
||||
|
||||
/* Message set for Connectionless (802.3) Devices */
|
||||
#define REMOTE_NDIS_PACKET_MSG 0x00000001
|
||||
#define REMOTE_NDIS_INITIALIZE_MSG 0X00000002
|
||||
#define REMOTE_NDIS_HALT_MSG 0X00000003
|
||||
#define REMOTE_NDIS_QUERY_MSG 0X00000004
|
||||
#define REMOTE_NDIS_SET_MSG 0X00000005
|
||||
#define REMOTE_NDIS_RESET_MSG 0X00000006
|
||||
#define REMOTE_NDIS_INDICATE_STATUS_MSG 0X00000007
|
||||
#define REMOTE_NDIS_KEEPALIVE_MSG 0X00000008
|
||||
#define REMOTE_NDIS_INITIALIZE_CMPLT 0X80000002
|
||||
#define REMOTE_NDIS_QUERY_CMPLT 0X80000004
|
||||
#define REMOTE_NDIS_SET_CMPLT 0X80000005
|
||||
#define REMOTE_NDIS_RESET_CMPLT 0X80000006
|
||||
#define REMOTE_NDIS_KEEPALIVE_CMPLT 0X80000008
|
||||
|
||||
typedef uint32_t rndis_MessageType_t;
|
||||
typedef uint32_t rndis_MessageLength_t;
|
||||
typedef uint32_t rndis_RequestId_t;
|
||||
typedef uint32_t rndis_MajorVersion_t;
|
||||
typedef uint32_t rndis_MinorVersion_t;
|
||||
typedef uint32_t rndis_MaxTransferSize_t;
|
||||
typedef uint32_t rndis_Status_t;
|
||||
|
||||
|
||||
/* Device Flags */
|
||||
#define RNDIS_DF_CONNECTIONLESS 0x00000001
|
||||
#define RNDIS_DF_CONNECTION_ORIENTED 0x00000002
|
||||
typedef uint32_t rndis_DeviceFlags_t;
|
||||
|
||||
/* Mediums */
|
||||
#define RNDIS_MEDIUM_802_3 0x00000000
|
||||
typedef uint32_t rndis_Medium_t;
|
||||
|
||||
|
||||
typedef uint32_t rndis_MaxPacketsPerTransfer_t;
|
||||
typedef uint32_t rndis_PacketAlignmentFactor_t;
|
||||
typedef uint32_t rndis_AfListOffset_t;
|
||||
typedef uint32_t rndis_AfListSize_t;
|
||||
|
||||
/*** Remote NDIS Generic Message type ***/
|
||||
typedef struct{
|
||||
rndis_MessageType_t MessageType;
|
||||
rndis_MessageLength_t MessageLength;
|
||||
} rndis_generic_msg_t;
|
||||
|
||||
|
||||
/*** Remote NDIS Initialize Message ***/
|
||||
typedef struct{
|
||||
rndis_MessageType_t MessageType;
|
||||
rndis_MessageLength_t MessageLength;
|
||||
rndis_RequestId_t RequestId;
|
||||
rndis_MajorVersion_t MajorVersion;
|
||||
rndis_MinorVersion_t MinorVersion;
|
||||
rndis_MaxTransferSize_t MaxTransferSize;
|
||||
} rndis_initialize_msg_t;
|
||||
|
||||
/* Response: */
|
||||
typedef struct{
|
||||
rndis_MessageType_t MessageType;
|
||||
rndis_MessageLength_t MessageLength;
|
||||
rndis_RequestId_t RequestId;
|
||||
rndis_Status_t Status;
|
||||
rndis_MajorVersion_t MajorVersion;
|
||||
rndis_MinorVersion_t MinorVersion;
|
||||
rndis_DeviceFlags_t DeviceFlags;
|
||||
rndis_Medium_t Medium;
|
||||
rndis_MaxPacketsPerTransfer_t MaxPacketsPerTransfer;
|
||||
rndis_MaxTransferSize_t MaxTransferSize;
|
||||
rndis_PacketAlignmentFactor_t PacketAlignmentFactor;
|
||||
rndis_AfListOffset_t AfListOffset;
|
||||
rndis_AfListSize_t AfListSize;
|
||||
} rndis_initialize_cmplt_t;
|
||||
|
||||
|
||||
/*** Remote NDIS Halt Message ***/
|
||||
typedef struct{
|
||||
rndis_MessageType_t MessageType;
|
||||
rndis_MessageLength_t MessageLength;
|
||||
rndis_RequestId_t RequestId;
|
||||
} rndis_halt_msg_t;
|
||||
|
||||
typedef uint32_t rndis_Oid_t;
|
||||
typedef uint32_t rndis_InformationBufferLength_t;
|
||||
typedef uint32_t rndis_InformationBufferOffset_t;
|
||||
typedef uint32_t rndis_DeviceVcHandle_t;
|
||||
|
||||
/*** Remote NDIS Query Message ***/
|
||||
typedef struct{
|
||||
rndis_MessageType_t MessageType;
|
||||
rndis_MessageLength_t MessageLength;
|
||||
rndis_RequestId_t RequestId;
|
||||
rndis_Oid_t Oid;
|
||||
rndis_InformationBufferLength_t InformationBufferLength;
|
||||
rndis_InformationBufferOffset_t InformationBufferOffset;
|
||||
rndis_DeviceVcHandle_t DeviceVcHandle;
|
||||
} rndis_query_msg_t;
|
||||
|
||||
/* Response: */
|
||||
|
||||
typedef struct{
|
||||
rndis_MessageType_t MessageType;
|
||||
rndis_MessageLength_t MessageLength;
|
||||
rndis_RequestId_t RequestId;
|
||||
rndis_Status_t Status;
|
||||
rndis_InformationBufferLength_t InformationBufferLength;
|
||||
rndis_InformationBufferOffset_t InformationBufferOffset;
|
||||
} rndis_query_cmplt_t;
|
||||
|
||||
/*** Remote NDIS Set Message ***/
|
||||
typedef struct{
|
||||
rndis_MessageType_t MessageType;
|
||||
rndis_MessageLength_t MessageLength;
|
||||
rndis_RequestId_t RequestId;
|
||||
rndis_Oid_t Oid;
|
||||
rndis_InformationBufferLength_t InformationBufferLength;
|
||||
rndis_InformationBufferOffset_t InformationBufferOffset;
|
||||
rndis_DeviceVcHandle_t DeviceVcHandle;
|
||||
} rndis_set_msg_t;
|
||||
|
||||
/* Response */
|
||||
typedef struct{
|
||||
rndis_MessageType_t MessageType;
|
||||
rndis_MessageLength_t MessageLength;
|
||||
rndis_RequestId_t RequestId;
|
||||
rndis_Status_t Status;
|
||||
}rndis_set_cmplt_t;
|
||||
|
||||
/* Information buffer layout for OID_GEN_RNDIS_CONFIG_PARAMETER */
|
||||
typedef uint32_t rndis_ParameterNameOffset_t;
|
||||
typedef uint32_t rndis_ParameterNameLength_t;
|
||||
typedef uint32_t rndis_ParameterType_t;
|
||||
typedef uint32_t rndis_ParameterValueOffset_t;
|
||||
typedef uint32_t rndis_ParameterValueLength_t;
|
||||
|
||||
#define PARAMETER_TYPE_STRING 2
|
||||
#define PARAMETER_TYPE_NUMERICAL 0
|
||||
|
||||
typedef struct{
|
||||
rndis_ParameterNameOffset_t ParameterNameOffset;
|
||||
rndis_ParameterNameLength_t ParameterNameLength;
|
||||
rndis_ParameterType_t ParameterType;
|
||||
rndis_ParameterValueOffset_t ParameterValueOffset;
|
||||
rndis_ParameterValueLength_t ParameterValueLength;
|
||||
}rndis_config_parameter_t;
|
||||
|
||||
typedef uint32_t rndis_Reserved_t;
|
||||
|
||||
/*** Remote NDIS Soft Reset Message ***/
|
||||
typedef struct{
|
||||
rndis_MessageType_t MessageType;
|
||||
rndis_MessageLength_t MessageLength;
|
||||
rndis_Reserved_t Reserved;
|
||||
} rndis_reset_msg_t;
|
||||
|
||||
typedef uint32_t rndis_AddressingReset_t;
|
||||
|
||||
/* Response: */
|
||||
typedef struct{
|
||||
rndis_MessageType_t MessageType;
|
||||
rndis_MessageLength_t MessageLength;
|
||||
rndis_Status_t Status;
|
||||
rndis_AddressingReset_t AddressingReset;
|
||||
} rndis_reset_cmplt_t;
|
||||
|
||||
/*** Remote NDIS Indicate Status Message ***/
|
||||
typedef struct{
|
||||
rndis_MessageType_t MessageType;
|
||||
rndis_MessageLength_t MessageLength;
|
||||
rndis_Status_t Status;
|
||||
rndis_Status_t StatusBufferLength;
|
||||
rndis_Status_t StatusBufferOffset;
|
||||
} rndis_indicate_status_t;
|
||||
|
||||
typedef uint32_t rndis_DiagStatus_t;
|
||||
typedef uint32_t rndis_ErrorOffset_t;
|
||||
|
||||
typedef struct {
|
||||
rndis_DiagStatus_t DiagStatus;
|
||||
rndis_ErrorOffset_t ErrorOffset;
|
||||
}rndis_diagnostic_info_t;
|
||||
|
||||
/*** Remote NDIS Keepalive Message */
|
||||
typedef struct{
|
||||
rndis_MessageType_t MessageType;
|
||||
rndis_MessageLength_t MessageLength;
|
||||
rndis_RequestId_t RequestId;
|
||||
}rndis_keepalive_msg_t;
|
||||
|
||||
/* Response: */
|
||||
typedef struct{
|
||||
rndis_MessageType_t MessageType;
|
||||
rndis_MessageLength_t MessageLength;
|
||||
rndis_RequestId_t RequestId;
|
||||
rndis_Status_t Status;
|
||||
}rndis_keepalive_cmplt_t;
|
||||
|
||||
/*** Remote NDIS Data Packet ***/
|
||||
|
||||
typedef uint32_t rndis_DataOffset_t;
|
||||
typedef uint32_t rndis_DataLength_t;
|
||||
typedef uint32_t rndis_OOBDataOffset_t;
|
||||
typedef uint32_t rndis_OOBDataLength_t;
|
||||
typedef uint32_t rndis_NumOOBDataElements_t;
|
||||
typedef uint32_t rndis_PerPacketInfoOffset_t;
|
||||
typedef uint32_t rndis_PerPacketInfoLength_t;
|
||||
|
||||
typedef struct{
|
||||
rndis_MessageType_t MessageType;
|
||||
rndis_MessageLength_t MessageLength;
|
||||
rndis_DataOffset_t DataOffset;
|
||||
rndis_DataLength_t DataLength;
|
||||
rndis_OOBDataOffset_t OOBDataOffset;
|
||||
rndis_OOBDataLength_t OOBDataLength;
|
||||
rndis_NumOOBDataElements_t NumOOBDataElements;
|
||||
rndis_PerPacketInfoOffset_t PerPacketInfoOffset;
|
||||
rndis_PerPacketInfoLength_t PerPacketInfoLength;
|
||||
rndis_DeviceVcHandle_t DeviceVcHandle;
|
||||
rndis_Reserved_t Reserved;
|
||||
}rndis_data_packet_t;
|
||||
|
||||
typedef uint32_t rndis_ClassInformationOffset_t;
|
||||
typedef uint32_t rndis_Size_t;
|
||||
typedef uint32_t rndis_Type_t;
|
||||
|
||||
typedef struct{
|
||||
rndis_Size_t Size;
|
||||
rndis_Type_t Type;
|
||||
rndis_ClassInformationOffset_t ClassInformationType;
|
||||
}rndis_OOB_packet_t;
|
||||
|
||||
|
||||
|
||||
#include "ndis.h"
|
||||
|
||||
|
||||
typedef enum rnids_state_e {
|
||||
rndis_uninitialized,
|
||||
rndis_initialized,
|
||||
rndis_data_initialized
|
||||
} rndis_state_t;
|
||||
|
||||
typedef struct{
|
||||
uint32_t txok;
|
||||
uint32_t rxok;
|
||||
uint32_t txbad;
|
||||
uint32_t rxbad;
|
||||
} rndis_stat_t;
|
||||
|
||||
extern rndis_stat_t rndis_stat;
|
||||
|
||||
extern rndis_state_t rndis_state;
|
||||
|
||||
extern uint8_t schedule_interrupt;
|
||||
|
||||
extern uint64_t rndis_ethernet_addr;
|
||||
|
||||
uint8_t send_encapsulated_command(uint16_t wLength);
|
||||
uint8_t get_encapsulated_command(void);
|
||||
void rndis_send_interrupt(void);
|
||||
void rndis_query_process(void);
|
||||
void rndis_set_process(void);
|
||||
uint8_t rndis_send_status(rndis_Status_t stat);
|
||||
|
||||
#endif //_RNDIS_H
|
||||
|
||||
/** @} */
|
422
cpu/avr/dev/usb/rndis/rndis_task.c
Normal file
422
cpu/avr/dev/usb/rndis/rndis_task.c
Normal file
|
@ -0,0 +1,422 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file rndis_task.c *********************************************************
|
||||
*
|
||||
* \brief
|
||||
* Manages the RNDIS Dataclass for the USB Device
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
\addtogroup RNDIS
|
||||
@{
|
||||
*/
|
||||
|
||||
//_____ I N C L U D E S ___________________________________________________
|
||||
|
||||
|
||||
#include "contiki.h"
|
||||
#include "usb_drv.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "usb_specific_request.h"
|
||||
#include "rndis/rndis_task.h"
|
||||
#include "rndis/rndis_protocol.h"
|
||||
#include "uip.h"
|
||||
#include "sicslow_ethernet.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
|
||||
#define PRINTF printf
|
||||
#define PRINTF_P printf_P
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//_____ D E F I N I T I O N S ______________________________________________
|
||||
|
||||
|
||||
#define IAD_TIMEOUT_DETACH 400
|
||||
#define IAD_TIMEOUT_ATTACH 800
|
||||
|
||||
#define RNDIS_TIMEOUT_DETACH 900
|
||||
#define RNDIS_TIMEOUT_ATTACH 1000
|
||||
|
||||
#define PBUF ((rndis_data_packet_t *) data_buffer)
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
|
||||
|
||||
//! Timers for LEDs
|
||||
uint8_t led1_timer, led2_timer;
|
||||
|
||||
//! Temp data buffer when adding RNDIS headers
|
||||
uint8_t data_buffer[64];
|
||||
|
||||
//! Usb is busy with RNDIS
|
||||
char usb_busy = 0;
|
||||
|
||||
|
||||
static struct etimer et;
|
||||
static struct timer flood_timer;
|
||||
static uint16_t iad_fail_timeout, rndis_fail_timeout;
|
||||
|
||||
static uint8_t doInit = 1;
|
||||
|
||||
extern uint8_t fingerPresent;
|
||||
|
||||
PROCESS(rndis_process, "RNDIS process");
|
||||
|
||||
/**
|
||||
* \brief RNDIS Process
|
||||
*
|
||||
* This is the link between USB and the "good stuff". In this routine data
|
||||
* is received and processed by RNDIS
|
||||
*/
|
||||
PROCESS_THREAD(rndis_process, ev, data_proc)
|
||||
{
|
||||
|
||||
PROCESS_BEGIN();
|
||||
uint8_t bytecounter, headercounter;
|
||||
uint16_t i, dataoffset;
|
||||
|
||||
while(1) {
|
||||
|
||||
// turn off LED's if necessary
|
||||
if (led1_timer) led1_timer--;
|
||||
else Led1_off();
|
||||
if (led2_timer) led2_timer--;
|
||||
else Led2_off();
|
||||
|
||||
/* Device is Enumerated but RNDIS not loading. We might
|
||||
have a system that does not support IAD (winXP). If so
|
||||
count the timeout then switch to just network interface. */
|
||||
if (usb_mode == rndis_debug) {
|
||||
//If we have timed out, detach
|
||||
if (iad_fail_timeout == IAD_TIMEOUT_DETACH) {
|
||||
|
||||
//Failed - BUT we are using "reverse logic", hence we force device
|
||||
//into this mode. This is used to allow Windows Vista have time to
|
||||
//install the drivers
|
||||
if (fingerPresent && (rndis_state != rndis_data_initialized) && Is_device_enumerated() ) {
|
||||
iad_fail_timeout = 0;
|
||||
} else {
|
||||
stdout = NULL;
|
||||
Usb_detach();
|
||||
doInit = 1; //Also mark system as needing intilizing
|
||||
}
|
||||
|
||||
//Then wait a few before re-attaching
|
||||
} else if (iad_fail_timeout == IAD_TIMEOUT_ATTACH) {
|
||||
|
||||
if (fingerPresent) {
|
||||
usb_mode = mass_storage;
|
||||
} else {
|
||||
usb_mode = rndis_only;
|
||||
}
|
||||
Usb_attach();
|
||||
}
|
||||
|
||||
//Increment timeout when device is not initializing, OR we have already detached,
|
||||
//OR the user had their finger on the device, indicating a reverse of logic
|
||||
if ( ( (rndis_state != rndis_data_initialized) && Is_device_enumerated() ) ||
|
||||
(iad_fail_timeout > IAD_TIMEOUT_DETACH) ||
|
||||
(fingerPresent) ) {
|
||||
iad_fail_timeout++;
|
||||
} else {
|
||||
iad_fail_timeout = 0;
|
||||
}
|
||||
} //usb_mode == rndis_debug
|
||||
|
||||
|
||||
/* Device is Enumerated but RNDIS STIL not loading. We just
|
||||
have RNDIS interface, so obviously no drivers on target.
|
||||
Just go ahead and mount ourselves as mass storage... */
|
||||
if (usb_mode == rndis_only) {
|
||||
//If we have timed out, detach
|
||||
if (rndis_fail_timeout == RNDIS_TIMEOUT_DETACH) {
|
||||
Usb_detach();
|
||||
//Then wait a few before re-attaching
|
||||
} else if (rndis_fail_timeout == RNDIS_TIMEOUT_ATTACH) {
|
||||
usb_mode = mass_storage;
|
||||
Usb_attach();
|
||||
}
|
||||
|
||||
//Increment timeout when device is not initializing, OR we are already
|
||||
//counting to detach
|
||||
if ( ( (rndis_state != rndis_data_initialized)) ||
|
||||
(rndis_fail_timeout > RNDIS_TIMEOUT_DETACH) ) {
|
||||
rndis_fail_timeout++;
|
||||
} else {
|
||||
rndis_fail_timeout = 0;
|
||||
}
|
||||
}//usb_mode == rnids_only
|
||||
|
||||
|
||||
if(rndis_state == rndis_data_initialized) //Enumeration processs OK ?
|
||||
{
|
||||
if (doInit) {
|
||||
//start flood timer
|
||||
timer_set(&flood_timer, CLOCK_SECOND / 5);
|
||||
|
||||
mac_ethernetSetup();
|
||||
doInit = 0;
|
||||
}
|
||||
|
||||
//Connected!
|
||||
Led0_on();
|
||||
|
||||
Usb_select_endpoint(RX_EP);
|
||||
|
||||
//If we have data and a free buffer
|
||||
if(Is_usb_receive_out() && (uip_len == 0)) {
|
||||
|
||||
//TODO: Fix this some better way
|
||||
//If you need a delay in RNDIS to slow down super-fast sending, insert it here
|
||||
//Also mark the USB as "in use"
|
||||
|
||||
//This is done as "flood control" by only allowing one IP packet per time limit
|
||||
clock_time_t timediff = clock_time() - flood_timer.start;
|
||||
|
||||
|
||||
//If timer not yet expired
|
||||
if (timediff < flood_timer.interval) {
|
||||
//Wait until timer expiers
|
||||
usb_busy = 1;
|
||||
etimer_set(&et, flood_timer.interval - timediff);
|
||||
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
|
||||
|
||||
//Reselect endpoint in case we lost it
|
||||
Usb_select_endpoint(RX_EP);
|
||||
usb_busy = 0;
|
||||
}
|
||||
|
||||
//Restart flood timer
|
||||
timer_restart(&flood_timer);
|
||||
|
||||
//Read how much (endpoint only stores up to 64 bytes anyway)
|
||||
bytecounter = Usb_byte_counter_8();
|
||||
|
||||
//Try and read the header in
|
||||
headercounter = sizeof(rndis_data_packet_t);
|
||||
|
||||
//Hmm.. what's going on here
|
||||
if (bytecounter < headercounter) {
|
||||
Usb_ack_receive_out();
|
||||
break;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (headercounter) {
|
||||
data_buffer[i] = Usb_read_byte();
|
||||
bytecounter--;
|
||||
headercounter--;
|
||||
i++;
|
||||
}
|
||||
|
||||
//This is no good. Probably lost syncronization... just drop it for now
|
||||
if(PBUF->MessageType != REMOTE_NDIS_PACKET_MSG) {
|
||||
Usb_ack_receive_out();
|
||||
break;
|
||||
}
|
||||
|
||||
//Looks like we've got a live one
|
||||
rx_start_led();
|
||||
|
||||
|
||||
//802.3 does not have OOB data, and we don't care about per-packet data
|
||||
//so that just leave regular packet data...
|
||||
if (PBUF->DataLength) {
|
||||
|
||||
//Get offset
|
||||
dataoffset = PBUF->DataOffset;
|
||||
|
||||
//Make it offset from start of message, not DataOffset field
|
||||
dataoffset += (sizeof(rndis_MessageType_t) + sizeof(rndis_MessageLength_t));
|
||||
|
||||
//Subtract what we already took
|
||||
dataoffset -= sizeof(rndis_data_packet_t);
|
||||
|
||||
//Read to the start of data
|
||||
while(dataoffset) {
|
||||
Usb_read_byte();
|
||||
dataoffset--;
|
||||
bytecounter--;
|
||||
|
||||
//If endpoint is done
|
||||
if (bytecounter == 0) {
|
||||
|
||||
Usb_ack_receive_out();
|
||||
|
||||
|
||||
//Wait for new data
|
||||
while (!Is_usb_receive_out());
|
||||
|
||||
|
||||
bytecounter = Usb_byte_counter_8();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Read the data itself in
|
||||
uint8_t * uipdata = uip_buf;
|
||||
uint16_t datalen = PBUF->DataLength;
|
||||
|
||||
while(datalen) {
|
||||
*uipdata++ = Usb_read_byte();
|
||||
datalen--;
|
||||
bytecounter--;
|
||||
|
||||
//If endpoint is done
|
||||
if (bytecounter == 0) {
|
||||
//Might be everything we need!
|
||||
if (datalen) {
|
||||
Usb_ack_receive_out();
|
||||
//Wait for new data
|
||||
while (!Is_usb_receive_out());
|
||||
bytecounter = Usb_byte_counter_8();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Ack final data packet
|
||||
Usb_ack_receive_out();
|
||||
|
||||
/*** SEND DATA TO UIP ***/
|
||||
if(BUF->type == htons(UIP_ETHTYPE_IPV6)) {
|
||||
|
||||
//Send data over RF or to local stack
|
||||
uip_len = PBUF->DataLength; //uip_len includes LLH_LEN
|
||||
mac_ethernetToLowpan(uip_buf);
|
||||
}
|
||||
|
||||
} //if (PBUF->DataLength)
|
||||
|
||||
|
||||
} //if(Is_usb_receive_out() && (uip_len == 0))
|
||||
|
||||
} // if (rndis_data_intialized)
|
||||
|
||||
if ((usb_mode == rndis_only) || (usb_mode == rndis_debug)) {
|
||||
etimer_set(&et, CLOCK_SECOND/80);
|
||||
} else {
|
||||
etimer_set(&et, CLOCK_SECOND);
|
||||
}
|
||||
|
||||
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
|
||||
} // while(1)
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Send data over RNDIS interface, data is in uipbuf and length is uiplen
|
||||
*/
|
||||
uint8_t rndis_send(uint8_t * senddata, uint16_t sendlen)
|
||||
{
|
||||
|
||||
|
||||
uint16_t i;
|
||||
|
||||
//Setup Header
|
||||
PBUF->MessageType = REMOTE_NDIS_PACKET_MSG;
|
||||
PBUF->DataOffset = sizeof(rndis_data_packet_t) - sizeof(rndis_MessageType_t) - sizeof(rndis_MessageLength_t);
|
||||
PBUF->DataLength = sendlen;
|
||||
PBUF->OOBDataLength = 0;
|
||||
PBUF->OOBDataOffset = 0;
|
||||
PBUF->NumOOBDataElements = 0;
|
||||
PBUF->PerPacketInfoOffset = 0;
|
||||
PBUF->PerPacketInfoLength = 0;
|
||||
PBUF->DeviceVcHandle = 0;
|
||||
PBUF->Reserved = 0;
|
||||
PBUF->MessageLength = sizeof(rndis_data_packet_t) + PBUF->DataLength;
|
||||
|
||||
//Send Data
|
||||
Usb_select_endpoint(TX_EP);
|
||||
Usb_send_in();
|
||||
|
||||
//Wait for ready
|
||||
while(!Is_usb_write_enabled());
|
||||
|
||||
//Setup first part of transfer...
|
||||
for(i = 0; i < sizeof(rndis_data_packet_t); i++) {
|
||||
Usb_write_byte(data_buffer[i]);
|
||||
}
|
||||
|
||||
//Send packet
|
||||
while(sendlen) {
|
||||
Usb_write_byte(*senddata);
|
||||
senddata++;
|
||||
sendlen--;
|
||||
|
||||
//If endpoint is full, send data in
|
||||
//And then wait for data to transfer
|
||||
if (!Is_usb_write_enabled()) {
|
||||
Usb_send_in();
|
||||
|
||||
while(!Is_usb_write_enabled());
|
||||
}
|
||||
|
||||
tx_end_led();
|
||||
}
|
||||
|
||||
Usb_send_in();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief This will enable the RX_START LED for a period
|
||||
*/
|
||||
void rx_start_led(void)
|
||||
{
|
||||
Led1_on();
|
||||
led1_timer = 10;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief This will enable the TRX_END LED for a period
|
||||
*/
|
||||
void tx_end_led(void)
|
||||
{
|
||||
Led2_on();
|
||||
led2_timer = 10;
|
||||
}
|
||||
/** @} */
|
75
cpu/avr/dev/usb/rndis/rndis_task.h
Normal file
75
cpu/avr/dev/usb/rndis/rndis_task.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file rndis_task.h *********************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file manages the RNDIS task
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Colin O'Flynn
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 ATMEL Corporation
|
||||
Copyright (c) 2008 Colin O'Flynn
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _RNDIS_TASK_H_
|
||||
#define _RNDIS_TASK_H_
|
||||
|
||||
/**
|
||||
\addtogroup RNDIS
|
||||
@{
|
||||
*/
|
||||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
|
||||
|
||||
uint8_t rndis_send(uint8_t * senddata, uint16_t sendlen);
|
||||
void sof_action(void);
|
||||
void rx_start_led(void);
|
||||
void tx_end_led(void);
|
||||
|
||||
extern char usb_busy;
|
||||
|
||||
PROCESS_NAME(rndis_process);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* _RNDIS_TASK_H_ */
|
||||
|
293
cpu/avr/dev/usb/serial/cdc_task.c
Normal file
293
cpu/avr/dev/usb/serial/cdc_task.c
Normal file
|
@ -0,0 +1,293 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file cdc_task.c **********************************************************
|
||||
*
|
||||
* \brief
|
||||
* Manages the CDC-ACM Virtual Serial Port Dataclass for the USB Device
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
\ingroup usbstick
|
||||
\defgroup cdctask CDC Task
|
||||
@{
|
||||
*/
|
||||
|
||||
//_____ I N C L U D E S ___________________________________________________
|
||||
|
||||
|
||||
#include "contiki.h"
|
||||
#include "usb_drv.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "usb_specific_request.h"
|
||||
#include "serial/cdc_task.h"
|
||||
#include "serial/uart_usb_lib.h"
|
||||
#include "rndis/rndis_protocol.h"
|
||||
#include "sicslow_ethernet.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
|
||||
#define PRINTF printf
|
||||
#define PRINTF_P printf_P
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//_____ D E F I N I T I O N S ______________________________________________
|
||||
|
||||
|
||||
#define IAD_TIMEOUT_DETACH 300
|
||||
#define IAD_TIMEOUT_ATTACH 600
|
||||
#define PBUF ((rndis_data_packet_t *) data_buffer)
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
|
||||
|
||||
void menu_print(void);
|
||||
void menu_process(char c);
|
||||
|
||||
extern char usb_busy;
|
||||
|
||||
//! Counter for USB Serial port
|
||||
extern U8 tx_counter;
|
||||
|
||||
//! Timers for LEDs
|
||||
uint8_t led3_timer;
|
||||
|
||||
|
||||
//! Was USB device *just* enumerated?
|
||||
uint8_t justenumerated = 1;
|
||||
|
||||
|
||||
static uint8_t timer = 0;
|
||||
static struct etimer et;
|
||||
|
||||
|
||||
PROCESS(cdc_process, "CDC process");
|
||||
|
||||
/**
|
||||
* \brief Communication Data Class (CDC) Process
|
||||
*
|
||||
* This is the link between USB and the "good stuff". In this routine data
|
||||
* is received and processed by CDC-ACM Class
|
||||
*/
|
||||
PROCESS_THREAD(cdc_process, ev, data_proc)
|
||||
{
|
||||
|
||||
PROCESS_BEGIN();
|
||||
uart_usb_init();
|
||||
|
||||
while(1) {
|
||||
|
||||
|
||||
// turn off LED's if necessary
|
||||
if (led3_timer) led3_timer--;
|
||||
else Led3_off();
|
||||
|
||||
if(Is_device_enumerated() && (usb_mode == rndis_debug) && rndis_state && (!usb_busy)) {
|
||||
|
||||
if (justenumerated) {
|
||||
|
||||
//If we have serial port, set it as output
|
||||
if (usb_mode == rndis_debug) {
|
||||
uart_usb_set_stdout();
|
||||
menu_print();
|
||||
}
|
||||
justenumerated = 0;
|
||||
}
|
||||
|
||||
//Flush buffer if timeout
|
||||
if(timer >= 4 && tx_counter!=0 ){
|
||||
timer = 0;
|
||||
uart_usb_flush();
|
||||
} else {
|
||||
timer++;
|
||||
}
|
||||
|
||||
while (uart_usb_test_hit()){
|
||||
menu_process(uart_usb_getchar()); // See what they want
|
||||
}
|
||||
|
||||
|
||||
}//if (Is_device_enumerated())
|
||||
|
||||
|
||||
if (usb_mode == rndis_debug) {
|
||||
etimer_set(&et, CLOCK_SECOND/80);
|
||||
} else {
|
||||
etimer_set(&et, CLOCK_SECOND);
|
||||
}
|
||||
|
||||
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
|
||||
|
||||
} // while(1)
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Print debug menu
|
||||
*/
|
||||
void menu_print(void)
|
||||
{
|
||||
PRINTF_P(PSTR("\n\n\r********** Jackdaw Menu ******************\n\r"));
|
||||
PRINTF_P(PSTR("* *\n\r"));
|
||||
PRINTF_P(PSTR("* Main Menu: *\n\r"));
|
||||
PRINTF_P(PSTR("* h,? Print this menu *\n\r"));
|
||||
PRINTF_P(PSTR("* m Print current mode *\n\r"));
|
||||
PRINTF_P(PSTR("* s Set to sniffer mode *\n\r"));
|
||||
PRINTF_P(PSTR("* n Set to network mode *\n\r"));
|
||||
PRINTF_P(PSTR("* 6 Toggle 6lowpan *\n\r"));
|
||||
PRINTF_P(PSTR("* r Toggle raw mode *\n\r"));
|
||||
PRINTF_P(PSTR("* u Switch to mass-storage*\n\r"));
|
||||
PRINTF_P(PSTR("* *\n\r"));
|
||||
PRINTF_P(PSTR("* Make selection at any time by pressing *\n\r"));
|
||||
PRINTF_P(PSTR("* your choice on keyboard. *\n\r"));
|
||||
PRINTF_P(PSTR("******************************************\n\r"));
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Process incomming char on debug port
|
||||
*/
|
||||
void menu_process(char c)
|
||||
{
|
||||
uint8_t i;
|
||||
switch(c) {
|
||||
case '\r':
|
||||
case '\n':
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
case '?':
|
||||
menu_print();
|
||||
break;
|
||||
|
||||
case 's':
|
||||
PRINTF_P(PSTR("Jackdaw now in sniffer mode\n\r"));
|
||||
usbstick_mode.sendToRf = 0;
|
||||
usbstick_mode.translate = 0;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
PRINTF_P(PSTR("Jackdaw now in network mode\n\r"));
|
||||
usbstick_mode.sendToRf = 1;
|
||||
usbstick_mode.translate = 1;
|
||||
break;
|
||||
|
||||
case '6':
|
||||
if (usbstick_mode.sicslowpan) {
|
||||
PRINTF_P(PSTR("Jackdaw does not perform 6lowpan translation\n\r"));
|
||||
usbstick_mode.sicslowpan = 0;
|
||||
} else {
|
||||
PRINTF_P(PSTR("Jackdaw now performs 6lowpan translations\n\r"));
|
||||
usbstick_mode.sicslowpan = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
if (usbstick_mode.raw) {
|
||||
PRINTF_P(PSTR("Jackdaw does not capture raw frames\n\r"));
|
||||
usbstick_mode.raw = 0;
|
||||
} else {
|
||||
PRINTF_P(PSTR("Jackdaw now captures raw frames\n\r"));
|
||||
usbstick_mode.raw = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'm':
|
||||
PRINTF_P(PSTR("Currently Jackdaw:\n\r * Will "));
|
||||
if (usbstick_mode.sendToRf == 0) { PRINTF_P(PSTR("not "));}
|
||||
PRINTF_P(PSTR("send data over RF\n\r * Will "));
|
||||
if (usbstick_mode.translate == 0) { PRINTF_P(PSTR("not "));}
|
||||
PRINTF_P(PSTR("change link-local addresses inside IP messages\n\r * Will "));
|
||||
if (usbstick_mode.sicslowpan == 0) { PRINTF_P(PSTR("not "));}
|
||||
PRINTF_P(PSTR("decompress 6lowpan headers\n\r * Will "));
|
||||
if (usbstick_mode.raw == 0) { PRINTF_P(PSTR("not "));}
|
||||
PRINTF_P(PSTR("Output raw 802.15.4 frames\n\r "));
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
|
||||
//Mass storage mode
|
||||
usb_mode = mass_storage;
|
||||
|
||||
//No more serial port
|
||||
stdout = NULL;
|
||||
|
||||
//RNDIS is over
|
||||
rndis_state = rndis_uninitialized;
|
||||
Leds_off();
|
||||
|
||||
//Deatch USB
|
||||
Usb_detach();
|
||||
|
||||
//Wait a few seconds
|
||||
for(i = 0; i < 50; i++)
|
||||
_delay_ms(100);
|
||||
|
||||
//Attach USB
|
||||
Usb_attach();
|
||||
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
PRINTF_P(PSTR("%c is not a valid option! h for menu\n\r"), c);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief This will enable the VCP_TRX_END LED for a period
|
||||
*/
|
||||
void vcptx_end_led(void)
|
||||
{
|
||||
Led3_on();
|
||||
led3_timer = 10;
|
||||
}
|
||||
/** @} */
|
||||
|
74
cpu/avr/dev/usb/serial/cdc_task.h
Normal file
74
cpu/avr/dev/usb/serial/cdc_task.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file cdc_task.h ************************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file manages the CDC task for the virtual COM port.
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 ATMEL Corporation
|
||||
Copyright (c) 2008 Colin O'Flynn
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _CDC_TASK_H_
|
||||
#define _CDC_TASK_H_
|
||||
|
||||
/**
|
||||
\addtogroup cdctask
|
||||
@{
|
||||
*/
|
||||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
|
||||
|
||||
void sof_action(void);
|
||||
void vcptx_end_led(void);
|
||||
|
||||
void rawmode_enable(void);
|
||||
void rawmode_disable(void);
|
||||
|
||||
PROCESS_NAME(cdc_process);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* _CDC_TASK_H_ */
|
||||
|
197
cpu/avr/dev/usb/serial/uart_usb_lib.c
Normal file
197
cpu/avr/dev/usb/serial/uart_usb_lib.c
Normal file
|
@ -0,0 +1,197 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file uart_usb_lib.c *********************************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file controls the UART USB functions.
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*_____ I N C L U D E S ____________________________________________________*/
|
||||
|
||||
#include "config.h"
|
||||
#include "usb_drv.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "serial/cdc_task.h"
|
||||
#include "serial/uart_usb_lib.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
\addtogroup cdctask
|
||||
@{
|
||||
*/
|
||||
|
||||
/*_____ M A C R O S ________________________________________________________*/
|
||||
|
||||
/*_____ D E F I N I T I O N ________________________________________________*/
|
||||
|
||||
Uchar tx_counter;
|
||||
Uchar rx_counter;
|
||||
S_line_coding line_coding;
|
||||
|
||||
/*_____ D E C L A R A T I O N ______________________________________________*/
|
||||
|
||||
|
||||
int usb_stdout_putchar(char c, FILE *stream)
|
||||
{
|
||||
// send to USB port
|
||||
// don't send anything if USB can't accept chars
|
||||
Usb_select_endpoint(TX_EP);
|
||||
if (!uart_usb_tx_ready())
|
||||
return 0;
|
||||
|
||||
// turn on LED
|
||||
vcptx_end_led();
|
||||
|
||||
uart_usb_putchar(c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FILE usb_stdout = FDEV_SETUP_STREAM(usb_stdout_putchar,
|
||||
NULL,
|
||||
_FDEV_SETUP_WRITE);
|
||||
|
||||
/**
|
||||
* @brief Initializes the uart_usb library
|
||||
*/
|
||||
void uart_usb_init(void)
|
||||
{
|
||||
tx_counter = 0;
|
||||
rx_counter = 0;
|
||||
}
|
||||
|
||||
void uart_usb_set_stdout(void)
|
||||
{
|
||||
stdout = &usb_stdout;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function checks if the USB emission buffer is ready to accept at
|
||||
* at least 1 byte
|
||||
*
|
||||
* @retval TRUE if the firmware can write a new byte to transmit.
|
||||
* @retval FALSE otherwise
|
||||
*/
|
||||
bit uart_usb_tx_ready(void)
|
||||
{
|
||||
if (!Is_usb_write_enabled())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function fills the USB transmit buffer with the new data. This buffer
|
||||
* is sent if complete. To flush this buffer before waiting full, launch
|
||||
* the uart_usb_flush() function.
|
||||
*
|
||||
* @param data_to_send Data to send
|
||||
*
|
||||
* @return data_to_send Data that was sent
|
||||
*/
|
||||
int uart_usb_putchar(int data_to_send)
|
||||
{
|
||||
Usb_select_endpoint(VCP_TX_EP);
|
||||
|
||||
if(!uart_usb_tx_ready()) return -1;
|
||||
|
||||
Usb_write_byte(data_to_send);
|
||||
tx_counter++;
|
||||
if(!Is_usb_write_enabled()) //If Endpoint full -> flush
|
||||
{
|
||||
uart_usb_flush();
|
||||
}
|
||||
return data_to_send;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function checks if a character has been received on the USB bus.
|
||||
*
|
||||
* @return bit (true if a byte is ready to be read)
|
||||
*/
|
||||
bit uart_usb_test_hit(void)
|
||||
{
|
||||
if (!rx_counter)
|
||||
{
|
||||
Usb_select_endpoint(VCP_RX_EP);
|
||||
if (Is_usb_receive_out())
|
||||
{
|
||||
rx_counter = Usb_byte_counter();
|
||||
if (!rx_counter)
|
||||
{
|
||||
Usb_ack_receive_out();
|
||||
}
|
||||
}
|
||||
}
|
||||
return (rx_counter!=0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function reads one byte from the USB bus
|
||||
*
|
||||
* If one byte is present in the USB fifo, this byte is returned. If no data
|
||||
* is present in the USB fifo, this function waits for USB data.
|
||||
*
|
||||
* @return U8 byte received
|
||||
*/
|
||||
char uart_usb_getchar(void)
|
||||
{
|
||||
register Uchar data_rx;
|
||||
|
||||
Usb_select_endpoint(VCP_RX_EP);
|
||||
if (!rx_counter) while (!uart_usb_test_hit());
|
||||
data_rx=Usb_read_byte();
|
||||
rx_counter--;
|
||||
if (!rx_counter) Usb_ack_receive_out();
|
||||
return data_rx;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function sends the data stored in the USB transmit buffer.
|
||||
* This function does nothing if there is no data in the buffer.
|
||||
*/
|
||||
void uart_usb_flush (void)
|
||||
{
|
||||
Usb_select_endpoint(VCP_TX_EP);
|
||||
Usb_send_in();
|
||||
tx_counter = 0;
|
||||
}
|
||||
|
||||
/** @} */
|
85
cpu/avr/dev/usb/serial/uart_usb_lib.h
Normal file
85
cpu/avr/dev/usb/serial/uart_usb_lib.h
Normal file
|
@ -0,0 +1,85 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file uart_usb_lib.c *******************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file controls the UART USB functions.
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _UART_USB_LIB_H_
|
||||
#define _UART_USB_LIB_H_
|
||||
|
||||
/**
|
||||
\addtogroup cdctask
|
||||
@{
|
||||
*/
|
||||
|
||||
/*_____ I N C L U D E S ____________________________________________________*/
|
||||
|
||||
|
||||
/*_____ M A C R O S ________________________________________________________*/
|
||||
|
||||
|
||||
#ifdef UART_USB_DEFAULT_OUTPUT
|
||||
#define uart_usb_putchar putchar
|
||||
#endif
|
||||
|
||||
/*_____ D E F I N I T I O N ________________________________________________*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U32 dwDTERate;
|
||||
U8 bCharFormat;
|
||||
U8 bParityType;
|
||||
U8 bDataBits;
|
||||
}S_line_coding;
|
||||
|
||||
|
||||
/*_____ D E C L A R A T I O N ______________________________________________*/
|
||||
|
||||
void uart_usb_init(void);
|
||||
bit uart_usb_tx_ready(void);
|
||||
int uart_usb_putchar(int);
|
||||
void uart_usb_flush(void);
|
||||
bit uart_usb_test_hit(void);
|
||||
char uart_usb_getchar(void);
|
||||
|
||||
/** @} **/
|
||||
|
||||
#endif /* _UART_USB_LIB_H_ */
|
||||
|
||||
|
515
cpu/avr/dev/usb/storage/avr_flash.c
Normal file
515
cpu/avr/dev/usb/storage/avr_flash.c
Normal file
|
@ -0,0 +1,515 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file avr_flash.c *********************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file writes/reads to/from flash memory internal to the AVR.
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
******************************************************************************/
|
||||
/*
|
||||
Copyright (c) 2008 Colin O'Flynn
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup usbstorage
|
||||
@{
|
||||
*/
|
||||
|
||||
//_____ I N C L U D E S ___________________________________________________
|
||||
|
||||
#include "config.h" // system configuration
|
||||
#include "storage/avr_flash.h"
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/boot.h>
|
||||
|
||||
#ifndef SPM_PAGESIZE
|
||||
#error SPM_PAGESIZE undefined!!!
|
||||
#endif
|
||||
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
//_____ P R I V A T E D E C L A R A T I O N _____________________________
|
||||
|
||||
|
||||
//_____ D E F I N I T I O N ________________________________________________
|
||||
|
||||
|
||||
#define MEM_BASE_ADDRESS 0x10000UL
|
||||
|
||||
|
||||
DATA U32 gl_ptr_mem; /* memory data pointer */
|
||||
|
||||
|
||||
/* Disk management */
|
||||
bit reserved_disk_space = FALSE; /* reserved space for application on disk */
|
||||
|
||||
|
||||
U32 AVRF_DISK_SIZE = 111; /* 57 KB, some room at end saved for bootloader section */
|
||||
|
||||
|
||||
void avrf_check_init( void );
|
||||
|
||||
|
||||
//_____ D E C L A R A T I O N ______________________________________________
|
||||
|
||||
//!
|
||||
//! @brief This function initializes the hw/sw ressources required to drive the AVR Flash
|
||||
//!
|
||||
//! @warning Code:?? bytes (function code length)
|
||||
//!
|
||||
//!/
|
||||
void avrf_mem_init(void)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
//!
|
||||
//! @brief This function tests the state of the AVR Flash
|
||||
//!
|
||||
//! @warning Code:?? bytes (function code length)
|
||||
//!
|
||||
//! @return Ctrl_status
|
||||
//! It is ready -> CTRL_GOOD
|
||||
//! Else -> CTRL_NO_PRESENT
|
||||
//!/
|
||||
Ctrl_status avrf_test_unit_ready(void)
|
||||
{
|
||||
return CTRL_GOOD;
|
||||
}
|
||||
|
||||
|
||||
//!
|
||||
//! @brief This function gives the address of the last valid sector.
|
||||
//!
|
||||
//! @warning Code:?? bytes (function code length)
|
||||
//!
|
||||
//! @param *u32_nb_sector number of sector (sector = 512B). OUT
|
||||
//!
|
||||
//! @return Ctrl_status
|
||||
//! It is ready -> CTRL_GOOD
|
||||
//!/
|
||||
Ctrl_status avrf_read_capacity( U32 *u32_nb_sector )
|
||||
{
|
||||
*u32_nb_sector = AVRF_DISK_SIZE;
|
||||
return CTRL_GOOD;
|
||||
}
|
||||
|
||||
|
||||
//!
|
||||
//! @brief This function returns the write protected status of the memory.
|
||||
//!
|
||||
//! Only used by memory removal with a HARDWARE SPECIFIC write protected detection
|
||||
//! !!! The customer must unplug the memory to change this write protected status,
|
||||
//! which cannot be for a DF.
|
||||
//!
|
||||
//! @warning Code:?? bytes (function code length)
|
||||
//!
|
||||
//! @return FALSE -> the memory is not write-protected (always)
|
||||
//!/
|
||||
Bool avrf_wr_protect(void)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
//!
|
||||
//! @brief This function tells if the memory has been removed or not.
|
||||
//!
|
||||
//! @warning Code:?? bytes (function code length)
|
||||
//!
|
||||
//! @return FALSE -> The memory isn't removed
|
||||
//!/
|
||||
Bool avrf_removal(void)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------ STANDARD FUNCTIONS to read/write the memory --------------------
|
||||
|
||||
//!
|
||||
//! @brief This function performs a read operation of n sectors from a given address on.
|
||||
//! (sector = 512B)
|
||||
//!
|
||||
//! DATA FLOW is: AVRF => USB
|
||||
//!
|
||||
//!
|
||||
//! @warning Code:?? bytes (function code length)
|
||||
//!
|
||||
//! @param addr Sector address to start the read from
|
||||
//! @param nb_sector Number of sectors to transfer
|
||||
//!
|
||||
//! @return Ctrl_status
|
||||
//! It is ready -> CTRL_GOOD
|
||||
//! A error occur -> CTRL_FAIL
|
||||
//!
|
||||
Ctrl_status avrf_read_10( U32 addr , U16 nb_sector )
|
||||
{
|
||||
avrf_read_open(addr); // wait device is not busy, then send command & address
|
||||
avrf_read_sector(nb_sector); // transfer data from memory to USB
|
||||
avrf_read_close(); // unselect memory
|
||||
return CTRL_GOOD;
|
||||
}
|
||||
|
||||
|
||||
//! This fonction initialise the memory for a write operation
|
||||
//!
|
||||
//! DATA FLOW is: USB => DF
|
||||
//!
|
||||
//!
|
||||
//! (sector = 512B)
|
||||
//! @param addr Sector address to start write
|
||||
//! @param nb_sector Number of sectors to transfer
|
||||
//!
|
||||
//! @return Ctrl_status
|
||||
//! It is ready -> CTRL_GOOD
|
||||
//! A error occur -> CTRL_FAIL
|
||||
//!
|
||||
Ctrl_status avrf_write_10( U32 addr , U16 nb_sector )
|
||||
{
|
||||
|
||||
avrf_write_open(addr); // wait device is not busy, then send command & address
|
||||
avrf_write_sector(nb_sector); // transfer data from memory to USB
|
||||
avrf_write_close(); // unselect memory
|
||||
return CTRL_GOOD;
|
||||
}
|
||||
|
||||
|
||||
//------------ AVR FLASH LOWER LEVEL ROUTIENS -----------------------------------------
|
||||
|
||||
//!
|
||||
//! @brief This function opens a DF memory in read mode at a given sector address.
|
||||
//!
|
||||
//! NOTE: Address may not be synchronized on the beginning of a page (depending on the DF page size).
|
||||
//!
|
||||
//! @warning Code:?? bytes (function code length)
|
||||
//!
|
||||
//! @param pos Logical sector address
|
||||
//!
|
||||
//! @return bit
|
||||
//! The open succeeded -> OK
|
||||
//!/
|
||||
bit avrf_read_open (Uint32 pos)
|
||||
{
|
||||
// Set the global memory ptr at a Byte address.
|
||||
gl_ptr_mem = (pos * 512) + MEM_BASE_ADDRESS;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
//!
|
||||
//! @brief This function unselects the current DF memory.
|
||||
//!
|
||||
//! @warning Code:?? bytes (function code length)
|
||||
//!
|
||||
//!/
|
||||
void avrf_read_close (void)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//!
|
||||
//! @brief This function is optimized and writes nb-sector * 512 Bytes from
|
||||
//! DataFlash memory to USB controller
|
||||
//!
|
||||
//! DATA FLOW is: DF => USB
|
||||
//!
|
||||
//!
|
||||
//! NOTE:
|
||||
//! - First call must be preceded by a call to the df_read_open() function,
|
||||
//! - The USB EPIN must have been previously selected,
|
||||
//! - USB ping-pong buffers are free,
|
||||
//! - As 512 is always a sub-multiple of page size, there is no need to check
|
||||
//! page end for each Bytes,
|
||||
//! - Interrupts are disabled during transfer to avoid timer interrupt,
|
||||
//! - nb_sector always >= 1, cannot be zero.
|
||||
//!
|
||||
//! @warning code:?? bytes (function code length)
|
||||
//!
|
||||
//! @param nb_sector number of contiguous sectors to read [IN]
|
||||
//!
|
||||
//! @return bit
|
||||
//! The read succeeded -> OK
|
||||
//!/
|
||||
bit avrf_read_sector (Uint16 nb_sector)
|
||||
{
|
||||
U8 i,j;
|
||||
do
|
||||
{
|
||||
for (i = 8; i != 0; i--)
|
||||
{
|
||||
Disable_interrupt(); // Global disable.
|
||||
|
||||
for (j = 0; j < 64; j++) {
|
||||
Usb_write_byte(pgm_read_byte_far(gl_ptr_mem++));
|
||||
}
|
||||
|
||||
|
||||
//# Send the USB FIFO IN content to the USB Host.
|
||||
Usb_send_in(); // Send the FIFO IN content to the USB Host.
|
||||
|
||||
Enable_interrupt(); // Global interrupt re-enable.
|
||||
|
||||
// Wait until the tx is done so that we may write to the FIFO IN again.
|
||||
while(Is_usb_write_enabled()==FALSE);
|
||||
}
|
||||
nb_sector--; // 1 more sector read
|
||||
}
|
||||
while (nb_sector != 0);
|
||||
|
||||
return OK; // Read done.
|
||||
}
|
||||
|
||||
|
||||
//!
|
||||
//! @brief This function opens a DF memory in write mode at a given sector
|
||||
//! address.
|
||||
//!
|
||||
//! NOTE: If page buffer > 512 bytes, page content is first loaded in buffer to
|
||||
//! be partially updated by write_byte or write64 functions.
|
||||
//!
|
||||
//! @warning Code:?? bytes (function code length)
|
||||
//!
|
||||
//! @param pos Sector address
|
||||
//!
|
||||
//! @return bit
|
||||
//! The open succeeded -> OK
|
||||
//!/
|
||||
bit avrf_write_open (Uint32 pos)
|
||||
{
|
||||
// Set the global memory ptr at a Byte address.
|
||||
gl_ptr_mem = (pos * 512) + MEM_BASE_ADDRESS;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
//!
|
||||
//! @brief This function fills the end of the logical sector (512B) and launch
|
||||
//! page programming.
|
||||
//!
|
||||
//! @warning Code:?? bytes (function code length)
|
||||
//!
|
||||
//!/
|
||||
void avrf_write_close (void)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* This code can be setup to work with the DFU bootloader, which comes with the AT90USB1287. However I haven't
|
||||
had time to test it with such */
|
||||
#define LAST_BOOT_ENTRY 0xFFFE
|
||||
|
||||
|
||||
void dfuclone_boot_buffer_write(uint16_t dummy, uint32_t baseaddr, uint16_t pageaddr, uint16_t word);
|
||||
void dfuclone_boot_page_erase(uint32_t dummy1, uint16_t dummy2, uint32_t address);
|
||||
void dfuclone_boot_page_write(uint32_t dummy1, uint16_t dummy2, uint32_t address);
|
||||
|
||||
|
||||
/* Enable the use of the AVR DFU bootloader by defining "USE_AVRDFU_BOOTLOADER", it will
|
||||
then call the low-level routines already in the bootloader. */
|
||||
#ifdef USE_AVRDFU_BOOTLOADER
|
||||
|
||||
#error UNTESTED/UNSUPPORTED AT THIS TIME
|
||||
|
||||
// These functions pointers are used to call functions entry points in bootloader
|
||||
void (*dfu_boot_buffer_write) (uint16_t dummy, uint32_t baseaddr, uint16_t pageaddr, uint16_t word)=
|
||||
(void (*)(uint16_t, uint32_t, uint16_t, uint16_t))(LAST_BOOT_ENTRY-6);
|
||||
|
||||
void (*dfu_boot_page_write) (uint32_t dummy1, uint16_t dummy2, uint32_t address)=
|
||||
(void (*)(uint32_t, uint16_t, uint32_t))(LAST_BOOT_ENTRY-4);
|
||||
|
||||
void (*dfu_boot_page_erase) (uint32_t dummy1, uint16_t dummy2, uint32_t address)=
|
||||
(void (*)(uint32_t, uint16_t, uint32_t))(LAST_BOOT_ENTRY-2);
|
||||
|
||||
#else
|
||||
|
||||
// These functions pointers are used to call functions entry points in bootloader
|
||||
void (*dfu_boot_buffer_write) (uint16_t dummy, uint32_t baseaddr, uint16_t pageaddr, uint16_t word)=
|
||||
dfuclone_boot_buffer_write;
|
||||
|
||||
void (*dfu_boot_page_write) (uint32_t dummy1, uint16_t dummy2, uint32_t address)=
|
||||
dfuclone_boot_page_write;
|
||||
|
||||
void (*dfu_boot_page_erase) (uint32_t dummy1, uint16_t dummy2, uint32_t address)=
|
||||
dfuclone_boot_page_erase;
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
//!
|
||||
//! @brief This function is optimized and writes nb-sector * 512 Bytes from
|
||||
//! USB controller to DataFlash memory
|
||||
//!
|
||||
//! DATA FLOW is: USB => DF
|
||||
//!
|
||||
//!
|
||||
//! NOTE:
|
||||
//! - First call must be preceded by a call to the df_write_open() function,
|
||||
//! - As 512 is always a sub-multiple of page size, there is no need to check
|
||||
//! page end for each Bytes,
|
||||
//! - The USB EPOUT must have been previously selected,
|
||||
//! - Interrupts are disabled during transfer to avoid timer interrupt,
|
||||
//! - nb_sector always >= 1, cannot be zero.
|
||||
//!
|
||||
//! @warning code:?? bytes (function code length)
|
||||
//!
|
||||
//! @param nb_sector number of contiguous sectors to write [IN]
|
||||
//!
|
||||
//! @return bit
|
||||
//! The write succeeded -> OK
|
||||
//!/
|
||||
bit avrf_write_sector (Uint16 nb_sector)
|
||||
{
|
||||
Byte i, j;
|
||||
U16 w;
|
||||
|
||||
U16 pgindex = 0;
|
||||
U16 sector_bytecounter = 0;
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
//# Write 8x64b = 512b from the USB FIFO OUT.
|
||||
for (i = 8; i != 0; i--)
|
||||
{
|
||||
// Wait end of rx in USB EPOUT.
|
||||
while(Is_usb_read_enabled()==FALSE);
|
||||
|
||||
Disable_interrupt(); // Global disable.
|
||||
|
||||
//If start of page, erase it!
|
||||
if (pgindex == 0) {
|
||||
(*dfu_boot_page_erase)(0, 0, gl_ptr_mem);
|
||||
}
|
||||
|
||||
//For all the data in the endpoint, write to flash temp page
|
||||
for (j = 0; j < 32; j++) {
|
||||
w = Usb_read_byte();
|
||||
w += Usb_read_byte() << 8;
|
||||
(*dfu_boot_buffer_write)(0, gl_ptr_mem, pgindex, w);
|
||||
pgindex += 2;
|
||||
}
|
||||
|
||||
Usb_ack_receive_out(); // USB EPOUT read acknowledgement.
|
||||
|
||||
//If we have filled flash page, write that sucker to memory
|
||||
if (pgindex == SPM_PAGESIZE) {
|
||||
|
||||
(*dfu_boot_page_write)(0,0, gl_ptr_mem);
|
||||
|
||||
Enable_interrupt(); // Global enable again
|
||||
|
||||
gl_ptr_mem += SPM_PAGESIZE; // Update the memory pointer.
|
||||
pgindex = 0;
|
||||
|
||||
sector_bytecounter += SPM_PAGESIZE;
|
||||
|
||||
if(sector_bytecounter == 512) {
|
||||
nb_sector--; // 1 more sector written
|
||||
sector_bytecounter = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // for (i = 8; i != 0; i--)
|
||||
|
||||
}
|
||||
while (nb_sector != 0);
|
||||
|
||||
return OK; // Write done
|
||||
}
|
||||
|
||||
|
||||
#ifndef USE_AVRDFU_BOOTLOADER
|
||||
/* Perform read/write of FLASH, using same calling convention as low-level routines in AVR DFU bootloader */
|
||||
|
||||
BOOTLOADER_SECTION void dfuclone_boot_buffer_write(uint16_t dummy, uint32_t baseaddr, uint16_t pageaddr, uint16_t word)
|
||||
{
|
||||
boot_page_fill(baseaddr + pageaddr, word);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
BOOTLOADER_SECTION void dfuclone_boot_page_erase(uint32_t dummy1, uint16_t dummy2, uint32_t address)
|
||||
{
|
||||
boot_page_erase(address);
|
||||
boot_spm_busy_wait();
|
||||
boot_rww_enable();
|
||||
return;
|
||||
}
|
||||
|
||||
BOOTLOADER_SECTION void dfuclone_boot_page_write(uint32_t dummy1, uint16_t dummy2, uint32_t address)
|
||||
{
|
||||
boot_page_write(address);
|
||||
boot_spm_busy_wait();
|
||||
boot_rww_enable();
|
||||
return;
|
||||
}
|
||||
#endif //USE_AVRDFU_BOOTLOADER
|
||||
|
||||
//------------ SPECIFIC FONCTION USB TRANSFER -----------------------------------------
|
||||
|
||||
//** If your device transfer have a specific transfer for USB (Particularity of Chejudo product, or bootloader)
|
||||
// !!! In this case the driver must be know the USB access
|
||||
|
||||
//! This fonction transfer the memory data (programed in scsi_read_10) directly to the usb interface
|
||||
//!
|
||||
//! @return Ctrl_status
|
||||
//! It is ready -> CTRL_GOOD
|
||||
//!
|
||||
Ctrl_status avrf_usb_read()
|
||||
{
|
||||
return CTRL_GOOD;
|
||||
}
|
||||
|
||||
|
||||
//! This fonction transfer the usb data (programed in scsi_write_10) directly to the memory data
|
||||
//!
|
||||
//! @return Ctrl_status
|
||||
//! It is ready -> CTRL_GOOD
|
||||
//!
|
||||
Ctrl_status avrf_usb_write( void )
|
||||
{
|
||||
return CTRL_GOOD;
|
||||
}
|
||||
|
||||
/** @} */
|
135
cpu/avr/dev/usb/storage/avr_flash.h
Normal file
135
cpu/avr/dev/usb/storage/avr_flash.h
Normal file
|
@ -0,0 +1,135 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file avr_flash.h *********************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file writes/reads to/from flash memory internal to the AVR.
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
******************************************************************************/
|
||||
/*
|
||||
Copyright (c) 2008 Colin O'Flynn
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup usbstorage
|
||||
@{
|
||||
*/
|
||||
|
||||
#ifndef _DFMEM_H_
|
||||
#define _DFMEM_H_
|
||||
|
||||
#include "conf_access.h"
|
||||
#include "ctrl_status.h"
|
||||
|
||||
|
||||
|
||||
|
||||
//_____ D E F I N I T I O N S ______________________________________________
|
||||
|
||||
//! FAT specification
|
||||
#define ENTRY_SIZE 32 // size of entrie in byte
|
||||
|
||||
|
||||
|
||||
// First sector of the disk virtual (this disk isn't partitioned, only one partion)
|
||||
#define PBR_SECTOR (0)
|
||||
#define FAT_SECTOR (PBR_SECTOR + VMEM_RESERVED_SIZE)
|
||||
#define ROOT_SECTOR (FAT_SECTOR + (VMEM_SIZE_FAT*VMEM_NB_FATS))
|
||||
#define FILE_SECTOR (ROOT_SECTOR + ((ENTRY_SIZE*VMEM_NB_ROOT_ENTRY) / VMEM_SECTOR_SIZE)) // 1(sector) = size root dir
|
||||
|
||||
|
||||
/* FAT Format Structure */
|
||||
typedef struct
|
||||
{
|
||||
Uint16 nb_cylinder;
|
||||
Byte nb_head;
|
||||
Byte nb_sector;
|
||||
Byte nb_hidden_sector;
|
||||
Byte nb_sector_per_cluster;
|
||||
} s_format;
|
||||
|
||||
#define MEM_BSY 0
|
||||
#define MEM_OK 1
|
||||
#define MEM_KO 2
|
||||
|
||||
|
||||
|
||||
|
||||
//---- CONTROL FONCTIONS ----
|
||||
|
||||
// those fonctions are declared in df_mem.h
|
||||
void avrf_mem_init(void);
|
||||
Ctrl_status avrf_test_unit_ready(void);
|
||||
Ctrl_status avrf_read_capacity( U32 _MEM_TYPE_SLOW_ *u32_nb_sector );
|
||||
Bool avrf_wr_protect(void);
|
||||
Bool avrf_removal(void);
|
||||
|
||||
//---- AVR FLASH LOW-LEVEL----
|
||||
|
||||
|
||||
bit avrf_init (void);
|
||||
bit avrf_mem_check(void);
|
||||
bit avrf_read_open (Uint32);
|
||||
void avrf_read_close (void);
|
||||
bit avrf_write_open (Uint32);
|
||||
void avrf_write_close (void);
|
||||
|
||||
//! Funtions to link USB DEVICE flow with data flash
|
||||
bit avrf_write_sector (Uint16);
|
||||
bit avrf_read_sector (Uint16);
|
||||
|
||||
|
||||
s_format * avrf_format (void);
|
||||
|
||||
|
||||
|
||||
//---- ACCESS DATA FONCTIONS ----
|
||||
|
||||
// Standard functions for open in read/write mode the device
|
||||
Ctrl_status avrf_read_10( U32 addr , U16 nb_sector );
|
||||
Ctrl_status avrf_write_10( U32 addr , U16 nb_sector );
|
||||
|
||||
|
||||
//** If your device transfer have a specific transfer for USB (Particularity of Chejudo product, or bootloader)
|
||||
#ifdef DF_VALIDATION
|
||||
#include "virtual_usb.h"
|
||||
#else
|
||||
#include "usb_drv.h" // In this case the driver must be known for the USB access
|
||||
#endif
|
||||
Ctrl_status avr_usb_read( void );
|
||||
Ctrl_status avr_usb_write( void );
|
||||
|
||||
|
||||
|
||||
#endif // _DFMEM_H_
|
||||
|
||||
/** @} */
|
197
cpu/avr/dev/usb/storage/conf_access.h
Normal file
197
cpu/avr/dev/usb/storage/conf_access.h
Normal file
|
@ -0,0 +1,197 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file conf_access.h *********************************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file contains the possible external configuration of the control access
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
******************************************************************************/
|
||||
/*
|
||||
Copyright (c) 2004 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup usbstorage
|
||||
@{
|
||||
*/
|
||||
|
||||
#ifndef _CONF_ACCESS_H_
|
||||
#define _CONF_ACCESS_H_
|
||||
|
||||
|
||||
// Active the Logical Unit
|
||||
#define LUN_0 DISABLE // On-Chip flash vitual memory
|
||||
#define LUN_1 DISABLE // NF 2KB
|
||||
#define LUN_2 DISABLE // NF 512B
|
||||
#define LUN_3 DISABLE // Data Flash
|
||||
#define LUN_4 ENABLE //On-chip 32KB
|
||||
#define LUN_5 DISABLE
|
||||
#define LUN_6 DISABLE
|
||||
#define LUN_7 DISABLE
|
||||
#define LUN_USB DISABLE
|
||||
|
||||
// LUN 0 DEFINE
|
||||
#define LUN_0_INCLUDE "lib_mem\virtual_mem\virtual_mem.h"
|
||||
#define Lun_0_test_unit_ready() virtual_test_unit_ready()
|
||||
#define Lun_0_read_capacity(nb_sect) virtual_read_capacity(nb_sect)
|
||||
#define Lun_0_wr_protect() virtual_wr_protect()
|
||||
#define Lun_0_removal() virtual_removal()
|
||||
#define Lun_0_read_10(ad, sec) virtual_read_10(ad, sec)
|
||||
#define Lun_0_usb_read() virtual_usb_read()
|
||||
#define Lun_0_write_10(ad, sec) virtual_write_10(ad, sec)
|
||||
#define Lun_0_usb_write() virtual_usb_write()
|
||||
#define Lun_0_ram_2_mem(addr , ram) virtual_ram_2_mem(addr, ram)
|
||||
#define Lun_0_ram_2_mem_write() virtual_ram_2_mem_write()
|
||||
#define Lun_0_mem_2_ram(addr , ram) virtual_mem_2_ram(addr, ram)
|
||||
#define Lun_0_mem_2_ram_read() virtual_mem_2_ram_read()
|
||||
#define LUN_0_NAME "VIRTUAL_MEM_ON_CHIP"
|
||||
|
||||
// LUN 1 DEFINE
|
||||
#if (LUN_1 == ENABLE)
|
||||
#define NF_2K_MEM ENABLE
|
||||
#else
|
||||
#define NF_2K_MEM DISABLE
|
||||
#endif
|
||||
#define LUN_1_INCLUDE "lib_mem\nf_1x_2kb\nf_mem.h"
|
||||
#define Lun_1_test_unit_ready() nf_test_unit_ready()
|
||||
#define Lun_1_read_capacity(nb_sect) nf_read_capacity(nb_sect)
|
||||
#define Lun_1_wr_protect() nf_wr_protect()
|
||||
#define Lun_1_removal() nf_removal()
|
||||
#define Lun_1_read_10(ad, sec) nf_read_10(ad, sec)
|
||||
#define Lun_1_usb_read() nf_usb_read()
|
||||
#define Lun_1_write_10(ad, sec) nf_write_10(ad, sec)
|
||||
#define Lun_1_usb_write() nf_usb_write()
|
||||
#define Lun_1_ram_2_mem(addr , ram) TODO
|
||||
#define Lun_1_ram_2_mem_write() TODO
|
||||
#define Lun_1_mem_2_ram(addr , ram) TODO
|
||||
#define Lun_1_mem_2_ram_read() TODO
|
||||
|
||||
// LUN 2 DEFINE
|
||||
#if (LUN_2 == ENABLE)
|
||||
#define NF_512_MEM ENABLE
|
||||
#else
|
||||
#define NF_512_MEM DISABLE
|
||||
#endif
|
||||
#define LUN_2_INCLUDE "lib_mem\nf_1x_512\nf_mem.h"
|
||||
#define Lun_2_test_unit_ready() nf_test_unit_ready()
|
||||
#define Lun_2_read_capacity(nb_sect) nf_read_capacity(nb_sect)
|
||||
#define Lun_2_wr_protect() nf_wr_protect()
|
||||
#define Lun_2_removal() nf_removal()
|
||||
#define Lun_2_read_10(ad, sec) nf_read_10(ad, sec)
|
||||
#define Lun_2_usb_read() nf_usb_read()
|
||||
#define Lun_2_write_10(ad, sec) nf_write_10(ad, sec)
|
||||
#define Lun_2_usb_write() nf_usb_write()
|
||||
#define Lun_2_ram_2_mem(addr , ram) TODO
|
||||
#define Lun_2_ram_2_mem_write() TODO
|
||||
#define Lun_2_mem_2_ram(addr , ram) TODO
|
||||
#define Lun_2_mem_2_ram_read() TODO
|
||||
|
||||
// LUN 3 DEFINE
|
||||
#if (LUN_3 == ENABLE)
|
||||
#define DF_MEM ENABLE
|
||||
#else
|
||||
#define DF_MEM DISABLE
|
||||
#endif
|
||||
#define LUN_ID_DF LUN_ID_3
|
||||
#define LUN_3_INCLUDE "lib_mem\df\df_mem.h"
|
||||
#define Lun_3_test_unit_ready() df_test_unit_ready()
|
||||
#define Lun_3_read_capacity(nb_sect) df_read_capacity(nb_sect)
|
||||
#define Lun_3_wr_protect() df_wr_protect()
|
||||
#define Lun_3_removal() df_removal()
|
||||
#define Lun_3_read_10(ad, sec) df_read_10(ad, sec)
|
||||
#define Lun_3_usb_read() df_usb_read()
|
||||
#define Lun_3_write_10(ad, sec) df_write_10(ad, sec)
|
||||
#define Lun_3_usb_write() df_usb_write()
|
||||
#define Lun_3_ram_2_mem(addr , ram) df_ram_2_df(addr, ram)
|
||||
#define Lun_3_ram_2_mem_write() df_ram_2_df_write()
|
||||
#define Lun_3_mem_2_ram(addr , ram) df_df_2_ram(addr, ram)
|
||||
#define Lun_3_mem_2_ram_read() df_df_2_ram_read()
|
||||
#define LUN_3_NAME "\"On board data flash\""
|
||||
|
||||
// LUN 3 DEFINE
|
||||
#if (LUN_3 == ENABLE)
|
||||
#define AVR_MEM ENABLE
|
||||
#else
|
||||
#define AVR_MEM DISABLE
|
||||
#endif
|
||||
#define LUN_ID_AVRF LUN_ID_4
|
||||
#define LUN_4_INCLUDE "storage/avr_flash.h"
|
||||
#define Lun_4_test_unit_ready() avrf_test_unit_ready()
|
||||
#define Lun_4_read_capacity(nb_sect) avrf_read_capacity(nb_sect)
|
||||
#define Lun_4_wr_protect() avrf_wr_protect()
|
||||
#define Lun_4_removal() avrf_removal()
|
||||
#define Lun_4_read_10(ad, sec) avrf_read_10(ad, sec)
|
||||
#define Lun_4_usb_read() avrf_usb_read()
|
||||
#define Lun_4_write_10(ad, sec) avrf_write_10(ad,sec)
|
||||
#define Lun_4_usb_write() avrf_usb_write()
|
||||
#define Lun_4_ram_2_mem(addr , ram) TODO
|
||||
#define Lun_4_ram_2_mem_write() TODO
|
||||
#define Lun_4_mem_2_ram(addr , ram) TODO
|
||||
#define Lun_4_mem_2_ram_read() TODO
|
||||
#define LUN_4_NAME "\"AVR Flash Memory\""
|
||||
|
||||
|
||||
// LUN USB DEFINE
|
||||
#if (LUN_USB == ENABLE)
|
||||
#define MEM_USB ENABLE
|
||||
#else
|
||||
#define MEM_USB DISABLE
|
||||
#endif
|
||||
#define LUN_USB_INCLUDE "lib_mem\host_mem\host_mem.h"
|
||||
#define Lun_usb_test_unit_ready(lun) host_test_unit_ready(lun)
|
||||
#define Lun_usb_read_capacity(lun,nb_sect) host_read_capacity(lun,nb_sect)
|
||||
#define Lun_usb_wr_protect(lun) host_wr_protect(lun)
|
||||
#define Lun_usb_removal() host_removal()
|
||||
#define Lun_usb_ram_2_mem(addr , ram) host_write_10_ram(addr, ram)
|
||||
#define Lun_usb_mem_2_ram(addr , ram) host_read_10_ram(addr, ram)
|
||||
#define LUN_USB_NAME "\"USB Remote memory\""
|
||||
|
||||
|
||||
// ATMEL DEFINE - DO NOT MODIFY
|
||||
|
||||
// Active interface fonction
|
||||
#define ACCESS_USB ENABLED // USB I/O in control access
|
||||
#define ACCESS_STREAM DISABLED // Stream I/O in control access
|
||||
#define ACCESS_STREAM_RECORD DISABLED // Stream I/O in control access AND RECORD MODE
|
||||
#define ACCESS_MEM_TO_RAM DISABLED // RAM to Mem I/O in control access
|
||||
#define ACCESS_MEM_TO_MEM DISABLED // Mem to Mem I/O in control access
|
||||
|
||||
|
||||
|
||||
// Specific option control access
|
||||
#define GLOBAL_WR_PROTECT DISABLED // To manage a global write protection
|
||||
|
||||
|
||||
#endif //! _CONF_ACCESS_H_
|
||||
|
||||
/** @} */
|
973
cpu/avr/dev/usb/storage/ctrl_access.c
Normal file
973
cpu/avr/dev/usb/storage/ctrl_access.c
Normal file
|
@ -0,0 +1,973 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file ctrl_access.c *********************************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file contains the interface :
|
||||
* - between USB <-> MEMORY
|
||||
* OR
|
||||
* - between USB <- Access Memory Ctrl -> Memory
|
||||
*
|
||||
* This interface may be controled by a "Access Memory Control" for :
|
||||
* - include a management of write protect global or specific
|
||||
* - include a management of access password
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
******************************************************************************/
|
||||
/*
|
||||
Copyright (c) 2004 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup usbstorage
|
||||
@{
|
||||
*/
|
||||
|
||||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
#include "config.h"
|
||||
#include "storage/ctrl_access.h"
|
||||
|
||||
|
||||
//_____ D E F I N I T I O N S ______________________________________________
|
||||
|
||||
#if (ACCESS_MEM_TO_MEM == ENABLED)
|
||||
#include "modules/file_system/fat.h"
|
||||
U8 buf_sector[FS_SIZE_OF_SECTOR];
|
||||
#endif
|
||||
|
||||
|
||||
//! Computed the maximum of static lun (don't add the lun of Mass Storage in mode USB Host)
|
||||
// FYC: Memory = Logical Unit
|
||||
|
||||
|
||||
|
||||
// CHECK FOR LUN DEFINE
|
||||
#ifndef LUN_0
|
||||
# error LUN_0 must be defined with ENABLE or DISABLE in conf_access.h
|
||||
#endif
|
||||
#ifndef LUN_1
|
||||
# error LUN_1 must be defined with ENABLE or DISABLE in conf_access.h
|
||||
#endif
|
||||
#ifndef LUN_2
|
||||
# error LUN_2 must be defined with ENABLE or DISABLE in conf_access.h
|
||||
#endif
|
||||
#ifndef LUN_3
|
||||
# error LUN_3 must be defined with ENABLE or DISABLE in conf_access.h
|
||||
#endif
|
||||
#ifndef LUN_4
|
||||
# error LUN_4 must be defined with ENABLE or DISABLE in conf_access.h
|
||||
#endif
|
||||
#ifndef LUN_5
|
||||
# error LUN_5 must be defined with ENABLE or DISABLE in conf_access.h
|
||||
#endif
|
||||
#ifndef LUN_6
|
||||
# error LUN_6 must be defined with ENABLE or DISABLE in conf_access.h
|
||||
#endif
|
||||
#ifndef LUN_7
|
||||
# error LUN_7 must be defined with ENABLE or DISABLE in conf_access.h
|
||||
#endif
|
||||
#ifndef LUN_USB
|
||||
# error LUN_USB must be defined with ENABLE or DISABLE in conf_access.h
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if (LUN_0 == ENABLE)
|
||||
#define LUN_0_EN 1
|
||||
U8 FLASH lun0_name[]=LUN_0_NAME;
|
||||
#else
|
||||
#define LUN_0_EN 0
|
||||
#endif
|
||||
#if (LUN_1 == ENABLE)
|
||||
#define LUN_1_EN 1
|
||||
U8 FLASH lun1_name[]=LUN_1_NAME;
|
||||
#else
|
||||
#define LUN_1_EN 0
|
||||
#endif
|
||||
#if (LUN_2 == ENABLE)
|
||||
#define LUN_2_EN 1
|
||||
U8 FLASH lun2_name[]=LUN_2_NAME;
|
||||
#else
|
||||
#define LUN_2_EN 0
|
||||
#endif
|
||||
#if (LUN_3 == ENABLE)
|
||||
#define LUN_3_EN 1
|
||||
U8 FLASH lun3_name[]=LUN_3_NAME;
|
||||
#else
|
||||
#define LUN_3_EN 0
|
||||
#endif
|
||||
#if (LUN_4 == ENABLE)
|
||||
#define LUN_4_EN 1
|
||||
U8 FLASH lun4_name[]=LUN_4_NAME;
|
||||
#else
|
||||
#define LUN_4_EN 0
|
||||
#endif
|
||||
#if (LUN_5 == ENABLE)
|
||||
#define LUN_5_EN 1
|
||||
U8 FLASH lun5_name[]=LUN_5_NAME;
|
||||
#else
|
||||
#define LUN_5_EN 0
|
||||
#endif
|
||||
#if (LUN_6 == ENABLE)
|
||||
#define LUN_6_EN 1
|
||||
U8 FLASH lun6_name[]=LUN_6_NAME;
|
||||
#else
|
||||
#define LUN_6_EN 0
|
||||
#endif
|
||||
#if (LUN_7 == ENABLE)
|
||||
#define LUN_7_EN 1
|
||||
U8 FLASH lun7_name[]=LUN_7_NAME;
|
||||
#else
|
||||
#define LUN_7_EN 0
|
||||
#endif
|
||||
#if (LUN_USB == ENABLE)
|
||||
#define LUN_USB_EN 1
|
||||
U8 FLASH lunusb_name[]=LUN_USB_NAME;
|
||||
#else
|
||||
#define LUN_USB_EN 0
|
||||
#endif
|
||||
|
||||
|
||||
#define LUN_ID_0 (0)
|
||||
#define LUN_ID_1 (LUN_0_EN)
|
||||
#define LUN_ID_2 (LUN_0_EN+LUN_1_EN)
|
||||
#define LUN_ID_3 (LUN_0_EN+LUN_1_EN+LUN_2_EN)
|
||||
#define LUN_ID_4 (LUN_0_EN+LUN_1_EN+LUN_2_EN+LUN_3_EN)
|
||||
#define LUN_ID_5 (LUN_0_EN+LUN_1_EN+LUN_2_EN+LUN_3_EN+LUN_4_EN)
|
||||
#define LUN_ID_6 (LUN_0_EN+LUN_1_EN+LUN_2_EN+LUN_3_EN+LUN_4_EN+LUN_5_EN)
|
||||
#define LUN_ID_7 (LUN_0_EN+LUN_1_EN+LUN_2_EN+LUN_3_EN+LUN_4_EN+LUN_5_EN+LUN_6_EN)
|
||||
#define MAX_LUN (LUN_0_EN+LUN_1_EN+LUN_2_EN+LUN_3_EN+LUN_4_EN+LUN_5_EN+LUN_6_EN+LUN_7_EN)
|
||||
#define LUN_ID_USB (MAX_LUN)
|
||||
|
||||
// Check configuration
|
||||
#if (MAX_LUN == 0)
|
||||
#error No memory is active in conf_access.h
|
||||
#endif
|
||||
|
||||
// Write protect variable
|
||||
#if (GLOBAL_WR_PROTECT == ENABLED)
|
||||
static U8 g_u8_wr_protect;
|
||||
#endif
|
||||
|
||||
|
||||
//_____ D E F I N I T I O N S __ F O N C T I O N S _________________________
|
||||
|
||||
|
||||
//! This fonction return the number of logical unit
|
||||
//!
|
||||
//! @return U8 number of logical unit in the system
|
||||
//!
|
||||
U8 get_nb_lun()
|
||||
{
|
||||
#if (MEM_USB == ENABLED)
|
||||
return (MAX_LUN + Host_getlun());
|
||||
#else
|
||||
return MAX_LUN;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//! This fonction return the current logical unit
|
||||
//!
|
||||
//! @return U8 number of logical unit in the system
|
||||
//!
|
||||
U8 get_cur_lun()
|
||||
{
|
||||
return 0; //TODO
|
||||
}
|
||||
|
||||
|
||||
//! This fonction test the state of memory, and start the initialisation of the memory
|
||||
//!
|
||||
//! MORE (see SPC-3 §5.2.4) : The TEST UNIT READY command allows an application client
|
||||
//! to poll a logical unit until it is ready without the need to allocate space for returned data.
|
||||
//! The TEST UNIT READY command may be used to check the media status of logical units with removable media.
|
||||
//!
|
||||
//! @param lun Logical unit number
|
||||
//!
|
||||
//! @return Ctrl_status
|
||||
//! It is ready -> CTRL_GOOD
|
||||
//! Memory unplug -> CTRL_NO_PRESENT
|
||||
//! Not initialize -> CTRL_BUSY
|
||||
//!
|
||||
Ctrl_status mem_test_unit_ready( U8 lun )
|
||||
{
|
||||
switch( lun )
|
||||
{
|
||||
# if (LUN_0 == ENABLE)
|
||||
case LUN_ID_0:
|
||||
return Lun_0_test_unit_ready();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_1 == ENABLE)
|
||||
case LUN_ID_1:
|
||||
return Lun_1_test_unit_ready();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_2 == ENABLE)
|
||||
case LUN_ID_2:
|
||||
return Lun_2_test_unit_ready();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_3 == ENABLE)
|
||||
case LUN_ID_3:
|
||||
return Lun_3_test_unit_ready();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_4 == ENABLE)
|
||||
case LUN_ID_4:
|
||||
return Lun_4_test_unit_ready();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_5 == ENABLE)
|
||||
case LUN_ID_5:
|
||||
return Lun_5_test_unit_ready();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_6 == ENABLE)
|
||||
case LUN_ID_6:
|
||||
return Lun_6_test_unit_ready();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_7 == ENABLE)
|
||||
case LUN_ID_7:
|
||||
return Lun_7_test_unit_ready();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_USB == ENABLE)
|
||||
default:
|
||||
return Lun_usb_test_unit_ready(lun - LUN_ID_USB);
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
return CTRL_FAIL;
|
||||
}
|
||||
|
||||
//! This fonction return the capacity of the memory
|
||||
//!
|
||||
//! @param lun Logical unit number
|
||||
//! @param u32_nb_sector The sector to query
|
||||
//!
|
||||
//! @return *u16_nb_sector number of sector (sector = 512B)
|
||||
//! @return Ctrl_status
|
||||
//! It is ready -> CTRL_GOOD
|
||||
//! Memory unplug -> CTRL_NO_PRESENT
|
||||
//!
|
||||
Ctrl_status mem_read_capacity( U8 lun , U32 _MEM_TYPE_SLOW_ *u32_nb_sector )
|
||||
{
|
||||
switch( lun )
|
||||
{
|
||||
# if (LUN_0 == ENABLE)
|
||||
case LUN_ID_0:
|
||||
return Lun_0_read_capacity( u32_nb_sector );
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_1 == ENABLE)
|
||||
case LUN_ID_1:
|
||||
return Lun_1_read_capacity( u32_nb_sector );
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_2 == ENABLE)
|
||||
case LUN_ID_2:
|
||||
return Lun_2_read_capacity( u32_nb_sector );
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_3 == ENABLE)
|
||||
case LUN_ID_3:
|
||||
return Lun_3_read_capacity( u32_nb_sector );
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_4 == ENABLE)
|
||||
case LUN_ID_4:
|
||||
return Lun_4_read_capacity( u32_nb_sector );
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_5 == ENABLE)
|
||||
case LUN_ID_5:
|
||||
return Lun_5_read_capacity( u32_nb_sector );
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_6 == ENABLE)
|
||||
case LUN_ID_6:
|
||||
return Lun_6_read_capacity( u32_nb_sector );
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_7 == ENABLE)
|
||||
case LUN_ID_7:
|
||||
return Lun_7_read_capacity( u32_nb_sector );
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_USB == ENABLE)
|
||||
default:
|
||||
return Lun_usb_read_capacity( lun - LUN_ID_USB,u32_nb_sector );
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
return CTRL_FAIL;
|
||||
}
|
||||
|
||||
//! This fonction return is the write protected mode
|
||||
//!
|
||||
//! @param lun Logical unit number
|
||||
//!
|
||||
//! Only used by memory removal with a HARDWARE SPECIFIC write protected detection
|
||||
//! !!! The customer must be unplug the card for change this write protected mode.
|
||||
//!
|
||||
//! @return TRUE -> the memory is protected
|
||||
//!
|
||||
Bool mem_wr_protect( U8 lun )
|
||||
{
|
||||
switch( lun )
|
||||
{
|
||||
# if (LUN_0 == ENABLE)
|
||||
case LUN_ID_0:
|
||||
return Lun_0_wr_protect();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_1 == ENABLE)
|
||||
case LUN_ID_1:
|
||||
return Lun_1_wr_protect();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_2 == ENABLE)
|
||||
case LUN_ID_2:
|
||||
return Lun_2_wr_protect();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_3 == ENABLE)
|
||||
case LUN_ID_3:
|
||||
return Lun_3_wr_protect();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_4 == ENABLE)
|
||||
case LUN_ID_4:
|
||||
return Lun_4_wr_protect();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_5 == ENABLE)
|
||||
case LUN_ID_5:
|
||||
return Lun_5_wr_protect();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_6 == ENABLE)
|
||||
case LUN_ID_6:
|
||||
return Lun_6_wr_protect();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_7 == ENABLE)
|
||||
case LUN_ID_7:
|
||||
return Lun_7_wr_protect();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_USB == ENABLE)
|
||||
default:
|
||||
return Lun_usb_wr_protect(lun - LUN_ID_USB);
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
return CTRL_FAIL;
|
||||
}
|
||||
|
||||
|
||||
//! This fonction inform about the memory type
|
||||
//!
|
||||
//! @param lun Logical unit number
|
||||
//!
|
||||
//! @return TRUE -> The memory is removal
|
||||
//!
|
||||
Bool mem_removal( U8 lun )
|
||||
{
|
||||
switch( lun )
|
||||
{
|
||||
# if (LUN_0 == ENABLE)
|
||||
case LUN_ID_0:
|
||||
return Lun_0_removal();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_1 == ENABLE)
|
||||
case LUN_ID_1:
|
||||
return Lun_1_removal();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_2 == ENABLE)
|
||||
case LUN_ID_2:
|
||||
return Lun_2_removal();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_3 == ENABLE)
|
||||
case LUN_ID_3:
|
||||
return Lun_3_removal();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_4 == ENABLE)
|
||||
case LUN_ID_4:
|
||||
return Lun_4_removal();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_5 == ENABLE)
|
||||
case LUN_ID_5:
|
||||
return Lun_5_removal();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_6 == ENABLE)
|
||||
case LUN_ID_6:
|
||||
return Lun_6_removal();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_7 == ENABLE)
|
||||
case LUN_ID_7:
|
||||
return Lun_7_removal();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_USB == ENABLE)
|
||||
default:
|
||||
return Lun_usb_removal();
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
return CTRL_FAIL;
|
||||
}
|
||||
|
||||
//! This fonction returns a pointer to the LUN name
|
||||
//!
|
||||
//! @param lun Logical unit number
|
||||
//!
|
||||
//! @return pointer to code string
|
||||
//!
|
||||
U8 FLASH* mem_name( U8 lun )
|
||||
{
|
||||
switch( lun )
|
||||
{
|
||||
# if (LUN_0 == ENABLE)
|
||||
case LUN_ID_0:
|
||||
return (U8 FLASH*)lun0_name;
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_1 == ENABLE)
|
||||
case LUN_ID_1:
|
||||
return (U8 FLASH*)lun1_name;
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_2 == ENABLE)
|
||||
case LUN_ID_2:
|
||||
return (U8 FLASH*)lun2_name;
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_3 == ENABLE)
|
||||
case LUN_ID_3:
|
||||
return (U8 FLASH*)lun3_name;
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_4 == ENABLE)
|
||||
case LUN_ID_4:
|
||||
return (U8 FLASH*)lun4_name;
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_5 == ENABLE)
|
||||
case LUN_ID_5:
|
||||
return (U8 FLASH*)lun5_name;
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_6 == ENABLE)
|
||||
case LUN_ID_6:
|
||||
return (U8 FLASH*)lun6_name;
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_7 == ENABLE)
|
||||
case LUN_ID_7:
|
||||
return (U8 FLASH*)lun7_name;
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_USB == ENABLE)
|
||||
default:
|
||||
return (U8 FLASH*)lunusb_name;
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
return 0; // Remove compiler warning
|
||||
}
|
||||
|
||||
//************************************************************************************
|
||||
//!----------- Listing of READ/WRITE interface with MODE ACCESS REGISTER -------------
|
||||
//************************************************************************************
|
||||
|
||||
|
||||
//! This fonction tranfer a data from memory to usb
|
||||
//!
|
||||
//! @param lun Logical unit number
|
||||
//! @param addr Sector address to start read (sector = 512B)
|
||||
//! @param nb_sector Number of sectors to transfer
|
||||
//!
|
||||
//! @return Ctrl_status
|
||||
//! It is ready -> CTRL_GOOD
|
||||
//! A error occur -> CTRL_FAIL
|
||||
//! Memory unplug -> CTRL_NO_PRESENT
|
||||
//!
|
||||
Ctrl_status memory_2_usb( U8 lun , U32 addr , U16 nb_sector )
|
||||
{
|
||||
Ctrl_status status;
|
||||
|
||||
switch( lun )
|
||||
{
|
||||
# if (LUN_0 == ENABLE)
|
||||
case LUN_ID_0:
|
||||
status = Lun_0_read_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_0_usb_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_1 == ENABLE)
|
||||
case LUN_ID_1:
|
||||
status = Lun_1_read_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_1_usb_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_2 == ENABLE)
|
||||
case LUN_ID_2:
|
||||
status = Lun_2_read_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_2_usb_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_3 == ENABLE)
|
||||
case LUN_ID_3:
|
||||
status = Lun_3_read_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_3_usb_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_4 == ENABLE)
|
||||
case LUN_ID_4:
|
||||
status = Lun_4_read_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_4_usb_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_5 == ENABLE)
|
||||
case LUN_ID_5:
|
||||
status = Lun_5_read_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_5_usb_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_6 == ENABLE)
|
||||
case LUN_ID_6:
|
||||
status = Lun_6_read_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_6_usb_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_7 == ENABLE)
|
||||
case LUN_ID_7:
|
||||
status = Lun_7_read_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_7_usb_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
//! This fonction trabsfer a data from usb to memory
|
||||
//!
|
||||
//! @param lun Logical unit number
|
||||
//! @param addr Sector address to start write (sector = 512B)
|
||||
//! @param nb_sector Number of sectors to transfer
|
||||
//!
|
||||
//! @return Ctrl_status
|
||||
//! It is ready -> CTRL_GOOD
|
||||
//! A error occur -> CTRL_FAIL
|
||||
//! Memory unplug -> CTRL_NO_PRESENT
|
||||
//!
|
||||
Ctrl_status usb_2_memory( U8 lun , U32 addr , U16 nb_sector )
|
||||
{
|
||||
Ctrl_status status;
|
||||
|
||||
switch( lun )
|
||||
{
|
||||
# if (LUN_0 == ENABLE)
|
||||
case LUN_ID_0:
|
||||
status = Lun_0_write_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_0_usb_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_1 == ENABLE)
|
||||
case LUN_ID_1:
|
||||
status = Lun_1_write_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_1_usb_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_2 == ENABLE)
|
||||
case LUN_ID_2:
|
||||
status = Lun_2_write_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_2_usb_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_3 == ENABLE)
|
||||
case LUN_ID_3:
|
||||
status = Lun_3_write_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_3_usb_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_4 == ENABLE)
|
||||
case LUN_ID_4:
|
||||
status = Lun_4_write_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_4_usb_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_5 == ENABLE)
|
||||
case LUN_ID_5:
|
||||
status = Lun_5_write_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_5_usb_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_6 == ENABLE)
|
||||
case LUN_ID_6:
|
||||
status = Lun_6_write_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_6_usb_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_7 == ENABLE)
|
||||
case LUN_ID_7:
|
||||
status = Lun_7_write_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_7_usb_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
//! Interface for RAM
|
||||
#if (ACCESS_MEM_TO_RAM == ENABLED)
|
||||
|
||||
//! This fonction tranfer one sector data from memory to ram
|
||||
//!
|
||||
//! @param lun Logical unit number
|
||||
//! @param addr Sector address to start read (sector = 512B)
|
||||
//! @param ram Adresse of ram buffer (only xdata)
|
||||
//!
|
||||
//! @return TRUE -> The memory is removal
|
||||
//!
|
||||
Ctrl_status memory_2_ram( U8 lun , const U32 _MEM_TYPE_SLOW_ *addr , U8 _MEM_TYPE_SLOW_ *ram )
|
||||
{
|
||||
|
||||
Ctrl_status status;
|
||||
|
||||
switch( lun )
|
||||
{
|
||||
# if (LUN_0 == ENABLE)
|
||||
case LUN_ID_0:
|
||||
status = Lun_0_mem_2_ram(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_0_mem_2_ram_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_1 == ENABLE)
|
||||
case LUN_ID_1:
|
||||
status = Lun_1_mem_2_ram(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_1_mem_2_ram_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_2 == ENABLE)
|
||||
case LUN_ID_2:
|
||||
status = Lun_2_mem_2_ram(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_2_mem_2_ram_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_3 == ENABLE)
|
||||
case LUN_ID_3:
|
||||
status = Lun_3_mem_2_ram(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_3_mem_2_ram_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_4 == ENABLE)
|
||||
case LUN_ID_4:
|
||||
status = Lun_4_mem_2_ram(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_4_mem_2_ram_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_5 == ENABLE)
|
||||
case LUN_ID_5:
|
||||
status = Lun_5_mem_2_ram(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_5_mem_2_ram_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_6 == ENABLE)
|
||||
case LUN_ID_6:
|
||||
status = Lun_6_mem_2_ram(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_6_mem_2_ram_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_7 == ENABLE)
|
||||
case LUN_ID_7:
|
||||
status = Lun_7_mem_2_ram(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_7_mem_2_ram_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_USB == ENABLE)
|
||||
default:
|
||||
return Lun_usb_mem_2_ram(*addr , ram);
|
||||
# endif
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#endif // ACCESS_MEM_TO_RAM == ENABLED
|
||||
|
||||
|
||||
|
||||
#if (ACCESS_MEM_TO_RAM==ENABLE)
|
||||
|
||||
//! This fonction trabsfer a data from ram to memory
|
||||
//!
|
||||
//! @param lun Logical unit number
|
||||
//! @param addr Sector address to start write (sector = 512B)
|
||||
//! @param ram Adresse of ram buffer (only xdata)
|
||||
//!
|
||||
//! @return TRUE -> The memory is removal
|
||||
//!
|
||||
Ctrl_status ram_2_memory( U8 lun , const U32 _MEM_TYPE_SLOW_ *addr , U8 _MEM_TYPE_SLOW_ * ram )
|
||||
{
|
||||
Ctrl_status status;
|
||||
|
||||
switch( lun )
|
||||
{
|
||||
# if (LUN_0 == ENABLE)
|
||||
case LUN_ID_0:
|
||||
status = Lun_0_ram_2_mem(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_0_ram_2_mem_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_1 == ENABLE)
|
||||
case LUN_ID_1:
|
||||
status = Lun_1_ram_2_mem(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_1_ram_2_mem_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_2 == ENABLE)
|
||||
case LUN_ID_2:
|
||||
status = Lun_2_ram_2_mem(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_2_ram_2_mem_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_3 == ENABLE)
|
||||
case LUN_ID_3:
|
||||
status = Lun_3_ram_2_mem(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_3_ram_2_mem_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_4 == ENABLE)
|
||||
case LUN_ID_4:
|
||||
status = Lun_4_ram_2_mem(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_4_ram_2_mem_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_5 == ENABLE)
|
||||
case LUN_ID_5:
|
||||
status = Lun_5_ram_2_mem(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_5_ram_2_mem_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_6 == ENABLE)
|
||||
case LUN_ID_6:
|
||||
status = Lun_6_ram_2_mem(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_6_ram_2_mem_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_7 == ENABLE)
|
||||
case LUN_ID_7:
|
||||
status = Lun_7_ram_2_mem(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_7_ram_2_mem_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_USB == ENABLE)
|
||||
default:
|
||||
return Lun_usb_ram_2_mem(*addr , ram);
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#endif // ACCESS_RAM_TO_MEM == ENABLED
|
||||
|
||||
|
||||
|
||||
//! Interface for streaming interface
|
||||
#if (ACCESS_STREAM == ENABLED)
|
||||
|
||||
|
||||
|
||||
// Interface for transfer MEM to MEM
|
||||
# if (ACCESS_MEM_TO_MEM == ENABLED)
|
||||
//! This fonction copy a data from memory to other memory
|
||||
//!
|
||||
//! @param src_lun The LUN of the source
|
||||
//! @param src_addr The address of the source
|
||||
//! @param dest_lun The LUN of the destination
|
||||
//! @param dest_addr The address of the destination
|
||||
//! @param nb_sector Number of sectors to transfer
|
||||
//!
|
||||
U8 stream_mem_to_mem( U8 src_lun , U32 src_addr , U8 dest_lun , U32 dest_addr , U16 nb_sector )
|
||||
{
|
||||
while(nb_sector)
|
||||
{
|
||||
memory_2_ram( src_lun , &src_addr , buf_sector );
|
||||
ram_2_memory( dest_lun , &dest_addr , buf_sector );
|
||||
src_addr++;
|
||||
dest_addr++;
|
||||
nb_sector--;
|
||||
}
|
||||
return CTRL_GOOD;
|
||||
}
|
||||
# endif // ACCESS_MEM_TO_MEM == ENABLED
|
||||
|
||||
|
||||
|
||||
|
||||
//! Returns the state on a data transfer
|
||||
//!
|
||||
//! @param Id transfer id
|
||||
//!
|
||||
//! @return the state of the transfer
|
||||
//! CTRL_GOOD It is finish
|
||||
//! CTRL_BUSY It is running
|
||||
//! CTRL_FAIL It is fail
|
||||
//!
|
||||
Ctrl_status stream_state( U8 Id )
|
||||
{
|
||||
|
||||
return CTRL_GOOD;
|
||||
}
|
||||
|
||||
//! Stop the data transfer
|
||||
//!
|
||||
//! @param Id Transfer id
|
||||
//!
|
||||
//! @return the number of sector remainder
|
||||
//!
|
||||
U16 stream_stop( U8 Id )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // ACCESS_STREAM == ENABLED
|
||||
|
||||
/** @} */
|
157
cpu/avr/dev/usb/storage/ctrl_access.h
Normal file
157
cpu/avr/dev/usb/storage/ctrl_access.h
Normal file
|
@ -0,0 +1,157 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file ctrl_access.h *******************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file contains the interface :
|
||||
* - between USB <-> MEMORY
|
||||
* OR
|
||||
* - between USB <- Access Memory Ctrl -> Memory
|
||||
*
|
||||
* This interface may be controled by a "Access Memory Control" for :
|
||||
* - include a management of write protect global or specific
|
||||
* - include a management of access password
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
******************************************************************************/
|
||||
/*
|
||||
Copyright (c) 2004 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup usbstorage
|
||||
@{
|
||||
*/
|
||||
|
||||
#ifndef _MEM_CTRL_H_
|
||||
#define _MEM_CTRL_H_
|
||||
|
||||
#include "storage/conf_access.h"
|
||||
#include "storage/ctrl_status.h"
|
||||
|
||||
// FYC: Memory = Logical Unit
|
||||
#if (LUN_0 == ENABLE)
|
||||
#include LUN_0_INCLUDE
|
||||
#endif
|
||||
#if (LUN_1 == ENABLE)
|
||||
#include LUN_1_INCLUDE
|
||||
#endif
|
||||
#if (LUN_2 == ENABLE)
|
||||
#include LUN_2_INCLUDE
|
||||
#endif
|
||||
#if (LUN_3 == ENABLE)
|
||||
#include LUN_3_INCLUDE
|
||||
#endif
|
||||
#if (LUN_4 == ENABLE)
|
||||
#include LUN_4_INCLUDE
|
||||
#endif
|
||||
#if (LUN_5 == ENABLE)
|
||||
#include LUN_5_INCLUDE
|
||||
#endif
|
||||
#if (LUN_6 == ENABLE)
|
||||
#include LUN_6_INCLUDE
|
||||
#endif
|
||||
#if (LUN_7 == ENABLE)
|
||||
#include LUN_7_INCLUDE
|
||||
#endif
|
||||
#if (LUN_USB == ENABLE)
|
||||
#include LUN_USB_INCLUDE
|
||||
#endif
|
||||
|
||||
|
||||
//------- Test the configuration in conf_access.h
|
||||
|
||||
// Specific option control access
|
||||
#ifndef GLOBAL_WR_PROTECT
|
||||
# error GLOBAL_WR_PROTECT must be defined with ENABLED or DISABLED in conf_access.h
|
||||
#endif
|
||||
//------- END OF Test the configuration in conf_access.h
|
||||
|
||||
|
||||
|
||||
//_____ D E F I N I T I O N S ______________________________________________
|
||||
|
||||
|
||||
|
||||
//!**** Listing of commun interface ****************************************
|
||||
|
||||
U8 get_nb_lun();
|
||||
U8 get_cur_lun();
|
||||
Ctrl_status mem_test_unit_ready( U8 lun );
|
||||
Ctrl_status mem_read_capacity( U8 lun , U32 _MEM_TYPE_SLOW_ *u32_nb_sector );
|
||||
Bool mem_wr_protect( U8 lun );
|
||||
Bool mem_removal( U8 lun );
|
||||
U8 FLASH* mem_name( U8 lun );
|
||||
|
||||
|
||||
//!**** Listing of READ/WRITE interface ************************************
|
||||
|
||||
|
||||
//---- Interface for USB ---------------------------------------------------
|
||||
Ctrl_status memory_2_usb( U8 lun , U32 addr , U16 nb_sector );
|
||||
Ctrl_status usb_2_memory( U8 lun , U32 addr , U16 nb_sector );
|
||||
#include "usb_drv.h"
|
||||
#include "conf_usb.h"
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
//---- Interface for RAM to MEM --------------------------------------------
|
||||
Ctrl_status memory_2_ram( U8 lun , const U32 _MEM_TYPE_SLOW_ *addr , U8 _MEM_TYPE_SLOW_ *ram );
|
||||
Ctrl_status ram_2_memory( U8 lun , const U32 _MEM_TYPE_SLOW_ *addr , U8 _MEM_TYPE_SLOW_ * ram );
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
//!---- Interface for streaming interface ----------------------------------
|
||||
#if (ACCESS_STREAM == ENABLED)
|
||||
|
||||
#define ID_STREAM_ERR 0xFF
|
||||
|
||||
|
||||
// RLE #include "dfc_mngt.h"
|
||||
|
||||
#define TYPE_STREAM_AUDIO DFC_ID_AUDIOPROC1
|
||||
#define TYPE_STREAM_AUDIO2 DFC_ID_AUDIOPROC2
|
||||
#define TYPE_STREAM_SIO DFC_ID_SIO
|
||||
#define TYPE_STREAM_SPI DFC_ID_SPI
|
||||
#define TYPE_STREAM_DEVNULL DFC_ID_NULL_DEV
|
||||
|
||||
U8 stream_mem_to_mem ( U8 src_lun , U32 src_addr , U8 dest_lun , U32 dest_addr , U16 nb_sector );
|
||||
U8 stream_read_10_start ( U8 TypeStream , U8 lun , U32 addr , U16 nb_sector );
|
||||
U8 stream_write_10_start ( U8 TypeStream , U8 lun , U32 addr , U16 nb_sector );
|
||||
U8 stream_to_stream_start ( U8 TypeStream_src , U8 TypeStream_dest , U16 nb_sector );
|
||||
Ctrl_status stream_state( U8 Id );
|
||||
U16 stream_stop( U8 Id );
|
||||
|
||||
#endif // (ACCESS_STREAM == ENABLED)
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
#endif // _MEM_CTRL_H_
|
||||
/**@}*/
|
70
cpu/avr/dev/usb/storage/ctrl_status.h
Normal file
70
cpu/avr/dev/usb/storage/ctrl_status.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file ctrl_status.h ********************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file contains the interface :
|
||||
* - between USB <-> MEMORY
|
||||
* OR
|
||||
* - between USB <- Access Memory Ctrl -> Memory
|
||||
*
|
||||
* This interface may be controled by a "Access Memory Control" for :
|
||||
* - include a management of write protect global or specific
|
||||
* - include a management of access password
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
******************************************************************************/
|
||||
/*
|
||||
Copyright (c) 2004 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup usbstorage
|
||||
@{
|
||||
*/
|
||||
|
||||
#ifndef _CTRL_STATUS_H_
|
||||
#define _CTRL_STATUS_H_
|
||||
|
||||
//_____ D E F I N I T I O N S ______________________________________________
|
||||
|
||||
//! Define control status
|
||||
typedef enum
|
||||
{
|
||||
CTRL_GOOD =(PASS ) // It is ready
|
||||
, CTRL_FAIL =(FAIL ) // Memory fail
|
||||
, CTRL_NO_PRESENT =(FAIL+1) // Memory unplug
|
||||
, CTRL_BUSY =(FAIL+2) // Not initialize
|
||||
} Ctrl_status;
|
||||
|
||||
#endif // _CTRL_STATUS_H_
|
||||
/** @} */
|
787
cpu/avr/dev/usb/storage/scsi_decoder.c
Normal file
787
cpu/avr/dev/usb/storage/scsi_decoder.c
Normal file
|
@ -0,0 +1,787 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file scsi_decoder.c *******************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file is the scsi decoder
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
******************************************************************************/
|
||||
/*
|
||||
Copyright (c) 2004 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup usbstorage
|
||||
@{
|
||||
*/
|
||||
|
||||
//_____ I N C L U D E S ___________________________________________________
|
||||
|
||||
#include "config.h"
|
||||
#include "storage/scsi_decoder.h"
|
||||
#include "conf_usb.h"
|
||||
#include "usb_drv.h"
|
||||
#include "storage/ctrl_status.h"
|
||||
#include "storage/ctrl_access.h"
|
||||
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
||||
//_____ D E F I N I T I O N S ______________________________________________
|
||||
|
||||
|
||||
U8 g_scsi_command[16];
|
||||
U8 g_scsi_status;
|
||||
U32 g_scsi_data_remaining;
|
||||
|
||||
FLASH U8 g_sbc_vendor_id[8] = SBC_VENDOR_ID;
|
||||
FLASH U8 g_sbc_product_id[16] = SBC_PRODUCT_ID;
|
||||
FLASH U8 g_sbc_revision_id[4] = SBC_REVISION_ID;
|
||||
|
||||
extern U8 usb_LUN;
|
||||
|
||||
s_scsi_sense g_scsi_sense;
|
||||
|
||||
|
||||
FLASH struct sbc_st_std_inquiry_data sbc_std_inquiry_data =
|
||||
{
|
||||
/* Byte 0 : 0x00 */
|
||||
0x00, /* DeviceType: Direct-access device */
|
||||
0, /* PeripheralQualifier : Currently connected */
|
||||
|
||||
/* Byte 1 : 0x80 */
|
||||
0, /* Reserved1 */
|
||||
1, /* RMB : Medium is removable (this bit must be at 1, else the medium isn't see on Windows) */
|
||||
|
||||
// /* Byte 2 : 0x02 */
|
||||
// 0x02, /* Version: Device compliant to ANSI X3.131:1994 */
|
||||
|
||||
/* Byte 2 : 0x00 */
|
||||
0x00, /* Version: Device not compliant to any standard */
|
||||
|
||||
/* Byte 3 : 0x02 */
|
||||
2, /* Response data format */
|
||||
0, /* NormACA */
|
||||
0, /* Obsolete0 */
|
||||
0, /* AERC */
|
||||
|
||||
/* Byte 4 : 0x1F */
|
||||
/* Byte 5 : 0x00 */
|
||||
/* Byte 6 : 0x00 */
|
||||
/* Reserved4[3] */
|
||||
{
|
||||
0x1F, /* Additional Length (n-4) */
|
||||
0, /* SCCS : SCC supported */
|
||||
0
|
||||
},
|
||||
|
||||
/* Byte 7 : 0x00 */
|
||||
0, /* SoftReset */
|
||||
0, /* CommandQueue */
|
||||
0, /* Reserved5 */
|
||||
0, /* LinkedCommands */
|
||||
0, /* Synchronous */
|
||||
0, /* Wide16Bit */
|
||||
0, /* Wide32Bit */
|
||||
0, /* RelativeAddressing */
|
||||
};
|
||||
|
||||
|
||||
static void send_informational_exceptions_page (void);
|
||||
static void send_read_write_error_recovery_page (U8);
|
||||
static void sbc_header_mode_sense( Bool b_sense_10 , U8 u8_data_length );
|
||||
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
/**
|
||||
* @brief SCSI decoder function
|
||||
*
|
||||
* This function read the SCSI command and launches the appropriate function
|
||||
*
|
||||
* @warning Code:.. bytes (function FLASH length)
|
||||
*
|
||||
* @return FALSE: result KO,
|
||||
* TRUE: result OK
|
||||
*
|
||||
*/
|
||||
Bool scsi_decode_command(void)
|
||||
{
|
||||
Bool status;
|
||||
|
||||
if (g_scsi_command[0] == SBC_CMD_WRITE_10)
|
||||
{
|
||||
Scsi_start_write_action();
|
||||
status = sbc_write_10();
|
||||
Scsi_stop_write_action();
|
||||
return status;
|
||||
}
|
||||
if (g_scsi_command[0] == SBC_CMD_READ_10 )
|
||||
{
|
||||
Scsi_start_read_action();
|
||||
status = sbc_read_10();
|
||||
Scsi_stop_read_action();
|
||||
return status;
|
||||
}
|
||||
|
||||
switch (g_scsi_command[0]) /* check other command received */
|
||||
{
|
||||
case SBC_CMD_REQUEST_SENSE: /* 0x03 - Mandatory */
|
||||
return sbc_request_sense();
|
||||
break;
|
||||
|
||||
case SBC_CMD_INQUIRY: /* 0x12 - Mandatory */
|
||||
return sbc_inquiry();
|
||||
break;
|
||||
|
||||
case SBC_CMD_TEST_UNIT_READY: /* 0x00 - Mandatory */
|
||||
return sbc_test_unit_ready();
|
||||
break;
|
||||
|
||||
case SBC_CMD_READ_CAPACITY: /* 0x25 - Mandatory */
|
||||
return sbc_read_capacity();
|
||||
break;
|
||||
|
||||
case SBC_CMD_MODE_SENSE_6: /* 0x1A - Optional */
|
||||
return sbc_mode_sense( FALSE );
|
||||
break;
|
||||
|
||||
case SBC_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:/* 0x1E */
|
||||
return sbc_prevent_allow_medium_removal();
|
||||
break;
|
||||
|
||||
case SBC_CMD_VERIFY_10: /* 0x2F - Optional */
|
||||
sbc_lun_status_is_good();
|
||||
break;
|
||||
case SBC_CMD_MODE_SENSE_10: /* 0x5A - Optional */
|
||||
return sbc_mode_sense( TRUE );
|
||||
break;
|
||||
|
||||
case SBC_CMD_FORMAT_UNIT: /* 0x04 - Mandatory */
|
||||
|
||||
case SBC_CMD_MODE_SELECT_6: /* 0x15 - Optional */
|
||||
|
||||
|
||||
|
||||
|
||||
case SBC_CMD_START_STOP_UNIT: /* 0x1B - Optional */
|
||||
case SBC_CMD_SEND_DIAGNOSTIC: /* 0x1D - */
|
||||
case SBC_CMD_READ_LONG: /* 0x23 - Optional */
|
||||
case SBC_CMD_SYNCHRONIZE_CACHE: /* 0x35 - Optional */
|
||||
case SBC_CMD_WRITE_BUFFER: /* 0x3B - Optional */
|
||||
case SBC_CMD_RESERVE_10: /* 0x56 - Mandatory */
|
||||
case SBC_CMD_RELEASE_10: /* 0x57 - Mandatory - see chapter 7.16 - SPC 2 */
|
||||
default:
|
||||
{ /* Command not supported */
|
||||
Sbc_send_failed();
|
||||
Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_COMMAND_OPERATION_CODE, 0x00);
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function manages the SCSI REQUEST SENSE command (0x03)
|
||||
*
|
||||
* The SCSI Sense contains the status of the last command
|
||||
* This status is composed of 3 Bytes :
|
||||
* - sense key (g_scsi_sense.key)
|
||||
* - additional sense code (g_scsi_sense.asc)
|
||||
* - additional sense code qualifier (g_scsi_sense.ascq)
|
||||
*
|
||||
* @warning Code:.. bytes (function code length)
|
||||
*
|
||||
* @return FALSE: result KO,
|
||||
* TRUE: result OK
|
||||
*
|
||||
*/
|
||||
Bool sbc_request_sense (void)
|
||||
{
|
||||
U8 allocation_length, i;
|
||||
U8 request_sens_output[18]; /* the maximum size of request is 17 */
|
||||
|
||||
allocation_length = g_scsi_command[4]; /* Allocation length */
|
||||
|
||||
/* Initialize the request sense data */
|
||||
request_sens_output[0] = SBC_RESPONSE_CODE_SENSE; /* 70h */
|
||||
request_sens_output[1] = 0x00; /* Obsolete */
|
||||
request_sens_output[2] = g_scsi_sense.key;
|
||||
|
||||
request_sens_output[3] = 0x00; /* For direct access media, Information field */
|
||||
request_sens_output[4] = 0x00; /* give the unsigned logical block */
|
||||
request_sens_output[5] = 0x00; /* address associated with the sense key */
|
||||
request_sens_output[6] = 0x00;
|
||||
|
||||
request_sens_output[7] = SBC_ADDITIONAL_SENSE_LENGTH; /* !! UFI device shall not adjust the Additional sense length to reflect truncation */
|
||||
request_sens_output[8] = SBC_COMMAND_SPECIFIC_INFORMATION_3;
|
||||
request_sens_output[9] = SBC_COMMAND_SPECIFIC_INFORMATION_2;
|
||||
request_sens_output[10] = SBC_COMMAND_SPECIFIC_INFORMATION_1;
|
||||
request_sens_output[11] = SBC_COMMAND_SPECIFIC_INFORMATION_0;
|
||||
|
||||
request_sens_output[12] = g_scsi_sense.asc;
|
||||
request_sens_output[13] = g_scsi_sense.ascq;
|
||||
|
||||
request_sens_output[14] = SBC_FIELD_REPLACEABLE_UNIT_CODE;
|
||||
request_sens_output[15] = SBC_SENSE_KEY_SPECIFIC_2;
|
||||
request_sens_output[16] = SBC_SENSE_KEY_SPECIFIC_1;
|
||||
request_sens_output[17] = SBC_SENSE_KEY_SPECIFIC_0;
|
||||
|
||||
/* Send the request data */
|
||||
for( i=0 ; i<allocation_length ; i++ )
|
||||
{
|
||||
Usb_write_byte( request_sens_output[i] );
|
||||
}
|
||||
Sbc_valid_write_usb( allocation_length );
|
||||
|
||||
sbc_lun_status_is_good();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function manages the SCSI INQUIRY command (0x12)
|
||||
*
|
||||
* The SCSI Inquiry field contains information regarding parameters
|
||||
* of the target. For example:
|
||||
* - vendor identification
|
||||
* - product identification
|
||||
* - peripheral qualifier
|
||||
* - peripheral device type
|
||||
* - etc
|
||||
*
|
||||
* @warning Code:.. bytes (function code length)
|
||||
*
|
||||
* @return FALSE: result KO,
|
||||
* TRUE: result OK
|
||||
*
|
||||
*/
|
||||
Bool sbc_inquiry (void)
|
||||
{
|
||||
U8 allocation_length, i;
|
||||
|
||||
#ifdef AVRGCC
|
||||
PGM_VOID_P ptr;
|
||||
#else
|
||||
U8 FLASH *ptr;
|
||||
#endif
|
||||
|
||||
if( (0 == (g_scsi_command[1] & 0x03) ) // CMDT and EPVD bits are 0
|
||||
&& (0 == g_scsi_command[2] ) ) // PAGE or OPERATION CODE fields = 0x00?
|
||||
{
|
||||
//** send standard inquiry data
|
||||
|
||||
// Check the size of inquiry data
|
||||
allocation_length = g_scsi_command[4];
|
||||
if (allocation_length > SBC_MAX_INQUIRY_DATA)
|
||||
{
|
||||
allocation_length = SBC_MAX_INQUIRY_DATA;
|
||||
}
|
||||
|
||||
// send first inquiry data (0 to 8)
|
||||
ptr = (FLASH U8*) &sbc_std_inquiry_data;
|
||||
|
||||
for ( i=0 ; ((i != 36) && (allocation_length > i)); i++)
|
||||
{
|
||||
if( 8 == i )
|
||||
{ // send vendor id (8 to 16)
|
||||
ptr = (FLASH U8 *) &g_sbc_vendor_id;
|
||||
}
|
||||
if( 16 == i )
|
||||
{ // send product id (16 to 32)
|
||||
ptr = (FLASH U8 *) &g_sbc_product_id;
|
||||
}
|
||||
if( 32 == i )
|
||||
{ // send revision id (32 to 36)
|
||||
ptr = (FLASH U8 *) &g_sbc_revision_id;
|
||||
}
|
||||
#ifndef AVRGCC
|
||||
Usb_write_byte((U8)(*ptr++)); // send tab
|
||||
#else // AVRGCC does not support point to PGM space
|
||||
#warning with avrgcc assumes devices descriptors are stored in the lower 64Kbytes of on-chip flash memory
|
||||
Usb_write_byte(pgm_read_byte_near((unsigned int)ptr++));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
// send data (36 to SBC_MAX_INQUIRY_DATA), and can be tranmitted by Bulk
|
||||
// Description of next bytes (this bytes is always egal to 0) :
|
||||
// VendorSpecific : 20 Bytes
|
||||
// Next byte : 1 byte
|
||||
// - InfoUnitSupport : 1 bit
|
||||
// - QuickArbitSupport : 1 bit
|
||||
// - Clocking : 2 bits
|
||||
// - Reserved6 : 4 bits
|
||||
// Reserved7 : 1 byte
|
||||
// VersionDescriptor : 8 bytes
|
||||
// Reserved8 : 22 bytes
|
||||
// ...
|
||||
while( allocation_length > i )
|
||||
{
|
||||
if (64 == i)
|
||||
{ // for each 64 bytes, send USB packet
|
||||
Sbc_valid_write_usb(64);
|
||||
allocation_length -= 64;
|
||||
i = 0;
|
||||
}
|
||||
Usb_write_byte(0); // write value of last bytes of inquiry data
|
||||
i++;
|
||||
}
|
||||
// send last USB packet
|
||||
Sbc_valid_write_usb(allocation_length);
|
||||
sbc_lun_status_is_good();
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{ // (CMDT=EVPD <> 0) or (PAGE CODE <> 0x00)
|
||||
Sbc_send_failed();
|
||||
Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_FIELD_IN_CDB, 0x00);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Bool sbc_test_unit_ready(void)
|
||||
{
|
||||
switch ( mem_test_unit_ready(usb_LUN) )
|
||||
{
|
||||
case CTRL_GOOD :
|
||||
sbc_lun_status_is_good();
|
||||
break;
|
||||
|
||||
case CTRL_NO_PRESENT :
|
||||
sbc_lun_status_is_not_present();
|
||||
break;
|
||||
|
||||
case CTRL_BUSY :
|
||||
sbc_lun_status_is_busy_or_change();
|
||||
break;
|
||||
|
||||
case CTRL_FAIL :
|
||||
default :
|
||||
sbc_lun_status_is_fail();
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
Bool sbc_read_capacity (void)
|
||||
{
|
||||
_MEM_TYPE_SLOW_ U32 mem_size_nb_sector;
|
||||
|
||||
switch ( mem_read_capacity( usb_LUN, &mem_size_nb_sector ) )
|
||||
{
|
||||
case CTRL_GOOD :
|
||||
Usb_write_byte(MSB0(mem_size_nb_sector)); // return nb block
|
||||
Usb_write_byte(MSB1(mem_size_nb_sector));
|
||||
Usb_write_byte(MSB2(mem_size_nb_sector));
|
||||
Usb_write_byte(MSB3(mem_size_nb_sector));
|
||||
Usb_write_byte( 0 ); // return block size (= 512B)
|
||||
Usb_write_byte( 0 );
|
||||
Usb_write_byte( (U8)(512 >> 8) );
|
||||
Usb_write_byte( (U8)(512 & 0xFF));
|
||||
|
||||
Sbc_valid_write_usb(SBC_READ_CAPACITY_LENGTH);
|
||||
sbc_lun_status_is_good();
|
||||
return TRUE;
|
||||
break;
|
||||
|
||||
case CTRL_NO_PRESENT :
|
||||
sbc_lun_status_is_not_present();
|
||||
break;
|
||||
|
||||
case CTRL_BUSY :
|
||||
sbc_lun_status_is_busy_or_change();
|
||||
break;
|
||||
|
||||
case CTRL_FAIL :
|
||||
default :
|
||||
sbc_lun_status_is_fail();
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
Bool sbc_read_10 (void)
|
||||
{
|
||||
U32 mass_addr; // rd or wr block address
|
||||
U16 mass_size; // rd or write nb of blocks
|
||||
|
||||
MSB0(mass_addr) = g_scsi_command[2]; // read address
|
||||
MSB1(mass_addr) = g_scsi_command[3];
|
||||
MSB2(mass_addr) = g_scsi_command[4];
|
||||
MSB3(mass_addr) = g_scsi_command[5];
|
||||
|
||||
MSB(mass_size) = g_scsi_command[7]; // read size
|
||||
LSB(mass_size) = g_scsi_command[8];
|
||||
|
||||
if (mass_size != 0)
|
||||
{
|
||||
switch ( memory_2_usb( usb_LUN , mass_addr, mass_size ) )
|
||||
{
|
||||
case CTRL_GOOD :
|
||||
sbc_lun_status_is_good();
|
||||
g_scsi_data_remaining = g_scsi_data_remaining - (512 * (Uint32)mass_size);
|
||||
return TRUE;
|
||||
break;
|
||||
|
||||
case CTRL_NO_PRESENT :
|
||||
sbc_lun_status_is_not_present();
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case CTRL_BUSY :
|
||||
sbc_lun_status_is_busy_or_change();
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case CTRL_FAIL :
|
||||
default :
|
||||
sbc_lun_status_is_fail();
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // No data to transfer
|
||||
sbc_lun_status_is_good();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
Bool sbc_write_10 (void)
|
||||
{
|
||||
U32 mass_addr; // rd or wr block address
|
||||
U16 mass_size; // rd or write nb of blocks
|
||||
|
||||
MSB0(mass_addr) = g_scsi_command[2]; // read address
|
||||
MSB1(mass_addr) = g_scsi_command[3];
|
||||
MSB2(mass_addr) = g_scsi_command[4];
|
||||
MSB3(mass_addr) = g_scsi_command[5];
|
||||
|
||||
MSB(mass_size) = g_scsi_command[7]; // read size
|
||||
LSB(mass_size) = g_scsi_command[8];
|
||||
|
||||
if (mass_size != 0)
|
||||
{
|
||||
if( TRUE == mem_wr_protect( usb_LUN ) )
|
||||
{
|
||||
sbc_lun_status_is_protected();
|
||||
return FALSE;
|
||||
#warning For Win98 data must be read to avoid blocking
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (usb_2_memory( usb_LUN , mass_addr, mass_size ))
|
||||
{
|
||||
case CTRL_GOOD :
|
||||
sbc_lun_status_is_good();
|
||||
g_scsi_data_remaining = g_scsi_data_remaining - (512 * (Uint32)mass_size);
|
||||
return TRUE;
|
||||
break;
|
||||
|
||||
case CTRL_NO_PRESENT :
|
||||
sbc_lun_status_is_not_present();
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case CTRL_BUSY :
|
||||
sbc_lun_status_is_busy_or_change();
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case CTRL_FAIL :
|
||||
default :
|
||||
sbc_lun_status_is_fail();
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // No data to transfer
|
||||
sbc_lun_status_is_good();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function manages the SCSI MODE SENSE command (0x1A for sense 6 and 0x5A for sense 10)
|
||||
*
|
||||
* The SCSI mode sense function returns parameters to an application client.
|
||||
* It is a complementary command to the SCSI MODE SELECT command.
|
||||
*
|
||||
* @warning Code:.. bytes (function code length)
|
||||
*
|
||||
* @param b_sense_10 ( TRUE = sense 10, TRUE = sense 6)
|
||||
*
|
||||
* @return FALSE: result KO,
|
||||
* TRUE: result OK
|
||||
*
|
||||
*/
|
||||
Bool sbc_mode_sense( Bool b_sense_10 )
|
||||
{
|
||||
U8 allocation_length;
|
||||
|
||||
if( b_sense_10 )
|
||||
allocation_length = g_scsi_command[8];
|
||||
else
|
||||
allocation_length = g_scsi_command[4];
|
||||
|
||||
// switch for page code
|
||||
switch ( g_scsi_command[2] & SBC_MSK_PAGE_CODE )
|
||||
{
|
||||
case SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS: /* Page Code: Informational exceptions control page */
|
||||
sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS );
|
||||
send_informational_exceptions_page();
|
||||
Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS + 1);
|
||||
break;
|
||||
|
||||
case SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY:
|
||||
sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY );
|
||||
send_read_write_error_recovery_page(allocation_length);
|
||||
Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY + 1);
|
||||
break;
|
||||
|
||||
case SBC_PAGE_CODE_ALL:
|
||||
sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_CODE_ALL );
|
||||
if( b_sense_10 )
|
||||
{
|
||||
if (allocation_length == 8)
|
||||
{
|
||||
Sbc_valid_write_usb(8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (allocation_length == 4)
|
||||
{
|
||||
Sbc_valid_write_usb(4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// send page by ascending order code
|
||||
send_read_write_error_recovery_page(allocation_length); // 12 bytes
|
||||
if (allocation_length > 12)
|
||||
{
|
||||
send_informational_exceptions_page(); // 12 bytes
|
||||
Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_CODE_ALL + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Sbc_valid_write_usb(allocation_length);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Sbc_send_failed();
|
||||
Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_FIELD_IN_CDB, 0x00);
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
sbc_lun_status_is_good();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function send the header of the SCSI MODE SENSE command
|
||||
*
|
||||
* @param b_sense_10 TRUE = sense 10, FALSE = sense 6
|
||||
* @param u8_data_length data length in byte
|
||||
*
|
||||
*/
|
||||
void sbc_header_mode_sense( Bool b_sense_10 , U8 u8_data_length )
|
||||
{
|
||||
// Send Data length
|
||||
if( b_sense_10 )
|
||||
{
|
||||
Usb_write_byte(0);
|
||||
}
|
||||
Usb_write_byte( u8_data_length );
|
||||
|
||||
// Send device type
|
||||
Usb_write_byte(SBC_MEDIUM_TYPE);
|
||||
|
||||
// Write protect status
|
||||
if (mem_wr_protect( usb_LUN ))
|
||||
{
|
||||
Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_PROTECT); // Device is write protected
|
||||
}
|
||||
else
|
||||
{
|
||||
Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_ENABLE); // Device is write enabled
|
||||
}
|
||||
|
||||
if( b_sense_10 )
|
||||
{ // Reserved
|
||||
Usb_write_byte(0);
|
||||
Usb_write_byte(0);
|
||||
}
|
||||
|
||||
// Send Block descriptor length
|
||||
if( b_sense_10 )
|
||||
{
|
||||
Usb_write_byte(0);
|
||||
}
|
||||
Usb_write_byte(SBC_BLOCK_DESCRIPTOR_LENGTH);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function writes informational exceptions page parameters
|
||||
*
|
||||
* @warning Code:.. bytes (function code length)
|
||||
*
|
||||
* @return FALSE: result KO,
|
||||
* TRUE: result OK
|
||||
*
|
||||
*/
|
||||
void send_informational_exceptions_page (void)
|
||||
{
|
||||
Usb_write_byte(SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS); /* Page Code: Informational exceptions control page */
|
||||
/* See chapter 8.3.8 on SPC-2 specification */
|
||||
Usb_write_byte(SBC_PAGE_LENGTH_INFORMATIONAL_EXCEPTIONS); /* Page Length */
|
||||
Usb_write_byte(0x00); /* ..., Test bit = 0, ... */
|
||||
Usb_write_byte(SBC_MRIE); /* MRIE = 0x05 */
|
||||
Usb_write_byte(0x00); /* Interval Timer (MSB) */
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00); /* Interval Timer (LSB) */
|
||||
Usb_write_byte(0x00); /* Report Count (MSB) */
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x01); /* Report Count (LSB) */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function writes error recovery page
|
||||
*
|
||||
* @warning Code:.. bytes (function code length)
|
||||
*
|
||||
* @param length The length of
|
||||
*
|
||||
* @return FALSE: result KO,
|
||||
* TRUE: result OK
|
||||
*
|
||||
*/
|
||||
void send_read_write_error_recovery_page (U8 length)
|
||||
{
|
||||
Usb_write_byte(SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY);
|
||||
|
||||
Usb_write_byte(SBC_PAGE_LENGTH_READ_WRITE_ERROR_RECOVERY); /* Page Length */
|
||||
Usb_write_byte(0x80);
|
||||
Usb_write_byte(SBC_READ_RETRY_COUNT);
|
||||
Usb_write_byte(SBC_CORRECTION_SPAN);
|
||||
Usb_write_byte(SBC_HEAD_OFFSET_COUNT);
|
||||
Usb_write_byte(SBC_DATA_STROBE_OFFSET);
|
||||
Usb_write_byte(0x00); /* Reserved */
|
||||
|
||||
if (length > 12)
|
||||
{
|
||||
Usb_write_byte(SBC_WRITE_RETRY_COUNT);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(SBC_RECOVERY_LIMIT_MSB);
|
||||
Usb_write_byte(SBC_RECOVERY_LIMIT_LSB);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function manages the SCSI PREVENT ALLOW MEDIUM REMOVAL
|
||||
* command (0x1E)
|
||||
*
|
||||
* The SCSI prevent allow medium removal command requests that the target
|
||||
* enable or disable the removal of the medium in the logical unit.
|
||||
*
|
||||
* @warning Code:.. bytes (function code length)
|
||||
*
|
||||
* @return FALSE: result KO,
|
||||
* TRUE: result OK
|
||||
*
|
||||
*/
|
||||
Bool sbc_prevent_allow_medium_removal(void)
|
||||
{
|
||||
sbc_lun_status_is_good();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//! This fonction send the UFI status GOOD
|
||||
//!
|
||||
void sbc_lun_status_is_good(void)
|
||||
{
|
||||
Sbc_send_good();
|
||||
Sbc_build_sense(SBC_SENSE_KEY_NO_SENSE, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
|
||||
}
|
||||
|
||||
//! This fonction send the UFI status "lun not present"
|
||||
//!
|
||||
void sbc_lun_status_is_not_present(void)
|
||||
{
|
||||
Sbc_send_failed();
|
||||
Sbc_build_sense(SBC_SENSE_KEY_NOT_READY, SBC_ASC_MEDIUM_NOT_PRESENT, 0x00);
|
||||
}
|
||||
|
||||
//! This fonction send the UFI status busy and change
|
||||
//!
|
||||
void sbc_lun_status_is_busy_or_change(void)
|
||||
{
|
||||
Sbc_send_failed();
|
||||
Sbc_build_sense(SBC_SENSE_KEY_UNIT_ATTENTION, SBC_ASC_NOT_READY_TO_READY_CHANGE, 0x00 );
|
||||
}
|
||||
|
||||
//! This fonction send the UFI status FAIL
|
||||
//!
|
||||
void sbc_lun_status_is_fail(void)
|
||||
{
|
||||
Sbc_send_failed();
|
||||
Sbc_build_sense(SBC_SENSE_KEY_HARDWARE_ERROR, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
|
||||
}
|
||||
|
||||
//! This fonction send the UFI status FAIL because write protection
|
||||
//!
|
||||
void sbc_lun_status_is_protected(void)
|
||||
{
|
||||
Sbc_send_failed();
|
||||
Sbc_build_sense(SBC_SENSE_KEY_DATA_PROTECT, SBC_ASC_WRITE_PROTECTED, 0x00);
|
||||
}
|
||||
|
||||
/** @} */
|
338
cpu/avr/dev/usb/storage/scsi_decoder.h
Normal file
338
cpu/avr/dev/usb/storage/scsi_decoder.h
Normal file
|
@ -0,0 +1,338 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file scsi_decoder.h *******************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file is the scsi decoder
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
******************************************************************************/
|
||||
/*
|
||||
Copyright (c) 2004 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup usbstorage
|
||||
@{
|
||||
*/
|
||||
#ifndef _SCSI_DECODER_H_
|
||||
#define _SCSI_DECODER_H_
|
||||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U8 key;
|
||||
U8 asc;
|
||||
U8 ascq;
|
||||
} s_scsi_sense;
|
||||
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
|
||||
Bool scsi_decode_command (void);
|
||||
|
||||
/****************************************************************************/
|
||||
/* Command for all SCSI device types */
|
||||
/****************************************************************************/
|
||||
|
||||
#define SBC_CMD_TEST_UNIT_READY (0x00)
|
||||
#define SBC_CMD_REQUEST_SENSE (0x03)
|
||||
#define SBC_CMD_FORMAT_UNIT (0x04)
|
||||
#define SBC_CMD_READ_6 (0x08)
|
||||
#define SBC_CMD_INQUIRY (0x12)
|
||||
#define SBC_CMD_MODE_SELECT_6 (0x15)
|
||||
#define SBC_CMD_MODE_SENSE_6 (0x1A)
|
||||
#define SBC_CMD_START_STOP_UNIT (0x1B)
|
||||
#define SBC_CMD_RECEIVE_DIAGNOSTICS (0x1C)
|
||||
#define SBC_CMD_SEND_DIAGNOSTIC (0x1D)
|
||||
#define SBC_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL (0x1E)
|
||||
#define SBC_CMD_READ_LONG (0x23)
|
||||
#define SBC_CMD_READ_CAPACITY (0x25)
|
||||
#define SBC_CMD_READ_CD_ROM_CAPACITY (0x25)
|
||||
#define SBC_CMD_READ_10 (0x28)
|
||||
#define SBC_CMD_WRITE_10 (0x2A)
|
||||
#define SBC_CMD_VERIFY_10 (0x2F)
|
||||
#define SBC_CMD_SYNCHRONIZE_CACHE (0x35)
|
||||
#define SBC_CMD_WRITE_BUFFER (0x3B)
|
||||
#define SBC_CMD_CHANGE_DEFINITION (0x40)
|
||||
#define SBC_CMD_READ_TOC (0x43)
|
||||
#define SBC_CMD_MODE_SELECT_10 (0x55)
|
||||
#define SBC_CMD_RESERVE_10 (0x56)
|
||||
#define SBC_CMD_RELEASE_10 (0x57)
|
||||
#define SBC_CMD_MODE_SENSE_10 (0x5A)
|
||||
|
||||
#define SBC_CONTROL_BYTE (0x00)
|
||||
#define SBC_CMD_DIR_IN (0x80)
|
||||
#define SBC_CMD_DIR_OUT (0x00)
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* Sense Key Code */
|
||||
/****************************************************************************/
|
||||
#define SBC_SENSE_KEY_NO_SENSE (0x00)
|
||||
#define SBC_SENSE_KEY_RECOVERED_ERROR (0x01)
|
||||
#define SBC_SENSE_KEY_NOT_READY (0x02)
|
||||
#define SBC_SENSE_KEY_MEDIUM_ERROR (0x03)
|
||||
#define SBC_SENSE_KEY_HARDWARE_ERROR (0x04)
|
||||
#define SBC_SENSE_KEY_ILLEGAL_REQUEST (0x05)
|
||||
#define SBC_SENSE_KEY_UNIT_ATTENTION (0x06)
|
||||
#define SBC_SENSE_KEY_DATA_PROTECT (0x07)
|
||||
#define SBC_SENSE_KEY_BLANK_CHECK (0x08)
|
||||
#define SBC_SENSE_KEY_VENDOR_SPECIFIC (0x09)
|
||||
#define SBC_SENSE_KEY_COPY_ABORTED (0x0A)
|
||||
#define SBC_SENSE_KEY_ABORTED_COMMAND (0x0B)
|
||||
#define SBC_SENSE_KEY_VOLUME_OVERFLOW (0x0D)
|
||||
#define SBC_SENSE_KEY_MISCOMPARE (0x0E)
|
||||
|
||||
/****************************************************************************/
|
||||
/* ASC code assignments */
|
||||
/****************************************************************************/
|
||||
#define SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION (0x00)
|
||||
#define SBC_ASC_LOGICAL_UNIT_NOT_READY (0x04)
|
||||
#define SBC_ASC_INVALID_FIELD_IN_CDB (0x24)
|
||||
#define SBC_ASC_WRITE_PROTECTED (0x27)
|
||||
#define SBC_ASC_FORMAT_ERROR (0x31)
|
||||
#define SBC_ASC_INVALID_COMMAND_OPERATION_CODE (0x20)
|
||||
#define SBC_ASC_NOT_READY_TO_READY_CHANGE (0x28)
|
||||
#define SBC_ASC_MEDIUM_NOT_PRESENT (0x3A)
|
||||
|
||||
/****************************************************************************/
|
||||
/* ASCQ code assignments */
|
||||
/****************************************************************************/
|
||||
#define SBC_ASCQ_FORMAT_COMMAND_FAILED (0x01)
|
||||
#define SBC_ASCQ_INITIALIZING_COMMAND_REQUIRED (0x02)
|
||||
#define SBC_ASCQ_OPERATION_IN_PROGRESS (0x07)
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* REQUEST SENSE PARAMETERS */
|
||||
/****************************************************************************/
|
||||
#define SBC_RESPONSE_CODE_SENSE (0x70)
|
||||
#define SBC_ADDITIONAL_SENSE_LENGTH (0x0A)
|
||||
#define SBC_COMMAND_SPECIFIC_INFORMATION_3 (0x00)
|
||||
#define SBC_COMMAND_SPECIFIC_INFORMATION_2 (0x00)
|
||||
#define SBC_COMMAND_SPECIFIC_INFORMATION_1 (0x00)
|
||||
#define SBC_COMMAND_SPECIFIC_INFORMATION_0 (0x00)
|
||||
#define SBC_FIELD_REPLACEABLE_UNIT_CODE (0x00)
|
||||
#define SBC_SENSE_KEY_SPECIFIC_2 (0x00)
|
||||
#define SBC_SENSE_KEY_SPECIFIC_1 (0x00)
|
||||
#define SBC_SENSE_KEY_SPECIFIC_0 (0x00)
|
||||
|
||||
/******* number of bytes of READ CAPACITY response *********/
|
||||
#define SBC_READ_CAPACITY_LENGTH (0x08)
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/*MODE SENSE and REQUEST SENSE DEFINITIONS */
|
||||
/****************************************************************************/
|
||||
|
||||
/*************** Direct access medium type ****************/
|
||||
#define SBC_DEFAULT_MEDIUM_TYPE (0x00)
|
||||
#define SBC_FLEXIBLE_DISK_SINGLE_SIDED_UNSPECIFIED (0x01)
|
||||
#define SBC_FLEXIBLE_DISK_DOUBLE_SIDED_UNSPECIFIED (0x02)
|
||||
|
||||
#define SBC_MEDIUM_TYPE SBC_DEFAULT_MEDIUM_TYPE
|
||||
|
||||
#define SBC_DEV_SPEC_PARAM_WR_ENABLE (0x00)
|
||||
#define SBC_DEV_SPEC_PARAM_WR_PROTECT (0x80)
|
||||
#define SBC_BLOCK_DESCRIPTOR_LENGTH (0x00)
|
||||
|
||||
#define SBC_MSK_DBD (0x08)
|
||||
#define SBC_MSK_PAGE_CONTROL (0xC0)
|
||||
#define SBC_MSK_PAGE_CODE (0x3F)
|
||||
|
||||
|
||||
/************ General Page Code paramaters *****************/
|
||||
#define SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY (0x01)
|
||||
#define SBC_PAGE_CODE_FORMAT_DEVICE (0x03)
|
||||
#define SBC_PAGE_CODE_FLEXIBLE_DISK (0x05)
|
||||
#define SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS (0x1C)
|
||||
#define SBC_PAGE_CODE_ALL (0x3F)
|
||||
|
||||
|
||||
#define SBC_PAGE_LENGTH_INFORMATIONAL_EXCEPTIONS (0x0A)
|
||||
#define SBC_PAGE_LENGTH_READ_WRITE_ERROR_RECOVERY (0x0A)
|
||||
#define SBC_PAGE_LENGTH_FLEXIBLE_DISK (0x1E)
|
||||
#define SBC_PAGE_LENGTH_FORMAT_DEVICE (0x16)
|
||||
|
||||
|
||||
|
||||
#define SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS (SBC_PAGE_LENGTH_INFORMATIONAL_EXCEPTIONS + 2 + 3)
|
||||
#define SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY (SBC_PAGE_LENGTH_READ_WRITE_ERROR_RECOVERY + 2 + 3 )
|
||||
#define SBC_MODE_DATA_LENGTH_FLEXIBLE_DISK (SBC_PAGE_LENGTH_FLEXIBLE_DISK + 2 + 3 )
|
||||
#define SBC_MODE_DATA_LENGTH_FORMAT_DEVICE (SBC_PAGE_LENGTH_FORMAT_DEVICE + 2 + 3 )
|
||||
/*SBC_PAGE_LENGTH_FLEXIBLE_DISK + 2 + \*/
|
||||
#define SBC_MODE_DATA_LENGTH_CODE_ALL (SBC_PAGE_LENGTH_READ_WRITE_ERROR_RECOVERY + 2 + \
|
||||
SBC_PAGE_LENGTH_INFORMATIONAL_EXCEPTIONS + 2 + \
|
||||
SBC_BLOCK_DESCRIPTOR_LENGTH + \
|
||||
+ 3 )
|
||||
|
||||
/* SBC_MODE_DATA_LENGTH_FORMAT_DEVICE + 2 + \*/
|
||||
/****** Information exceptions control page parameters *****/
|
||||
#define SBC_MRIE (0x05)
|
||||
|
||||
/*************** Format device page parameters *************/
|
||||
#define SBC_TRACK_PER_ZONE_MSB (0x00)
|
||||
#define SBC_TRACK_PER_ZONE_LSB (0x00)
|
||||
#define SBC_ALTERNATE_SECTORS_PER_ZONE_MSB (0x00)
|
||||
#define SBC_ALTERNATE_SECTORS_PER_ZONE_LSB (0x00)
|
||||
#define SBC_ALTERNATE_TRACK_PER_ZONE_MSB (0x00)
|
||||
#define SBC_ALTERNATE_TRACK_PER_ZONE_LSB (0x00)
|
||||
#define SBC_ALTERNATE_TRACK_PER_LU_MSB (0x00)
|
||||
#define SBC_ALTERNATE_TRACK_PER_LU_LSB (0x00)
|
||||
|
||||
/************* Flexible Disk page Parameters ***************/
|
||||
#define SBC_TRANSFER_RATE_MSB (0x13)
|
||||
#define SBC_TRANSFER_RATE_LSB (0x88)
|
||||
/* 1388h 5 Mbit/s */
|
||||
/* 07D0h 2 Mbit/s */
|
||||
/* 03E8h 1 Mbit/s */
|
||||
/* 01F4h 500 kbit/s */
|
||||
/* 012Ch 300 kbit/s */
|
||||
/* 00FAh 250 kbit/s */
|
||||
|
||||
#define SBC_NUMBER_OF_HEAD (0x04)
|
||||
#define SBC_SECTOR_PER_TRACK (0x20)
|
||||
#define SBC_DATA_BYTE_PER_SECTOR_MSB (0x02)
|
||||
#define SBC_DATA_BYTE_PER_SECTOR_LSB (0x00)
|
||||
#define SBC_NUMBER_OF_CYLINDERS_MSB (0x01)
|
||||
#define SBC_NUMBER_OF_CYLINDERS_LSB (0xE9)
|
||||
#define SBC_STARTING_CYLINDER_WRITE_COMPENSATION_MSB (0x00)
|
||||
#define SBC_STARTING_CYLINDER_WRITE_COMPENSATION_LSB (0x00)
|
||||
#define SBC_STARTING_CYLINDER_REDUCED_WRITE_MSB (0x00)
|
||||
#define SBC_STARTING_CYLINDER_REDUCED_WRITE_LSB (0x00)
|
||||
#define SBC_DEVICE_STEP_RATE_MSB (0x00)
|
||||
#define SBC_DEVICE_STEP_RATE_LSB (0x00)
|
||||
#define SBC_DEVICE_STEP_PULSE_WIDTH (0x00)
|
||||
#define SBC_HEAD_SETTLE_DELAY_MSB (0x00)
|
||||
#define SBC_HEAD_SETTLE_DELAY_LSB (0x00)
|
||||
#define SBC_MOTOR_ON_DELAY (0x00)
|
||||
#define SBC_MOTOR_OFF_DELAY (0x00)
|
||||
#define SBC_STEP_PULSE_PER_CYLINDER (0x00)
|
||||
#define SBC_WRITE_COMPENSATION (0x00)
|
||||
#define SBC_HEAD_LOAD_DELAY (0x00)
|
||||
#define SBC_HEAD_UNLOAD_DELAY (0x00)
|
||||
#define SBC_PIN34_PIN2 (0x00)
|
||||
#define SBC_PIN4_PIN1 (0x00)
|
||||
#define SBC_MEDIUM_ROTATION_RATE_MSB (0x00)
|
||||
#define SBC_MEDIUM_ROTATION_RATE_LSB (0x00)
|
||||
|
||||
/************ Read/Write Error Recovery parameters**********/
|
||||
#define SBC_READ_RETRY_COUNT (0x03)
|
||||
#define SBC_WRITE_RETRY_COUNT (0x80)
|
||||
#define SBC_CORRECTION_SPAN (0x00)
|
||||
#define SBC_HEAD_OFFSET_COUNT (0x00)
|
||||
#define SBC_DATA_STROBE_OFFSET (0x00)
|
||||
#define SBC_RECOVERY_LIMIT_MSB (0x00)
|
||||
#define SBC_RECOVERY_LIMIT_LSB (0x00)
|
||||
|
||||
|
||||
/*_____ D E F I N I T I O N ________________________________________________*/
|
||||
|
||||
#define SBC_MAX_INQUIRY_DATA (0x60) // value ?
|
||||
|
||||
struct sbc_st_std_inquiry_data
|
||||
{
|
||||
Byte DeviceType : 5;
|
||||
Byte PeripheralQualifier : 3;
|
||||
|
||||
Byte Reserved1 : 7;
|
||||
Byte RemovableMedia : 1;
|
||||
|
||||
Byte Version;
|
||||
|
||||
Byte Reserved3 : 5;
|
||||
Byte NormACA : 1;
|
||||
Byte Obsolete0 : 1;
|
||||
Byte AERC : 1;
|
||||
|
||||
Byte Reserved4[3];
|
||||
|
||||
Byte SoftReset : 1;
|
||||
Byte CommandQueue : 1;
|
||||
Byte Reserved5 : 1;
|
||||
Byte LinkedCommands : 1;
|
||||
Byte Synchronous : 1;
|
||||
Byte Wide16Bit : 1;
|
||||
Byte Wide32Bit : 1;
|
||||
Byte RelativeAddressing : 1;
|
||||
};
|
||||
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
|
||||
#define Sbc_send_failed() (g_scsi_status = COMMAND_FAILED)
|
||||
#define Sbc_send_check_condition() (g_scsi_status = CHECK_CONDITION)
|
||||
#define Sbc_send_good() (g_scsi_status = COMMAND_PASSED)
|
||||
|
||||
/*#define Sbc_valid_write_usb(length) ( Usb_set_TXRDY(), \
|
||||
dCBWDataTransferLength -= length, \
|
||||
while (!Usb_tx_complete()),\
|
||||
Usb_clear_TXCMPL() )
|
||||
*/
|
||||
#define Sbc_build_sense(skey, sasc, sascq) ( g_scsi_sense.key = skey, \
|
||||
g_scsi_sense.asc = sasc, \
|
||||
g_scsi_sense.ascq = sascq )
|
||||
|
||||
#define Sbc_valid_write_usb(length) ( Usb_send_in(), \
|
||||
g_scsi_data_remaining -= length )
|
||||
|
||||
|
||||
#define COMMAND_PASSED 0x00
|
||||
#define COMMAND_FAILED 0x01
|
||||
#define CHECK_CONDITION 0x02
|
||||
#define PHASE_ERROR 0x02
|
||||
|
||||
|
||||
Bool sbc_inquiry (void);
|
||||
Bool sbc_mode_sense( Bool sense_10 );
|
||||
Bool sbc_mode_select_6 (void);
|
||||
Bool sbc_request_sense (void);
|
||||
Bool sbc_format (void);
|
||||
Bool sbc_write_10 (void);
|
||||
Bool sbc_read_10 (void);
|
||||
Bool sbc_test_unit_ready(void);
|
||||
Bool sbc_read_capacity(void);
|
||||
Bool sbc_prevent_allow_medium_removal(void);
|
||||
|
||||
void sbc_lun_status_is_good(void);
|
||||
void sbc_lun_status_is_busy_or_change(void);
|
||||
void sbc_lun_status_is_not_present(void);
|
||||
void sbc_lun_status_is_fail(void);
|
||||
void sbc_lun_status_is_protected(void);
|
||||
|
||||
#endif /* _SCSI_DECODER_H_ */
|
||||
/** @} */
|
276
cpu/avr/dev/usb/storage/storage_task.c
Normal file
276
cpu/avr/dev/usb/storage/storage_task.c
Normal file
|
@ -0,0 +1,276 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file usb_task.c *********************************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file manages the USB storage.
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
******************************************************************************/
|
||||
/*
|
||||
Copyright (c) 2004 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup usbstorage
|
||||
@{
|
||||
*/
|
||||
|
||||
//_____ I N C L U D E S ___________________________________________________
|
||||
|
||||
|
||||
|
||||
#include "contiki.h"
|
||||
#include "usb_drv.h"
|
||||
#include "storage/storage_task.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "usb_standard_request.h"
|
||||
#include "usb_specific_request.h"
|
||||
#include "storage/scsi_decoder.h"
|
||||
#include "storage/ctrl_access.h"
|
||||
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//_____ D E F I N I T I O N S ______________________________________________
|
||||
|
||||
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
|
||||
|
||||
|
||||
extern U8 usb_configuration_nb;
|
||||
|
||||
|
||||
static bit ms_data_direction;
|
||||
static U8 dCBWTag[4];
|
||||
|
||||
extern U8 g_scsi_status;
|
||||
extern U32 g_scsi_data_remaining;
|
||||
extern bit ms_multiple_drive;
|
||||
extern U8 g_scsi_command[16];
|
||||
|
||||
|
||||
U8 usb_LUN;
|
||||
|
||||
|
||||
void usb_mass_storage_cbw (void);
|
||||
void usb_mass_storage_csw (void);
|
||||
|
||||
#define Usb_set_ms_data_direction_in() (ms_data_direction = 1)
|
||||
#define Usb_set_ms_data_direction_out() (ms_data_direction = 0)
|
||||
#define Is_usb_ms_data_direction_in() (ms_data_direction == 1)
|
||||
|
||||
static struct etimer et;
|
||||
|
||||
PROCESS(storage_process, "Storage process");
|
||||
|
||||
/**
|
||||
* \brief USB Mass Storage Class Process
|
||||
*
|
||||
* This is the link between USB and the "good stuff". In this routine data
|
||||
* is received and processed by USB Storage Class
|
||||
*/
|
||||
PROCESS_THREAD(storage_process, ev, data_proc)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
|
||||
while(1) {
|
||||
|
||||
|
||||
if (usb_mode == mass_storage) {
|
||||
|
||||
if (Is_device_enumerated()) {
|
||||
Usb_select_endpoint(MS_OUT_EP);
|
||||
|
||||
if (Is_usb_receive_out()) {
|
||||
usb_mass_storage_cbw();
|
||||
usb_mass_storage_csw();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (usb_mode == mass_storage) {
|
||||
etimer_set(&et, CLOCK_SECOND/250 + 1);
|
||||
} else {
|
||||
etimer_set(&et, CLOCK_SECOND);
|
||||
}
|
||||
|
||||
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
|
||||
|
||||
} //while(1)
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//! @brief USB Command Block Wrapper (CBW) management
|
||||
//!
|
||||
//! This function decodes the CBW command and stores the SCSI command
|
||||
//!
|
||||
//! @warning Code:?? bytes (function code length)
|
||||
//!
|
||||
void usb_mass_storage_cbw (void)
|
||||
{
|
||||
bit cbw_error;
|
||||
uint8_t c;
|
||||
uint8_t dummy;
|
||||
|
||||
cbw_error = FALSE;
|
||||
Usb_select_endpoint(MS_OUT_EP); //! check if dCBWSignature is correct
|
||||
if (0x55 != Usb_read_byte())
|
||||
{ cbw_error = TRUE; } //! 'U'
|
||||
if (0x53 != Usb_read_byte())
|
||||
{ cbw_error = TRUE; } //! 'S'
|
||||
if (0x42 != Usb_read_byte())
|
||||
{ cbw_error = TRUE; } //! 'B'
|
||||
if (0x43 != Usb_read_byte())
|
||||
{ cbw_error = TRUE; } //! 'C'
|
||||
|
||||
dCBWTag[0] = Usb_read_byte(); //! Store CBW Tag to be repeated in CSW
|
||||
dCBWTag[1] = Usb_read_byte();
|
||||
dCBWTag[2] = Usb_read_byte();
|
||||
dCBWTag[3] = Usb_read_byte();
|
||||
|
||||
LSB0(g_scsi_data_remaining) = Usb_read_byte();
|
||||
LSB1(g_scsi_data_remaining) = Usb_read_byte();
|
||||
LSB2(g_scsi_data_remaining) = Usb_read_byte();
|
||||
LSB3(g_scsi_data_remaining) = Usb_read_byte();
|
||||
|
||||
|
||||
if (Usb_read_byte() != 0x00) //! if (bmCBWFlags.bit7 == 1) {direction = IN}
|
||||
{
|
||||
Usb_set_ms_data_direction_in();
|
||||
if (cbw_error)
|
||||
{
|
||||
Usb_ack_receive_out();
|
||||
Usb_select_endpoint(MS_IN_EP);
|
||||
Usb_enable_stall_handshake();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Usb_set_ms_data_direction_out();
|
||||
if (cbw_error)
|
||||
{
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_out();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
usb_LUN = Usb_read_byte();
|
||||
|
||||
if (!ms_multiple_drive)
|
||||
{
|
||||
usb_LUN = get_cur_lun();
|
||||
}
|
||||
|
||||
dummy = Usb_read_byte(); //! dummy CBWCBLength read
|
||||
|
||||
|
||||
for (c=0; c<16; c++) // store scsi_command
|
||||
{
|
||||
g_scsi_command[c] = Usb_read_byte();
|
||||
}
|
||||
|
||||
Usb_ack_receive_out();
|
||||
|
||||
if (Is_usb_ms_data_direction_in())
|
||||
{
|
||||
Usb_select_endpoint(MS_IN_EP);
|
||||
}
|
||||
|
||||
if (TRUE != scsi_decode_command())
|
||||
{
|
||||
if (g_scsi_data_remaining != 0)
|
||||
{
|
||||
Usb_enable_stall_handshake();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! @brief USB Command Status Wrapper (CSW) management
|
||||
//!
|
||||
//! This function sends the status in relation with the last CBW
|
||||
//!
|
||||
void usb_mass_storage_csw (void)
|
||||
{
|
||||
Usb_select_endpoint(MS_IN_EP);
|
||||
while (Is_usb_endpoint_stall_requested())
|
||||
{
|
||||
Usb_select_endpoint(EP_CONTROL);
|
||||
if (Is_usb_receive_setup()) { usb_process_request(); }
|
||||
Usb_select_endpoint(MS_IN_EP);
|
||||
}
|
||||
|
||||
Usb_select_endpoint(MS_OUT_EP);
|
||||
while (Is_usb_endpoint_stall_requested())
|
||||
{
|
||||
Usb_select_endpoint(EP_CONTROL);
|
||||
if (Is_usb_receive_setup()) { usb_process_request(); }
|
||||
Usb_select_endpoint(MS_OUT_EP);
|
||||
}
|
||||
|
||||
Usb_select_endpoint(MS_IN_EP);
|
||||
while(!Is_usb_write_enabled());
|
||||
//! write CSW Signature
|
||||
Usb_write_byte(0x55); //! 'U'
|
||||
Usb_write_byte(0x53); //! 'S'
|
||||
Usb_write_byte(0x42); //! 'B'
|
||||
Usb_write_byte(0x53); //! 'S'
|
||||
//! write stored CBW Tag
|
||||
Usb_write_byte(dCBWTag[0]);
|
||||
Usb_write_byte(dCBWTag[1]);
|
||||
Usb_write_byte(dCBWTag[2]);
|
||||
Usb_write_byte(dCBWTag[3]);
|
||||
//! write data residue value
|
||||
Usb_write_byte( ((Byte*)&g_scsi_data_remaining)[3] );
|
||||
Usb_write_byte( ((Byte*)&g_scsi_data_remaining)[2] );
|
||||
Usb_write_byte( ((Byte*)&g_scsi_data_remaining)[1] );
|
||||
Usb_write_byte( ((Byte*)&g_scsi_data_remaining)[0] );
|
||||
|
||||
//! write command status
|
||||
Usb_write_byte(g_scsi_status); //! 0 -> PASS, 1 -> FAIL
|
||||
Usb_send_in();
|
||||
}
|
||||
|
||||
/** @} */
|
69
cpu/avr/dev/usb/storage/storage_task.h
Normal file
69
cpu/avr/dev/usb/storage/storage_task.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file storage_task.c **********************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file manages the USB storage.
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
******************************************************************************/
|
||||
/*
|
||||
Copyright (c) 2004 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
\ingroup usbstick
|
||||
\defgroup usbstorage USB Mass Storage Task
|
||||
@{
|
||||
*/
|
||||
#ifndef _STORAGE_TASK_H_
|
||||
#define _STORAGE_TASK_H_
|
||||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
|
||||
|
||||
void sof_action(void);
|
||||
|
||||
|
||||
PROCESS_NAME(storage_process);
|
||||
|
||||
#endif /* _STORAGE_TASK_H_ */
|
||||
/** @} */
|
537
cpu/avr/dev/usb/usb_descriptors.c
Normal file
537
cpu/avr/dev/usb/usb_descriptors.c
Normal file
|
@ -0,0 +1,537 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file usb_descriptors.c *****************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file contains the usb parameters that uniquely identify the
|
||||
* application through descriptor tables.
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
* \author
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup usbconf
|
||||
@{
|
||||
*/
|
||||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "usb_drv.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "usb_specific_request.h"
|
||||
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
||||
|
||||
|
||||
//_____ D E F I N I T I O N ________________________________________________
|
||||
|
||||
/************* COMPOSITE DEVICE DESCRIPTORS (using IAD) **********/
|
||||
|
||||
// usb_user_device_descriptor
|
||||
FLASH S_usb_device_descriptor usb_dev_desc_composite =
|
||||
{
|
||||
sizeof(usb_dev_desc_composite)
|
||||
, DEVICE_DESCRIPTOR
|
||||
, Usb_write_word_enum_struc(USB_SPECIFICATION)
|
||||
, COMPOSITE_DEVICE_CLASS
|
||||
, COMPOSITE_DEVICE_SUB_CLASS
|
||||
, COMPOSITE_DEVICE_PROTOCOL
|
||||
, EP_CONTROL_LENGTH
|
||||
, Usb_write_word_enum_struc(VENDOR_ID)
|
||||
, Usb_write_word_enum_struc(COMPOSITE_PRODUCT_ID)
|
||||
, Usb_write_word_enum_struc(RELEASE_NUMBER)
|
||||
, MAN_INDEX
|
||||
, PROD_INDEX
|
||||
, SN_INDEX
|
||||
, NB_CONFIGURATION
|
||||
};
|
||||
|
||||
|
||||
// usb_user_configuration_descriptor FS
|
||||
FLASH S_usb_user_configuration_descriptor_composite usb_conf_desc_composite = {
|
||||
{ sizeof(S_usb_configuration_descriptor)
|
||||
, CONFIGURATION_DESCRIPTOR
|
||||
, Usb_write_word_enum_struc(sizeof(S_usb_user_configuration_descriptor_composite))
|
||||
//, 0x0043 //TODO: Change to generic codewith sizeof
|
||||
, COMPOSITE_NB_INTERFACE
|
||||
, CONF_NB
|
||||
, CONF_INDEX
|
||||
, CONF_ATTRIBUTES
|
||||
, MAX_POWER
|
||||
},//9
|
||||
|
||||
// --------------------------- IAD ----------------------------
|
||||
{ // Interface Association Descriptor
|
||||
sizeof(S_usb_interface_association_descriptor), // bLength
|
||||
DSC_TYPE_IAD, // bDescriptorType = 11
|
||||
0x00, // bFirstInterface
|
||||
0x02, // bInterfaceCount
|
||||
0x02, // bFunctionClass (Communication Class)
|
||||
0x02, // bFunctionSubClass (Abstract Control Model)
|
||||
0xFF, // bFunctionProcotol (Vendor specific)
|
||||
0x00 // iInterface
|
||||
},//8
|
||||
|
||||
/// RNDIS DEVICE
|
||||
{ sizeof(S_usb_interface_descriptor)
|
||||
, INTERFACE_DESCRIPTOR
|
||||
, INTERFACE0_NB
|
||||
, ALTERNATE0
|
||||
, NB_ENDPOINT0
|
||||
, INTERFACE0_CLASS
|
||||
, INTERFACE0_SUB_CLASS
|
||||
, INTERFACE0_PROTOCOL
|
||||
, INTERFACE0_INDEX
|
||||
} //9
|
||||
,
|
||||
{
|
||||
// Header Functional Descriptor (marks beginning of the concatenated set of Functional Descriptors)
|
||||
0x05, // bFunctionLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x00, // bDescriptorSubtype, Header Functional Descriptor
|
||||
0x10,0x01, // bcdCDC, CDC specification release number in BCD format (1,1)
|
||||
|
||||
// Call Management Functional Descriptor
|
||||
0x05, // bFunctionLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x01, // bDescriptorSubtype, Call Management Functional Descriptor
|
||||
0x00, // bmCapabilities
|
||||
0x01, // bDataInterface, Interface used for call management
|
||||
|
||||
// Abstract Control Management Functional Descriptor
|
||||
0x04, // bDescriptorLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x02, // bDescriptorSubtype, Abstract Control Management Functional Descriptor
|
||||
0x00, // bmCapabilities
|
||||
|
||||
// Union Functional Descriptor
|
||||
0x05, // bFunctionLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x06, // bDescriptorSubtype, Union Functional Descriptor
|
||||
0x00, // bMasterInterface, The controlling interface for the union (bInterfaceNumber of a Communication or Data Class interface in this configuration)
|
||||
0x01, // bSlaveInterface0, The controlled interace in the union (bInterfaceNumber of an interface in this configuration)
|
||||
},
|
||||
{ sizeof(S_usb_endpoint_descriptor)
|
||||
, ENDPOINT_DESCRIPTOR
|
||||
, ENDPOINT_NB_1
|
||||
, EP_ATTRIBUTES_1
|
||||
, Usb_write_word_enum_struc(EP_SIZE_1)
|
||||
, EP_INTERVAL_1
|
||||
} //7
|
||||
,
|
||||
{ sizeof(S_usb_interface_descriptor)
|
||||
, INTERFACE_DESCRIPTOR
|
||||
, INTERFACE1_NB
|
||||
, ALTERNATE1
|
||||
, NB_ENDPOINT1
|
||||
, INTERFACE1_CLASS
|
||||
, INTERFACE1_SUB_CLASS
|
||||
, INTERFACE1_PROTOCOL
|
||||
, INTERFACE1_INDEX
|
||||
},
|
||||
{ sizeof(S_usb_endpoint_descriptor)
|
||||
, ENDPOINT_DESCRIPTOR
|
||||
, ENDPOINT_NB_2
|
||||
, EP_ATTRIBUTES_2
|
||||
, Usb_write_word_enum_struc(EP_SIZE_2)
|
||||
, EP_INTERVAL_2
|
||||
},
|
||||
{ sizeof(S_usb_endpoint_descriptor)
|
||||
, ENDPOINT_DESCRIPTOR
|
||||
, ENDPOINT_NB_3
|
||||
, EP_ATTRIBUTES_3
|
||||
, Usb_write_word_enum_struc(EP_SIZE_3)
|
||||
, EP_INTERVAL_3
|
||||
},
|
||||
|
||||
// --------------------------- IAD ----------------------------
|
||||
{ // Interface Association Descriptor
|
||||
sizeof(S_usb_interface_association_descriptor), // bLength
|
||||
DSC_TYPE_IAD, // bDescriptorType = 11
|
||||
0x02, // bFirstInterface
|
||||
0x02, // bInterfaceCount
|
||||
0x02, // bFunctionClass (Communication Class)
|
||||
0x02, // bFunctionSubClass (Abstract Control Model)
|
||||
0x01, // bFunctionProcotol (V.25ter, Common AT commands)
|
||||
0x00 // iInterface
|
||||
},//8
|
||||
|
||||
/// SERIAL PORT DEVICE
|
||||
|
||||
{ sizeof(S_usb_interface_descriptor)
|
||||
, INTERFACE_DESCRIPTOR
|
||||
, INTERFACE2_NB
|
||||
, ALTERNATE2
|
||||
, NB_ENDPOINT2
|
||||
, INTERFACE2_CLASS
|
||||
, INTERFACE2_SUB_CLASS
|
||||
, INTERFACE2_PROTOCOL
|
||||
, INTERFACE2_INDEX
|
||||
}//9
|
||||
,
|
||||
{
|
||||
// Header Functional Descriptor (marks beginning of the concatenated set of Functional Descriptors)
|
||||
0x05, // bFunctionLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x00, // bDescriptorSubtype, Header Functional Descriptor
|
||||
0x10,0x01, // bcdCDC, CDC specification release number in BCD format (1,1)
|
||||
|
||||
// Call Management Functional Descriptor
|
||||
0x05, // bFunctionLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x01, // bDescriptorSubtype, Call Management Functional Descriptor
|
||||
0x03, // bmCapabilities, can do calls on it's own
|
||||
0x03, // bDataInterface, Interface used for call management
|
||||
|
||||
// Abstract Control Management Functional Descriptor
|
||||
0x04, // bDescriptorLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x02, // bDescriptorSubtype, Abstract Control Management Functional Descriptor
|
||||
0x00, // bmCapabilities, support nothing!!! Deal with it
|
||||
|
||||
//Old was 0x06 indicating support for the GET/SET_LINE_CODING, BREAK & SET_CONTROL_LINE_STATE (2->6)
|
||||
|
||||
// Union Functional Descriptor
|
||||
0x05, // bFunctionLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x06, // bDescriptorSubtype, Union Functional Descriptor
|
||||
0x02, // bMasterInterface, The controlling interface for the union (bInterfaceNumber of a Communication or Data Class interface in this configuration)
|
||||
0x03, // bSlaveInterface0, The controlled interace in the union (bInterfaceNumber of an interface in this configuration)
|
||||
|
||||
},
|
||||
{ sizeof(S_usb_endpoint_descriptor)
|
||||
, ENDPOINT_DESCRIPTOR
|
||||
, ENDPOINT_NB_4
|
||||
, EP_ATTRIBUTES_4
|
||||
, Usb_write_word_enum_struc(EP_SIZE_4)
|
||||
, EP_INTERVAL_4
|
||||
} //7
|
||||
,
|
||||
{ sizeof(S_usb_interface_descriptor)
|
||||
, INTERFACE_DESCRIPTOR
|
||||
, INTERFACE3_NB
|
||||
, ALTERNATE3
|
||||
, NB_ENDPOINT3
|
||||
, INTERFACE3_CLASS
|
||||
, INTERFACE3_SUB_CLASS
|
||||
, INTERFACE3_PROTOCOL
|
||||
, INTERFACE3_INDEX
|
||||
}
|
||||
,
|
||||
{ sizeof(S_usb_endpoint_descriptor)
|
||||
, ENDPOINT_DESCRIPTOR
|
||||
, ENDPOINT_NB_5
|
||||
, EP_ATTRIBUTES_5
|
||||
, Usb_write_word_enum_struc(EP_SIZE_5)
|
||||
, EP_INTERVAL_5
|
||||
}
|
||||
,
|
||||
{ sizeof(S_usb_endpoint_descriptor)
|
||||
, ENDPOINT_DESCRIPTOR
|
||||
, ENDPOINT_NB_6
|
||||
, EP_ATTRIBUTES_6
|
||||
, Usb_write_word_enum_struc(EP_SIZE_6)
|
||||
, EP_INTERVAL_6
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/****************** NETWORK-ONLY DEVICE DESCRIPTORS **************************/
|
||||
|
||||
FLASH S_usb_device_descriptor usb_dev_desc_network =
|
||||
{
|
||||
sizeof(usb_dev_desc_network)
|
||||
, DEVICE_DESCRIPTOR
|
||||
, Usb_write_word_enum_struc(USB_SPECIFICATION)
|
||||
, NETWORK_DEVICE_CLASS
|
||||
, NETWORK_DEVICE_SUB_CLASS
|
||||
, NETWORK_DEVICE_PROTOCOL
|
||||
, EP_CONTROL_LENGTH
|
||||
, Usb_write_word_enum_struc(VENDOR_ID)
|
||||
, Usb_write_word_enum_struc(NETWORK_PRODUCT_ID)
|
||||
, Usb_write_word_enum_struc(RELEASE_NUMBER)
|
||||
, MAN_INDEX
|
||||
, PROD_INDEX
|
||||
, SN_INDEX
|
||||
, NB_CONFIGURATION
|
||||
};
|
||||
|
||||
// usb_user_configuration_descriptor FS
|
||||
FLASH S_usb_user_configuration_descriptor_network usb_conf_desc_network = {
|
||||
{ sizeof(S_usb_configuration_descriptor)
|
||||
, CONFIGURATION_DESCRIPTOR
|
||||
, Usb_write_word_enum_struc(sizeof(S_usb_user_configuration_descriptor_network))
|
||||
//, 0x0043 //TODO: Change to generic codewith sizeof
|
||||
, NETWORK_NB_INTERFACE
|
||||
, CONF_NB
|
||||
, CONF_INDEX
|
||||
, CONF_ATTRIBUTES
|
||||
, MAX_POWER
|
||||
},//9
|
||||
|
||||
/// RNDIS DEVICE
|
||||
{ sizeof(S_usb_interface_descriptor)
|
||||
, INTERFACE_DESCRIPTOR
|
||||
, INTERFACE0_NB
|
||||
, ALTERNATE0
|
||||
, NB_ENDPOINT0
|
||||
, INTERFACE0_CLASS
|
||||
, INTERFACE0_SUB_CLASS
|
||||
, INTERFACE0_PROTOCOL
|
||||
, INTERFACE0_INDEX
|
||||
} //9
|
||||
,
|
||||
{
|
||||
// Header Functional Descriptor (marks beginning of the concatenated set of Functional Descriptors)
|
||||
0x05, // bFunctionLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x00, // bDescriptorSubtype, Header Functional Descriptor
|
||||
0x10,0x01, // bcdCDC, CDC specification release number in BCD format (1,1)
|
||||
|
||||
// Call Management Functional Descriptor
|
||||
0x05, // bFunctionLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x01, // bDescriptorSubtype, Call Management Functional Descriptor
|
||||
0x00, // bmCapabilities
|
||||
0x01, // bDataInterface, Interface used for call management
|
||||
|
||||
// Abstract Control Management Functional Descriptor
|
||||
0x04, // bDescriptorLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x02, // bDescriptorSubtype, Abstract Control Management Functional Descriptor
|
||||
0x00, // bmCapabilities
|
||||
|
||||
// Union Functional Descriptor
|
||||
0x05, // bFunctionLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x06, // bDescriptorSubtype, Union Functional Descriptor
|
||||
0x00, // bMasterInterface, The controlling interface for the union (bInterfaceNumber of a Communication or Data Class interface in this configuration)
|
||||
0x01, // bSlaveInterface0, The controlled interace in the union (bInterfaceNumber of an interface in this configuration)
|
||||
},
|
||||
{ sizeof(S_usb_endpoint_descriptor)
|
||||
, ENDPOINT_DESCRIPTOR
|
||||
, ENDPOINT_NB_1
|
||||
, EP_ATTRIBUTES_1
|
||||
, Usb_write_word_enum_struc(EP_SIZE_1)
|
||||
, EP_INTERVAL_1
|
||||
} //7
|
||||
,
|
||||
{ sizeof(S_usb_interface_descriptor)
|
||||
, INTERFACE_DESCRIPTOR
|
||||
, INTERFACE1_NB
|
||||
, ALTERNATE1
|
||||
, NB_ENDPOINT1
|
||||
, INTERFACE1_CLASS
|
||||
, INTERFACE1_SUB_CLASS
|
||||
, INTERFACE1_PROTOCOL
|
||||
, INTERFACE1_INDEX
|
||||
},
|
||||
{ sizeof(S_usb_endpoint_descriptor)
|
||||
, ENDPOINT_DESCRIPTOR
|
||||
, ENDPOINT_NB_2
|
||||
, EP_ATTRIBUTES_2
|
||||
, Usb_write_word_enum_struc(EP_SIZE_2)
|
||||
, EP_INTERVAL_2
|
||||
},
|
||||
{ sizeof(S_usb_endpoint_descriptor)
|
||||
, ENDPOINT_DESCRIPTOR
|
||||
, ENDPOINT_NB_3
|
||||
, EP_ATTRIBUTES_3
|
||||
, Usb_write_word_enum_struc(EP_SIZE_3)
|
||||
, EP_INTERVAL_3
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/****************** MASS-STORAGE DEVICE DESCRIPTORS **************************/
|
||||
|
||||
FLASH S_usb_device_descriptor usb_dev_desc_mass =
|
||||
{
|
||||
sizeof(usb_dev_desc_mass)
|
||||
, DEVICE_DESCRIPTOR
|
||||
, Usb_write_word_enum_struc(USB_SPECIFICATION)
|
||||
, MASS_DEVICE_CLASS
|
||||
, MASS_DEVICE_SUB_CLASS
|
||||
, MASS_DEVICE_PROTOCOL
|
||||
, EP_CONTROL_LENGTH
|
||||
, Usb_write_word_enum_struc(VENDOR_ID)
|
||||
, Usb_write_word_enum_struc(MASS_PRODUCT_ID)
|
||||
, Usb_write_word_enum_struc(RELEASE_NUMBER)
|
||||
, MAN_INDEX
|
||||
, PROD_INDEX
|
||||
, SN_INDEX
|
||||
, NB_CONFIGURATION
|
||||
};
|
||||
|
||||
// usb_user_configuration_descriptor FS
|
||||
FLASH S_usb_user_configuration_descriptor_mass usb_conf_desc_mass = {
|
||||
{ sizeof(S_usb_configuration_descriptor)
|
||||
, CONFIGURATION_DESCRIPTOR
|
||||
, Usb_write_word_enum_struc(sizeof(S_usb_user_configuration_descriptor_mass))
|
||||
, MASS_NB_INTERFACE
|
||||
, CONF_NB
|
||||
, CONF_INDEX
|
||||
, CONF_ATTRIBUTES
|
||||
, MAX_POWER
|
||||
},//9
|
||||
|
||||
/// Mass storage
|
||||
{ sizeof(S_usb_interface_descriptor)
|
||||
, INTERFACE_DESCRIPTOR
|
||||
, MS_INTERFACE_NB
|
||||
, MS_ALTERNATE
|
||||
, MS_NB_ENDPOINT
|
||||
, MS_INTERFACE_CLASS
|
||||
, MS_INTERFACE_SUB_CLASS
|
||||
, MS_INTERFACE_PROTOCOL
|
||||
, MS_INTERFACE_INDEX
|
||||
} //9
|
||||
,
|
||||
{ sizeof(S_usb_endpoint_descriptor)
|
||||
, ENDPOINT_DESCRIPTOR
|
||||
, MS_ENDPOINT_NB_1
|
||||
, MS_EP_ATTRIBUTES_1
|
||||
, Usb_write_word_enum_struc(MS_EP_SIZE_1)
|
||||
, MS_EP_INTERVAL_1
|
||||
} //7
|
||||
,
|
||||
{ sizeof(S_usb_endpoint_descriptor)
|
||||
, ENDPOINT_DESCRIPTOR
|
||||
, MS_ENDPOINT_NB_2
|
||||
, MS_EP_ATTRIBUTES_2
|
||||
, Usb_write_word_enum_struc(MS_EP_SIZE_2)
|
||||
, MS_EP_INTERVAL_2
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/************* COMMON *****************/
|
||||
|
||||
|
||||
// usb_user_manufacturer_string_descriptor
|
||||
FLASH S_usb_manufacturer_string_descriptor usb_user_manufacturer_string_descriptor = {
|
||||
sizeof(usb_user_manufacturer_string_descriptor)
|
||||
, STRING_DESCRIPTOR
|
||||
, USB_MANUFACTURER_NAME
|
||||
};
|
||||
|
||||
|
||||
// usb_user_product_string_descriptor
|
||||
|
||||
FLASH S_usb_product_string_descriptor usb_user_product_string_descriptor = {
|
||||
sizeof(usb_user_product_string_descriptor)
|
||||
, STRING_DESCRIPTOR
|
||||
, USB_PRODUCT_NAME
|
||||
};
|
||||
|
||||
|
||||
// usb_user_serial_number
|
||||
|
||||
FLASH S_usb_serial_number usb_user_serial_number = {
|
||||
sizeof(usb_user_serial_number)
|
||||
, STRING_DESCRIPTOR
|
||||
, USB_SERIAL_NUMBER
|
||||
};
|
||||
|
||||
|
||||
// usb_user_language_id
|
||||
|
||||
FLASH S_usb_language_id usb_user_language_id = {
|
||||
sizeof(usb_user_language_id)
|
||||
, STRING_DESCRIPTOR
|
||||
, Usb_write_word_enum_struc(LANGUAGE_ID)
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
PGM_VOID_P Usb_get_dev_desc_pointer(void)
|
||||
{
|
||||
if (usb_mode == rndis_only)
|
||||
return &(usb_dev_desc_network.bLength);
|
||||
|
||||
if (usb_mode == rndis_debug)
|
||||
return &(usb_dev_desc_composite.bLength);
|
||||
|
||||
return &(usb_dev_desc_mass.bLength);
|
||||
}
|
||||
|
||||
|
||||
U8 Usb_get_dev_desc_length(void)
|
||||
{
|
||||
|
||||
if (usb_mode == rndis_only)
|
||||
return sizeof(usb_dev_desc_network);
|
||||
|
||||
if (usb_mode == rndis_debug)
|
||||
return sizeof(usb_dev_desc_composite);
|
||||
|
||||
return sizeof(usb_dev_desc_mass);
|
||||
}
|
||||
|
||||
|
||||
PGM_VOID_P Usb_get_conf_desc_pointer(void)
|
||||
{
|
||||
if (usb_mode == rndis_only)
|
||||
return &(usb_conf_desc_network.cfg.bLength);
|
||||
|
||||
if (usb_mode == rndis_debug)
|
||||
return &(usb_conf_desc_composite.cfg.bLength);
|
||||
|
||||
return &(usb_conf_desc_mass.cfg.bLength);
|
||||
}
|
||||
|
||||
|
||||
U8 Usb_get_conf_desc_length(void)
|
||||
{
|
||||
|
||||
if (usb_mode == rndis_only)
|
||||
return sizeof (usb_conf_desc_network);
|
||||
|
||||
if (usb_mode == rndis_debug)
|
||||
return sizeof(usb_conf_desc_composite);
|
||||
|
||||
return sizeof(usb_conf_desc_mass);
|
||||
}
|
||||
|
||||
/** @} */
|
453
cpu/avr/dev/usb/usb_descriptors.h
Normal file
453
cpu/avr/dev/usb/usb_descriptors.h
Normal file
|
@ -0,0 +1,453 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file usb_descriptors.h ***************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file contains the usb parameters that uniquely identify the
|
||||
* application through descriptor tables.
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com
|
||||
* \author
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 ATMEL Corporation
|
||||
Copyright (c) 2008 Colin O'Flynn
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup usbconf
|
||||
@{
|
||||
*/
|
||||
|
||||
#ifndef _USB_USERCONFIG_H_
|
||||
#define _USB_USERCONFIG_H_
|
||||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
#include "config.h"
|
||||
#include "usb_standard_request.h"
|
||||
#include "conf_usb.h"
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
||||
//_____ U S B D E F I N E _______________________________________________
|
||||
|
||||
// USB Device descriptor
|
||||
#define USB_SPECIFICATION 0x0200
|
||||
|
||||
#define COMPOSITE_DEVICE_CLASS 0xEF // Misc
|
||||
#define COMPOSITE_DEVICE_SUB_CLASS 0x02 // Common
|
||||
#define COMPOSITE_DEVICE_PROTOCOL 0x01 // IAD
|
||||
|
||||
#define NETWORK_DEVICE_CLASS 0x02 // CDC ACM
|
||||
#define NETWORK_DEVICE_SUB_CLASS 0x02 //
|
||||
#define NETWORK_DEVICE_PROTOCOL 0xFF // Vendor-specific
|
||||
|
||||
#define MASS_DEVICE_CLASS 0x00 //
|
||||
#define MASS_DEVICE_SUB_CLASS 0x00 //
|
||||
#define MASS_DEVICE_PROTOCOL 0x00 //
|
||||
|
||||
#define EP_CONTROL_LENGTH 64
|
||||
#define VENDOR_ID 0x03EB // Atmel vendor ID = 03EBh
|
||||
#define COMPOSITE_PRODUCT_ID 0x2021 //Product ID for composite device
|
||||
#define NETWORK_PRODUCT_ID 0x2019 //Product ID for just RNDIS device
|
||||
#define MASS_PRODUCT_ID 0x202F //Product ID for mass storage
|
||||
#define RELEASE_NUMBER 0x1000
|
||||
#define MAN_INDEX 0x01
|
||||
#define PROD_INDEX 0x02
|
||||
#define SN_INDEX 0x03
|
||||
#define NB_CONFIGURATION 1
|
||||
|
||||
#define NETWORK_NB_INTERFACE 2
|
||||
#define COMPOSITE_NB_INTERFACE 4
|
||||
#define MASS_NB_INTERFACE 1
|
||||
#define CONF_NB 1
|
||||
#define CONF_INDEX 0
|
||||
#define CONF_ATTRIBUTES USB_CONFIG_BUSPOWERED
|
||||
#define MAX_POWER 50 // 100 mA
|
||||
|
||||
/*** CDC RNDIS CONFIGURATION CONFIGURATION ***/
|
||||
|
||||
// Interface 0 descriptor
|
||||
#define INTERFACE0_NB 0
|
||||
#define ALTERNATE0 0
|
||||
#define NB_ENDPOINT0 1
|
||||
#define INTERFACE0_CLASS 0x02 // CDC ACM Com
|
||||
#define INTERFACE0_SUB_CLASS 0x02
|
||||
#define INTERFACE0_PROTOCOL 0xFF // Vendor specific
|
||||
#define INTERFACE0_INDEX 0
|
||||
|
||||
// Interface 1 descriptor
|
||||
#define INTERFACE1_NB 1
|
||||
#define ALTERNATE1 0
|
||||
#define NB_ENDPOINT1 2
|
||||
#define INTERFACE1_CLASS 0x0A // CDC ACM Data
|
||||
#define INTERFACE1_SUB_CLASS 0
|
||||
#define INTERFACE1_PROTOCOL 0
|
||||
#define INTERFACE1_INDEX 0
|
||||
|
||||
// USB Endpoint 1 descriptor
|
||||
// Interrupt IN
|
||||
#define ENDPOINT_NB_1 0x80 | INT_EP
|
||||
#define EP_ATTRIBUTES_1 0x03 // BULK = 0x02, INTERUPT = 0x03
|
||||
#define EP_SIZE_1 0x08
|
||||
#define EP_INTERVAL_1 0x01 //ms interrupt pooling from host
|
||||
|
||||
// USB Endpoint 1 descriptor
|
||||
// Bulk IN
|
||||
#define ENDPOINT_NB_2 0x80 | TX_EP
|
||||
#define EP_ATTRIBUTES_2 0x02 // BULK = 0x02, INTERUPT = 0x03
|
||||
#define EP_SIZE_2 0x40 //64 byte max size
|
||||
#define EP_INTERVAL_2 0x00
|
||||
|
||||
// USB Endpoint 2 descriptor
|
||||
//Bulk OUT RX endpoint
|
||||
#define ENDPOINT_NB_3 RX_EP
|
||||
#define EP_ATTRIBUTES_3 0x02 // BULK = 0x02, INTERUPT = 0x03
|
||||
#define EP_SIZE_3 0x40 //64 byte max size
|
||||
#define EP_INTERVAL_3 0x00
|
||||
|
||||
/*** CDC Virtual Serial Port ***/
|
||||
|
||||
// Interface 2 descriptor
|
||||
#define INTERFACE2_NB 2
|
||||
#define ALTERNATE2 0
|
||||
#define NB_ENDPOINT2 1
|
||||
#define INTERFACE2_CLASS 0x02 // CDC ACM Com
|
||||
#define INTERFACE2_SUB_CLASS 0x02
|
||||
#define INTERFACE2_PROTOCOL 0x01
|
||||
#define INTERFACE2_INDEX 0
|
||||
|
||||
// Interface 3 descriptor
|
||||
#define INTERFACE3_NB 3
|
||||
#define ALTERNATE3 0
|
||||
#define NB_ENDPOINT3 2
|
||||
#define INTERFACE3_CLASS 0x0A // CDC ACM Data
|
||||
#define INTERFACE3_SUB_CLASS 0
|
||||
#define INTERFACE3_PROTOCOL 0
|
||||
#define INTERFACE3_INDEX 0
|
||||
|
||||
// USB Endpoint 4 descriptor
|
||||
// Interrupt IN
|
||||
#define TX_EP_SIZE 0x20
|
||||
#define ENDPOINT_NB_4 0x80 | VCP_INT_EP
|
||||
#define EP_ATTRIBUTES_4 0x03 // BULK = 0x02, INTERUPT = 0x03
|
||||
#define EP_SIZE_4 TX_EP_SIZE
|
||||
#define EP_INTERVAL_4 0xFF //ms interrupt pooling from host
|
||||
|
||||
// USB Endpoint 5 descriptor
|
||||
// Bulk IN
|
||||
#define ENDPOINT_NB_5 0x80 | VCP_TX_EP
|
||||
#define EP_ATTRIBUTES_5 0x02 // BULK = 0x02, INTERUPT = 0x03
|
||||
#define EP_SIZE_5 0x20
|
||||
#define EP_INTERVAL_5 0x00
|
||||
|
||||
// USB Endpoint 6 descriptor
|
||||
// Bulk OUT
|
||||
#define ENDPOINT_NB_6 VCP_RX_EP
|
||||
#define EP_ATTRIBUTES_6 0x02 // BULK = 0x02, INTERUPT = 0x03
|
||||
#define EP_SIZE_6 0x20
|
||||
#define EP_INTERVAL_6 0x00
|
||||
|
||||
|
||||
/*** Mass Storage ***/
|
||||
|
||||
#define MS_INTERFACE_NB 0
|
||||
#define MS_ALTERNATE 0
|
||||
#define MS_NB_ENDPOINT 2
|
||||
#define MS_INTERFACE_CLASS 0x08 // Mass Storage Class
|
||||
#define MS_INTERFACE_SUB_CLASS 0x06 // SCSI transparent Command Set
|
||||
#define MS_INTERFACE_PROTOCOL 0x50 // Bulk-Only Transport
|
||||
#define MS_INTERFACE_INDEX 0
|
||||
|
||||
// USB Endpoint 1 descriptor FS
|
||||
#define MS_ENDPOINT_NB_1 (MS_IN_EP | 0x80)
|
||||
#define MS_EP_ATTRIBUTES_1 0x02 // BULK = 0x02, INTERUPT = 0x03
|
||||
#define MS_EP_IN_LENGTH 64
|
||||
#define MS_EP_SIZE_1 MS_EP_IN_LENGTH
|
||||
#define MS_EP_INTERVAL_1 0x00
|
||||
|
||||
|
||||
// USB Endpoint 2 descriptor FS
|
||||
#define MS_ENDPOINT_NB_2 MS_OUT_EP
|
||||
#define MS_EP_ATTRIBUTES_2 0x02 // BULK = 0x02, INTERUPT = 0x03
|
||||
#define MS_EP_IN_LENGTH 64
|
||||
#define MS_EP_SIZE_2 MS_EP_IN_LENGTH
|
||||
#define MS_EP_INTERVAL_2 0x00
|
||||
|
||||
|
||||
#define DEVICE_STATUS 0x00 // TBD
|
||||
#define INTERFACE_STATUS 0x00 // TBD
|
||||
|
||||
#define LANG_ID 0x00
|
||||
|
||||
|
||||
|
||||
|
||||
#define USB_MN_LENGTH 5
|
||||
#define USB_MANUFACTURER_NAME \
|
||||
{ Usb_unicode('A') \
|
||||
, Usb_unicode('t') \
|
||||
, Usb_unicode('m') \
|
||||
, Usb_unicode('e') \
|
||||
, Usb_unicode('l') \
|
||||
}
|
||||
|
||||
#define USB_PN_LENGTH 16
|
||||
#define USB_PRODUCT_NAME \
|
||||
{ Usb_unicode('R') \
|
||||
,Usb_unicode('Z') \
|
||||
,Usb_unicode('R') \
|
||||
,Usb_unicode('A') \
|
||||
,Usb_unicode('V') \
|
||||
,Usb_unicode('E') \
|
||||
,Usb_unicode('N') \
|
||||
,Usb_unicode(' ') \
|
||||
,Usb_unicode('U') \
|
||||
,Usb_unicode('S') \
|
||||
,Usb_unicode('B') \
|
||||
,Usb_unicode(' ') \
|
||||
,Usb_unicode('D') \
|
||||
,Usb_unicode('E') \
|
||||
,Usb_unicode('M') \
|
||||
,Usb_unicode('O') \
|
||||
}
|
||||
|
||||
#define USB_SN_LENGTH 0x05
|
||||
#define USB_SERIAL_NUMBER \
|
||||
{Usb_unicode('1') \
|
||||
,Usb_unicode('.') \
|
||||
,Usb_unicode('0') \
|
||||
,Usb_unicode('.') \
|
||||
,Usb_unicode('0') \
|
||||
}
|
||||
|
||||
#define LANGUAGE_ID 0x0409
|
||||
|
||||
//! Usb Request
|
||||
typedef struct
|
||||
{
|
||||
U8 bmRequestType; //!< Characteristics of the request
|
||||
U8 bRequest; //!< Specific request
|
||||
U16 wValue; //!< field that varies according to request
|
||||
U16 wIndex; //!< field that varies according to request
|
||||
U16 wLength; //!< Number of bytes to transfer if Data
|
||||
} S_UsbRequest;
|
||||
|
||||
//! Usb Device Descriptor
|
||||
typedef struct {
|
||||
U8 bLength; //!< Size of this descriptor in bytes
|
||||
U8 bDescriptorType; //!< DEVICE descriptor type
|
||||
U16 bscUSB; //!< Binay Coded Decimal Spec. release
|
||||
U8 bDeviceClass; //!< Class code assigned by the USB
|
||||
U8 bDeviceSubClass; //!< Sub-class code assigned by the USB
|
||||
U8 bDeviceProtocol; //!< Protocol code assigned by the USB
|
||||
U8 bMaxPacketSize0; //!< Max packet size for EP0
|
||||
U16 idVendor; //!< Vendor ID. ATMEL = 0x03EB
|
||||
U16 idProduct; //!< Product ID assigned by the manufacturer
|
||||
U16 bcdDevice; //!< Device release number
|
||||
U8 iManufacturer; //!< Index of manu. string descriptor
|
||||
U8 iProduct; //!< Index of prod. string descriptor
|
||||
U8 iSerialNumber; //!< Index of S.N. string descriptor
|
||||
U8 bNumConfigurations; //!< Number of possible configurations
|
||||
} S_usb_device_descriptor;
|
||||
|
||||
|
||||
//! Usb Configuration Descriptor
|
||||
typedef struct {
|
||||
U8 bLength; //!< size of this descriptor in bytes
|
||||
U8 bDescriptorType; //!< CONFIGURATION descriptor type
|
||||
U16 wTotalLength; //!< total length of data returned
|
||||
U8 bNumInterfaces; //!< number of interfaces for this conf.
|
||||
U8 bConfigurationValue; //!< value for SetConfiguration resquest
|
||||
U8 iConfiguration; //!< index of string descriptor
|
||||
U8 bmAttibutes; //!< Configuration characteristics
|
||||
U8 MaxPower; //!< maximum power consumption
|
||||
} S_usb_configuration_descriptor;
|
||||
|
||||
|
||||
//! Usb Interface Descriptor
|
||||
typedef struct {
|
||||
U8 bLength; //!< size of this descriptor in bytes
|
||||
U8 bDescriptorType; //!< INTERFACE descriptor type
|
||||
U8 bInterfaceNumber; //!< Number of interface
|
||||
U8 bAlternateSetting; //!< value to select alternate setting
|
||||
U8 bNumEndpoints; //!< Number of EP except EP 0
|
||||
U8 bInterfaceClass; //!< Class code assigned by the USB
|
||||
U8 bInterfaceSubClass; //!< Sub-class code assigned by the USB
|
||||
U8 bInterfaceProtocol; //!< Protocol code assigned by the USB
|
||||
U8 iInterface; //!< Index of string descriptor
|
||||
} S_usb_interface_descriptor;
|
||||
|
||||
|
||||
//! Usb Endpoint Descriptor
|
||||
typedef struct {
|
||||
U8 bLength; //!< Size of this descriptor in bytes
|
||||
U8 bDescriptorType; //!< ENDPOINT descriptor type
|
||||
U8 bEndpointAddress; //!< Address of the endpoint
|
||||
U8 bmAttributes; //!< Endpoint's attributes
|
||||
U16 wMaxPacketSize; //!< Maximum packet size for this EP
|
||||
U8 bInterval; //!< Interval for polling EP in ms
|
||||
} S_usb_endpoint_descriptor;
|
||||
|
||||
|
||||
//! Usb Device Qualifier Descriptor
|
||||
typedef struct {
|
||||
U8 bLength; //!< Size of this descriptor in bytes
|
||||
U8 bDescriptorType; //!< Device Qualifier descriptor type
|
||||
U16 bscUSB; //!< Binay Coded Decimal Spec. release
|
||||
U8 bDeviceClass; //!< Class code assigned by the USB
|
||||
U8 bDeviceSubClass; //!< Sub-class code assigned by the USB
|
||||
U8 bDeviceProtocol; //!< Protocol code assigned by the USB
|
||||
U8 bMaxPacketSize0; //!< Max packet size for EP0
|
||||
U8 bNumConfigurations; //!< Number of possible configurations
|
||||
U8 bReserved; //!< Reserved for future use, must be zero
|
||||
} S_usb_device_qualifier_descriptor;
|
||||
|
||||
|
||||
//! Usb Language Descriptor
|
||||
typedef struct {
|
||||
U8 bLength; //!< size of this descriptor in bytes
|
||||
U8 bDescriptorType; //!< STRING descriptor type
|
||||
U16 wlangid; //!< language id
|
||||
} S_usb_language_id;
|
||||
|
||||
|
||||
//_____ U S B M A N U F A C T U R E R D E S C R I P T O R _______________
|
||||
|
||||
|
||||
//struct usb_st_manufacturer
|
||||
typedef struct {
|
||||
U8 bLength; // size of this descriptor in bytes
|
||||
U8 bDescriptorType; // STRING descriptor type
|
||||
U16 wstring[USB_MN_LENGTH];// unicode characters
|
||||
} S_usb_manufacturer_string_descriptor;
|
||||
|
||||
|
||||
//_____ U S B P R O D U C T D E S C R I P T O R _________________________
|
||||
|
||||
|
||||
//struct usb_st_product
|
||||
typedef struct {
|
||||
U8 bLength; // size of this descriptor in bytes
|
||||
U8 bDescriptorType; // STRING descriptor type
|
||||
U16 wstring[USB_PN_LENGTH];// unicode characters
|
||||
} S_usb_product_string_descriptor;
|
||||
|
||||
|
||||
//_____ U S B S E R I A L N U M B E R D E S C R I P T O R _____________
|
||||
|
||||
|
||||
//struct usb_st_serial_number
|
||||
typedef struct {
|
||||
U8 bLength; // size of this descriptor in bytes
|
||||
U8 bDescriptorType; // STRING descriptor type
|
||||
U16 wstring[USB_SN_LENGTH];// unicode characters
|
||||
} S_usb_serial_number;
|
||||
|
||||
|
||||
/*_____ U S B I A D _______________________________________________________*/
|
||||
|
||||
#define DSC_TYPE_IAD 11
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U8 bLength;
|
||||
U8 bDescriptorType;
|
||||
U8 bFirstInterface;
|
||||
U8 bInterfaceCount;
|
||||
U8 bFunctionClass;
|
||||
U8 bFunctionSubClass;
|
||||
U8 bFunctionProtocol;
|
||||
U8 iInterface;
|
||||
} S_usb_interface_association_descriptor;
|
||||
|
||||
/*_____ U S B D E S C R I P T O R __________________________________*/
|
||||
|
||||
/* RNDIS + Serial Port */
|
||||
typedef struct
|
||||
{
|
||||
S_usb_configuration_descriptor cfg;
|
||||
|
||||
S_usb_interface_association_descriptor iad0;
|
||||
S_usb_interface_descriptor ifc0;
|
||||
U8 CS1_INTERFACE[19];
|
||||
S_usb_endpoint_descriptor ep1;
|
||||
S_usb_interface_descriptor ifc1;
|
||||
S_usb_endpoint_descriptor ep2;
|
||||
S_usb_endpoint_descriptor ep3;
|
||||
|
||||
S_usb_interface_association_descriptor iad1;
|
||||
S_usb_interface_descriptor ifc2;
|
||||
U8 CS2_INTERFACE[19];
|
||||
S_usb_endpoint_descriptor ep4;
|
||||
S_usb_interface_descriptor ifc3;
|
||||
S_usb_endpoint_descriptor ep5;
|
||||
S_usb_endpoint_descriptor ep6;
|
||||
|
||||
} S_usb_user_configuration_descriptor_composite;
|
||||
|
||||
/* Just RNDIS */
|
||||
typedef struct
|
||||
{
|
||||
S_usb_configuration_descriptor cfg;
|
||||
S_usb_interface_descriptor ifc0;
|
||||
U8 CS1_INTERFACE[19];
|
||||
S_usb_endpoint_descriptor ep1;
|
||||
S_usb_interface_descriptor ifc1;
|
||||
S_usb_endpoint_descriptor ep2;
|
||||
S_usb_endpoint_descriptor ep3;
|
||||
|
||||
} S_usb_user_configuration_descriptor_network;
|
||||
|
||||
/* Mass Storage */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
S_usb_configuration_descriptor cfg;
|
||||
S_usb_interface_descriptor ifc0;
|
||||
S_usb_endpoint_descriptor ep1;
|
||||
S_usb_endpoint_descriptor ep2;
|
||||
|
||||
} S_usb_user_configuration_descriptor_mass;
|
||||
|
||||
|
||||
PGM_VOID_P Usb_get_dev_desc_pointer(void);
|
||||
U8 Usb_get_dev_desc_length(void);
|
||||
PGM_VOID_P Usb_get_conf_desc_pointer(void) ;
|
||||
U8 Usb_get_conf_desc_length(void);
|
||||
|
||||
#endif // _USB_USERCONFIG_H_
|
||||
|
||||
/** @} */
|
333
cpu/avr/dev/usb/usb_drv.c
Normal file
333
cpu/avr/dev/usb/usb_drv.c
Normal file
|
@ -0,0 +1,333 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file usb_drv.c************************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file contains the USB driver routines.
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup usbdriver
|
||||
@{
|
||||
*/
|
||||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
#include "config.h"
|
||||
#include "conf_usb.h"
|
||||
#include "usb_drv.h"
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
//_____ D E C L A R A T I O N ______________________________________________
|
||||
|
||||
#if (USB_DEVICE_FEATURE==DISABLED && USB_HOST_FEATURE==DISABLED)
|
||||
#error at least one of USB_DEVICE_FEATURE or USB_HOST_FEATURE should be unabled
|
||||
#endif
|
||||
|
||||
#if (USB_DEVICE_FEATURE == ENABLED)
|
||||
|
||||
//! usb_configure_endpoint.
|
||||
//!
|
||||
//! This function configures an endpoint with the selected type.
|
||||
//!
|
||||
//! @param config0
|
||||
//! @param config1
|
||||
//!
|
||||
//! @return Is_endpoint_configured().
|
||||
//!
|
||||
U8 usb_config_ep(U8 config0, U8 config1)
|
||||
{
|
||||
Usb_enable_endpoint();
|
||||
UECFG0X = config0;
|
||||
UECFG1X = (UECFG1X & (1<<ALLOC)) | config1;
|
||||
Usb_allocate_memory();
|
||||
return (Is_endpoint_configured());
|
||||
}
|
||||
|
||||
//! usb_select_endpoint_interrupt.
|
||||
//!
|
||||
//! This function select the endpoint where an event occurs and returns the
|
||||
//! number of this endpoint. If no event occurs on the endpoints, this
|
||||
//! function returns 0.
|
||||
//!
|
||||
//! @return 0 endpoint number.
|
||||
//!
|
||||
U8 usb_select_enpoint_interrupt(void)
|
||||
{
|
||||
U8 interrupt_flags;
|
||||
U8 ep_num;
|
||||
|
||||
ep_num = 0;
|
||||
interrupt_flags = Usb_interrupt_flags();
|
||||
|
||||
while(ep_num < MAX_EP_NB)
|
||||
{
|
||||
if (interrupt_flags & 1)
|
||||
{
|
||||
return (ep_num);
|
||||
}
|
||||
else
|
||||
{
|
||||
ep_num++;
|
||||
interrupt_flags = interrupt_flags >> 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//! usb_send_packet.
|
||||
//!
|
||||
//! This function moves the data pointed by tbuf to the selected endpoint fifo
|
||||
//! and sends it through the USB.
|
||||
//!
|
||||
//!
|
||||
//! @param ep_num number of the addressed endpoint
|
||||
//! @param tbuf address of the first data to send
|
||||
//! @param data_length number of bytes to send
|
||||
//!
|
||||
//! @return remaining_length address of the next U8 to send.
|
||||
//!
|
||||
//! Example:
|
||||
//! usb_send_packet(3,&first_data,0x20); // send packet on the endpoint #3
|
||||
//! while(!(Usb_tx_complete)); // wait packet ACK'ed by the Host
|
||||
//! Usb_clear_tx_complete(); // acknowledge the transmit
|
||||
//!
|
||||
//! Note:
|
||||
//! tbuf is incremented of 'data_length'.
|
||||
//!
|
||||
U8 usb_send_packet(U8 ep_num, U8* tbuf, U8 data_length)
|
||||
{
|
||||
U8 remaining_length;
|
||||
|
||||
remaining_length = data_length;
|
||||
Usb_select_endpoint(ep_num);
|
||||
while(Is_usb_write_enabled() && (0 != remaining_length))
|
||||
{
|
||||
Usb_write_byte(*tbuf);
|
||||
remaining_length--;
|
||||
tbuf++;
|
||||
}
|
||||
return remaining_length;
|
||||
}
|
||||
|
||||
//! usb_read_packet.
|
||||
//!
|
||||
//! This function moves the data stored in the selected endpoint fifo to
|
||||
//! the address specified by *rbuf.
|
||||
//!
|
||||
//!
|
||||
//! @param ep_num number of the addressed endpoint
|
||||
//! @param rbuf aaddress of the first data to write with the USB data
|
||||
//! @param data_length number of bytes to read
|
||||
//!
|
||||
//! @return remaining_length address of the next U8 to send.
|
||||
//!
|
||||
//! Example:
|
||||
//! while(!(Usb_rx_complete)); // wait new packet received
|
||||
//! usb_read_packet(4,&first_data,usb_get_nb_byte); // read packet from ep 4
|
||||
//! Usb_clear_rx(); // acknowledge the transmit
|
||||
//!
|
||||
//! Note:
|
||||
//! rbuf is incremented of 'data_length'.
|
||||
//!
|
||||
U8 usb_read_packet(U8 ep_num, U8* rbuf, U8 data_length)
|
||||
{
|
||||
U8 remaining_length;
|
||||
|
||||
remaining_length = data_length;
|
||||
Usb_select_endpoint(ep_num);
|
||||
|
||||
while(Is_usb_read_enabled() && (0 != remaining_length))
|
||||
{
|
||||
*rbuf = Usb_read_byte();
|
||||
remaining_length--;
|
||||
rbuf++;
|
||||
}
|
||||
return remaining_length;
|
||||
}
|
||||
|
||||
//! usb_halt_endpoint.
|
||||
//!
|
||||
//! This function sends a STALL handshake for the next Host request. A STALL
|
||||
//! handshake will be send for each next request untill a SETUP or a Clear Halt
|
||||
//! Feature occurs for this endpoint.
|
||||
//!
|
||||
//! @param ep_num number of the addressed endpoint
|
||||
//!
|
||||
void usb_halt_endpoint (U8 ep_num)
|
||||
{
|
||||
Usb_select_endpoint(ep_num);
|
||||
Usb_enable_stall_handshake();
|
||||
}
|
||||
|
||||
//! usb_init_device.
|
||||
//!
|
||||
//! This function initializes the USB device controller and
|
||||
//! configures the Default Control Endpoint.
|
||||
//!
|
||||
//! @retval FALSE if not Is_usb_id_device() returns FALSE
|
||||
//! @return usb_configure_endpoint() status
|
||||
//!
|
||||
U8 usb_init_device (void)
|
||||
{
|
||||
U8 rv = FALSE;
|
||||
|
||||
Usb_select_device();
|
||||
if(Is_usb_id_device())
|
||||
{
|
||||
Usb_select_endpoint(EP_CONTROL);
|
||||
if(!Is_usb_endpoint_enabled())
|
||||
{
|
||||
#if (USB_LOW_SPEED_DEVICE==DISABLE)
|
||||
rv = usb_configure_endpoint(EP_CONTROL, \
|
||||
TYPE_CONTROL, \
|
||||
DIRECTION_OUT, \
|
||||
SIZE_64, \
|
||||
ONE_BANK, \
|
||||
NYET_DISABLED);
|
||||
#else
|
||||
rv = usb_configure_endpoint(EP_CONTROL, \
|
||||
TYPE_CONTROL, \
|
||||
DIRECTION_OUT, \
|
||||
SIZE_8, \
|
||||
ONE_BANK, \
|
||||
NYET_DISABLED);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//! ---------------------------------------------------------
|
||||
//! ------------------ HOST ---------------------------------
|
||||
//! ---------------------------------------------------------
|
||||
|
||||
#if (USB_HOST_FEATURE == ENABLED)
|
||||
|
||||
//! usb_configure_pipe.
|
||||
//!
|
||||
//! This function configures a pipe with the selected type.
|
||||
//!
|
||||
//! @param config0
|
||||
//! @param config1
|
||||
//!
|
||||
//! @return Is_endpoint_configured().
|
||||
U8 host_config_pipe(U8 config0, U8 config1)
|
||||
{
|
||||
Host_enable_pipe();
|
||||
UPCFG0X = config0;
|
||||
UPCFG1X = config1;
|
||||
Host_allocate_memory();
|
||||
return (Is_pipe_configured());
|
||||
}
|
||||
|
||||
//! host_determine_pipe_size.
|
||||
//!
|
||||
//! This function returns the size configuration register value according
|
||||
//! to the endpint size detected inthe device enumeration process.
|
||||
//!
|
||||
//! @retval SIZE_8 pipe size register value.
|
||||
//! @retval SIZE_16 pipe size register value.
|
||||
//! @retval SIZE_32 pipe size register value.
|
||||
//! @retval SIZE_64 pipe size register value.
|
||||
//! @retval SIZE_128 pipe size register value.
|
||||
//! @retval SIZE_256 pipe size register value.
|
||||
//! @retval SIZE_512 pipe size register value.
|
||||
//! @retval SIZE_1024 pipe size register value.
|
||||
//!
|
||||
U8 host_determine_pipe_size(U16 size)
|
||||
{
|
||||
if(size <= 8 ) {return (SIZE_8 );}
|
||||
else if(size <= 16 ) {return (SIZE_16 );}
|
||||
else if(size <= 32 ) {return (SIZE_32 );}
|
||||
else if(size <= 64 ) {return (SIZE_64 );}
|
||||
else if(size <= 128) {return (SIZE_128 );}
|
||||
else if(size <= 256) {return (SIZE_256 );}
|
||||
else if(size <= 512) {return (SIZE_512 );}
|
||||
else {return (SIZE_1024);}
|
||||
|
||||
}
|
||||
|
||||
//! host_disable_all_pipe.
|
||||
//!
|
||||
//! This function disable all pipes for the host controller
|
||||
//! Usefull to execute upon device disconnection.
|
||||
//!
|
||||
void host_disable_all_pipe(void)
|
||||
{
|
||||
U8 i;
|
||||
for (i=0;i<7;i++)
|
||||
{
|
||||
Host_reset_pipe(i);
|
||||
Host_select_pipe(i);
|
||||
Host_unallocate_memory();
|
||||
Host_disable_pipe();
|
||||
}
|
||||
}
|
||||
|
||||
//! @brief Returns the pipe number that generates a USB communication interrupt
|
||||
//!
|
||||
//! This function sould be called only when an interrupt has been detected. Otherwize
|
||||
//! the return value is incorect
|
||||
//!
|
||||
//! @retval MAX_EP_NB + 1 - pipe_number
|
||||
//!
|
||||
U8 usb_get_nb_pipe_interrupt(void)
|
||||
{
|
||||
U8 interrupt_flags;
|
||||
U8 i;
|
||||
|
||||
interrupt_flags = Host_get_pipe_interrupt();
|
||||
for(i=0;i< MAX_EP_NB;i++)
|
||||
{
|
||||
if (interrupt_flags & (1<<i))
|
||||
{
|
||||
return (i);
|
||||
}
|
||||
}
|
||||
// This return should never occurs ....
|
||||
return MAX_EP_NB+1;
|
||||
}
|
||||
|
||||
|
||||
#endif // USB_HOST_FEATURE == ENABLED
|
||||
|
||||
/** @} */
|
930
cpu/avr/dev/usb/usb_drv.h
Normal file
930
cpu/avr/dev/usb/usb_drv.h
Normal file
|
@ -0,0 +1,930 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file *********************************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file contains the USB driver routines.
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _USB_DRV_H_
|
||||
#define _USB_DRV_H_
|
||||
|
||||
#include "compiler.h"
|
||||
|
||||
/**
|
||||
* \addtogroup usbdriver
|
||||
* @{
|
||||
*/
|
||||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
|
||||
typedef enum endpoint_parameter{ep_num, ep_type, ep_direction, ep_size, ep_bank, nyet_status} t_endpoint_parameter;
|
||||
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
#define MAX_EP_NB 7
|
||||
|
||||
#define EP_CONTROL 0
|
||||
#define EP_1 1
|
||||
#define EP_2 2
|
||||
#define EP_3 3
|
||||
#define EP_4 4
|
||||
#define EP_5 5
|
||||
#define EP_6 6
|
||||
#define EP_7 7
|
||||
|
||||
#define PIPE_CONTROL 0
|
||||
#define PIPE_0 0
|
||||
#define PIPE_1 1
|
||||
#define PIPE_2 2
|
||||
#define PIPE_3 3
|
||||
#define PIPE_4 4
|
||||
#define PIPE_5 5
|
||||
#define PIPE_6 6
|
||||
#define PIPE_7 7
|
||||
|
||||
// USB EndPoint
|
||||
#define MSK_EP_DIR 0x7F
|
||||
#define MSK_UADD 0x7F
|
||||
#define MSK_EPTYPE 0xC0
|
||||
#define MSK_EPSIZE 0x70
|
||||
#define MSK_EPBK 0x0C
|
||||
#define MSK_DTSEQ 0x0C
|
||||
#define MSK_NBUSYBK 0x03
|
||||
#define MSK_CURRBK 0x03
|
||||
#define MSK_DAT 0xFF // UEDATX
|
||||
#define MSK_BYCTH 0x07 // UEBCHX
|
||||
#define MSK_BYCTL 0xFF // UEBCLX
|
||||
#define MSK_EPINT 0x7F // UEINT
|
||||
#define MSK_HADDR 0xFF // UHADDR
|
||||
|
||||
// USB Pipe
|
||||
#define MSK_PNUM 0x07 // UPNUM
|
||||
#define MSK_PRST 0x7F // UPRST
|
||||
#define MSK_PTYPE 0xC0 // UPCFG0X
|
||||
#define MSK_PTOKEN 0x30
|
||||
#define MSK_PEPNUM 0x0F
|
||||
#define MSK_PSIZE 0x70 // UPCFG1X
|
||||
#define MSK_PBK 0x0C
|
||||
|
||||
#define MSK_NBUSYBK 0x03
|
||||
|
||||
#define MSK_ERROR 0x1F
|
||||
|
||||
#define MSK_PTYPE 0xC0 // UPCFG0X
|
||||
#define MSK_PTOKEN 0x30
|
||||
#define MSK_TOKEN_SETUP 0x30
|
||||
#define MSK_TOKEN_IN 0x10
|
||||
#define MSK_TOKEN_OUT 0x20
|
||||
#define MSK_PEPNUM 0x0F
|
||||
|
||||
#define MSK_PSIZE 0x70 // UPCFG1X
|
||||
#define MSK_PBK 0x0C
|
||||
|
||||
|
||||
// Parameters for endpoint configuration
|
||||
// These define are the values used to enable and configure an endpoint.
|
||||
#define TYPE_CONTROL 0
|
||||
#define TYPE_ISOCHRONOUS 1
|
||||
#define TYPE_BULK 2
|
||||
#define TYPE_INTERRUPT 3
|
||||
//typedef enum ep_type {TYPE_CONTROL, TYPE_BULK, TYPE_ISOCHRONOUS, TYPE_INTERRUPT} e_ep_type;
|
||||
|
||||
#define DIRECTION_OUT 0
|
||||
#define DIRECTION_IN 1
|
||||
//typedef enum ep_dir {DIRECTION_OUT, DIRECTION_IN} e_ep_dir;
|
||||
|
||||
#define SIZE_8 0
|
||||
#define SIZE_16 1
|
||||
#define SIZE_32 2
|
||||
#define SIZE_64 3
|
||||
#define SIZE_128 4
|
||||
#define SIZE_256 5
|
||||
#define SIZE_512 6
|
||||
#define SIZE_1024 7
|
||||
//typedef enum ep_size {SIZE_8, SIZE_16, SIZE_32, SIZE_64,
|
||||
// SIZE_128, SIZE_256, SIZE_512, SIZE_1024} e_ep_size;
|
||||
|
||||
#define ONE_BANK 0
|
||||
#define TWO_BANKS 1
|
||||
//typedef enum ep_bank {ONE_BANK, TWO_BANKS} e_ep_bank;
|
||||
|
||||
#define NYET_ENABLED 0
|
||||
#define NYET_DISABLED 1
|
||||
//typedef enum ep_nyet {NYET_DISABLED, NYET_ENABLED} e_ep_nyet;
|
||||
|
||||
#define TOKEN_SETUP 0
|
||||
#define TOKEN_IN 1
|
||||
#define TOKEN_OUT 2
|
||||
|
||||
#define Is_ep_addr_in(x) ( (x&0x80)? TRUE : FALSE)
|
||||
|
||||
|
||||
//! @ingroup usbdriver
|
||||
//! @defgroup Endpoints_configuration Configuration macros for endpoints
|
||||
//! List of the standard macro used to configure pipes and endpoints
|
||||
//! @{
|
||||
#define Usb_build_ep_config0(type, dir, nyet) ((type<<6) | (nyet<<1) | (dir))
|
||||
#define Usb_build_ep_config1(size, bank ) ((size<<4) | (bank<<2) )
|
||||
#define usb_configure_endpoint(num, type, dir, size, bank, nyet) \
|
||||
( Usb_select_endpoint(num), \
|
||||
usb_config_ep(Usb_build_ep_config0(type, dir, nyet),\
|
||||
Usb_build_ep_config1(size, bank) ))
|
||||
|
||||
#define Host_build_pipe_config0(type, token, ep_num) ((type<<6) | (token<<4) | (ep_num))
|
||||
#define Host_build_pipe_config1(size, bank ) ((size<<4) | (bank<<2) )
|
||||
#define host_configure_pipe(num, type, token,ep_num, size, bank, freq) \
|
||||
( Host_select_pipe(num), \
|
||||
Host_set_interrupt_frequency(freq), \
|
||||
host_config_pipe(Host_build_pipe_config0(type, token, ep_num),\
|
||||
Host_build_pipe_config1(size, bank) ))
|
||||
//! @}
|
||||
|
||||
//! @ingroup usbdriver
|
||||
//! @defgroup USB_regulator USB Pads Regulator drivers
|
||||
//! Turns ON/OFF USB pads regulator
|
||||
//! @{
|
||||
//! Enable internal USB pads regulator
|
||||
#define Usb_enable_regulator() (UHWCON |= (1<<UVREGE))
|
||||
//! Disable internal USB pads regulator
|
||||
#define Usb_disable_regulator() (UHWCON &= ~(1<<UVREGE))
|
||||
//! Check regulator enable bit
|
||||
#define Is_usb_regulator_enabled() ((UHWCON & (1<<UVREGE)) ? TRUE : FALSE)
|
||||
//! @}
|
||||
|
||||
//! @ingroup usbdriver
|
||||
//! @defgroup gen_usb USB common management drivers
|
||||
//! These macros manage the USB controller
|
||||
//! @{
|
||||
//! Enable external UID pin
|
||||
#define Usb_enable_uid_pin() (UHWCON |= (1<<UIDE))
|
||||
//! Disable external UID pin
|
||||
#define Usb_disable_uid_pin() (UHWCON &= ~(1<<UIDE))
|
||||
//! Disable external UID pin and force device mode
|
||||
#define Usb_force_device_mode() (Usb_disable_uid_pin(), UHWCON |= (1<<UIMOD))
|
||||
//! Disable external UID pin and force host mode
|
||||
#define Usb_force_host_mode() (Usb_disable_uid_pin(), UHWCON &= ~(1<<UIMOD))
|
||||
//! Enable external UVCON pin
|
||||
#define Usb_enable_uvcon_pin() (UHWCON |= (1<<UVCONE))
|
||||
//! Enable external UVCON pin
|
||||
#define Usb_disable_uvcon_pin() (UHWCON &= ~(1<<UVCONE))
|
||||
//! Use device full speed mode (default mode)
|
||||
#define Usb_full_speed_mode() (UDCON &= ~(1<<LSM))
|
||||
//! For device mode, force low speed mode
|
||||
#define Usb_low_speed_mode() (UDCON |= (1<<LSM))
|
||||
|
||||
//! Enable both USB interface and Vbus pad
|
||||
#define Usb_enable() (USBCON |= ((1<<USBE) | (1<<OTGPADE)))
|
||||
//! Disable both USB interface and Vbus pad
|
||||
#define Usb_disable() (USBCON &= ~((1<<USBE) | (1<<OTGPADE)))
|
||||
#define Is_usb_enabled() ((USBCON & (1<<USBE)) ? TRUE : FALSE)
|
||||
|
||||
//! Enable VBUS pad
|
||||
#define Usb_enable_vbus_pad() (USBCON |= (1<<OTGPADE))
|
||||
//! Disable VBUS pad
|
||||
#define Usb_disable_vbus_pad() (USBCON &= ~(1<<OTGPADE))
|
||||
|
||||
#define Usb_select_device() (USBCON &= ~(1<<HOST))
|
||||
#define Usb_select_host() (USBCON |= (1<<HOST))
|
||||
#define Is_usb_host_enabled() ((USBCON & (1<<HOST)) ? TRUE : FALSE)
|
||||
|
||||
//! Stop internal USB clock in interface (freeze the interface register)
|
||||
#define Usb_freeze_clock() (USBCON |= (1<<FRZCLK))
|
||||
#define Usb_unfreeze_clock() (USBCON &= ~(1<<FRZCLK))
|
||||
#define Is_usb_clock_freezed() ((USBCON & (1<<FRZCLK)) ? TRUE : FALSE)
|
||||
|
||||
#define Usb_enable_id_interrupt() (USBCON |= (1<<IDTE))
|
||||
#define Usb_disable_id_interrupt() (USBCON &= ~(1<<IDTE))
|
||||
#define Is_usb_id_interrupt_enabled() ((USBCON & (1<<IDTE)) ? TRUE : FALSE)
|
||||
#define Is_usb_id_device() ((USBSTA & (1<<ID)) ? TRUE : FALSE)
|
||||
#define Usb_ack_id_transition() (USBINT = ~(1<<IDTI))
|
||||
#define Is_usb_id_transition() ((USBINT & (1<<IDTI)) ? TRUE : FALSE)
|
||||
|
||||
#define Usb_enable_vbus_interrupt() (USBCON |= (1<<VBUSTE))
|
||||
#define Usb_disable_vbus_interrupt() (USBCON &= ~(1<<VBUSTE))
|
||||
#define Is_usb_vbus_interrupt_enabled() ((USBCON & (1<<VBUSTE)) ? TRUE : FALSE)
|
||||
#define Is_usb_vbus_high() ((USBSTA & (1<<VBUS)) ? TRUE : FALSE)
|
||||
#define Is_usb_vbus_low() ((USBSTA & (1<<VBUS)) ? FALSE : TRUE)
|
||||
#define Usb_ack_vbus_transition() (USBINT = ~(1<<VBUSTI))
|
||||
#define Is_usb_vbus_transition() ((USBINT & (1<<VBUSTI)) ? TRUE : FALSE)
|
||||
|
||||
//! returns the USB general interrupts (interrupt enabled)
|
||||
#define Usb_get_general_interrupt() (USBINT & (USBCON & MSK_IDTE_VBUSTE))
|
||||
//! acks the general interrupts (interrupt enabled)
|
||||
#define Usb_ack_all_general_interrupt() (USBINT = ~(USBCON & MSK_IDTE_VBUSTE))
|
||||
#define Usb_ack_cache_id_transition(x) ((x) &= ~(1<<IDTI))
|
||||
#define Usb_ack_cache_vbus_transition(x) ((x) &= ~(1<<VBUSTI))
|
||||
#define Is_usb_cache_id_transition(x) (((x) & (1<<IDTI)) )
|
||||
#define Is_usb_cache_vbus_transition(x) (((x) & (1<<VBUSTI)))
|
||||
|
||||
//! returns the USB Pad interrupts (interrupt enabled)
|
||||
#define Usb_get_otg_interrupt() (OTGINT & OTGIEN)
|
||||
//! acks the USB Pad interrupts (interrupt enabled)
|
||||
#define Usb_ack_all_otg_interrupt() (OTGINT = ~OTGIEN)
|
||||
#define Is_otg_cache_bconnection_error(x) (((x) & MSK_BCERRI))
|
||||
#define Usb_ack_cache_bconnection_error(x) ((x) &= ~MSK_BCERRI)
|
||||
|
||||
#define Usb_enter_dpram_mode() (UDPADDH = (1<<DPACC))
|
||||
#define Usb_exit_dpram_mode() (UDPADDH = (U8)~(1<<DPACC))
|
||||
#define Usb_set_dpram_address(addr) (UDPADDH = (1<<DPACC) + ((Uint16)addr >> 8), UDPADDL = (Uchar)addr)
|
||||
#define Usb_write_dpram_byte(val) (UEDATX=val)
|
||||
#define Usb_read_dpram_byte() (UEDATX)
|
||||
|
||||
//! requests for VBus activation
|
||||
#define Usb_enable_vbus() (OTGCON |= (1<<VBUSREQ))
|
||||
//! requests for VBus desactivation
|
||||
#define Usb_disable_vbus() (OTGCON |= (1<<VBUSRQC))
|
||||
//! Manually request VBUS without UVCON signal from USB interface
|
||||
#define Usb_enable_manual_vbus() (PORTE|=0x80,DDRE|=0x80,Usb_disable_uvcon_pin())
|
||||
|
||||
//! initiates a Host Negociation Protocol
|
||||
#define Usb_device_initiate_hnp() (OTGCON |= (1<<HNPREQ))
|
||||
//! accepts a Host Negociation Protocol
|
||||
#define Usb_host_accept_hnp() (OTGCON |= (1<<HNPREQ))
|
||||
//! rejects a Host Negociation Protocol
|
||||
#define Usb_host_reject_hnp() (OTGCON &= ~(1<<HNPREQ))
|
||||
//! initiates a Session Request Protocol
|
||||
#define Usb_device_initiate_srp() (OTGCON |= (1<<SRPREQ))
|
||||
//! selects VBus as SRP method
|
||||
#define Usb_select_vbus_srp_method() (OTGCON |= (1<<SRPSEL))
|
||||
//! selects data line as SRP method
|
||||
#define Usb_select_data_srp_method() (OTGCON &= ~(1<<SRPSEL))
|
||||
//! enables hardware control on VBus
|
||||
#define Usb_enable_vbus_hw_control() (OTGCON &= ~(1<<VBUSHWC))
|
||||
//! disables hardware control on VBus
|
||||
#define Usb_disable_vbus_hw_control() (OTGCON |= (1<<VBUSHWC))
|
||||
//! tests if VBus has been requested
|
||||
#define Is_usb_vbus_enabled() ((OTGCON & (1<<VBUSREQ)) ? TRUE : FALSE)
|
||||
//! tests if a HNP occurs
|
||||
#define Is_usb_hnp() ((OTGCON & (1<<HNPREQ)) ? TRUE : FALSE)
|
||||
//! tests if a SRP from device occurs
|
||||
#define Is_usb_device_srp() ((OTGCON & (1<<SRPREQ)) ? TRUE : FALSE)
|
||||
|
||||
//! enables suspend time out interrupt
|
||||
#define Usb_enable_suspend_time_out_interrupt() (OTGIEN |= (1<<STOE))
|
||||
//! disables suspend time out interrupt
|
||||
#define Usb_disable_suspend_time_out_interrupt() (OTGIEN &= ~(1<<STOE))
|
||||
#define Is_suspend_time_out_interrupt_enabled() ((OTGIEN & (1<<STOE)) ? TRUE : FALSE)
|
||||
//! acks suspend time out interrupt
|
||||
#define Usb_ack_suspend_time_out_interrupt() (OTGINT &= ~(1<<STOI))
|
||||
//! tests if a suspend time out occurs
|
||||
#define Is_usb_suspend_time_out_interrupt() ((OTGINT & (1<<STOI)) ? TRUE : FALSE)
|
||||
|
||||
//! enables HNP error interrupt
|
||||
#define Usb_enable_hnp_error_interrupt() (OTGIEN |= (1<<HNPERRE))
|
||||
//! disables HNP error interrupt
|
||||
#define Usb_disable_hnp_error_interrupt() (OTGIEN &= ~(1<<HNPERRE))
|
||||
#define Is_hnp_error_interrupt_enabled() ((OTGIEN & (1<<HNPERRE)) ? TRUE : FALSE)
|
||||
//! acks HNP error interrupt
|
||||
#define Usb_ack_hnp_error_interrupt() (OTGINT &= ~(1<<HNPERRI))
|
||||
//! tests if a HNP error occurs
|
||||
#define Is_usb_hnp_error_interrupt() ((OTGINT & (1<<HNPERRI)) ? TRUE : FALSE)
|
||||
|
||||
//! enables role exchange interrupt
|
||||
#define Usb_enable_role_exchange_interrupt() (OTGIEN |= (1<<ROLEEXE))
|
||||
//! disables role exchange interrupt
|
||||
#define Usb_disable_role_exchange_interrupt() (OTGIEN &= ~(1<<ROLEEXE))
|
||||
#define Is_role_exchange_interrupt_enabled() ((OTGIEN & (1<<ROLEEXE)) ? TRUE : FALSE)
|
||||
//! acks role exchange interrupt
|
||||
#define Usb_ack_role_exchange_interrupt() (OTGINT &= ~(1<<ROLEEXI))
|
||||
//! tests if a role exchange occurs
|
||||
#define Is_usb_role_exchange_interrupt() ((OTGINT & (1<<ROLEEXI)) ? TRUE : FALSE)
|
||||
|
||||
//! enables B device connection error interrupt
|
||||
#define Usb_enable_bconnection_error_interrupt() (OTGIEN |= (1<<BCERRE))
|
||||
//! disables B device connection error interrupt
|
||||
#define Usb_disable_bconnection_error_interrupt() (OTGIEN &= ~(1<<BCERRE))
|
||||
#define Is_bconnection_error_interrupt_enabled() ((OTGIEN & (1<<BCERRE)) ? TRUE : FALSE)
|
||||
//! acks B device connection error interrupt
|
||||
#define Usb_ack_bconnection_error_interrupt() (OTGINT &= ~(1<<BCERRI))
|
||||
//! tests if a B device connection error occurs
|
||||
#define Is_usb_bconnection_error_interrupt() ((OTGINT & (1<<BCERRI)) ? TRUE : FALSE)
|
||||
|
||||
//! enables VBus error interrupt
|
||||
#define Usb_enable_vbus_error_interrupt() (OTGIEN |= (1<<VBERRE))
|
||||
//! disables VBus error interrupt
|
||||
#define Usb_disable_vbus_error_interrupt() (OTGIEN &= ~(1<<VBERRE))
|
||||
#define Is_vbus_error_interrupt_enabled() ((OTGIEN & (1<<VBERRE)) ? TRUE : FALSE)
|
||||
//! acks VBus error interrupt
|
||||
#define Usb_ack_vbus_error_interrupt() (OTGINT &= ~(1<<VBERRI))
|
||||
//! tests if a VBus error occurs
|
||||
#define Is_usb_vbus_error_interrupt() ((OTGINT & (1<<VBERRI)) ? TRUE : FALSE)
|
||||
|
||||
//! enables SRP interrupt
|
||||
#define Usb_enable_srp_interrupt() (OTGIEN |= (1<<SRPE))
|
||||
//! disables SRP interrupt
|
||||
#define Usb_disable_srp_interrupt() (OTGIEN &= ~(1<<SRPE))
|
||||
#define Is_srp_interrupt_enabled() ((OTGIEN & (1<<SRPE)) ? TRUE : FALSE)
|
||||
//! acks SRP interrupt
|
||||
#define Usb_ack_srp_interrupt() (OTGINT &= ~(1<<SRPI))
|
||||
//! tests if a SRP occurs
|
||||
#define Is_usb_srp_interrupt() ((OTGINT & (1<<SRPI)) ? TRUE : FALSE)
|
||||
//! @}
|
||||
|
||||
//! @ingroup usbdriver
|
||||
//! @defgroup USB_device_driver USB device controller drivers
|
||||
//! These macros manage the USB Device controller.
|
||||
//! @{
|
||||
//! initiates a remote wake-up
|
||||
#define Usb_initiate_remote_wake_up() (UDCON |= (1<<RMWKUP))
|
||||
//! detaches from USB bus
|
||||
#define Usb_detach() (UDCON |= (1<<DETACH))
|
||||
//! attaches to USB bus
|
||||
#define Usb_attach() (UDCON &= ~(1<<DETACH))
|
||||
//! test if remote wake-up still running
|
||||
#define Is_usb_pending_remote_wake_up() ((UDCON & (1<<RMWKUP)) ? TRUE : FALSE)
|
||||
//! test if the device is detached
|
||||
#define Is_usb_detached() ((UDCON & (1<<DETACH)) ? TRUE : FALSE)
|
||||
|
||||
//! returns the USB device interrupts (interrupt enabled)
|
||||
#define Usb_get_device_interrupt() (UDINT & (1<<UDIEN))
|
||||
//! acks the USB device interrupts (interrupt enabled)
|
||||
#define Usb_ack_all_device_interrupt() (UDINT = ~(1<<UDIEN))
|
||||
|
||||
//! enables remote wake-up interrupt
|
||||
#define Usb_enable_remote_wake_up_interrupt() (UDIEN |= (1<<UPRSME))
|
||||
//! disables remote wake-up interrupt
|
||||
#define Usb_disable_remote_wake_up_interrupt() (UDIEN &= ~(1<<UPRSME))
|
||||
#define Is_remote_wake_up_interrupt_enabled() ((UDIEN & (1<<UPRSME)) ? TRUE : FALSE)
|
||||
//! acks remote wake-up
|
||||
#define Usb_ack_remote_wake_up_start() (UDINT = ~(1<<UPRSMI))
|
||||
//! tests if remote wake-up still running
|
||||
#define Is_usb_remote_wake_up_start() ((UDINT & (1<<UPRSMI)) ? TRUE : FALSE)
|
||||
|
||||
//! enables resume interrupt
|
||||
#define Usb_enable_resume_interrupt() (UDIEN |= (1<<EORSME))
|
||||
//! disables resume interrupt
|
||||
#define Usb_disable_resume_interrupt() (UDIEN &= ~(1<<EORSME))
|
||||
#define Is_resume_interrupt_enabled() ((UDIEN & (1<<EORSME)) ? TRUE : FALSE)
|
||||
//! acks resume
|
||||
#define Usb_ack_resume() (UDINT = ~(1<<EORSMI))
|
||||
//! tests if resume occurs
|
||||
#define Is_usb_resume() ((UDINT & (1<<EORSMI)) ? TRUE : FALSE)
|
||||
|
||||
//! enables wake-up interrupt
|
||||
#define Usb_enable_wake_up_interrupt() (UDIEN |= (1<<WAKEUPE))
|
||||
//! disables wake-up interrupt
|
||||
#define Usb_disable_wake_up_interrupt() (UDIEN &= ~(1<<WAKEUPE))
|
||||
#define Is_swake_up_interrupt_enabled() ((UDIEN & (1<<WAKEUPE)) ? TRUE : FALSE)
|
||||
//! acks wake-up
|
||||
#define Usb_ack_wake_up() (UDINT = ~(1<<WAKEUPI))
|
||||
//! tests if wake-up occurs
|
||||
#define Is_usb_wake_up() ((UDINT & (1<<WAKEUPI)) ? TRUE : FALSE)
|
||||
|
||||
//! enables USB reset interrupt
|
||||
#define Usb_enable_reset_interrupt() (UDIEN |= (1<<EORSTE))
|
||||
//! disables USB reset interrupt
|
||||
#define Usb_disable_reset_interrupt() (UDIEN &= ~(1<<EORSTE))
|
||||
#define Is_reset_interrupt_enabled() ((UDIEN & (1<<EORSTE)) ? TRUE : FALSE)
|
||||
//! acks USB reset
|
||||
#define Usb_ack_reset() (UDINT = ~(1<<EORSTI))
|
||||
//! tests if USB reset occurs
|
||||
#define Is_usb_reset() ((UDINT & (1<<EORSTI)) ? TRUE : FALSE)
|
||||
|
||||
//! enables Start Of Frame Interrupt
|
||||
#define Usb_enable_sof_interrupt() (UDIEN |= (1<<SOFE))
|
||||
//! disables Start Of Frame Interrupt
|
||||
#define Usb_disable_sof_interrupt() (UDIEN &= ~(1<<SOFE))
|
||||
#define Is_sof_interrupt_enabled() ((UDIEN & (1<<SOFE)) ? TRUE : FALSE)
|
||||
//! acks Start Of Frame
|
||||
#define Usb_ack_sof() (UDINT = ~(1<<SOFI))
|
||||
//! tests if Start Of Frame occurs
|
||||
#define Is_usb_sof() ((UDINT & (1<<SOFI)) ? TRUE : FALSE)
|
||||
|
||||
//! enables suspend state interrupt
|
||||
#define Usb_enable_suspend_interrupt() (UDIEN |= (1<<SUSPE))
|
||||
//! disables suspend state interrupt
|
||||
#define Usb_disable_suspend_interrupt() (UDIEN &= ~(1<<SUSPE))
|
||||
#define Is_suspend_interrupt_enabled() ((UDIEN & (1<<SUSPE)) ? TRUE : FALSE)
|
||||
//! acks Suspend
|
||||
#define Usb_ack_suspend() (UDINT = ~(1<<SUSPI))
|
||||
//! tests if Suspend state detected
|
||||
#define Is_usb_suspend() ((UDINT & (1<<SUSPI)) ? TRUE : FALSE)
|
||||
|
||||
//! enables USB device address
|
||||
#define Usb_enable_address() (UDADDR |= (1<<ADDEN))
|
||||
//! disables USB device address
|
||||
#define Usb_disable_address() (UDADDR &= ~(1<<ADDEN))
|
||||
//! sets the USB device address
|
||||
#define Usb_configure_address(addr) (UDADDR = (UDADDR & (1<<ADDEN)) | ((U8)addr & MSK_UADD))
|
||||
|
||||
//! returns the last frame number
|
||||
#define Usb_frame_number() ((U16)((((U16)UDFNUMH) << 8) | ((U16)UDFNUML)))
|
||||
//! tests if a crc error occurs in frame number
|
||||
#define Is_usb_frame_number_crc_error() ((UDMFN & (1<<FNCERR)) ? TRUE : FALSE)
|
||||
//! @}
|
||||
|
||||
|
||||
|
||||
//! @ingroup usbdriver
|
||||
//! @defgroup usb_gen_ep USB endpoint drivers
|
||||
//! These macros manage the common features of the endpoints.
|
||||
//! @{
|
||||
//! selects the endpoint number to interface with the CPU
|
||||
#define Usb_select_endpoint(ep) (UENUM = (U8)ep )
|
||||
|
||||
//! get the currently selected endpoint number
|
||||
#define Usb_get_selected_endpoint() (UENUM )
|
||||
|
||||
//! resets the selected endpoint
|
||||
#define Usb_reset_endpoint(ep) (UERST = 1 << (U8)ep, UERST = 0)
|
||||
|
||||
//! enables the current endpoint
|
||||
#define Usb_enable_endpoint() (UECONX |= (1<<EPEN))
|
||||
//! enables the STALL handshake for the next transaction
|
||||
#define Usb_enable_stall_handshake() (UECONX |= (1<<STALLRQ))
|
||||
//! resets the data toggle sequence
|
||||
#define Usb_reset_data_toggle() (UECONX |= (1<<RSTDT))
|
||||
//! disables the current endpoint
|
||||
#define Usb_disable_endpoint() (UECONX &= ~(1<<EPEN))
|
||||
//! disables the STALL handshake
|
||||
#define Usb_disable_stall_handshake() (UECONX |= (1<<STALLRQC))
|
||||
//! selects endpoint interface on CPU
|
||||
#define Usb_select_epnum_for_cpu() (UECONX &= ~(1<<EPNUMS))
|
||||
//! tests if the current endpoint is enabled
|
||||
#define Is_usb_endpoint_enabled() ((UECONX & (1<<EPEN)) ? TRUE : FALSE)
|
||||
//! tests if STALL handshake request is running
|
||||
#define Is_usb_endpoint_stall_requested() ((UECONX & (1<<STALLRQ)) ? TRUE : FALSE)
|
||||
|
||||
//! configures the current endpoint
|
||||
#define Usb_configure_endpoint_type(type) (UECFG0X = (UECFG0X & ~(MSK_EPTYPE)) | ((U8)type << 6))
|
||||
//! configures the current endpoint direction
|
||||
#define Usb_configure_endpoint_direction(dir) (UECFG0X = (UECFG0X & ~(1<<EPDIR)) | ((U8)dir))
|
||||
|
||||
//! configures the current endpoint size
|
||||
#define Usb_configure_endpoint_size(size) (UECFG1X = (UECFG1X & ~MSK_EPSIZE) | ((U8)size << 4))
|
||||
//! configures the current endpoint number of banks
|
||||
#define Usb_configure_endpoint_bank(bank) (UECFG1X = (UECFG1X & ~MSK_EPBK) | ((U8)bank << 2))
|
||||
//! allocates the current configuration in DPRAM memory
|
||||
#define Usb_allocate_memory() (UECFG1X |= (1<<ALLOC))
|
||||
//! un-allocates the current configuration in DPRAM memory
|
||||
#define Usb_unallocate_memory() (UECFG1X &= ~(1<<ALLOC))
|
||||
|
||||
//! acks endpoint overflow interrupt
|
||||
#define Usb_ack_overflow_interrupt() (UESTA0X &= ~(1<<OVERFI))
|
||||
//! acks endpoint underflow memory
|
||||
#define Usb_ack_underflow_interrupt() (UESTA0X &= ~(1<<UNDERFI))
|
||||
//! acks Zero Length Packet received
|
||||
#define Usb_ack_zlp() (UESTA0X &= ~(1<<ZLPSEEN))
|
||||
//! returns data toggle
|
||||
#define Usb_data_toggle() ((UESTA0X&MSK_DTSEQ) >> 2)
|
||||
//! returns the number of busy banks
|
||||
#define Usb_nb_busy_bank() (UESTA0X & MSK_NBUSYBK)
|
||||
//! tests if at least one bank is busy
|
||||
#define Is_usb_one_bank_busy() ((UESTA0X & MSK_NBUSYBK) == 0 ? FALSE : TRUE)
|
||||
//! tests if current endpoint is configured
|
||||
#define Is_endpoint_configured() ((UESTA0X & (1<<CFGOK)) ? TRUE : FALSE)
|
||||
//! tests if an overflows occurs
|
||||
#define Is_usb_overflow() ((UESTA0X & (1<<OVERFI)) ? TRUE : FALSE)
|
||||
//! tests if an underflow occurs
|
||||
#define Is_usb_underflow() ((UESTA0X & (1<<UNDERFI)) ? TRUE : FALSE)
|
||||
//! tests if a ZLP has been detected
|
||||
#define Is_usb_zlp() ((UESTA0X & (1<<ZLPSEEN)) ? TRUE : FALSE)
|
||||
|
||||
//! returns the control direction
|
||||
#define Usb_control_direction() ((UESTA1X & (1<<CTRLDIR)) >> 2)
|
||||
//! returns the number of the current bank
|
||||
#define Usb_current_bank() ( UESTA1X & MSK_CURRBK)
|
||||
|
||||
//! clears FIFOCON bit
|
||||
#define Usb_ack_fifocon() (UEINTX &= ~(1<<FIFOCON))
|
||||
//! acks NAK IN received
|
||||
#define Usb_ack_nak_in() (UEINTX &= ~(1<<NAKINI))
|
||||
//! acks NAK OUT received
|
||||
#define Usb_ack_nak_out() (UEINTX &= ~(1<<NAKOUTI))
|
||||
//! acks receive SETUP
|
||||
#define Usb_ack_receive_setup() (UEINTX &= ~(1<<RXSTPI))
|
||||
//! acks reveive OUT
|
||||
#define Usb_ack_receive_out() (UEINTX &= ~(1<<RXOUTI), Usb_ack_fifocon())
|
||||
//! acks STALL sent
|
||||
#define Usb_ack_stalled() (MSK_STALLEDI= 0)
|
||||
//! acks IN ready
|
||||
#define Usb_ack_in_ready() (UEINTX &= ~(1<<TXINI), Usb_ack_fifocon())
|
||||
//! Kills last bank
|
||||
#define Usb_kill_last_in_bank() (UENTTX |= (1<<RXOUTI))
|
||||
//! tests if endpoint read allowed
|
||||
#define Is_usb_read_enabled() (UEINTX&(1<<RWAL))
|
||||
//! tests if endpoint write allowed
|
||||
#define Is_usb_write_enabled() (UEINTX&(1<<RWAL))
|
||||
//! tests if read allowed on control endpoint
|
||||
#define Is_usb_read_control_enabled() (UEINTX&(1<<TXINI))
|
||||
//! tests if SETUP received
|
||||
#define Is_usb_receive_setup() (UEINTX&(1<<RXSTPI))
|
||||
//! tests if OUT received
|
||||
#define Is_usb_receive_out() (UEINTX&(1<<RXOUTI))
|
||||
//! tests if IN ready
|
||||
#define Is_usb_in_ready() (UEINTX&(1<<TXINI))
|
||||
//! sends IN
|
||||
#define Usb_send_in() (UEINTX &= ~(1<<FIFOCON))
|
||||
//! sends IN on control endpoint
|
||||
#define Usb_send_control_in() (UEINTX &= ~(1<<TXINI))
|
||||
//! frees OUT bank
|
||||
#define Usb_free_out_bank() (UEINTX &= ~(1<<FIFOCON))
|
||||
//! acks OUT on control endpoint
|
||||
#define Usb_ack_control_out() (UEINTX &= ~(1<<RXOUTI))
|
||||
|
||||
//! enables flow error interrupt
|
||||
#define Usb_enable_flow_error_interrupt() (UEIENX |= (1<<FLERRE))
|
||||
//! enables NAK IN interrupt
|
||||
#define Usb_enable_nak_in_interrupt() (UEIENX |= (1<<NAKINE))
|
||||
//! enables NAK OUT interrupt
|
||||
#define Usb_enable_nak_out_interrupt() (UEIENX |= (1<<NAKOUTE))
|
||||
//! enables receive SETUP interrupt
|
||||
#define Usb_enable_receive_setup_interrupt() (UEIENX |= (1<<RXSTPE))
|
||||
//! enables receive OUT interrupt
|
||||
#define Usb_enable_receive_out_interrupt() (UEIENX |= (1<<RXOUTE))
|
||||
//! enables STALL sent interrupt
|
||||
#define Usb_enable_stalled_interrupt() (UEIENX |= (1<<STALLEDE))
|
||||
//! enables IN ready interrupt
|
||||
#define Usb_enable_in_ready_interrupt() (UEIENX |= (1<<TXINE))
|
||||
//! disables flow error interrupt
|
||||
#define Usb_disable_flow_error_interrupt() (UEIENX &= ~(1<<FLERRE))
|
||||
//! disables NAK IN interrupt
|
||||
#define Usb_disable_nak_in_interrupt() (UEIENX &= ~(1<<NAKINE))
|
||||
//! disables NAK OUT interrupt
|
||||
#define Usb_disable_nak_out_interrupt() (UEIENX &= ~(1<<NAKOUTE))
|
||||
//! disables receive SETUP interrupt
|
||||
#define Usb_disable_receive_setup_interrupt() (UEIENX &= ~(1<<RXSTPE))
|
||||
//! disables receive OUT interrupt
|
||||
#define Usb_disable_receive_out_interrupt() (UEIENX &= ~(1<<RXOUTE))
|
||||
//! disables STALL sent interrupt
|
||||
#define Usb_disable_stalled_interrupt() (UEIENX &= ~(1<<STALLEDE))
|
||||
//! disables IN ready interrupt
|
||||
#define Usb_disable_in_ready_interrupt() (UEIENX &= ~(1<<TXIN))
|
||||
|
||||
//! returns FIFO byte for current endpoint
|
||||
#define Usb_read_byte() (UEDATX)
|
||||
//! writes byte in FIFO for current endpoint
|
||||
#define Usb_write_byte(byte) (UEDATX = (U8)byte)
|
||||
|
||||
//! returns number of bytes in FIFO current endpoint (16 bits)
|
||||
#define Usb_byte_counter() ((((U16)UEBCHX) << 8) | (UEBCLX))
|
||||
//! returns number of bytes in FIFO current endpoint (8 bits)
|
||||
#define Usb_byte_counter_8() ((U8)UEBCLX)
|
||||
|
||||
//! tests the general endpoint interrupt flags
|
||||
#define Usb_interrupt_flags() (UEINT)
|
||||
//! tests the general endpoint interrupt flags
|
||||
#define Is_usb_endpoint_event() (Usb_interrupt_flags() != 0x00)
|
||||
//! @}
|
||||
|
||||
|
||||
//! @ingroup usbdriver
|
||||
//! @defgroup host_management USB host controller drivers
|
||||
//! These macros manage the USB Host controller.
|
||||
//! @{
|
||||
//! allocates the current configuration in DPRAM memory
|
||||
#define Host_allocate_memory() (UPCFG1X |= (1<<ALLOC))
|
||||
//! un-allocates the current configuration in DPRAM memory
|
||||
#define Host_unallocate_memory() (UPCFG1X &= ~(1<<ALLOC))
|
||||
|
||||
//! enables USB Host function
|
||||
#define Host_enable() (USBCON |= (1<<HOST))
|
||||
|
||||
#ifndef SOFEN
|
||||
#define SOFEN 0 //For AVRGCC, SOFEN bit missing in default sfr file
|
||||
#endif
|
||||
//! enables SOF generation
|
||||
#define Host_enable_sof() (UHCON |= (1<<SOFEN))
|
||||
//! disables SOF generation
|
||||
#define Host_disable_sof() (UHCON &= ~(1<<SOFEN))
|
||||
//! sends a USB Reset to the device
|
||||
#define Host_send_reset() (UHCON |= (1<<RESET))
|
||||
//! tests if USB Reset running
|
||||
#define Host_is_reset() ((UHCON & (1<<RESET)) ? TRUE : FALSE)
|
||||
//! sends a USB Resume to the device
|
||||
#define Host_send_resume() (UHCON |= (1<<RESUME))
|
||||
//! tests if USB Resume running
|
||||
#define Host_is_resume() ((UHCON & (1<<RESUME)) ? TRUE : FALSE)
|
||||
|
||||
//! enables host start of frame interrupt
|
||||
#define Host_enable_sof_interrupt() (UHIEN |= (1<<HSOFE))
|
||||
//! enables host start of frame interrupt
|
||||
#define Host_disable_sof_interrupt() (UHIEN &= ~(1<<HSOFE))
|
||||
#define Is_host_sof_interrupt_enabled() ((UHIEN & (1<<HSOFE)) ? TRUE : FALSE)
|
||||
//! tests if SOF detected
|
||||
#define Host_is_sof() ((UHINT & (1<<HSOFI)) ? TRUE : FALSE)
|
||||
#define Is_host_sof() ((UHINT & (1<<HSOFI)) ? TRUE : FALSE)
|
||||
#define Host_ack_sof() (UHINT &= ~(1<<HSOFI))
|
||||
|
||||
//! enables host wake up interrupt detection
|
||||
#define Host_enable_hwup_interrupt() (UHIEN |= (1<<HWUPE))
|
||||
//! disables host wake up interrupt detection
|
||||
#define Host_disable_hwup_interrupt() (UHIEN &= ~(1<<HWUPE))
|
||||
#define Is_host_hwup_interrupt_enabled() ((UHIEN & (1<<HWUPE)) ? TRUE : FALSE)
|
||||
//! tests if host wake up detected
|
||||
#define Host_is_hwup() ((UHINT & (1<<HWUPI)) ? TRUE : FALSE)
|
||||
//! Ack host wake up detection
|
||||
#define Is_host_hwup() ((UHINT & (1<<HWUPI)) ? TRUE : FALSE)
|
||||
#define Host_ack_hwup() (UHINT &= ~(1<<HWUPI))
|
||||
|
||||
//! enables host down stream rsm sent interrupt detection
|
||||
#define Host_enable_down_stream_resume_interrupt() (UHIEN |= (1<<RSMEDE))
|
||||
//! disables host down stream rsm sent interrupt detection
|
||||
#define Host_disable_down_stream_resume_interrupt() (UHIEN &= ~(1<<RSMEDE))
|
||||
#define Is_host_down_stream_resume_interrupt_enabled() ((UHIEN & (1<<RSMEDE)) ? TRUE : FALSE)
|
||||
//! Ack host down stream resume sent
|
||||
#define Is_host_down_stream_resume() ((UHINT & (1<<RSMEDI)) ? TRUE : FALSE)
|
||||
#define Host_ack_down_stream_resume() (UHINT &= ~(1<<RSMEDI))
|
||||
|
||||
//! enables host remote wake up interrupt detection
|
||||
#define Host_enable_remote_wakeup_interrupt() (UHIEN |= (1<<RXRSME))
|
||||
//! disables host remote wake up interrupt detection
|
||||
#define Host_disable_remote_wakeup_interrupt() (UHIEN &= ~(1<<RXRSME))
|
||||
#define Is_host_remote_wakeup_interrupt_enabled() ((UHIEN & (1<<RXRSME)) ? TRUE : FALSE)
|
||||
//! tests if host wake up detected
|
||||
#define Host_is_remote_wakeup() ((UHINT & (1<<RXRSMI)) ? TRUE : FALSE)
|
||||
//! Ack host wake up detection
|
||||
#define Is_host_remote_wakeup() ((UHINT & (1<<RXRSMI)) ? TRUE : FALSE)
|
||||
#define Host_ack_remote_wakeup() (UHINT &= ~(1<<RXRSMI))
|
||||
|
||||
//! enables host device connection interrupt
|
||||
#define Host_enable_device_connection_interrupt() (UHIEN |= (1<<DCONNE))
|
||||
//! disables USB device connection interrupt
|
||||
#define Host_disable_device_connection_interrupt() (UHIEN &= ~(1<<DCONNE))
|
||||
#define Is_host_device_connection_interrupt_enabled() ((UHIEN & (1<<DCONNE)) ? TRUE : FALSE)
|
||||
//! tests if a USB device has been detected
|
||||
#define Is_device_connection() (UHINT & (1<<DCONNI))
|
||||
//! acks device connection
|
||||
#define Host_ack_device_connection() (UHINT = ~(1<<DCONNI))
|
||||
|
||||
//! enables host device disconnection interrupt
|
||||
#define Host_enable_device_disconnection_interrupt() (UHIEN |= (1<<DDISCE))
|
||||
//! disables USB device connection interrupt
|
||||
#define Host_disable_device_disconnection_interrupt() (UHIEN &= ~(1<<DDISCE))
|
||||
#define Is_host_device_disconnection_interrupt_enabled() ((UHIEN & (1<<DDISCE)) ? TRUE : FALSE)
|
||||
//! tests if a USB device has been removed
|
||||
#define Is_device_disconnection() (UHINT & (1<<DDISCI) ? TRUE : FALSE)
|
||||
//! acks device disconnection
|
||||
#define Host_ack_device_disconnection() (UHINT = ~(1<<DDISCI))
|
||||
|
||||
//! enables host USB reset interrupt
|
||||
#define Host_enable_reset_interrupt() (UHIEN |= (1<<RSTE))
|
||||
//! disables host USB reset interrupt
|
||||
#define Host_disable_reset_interrupt() (UHIEN &= ~(1<<RSTE))
|
||||
#define Is_host_reset_interrupt_enabled() ((UHIEN & (1<<RSTE)) ? TRUE : FALSE)
|
||||
//! acks host USB reset sent
|
||||
#define Host_ack_reset() (UHINT = ~(1<<RSTI))
|
||||
//! tests if USB reset has been sent
|
||||
#define Is_host_reset() Host_is_reset()
|
||||
|
||||
|
||||
//! switches on VBus
|
||||
#define Host_vbus_request() (OTGCON |= (1<<VBUSREQ))
|
||||
//! switches off VBus
|
||||
#define Host_clear_vbus_request() (OTGCON |= (1<<VBUSRQC))
|
||||
//! configures the address to use for the device
|
||||
#define Host_configure_address(addr) (UHADDR = addr & MSK_HADDR)
|
||||
|
||||
//! Get connected device speed, returns TRUE when in full speed mode
|
||||
#define Is_host_full_speed() ((USBSTA & (1<<SPEED)) ? TRUE : FALSE)
|
||||
//! @}
|
||||
|
||||
|
||||
//! @ingroup usbdriver
|
||||
//! @defgroup general_pipe USB pipe drivers
|
||||
//! These macros manage the common features of the pipes.
|
||||
//! @{
|
||||
//! selects pipe for CPU interface
|
||||
#define Host_select_pipe(p) (UPNUM = (U8)p)
|
||||
|
||||
//! get the currently selected pipe number
|
||||
#define Host_get_selected_pipe() (UPNUM )
|
||||
|
||||
//! enables pipe
|
||||
#define Host_enable_pipe() (UPCONX |= (1<<PEN))
|
||||
//! disables pipe
|
||||
#define Host_disable_pipe() (UPCONX &= ~(1<<PEN))
|
||||
|
||||
//! sets SETUP token
|
||||
#define Host_set_token_setup() (UPCFG0X = UPCFG0X & ~MSK_TOKEN_SETUP)
|
||||
//! sets IN token
|
||||
#define Host_set_token_in() (UPCFG0X = (UPCFG0X & ~MSK_TOKEN_SETUP) | MSK_TOKEN_IN)
|
||||
//! sets OUT token
|
||||
#define Host_set_token_out() (UPCFG0X = (UPCFG0X & ~MSK_TOKEN_SETUP) | MSK_TOKEN_OUT)
|
||||
|
||||
//! returns the number of the endpoint associated to the current pipe
|
||||
#define Host_get_endpoint_number() (UPCFG0X & (MSK_PEPNUM))
|
||||
|
||||
//! returns pipe interrupt register
|
||||
#define Host_get_pipe_interrupt() (UPINT)
|
||||
|
||||
//! sets the interrupt frequency
|
||||
#define Host_set_interrupt_frequency(frq) (UPCFG2X = (U8)frq)
|
||||
|
||||
//! tests if current pipe is configured
|
||||
#define Is_pipe_configured() (UPSTAX & (1<<CFGOK))
|
||||
//! tests if at least one bank is busy
|
||||
#define Is_host_one_bank_busy() ((UPSTAX & (1<<MSK_NBUSYBK)) != 0)
|
||||
//! returns the number of busy banks
|
||||
#define Host_number_of_busy_bank() (UPSTAX & (1<<MSK_NBUSYBK))
|
||||
|
||||
//! resets the pipe
|
||||
#define Host_reset_pipe(p) (UPRST = 1<<p , UPRST = 0)
|
||||
|
||||
//! writes a byte into the pipe FIFO
|
||||
#define Host_write_byte(dat) (UPDATX = dat)
|
||||
//! reads a byte from the pipe FIFO
|
||||
#define Host_read_byte() (UPDATX)
|
||||
|
||||
//! freezes the pipe
|
||||
#define Host_freeze_pipe() (UPCONX |= (1<<PFREEZE))
|
||||
//! un-freezees the pipe
|
||||
#define Host_unfreeze_pipe() (UPCONX &= ~(1<<PFREEZE))
|
||||
//! tests if the current pipe is frozen
|
||||
#define Is_host_pipe_freeze() (UPCONX & (1<<PFREEZE))
|
||||
|
||||
//! resets data toggle
|
||||
#define Host_reset_pipe_data_toggle() (UPCONX |= (1<<RSTDT) )
|
||||
|
||||
//! tests if SETUP has been sent
|
||||
#define Is_host_setup_sent() ((UPINTX & (1<<TXSTPI)) ? TRUE : FALSE)
|
||||
//! tests if control IN has been received
|
||||
#define Is_host_control_in_received() ((UPINTX & (1<<RXINI)) ? TRUE : FALSE)
|
||||
//! tests if control OUT has been sent
|
||||
#define Is_host_control_out_sent() ((UPINTX & (1<<TXOUTI)) ? TRUE : FALSE)
|
||||
//! tests if a STALL has been received
|
||||
#define Is_host_stall() ((UPINTX & (1<<RXSTALLI)) ? TRUE : FALSE)
|
||||
//! tests if an error occurs on current pipe
|
||||
#define Is_host_pipe_error() ((UPINTX & (1<<PERRI)) ? TRUE : FALSE)
|
||||
//! sends a setup
|
||||
#define Host_send_setup() (UPINTX &= ~(1<<FIFOCON))
|
||||
//! sends a control IN
|
||||
#define Host_send_control_in() (UPINTX &= ~(1<<FIFOCON))
|
||||
//! sends a control OUT
|
||||
#define Host_send_control_out() (UPINTX &= ~(1<<FIFOCON))
|
||||
//! acks control OUT
|
||||
#define Host_ack_control_out() (UPINTX &= ~(1<<TXOUTI))
|
||||
//! acks control IN
|
||||
#define Host_ack_control_in() (UPINTX &= ~(1<<RXINI))
|
||||
//! acks setup
|
||||
#define Host_ack_setup() (UPINTX &= ~(1<<TXSTPI))
|
||||
//! acks STALL reception
|
||||
#define Host_ack_stall() (UPINTX &= ~(1<<RXSTALLI))
|
||||
|
||||
//! sends a OUT
|
||||
#define Host_send_out() (UPINTX &= ~(1<<FIFOCON))
|
||||
//! tests if OUT has been sent
|
||||
#define Is_host_out_sent() ((UPINTX & (1<<TXOUTI)) ? TRUE : FALSE)
|
||||
//! acks OUT sent
|
||||
#define Host_ack_out_sent() (UPINTX &= ~(1<<TXOUTI))
|
||||
//! tests if IN received
|
||||
#define Is_host_in_received() ((UPINTX & (1<<RXINI)) ? TRUE : FALSE)
|
||||
//! acks IN reception
|
||||
#define Host_ack_in_received() (UPINTX &= ~(1<<RXINI))
|
||||
//! sends a IN
|
||||
#define Host_send_in() (UPINTX &= ~(1<<FIFOCON))
|
||||
//! tests if nak handshake has been received
|
||||
#define Is_host_nak_received() ((UPINTX & (1<<NAKEDI)) ? TRUE : FALSE)
|
||||
//! acks NAk received sent
|
||||
#define Host_ack_nak_received() (UPINTX &= ~(1<<NAKEDI))
|
||||
|
||||
|
||||
|
||||
//! tests if endpoint read allowed
|
||||
#define Is_host_read_enabled() (UPINTX&(1<<RWAL))
|
||||
//! tests if endpoint read allowed
|
||||
#define Is_host_write_enabled() (UPINTX&(1<<RWAL))
|
||||
|
||||
//! sets IN in standard mode
|
||||
#define Host_standard_in_mode() (UPCONX &= ~(1<<INMODE))
|
||||
//! sets IN in continuous mode
|
||||
#define Host_continuous_in_mode() (UPCONX |= (1<<INMODE))
|
||||
|
||||
//! sets number of IN requests to perform before freeze
|
||||
#define Host_in_request_number(in_num) (UPINRQX = (U8)in_num)
|
||||
//! returns number of remaining IN requests
|
||||
#define Host_get_in_request_number() (UPINRQX)
|
||||
|
||||
//! returns number of bytes (8 bits)
|
||||
#define Host_data_length_U8() (UPBCLX)
|
||||
//! returns number of bytes (16 bits)
|
||||
#define Host_data_length_U16() ((((U16)UPBCHX)<<8) | UPBCLX)
|
||||
//! for device compatibility
|
||||
#define Host_byte_counter() Host_data_length_U16()
|
||||
//! for device compatibility
|
||||
#define Host_byte_counter_8() Host_data_length_U8()
|
||||
|
||||
//! returns the size of the current pipe
|
||||
#define Host_get_pipe_length() ((U16)0x08 << ((UPCFG1X & MSK_PSIZE)>>4))
|
||||
|
||||
//! returns the type of the current pipe
|
||||
#define Host_get_pipe_type() (UPCFG0X>>6)
|
||||
|
||||
//! tests if error occurs on pipe
|
||||
#define Host_error_status() (UPERRX & MSK_ERROR)
|
||||
//! acks all pipe error
|
||||
#define Host_ack_all_errors() (UPERRX = 0x00)
|
||||
|
||||
//! Enable pipe end transmission interrupt
|
||||
#define Host_enable_transmit_interrupt() (UPIENX |= (1<<TXOUTE))
|
||||
//! Disable pipe end transmission interrupt
|
||||
#define Host_disable_transmit_interrupt() (UPIENX &= ~(1<<TXOUTE))
|
||||
|
||||
//! Enable pipe reception interrupt
|
||||
#define Host_enable_receive_interrupt() (UPIENX |= (1<<RXINE))
|
||||
//! Disable pipe recption interrupt
|
||||
#define Host_disable_receive_interrupt() (UPIENX &= ~(1<<RXINE))
|
||||
|
||||
//! Enable pipe stall interrupt
|
||||
#define Host_enable_stall_interrupt() (UPIENX |= (1<<RXSTALLE))
|
||||
//! Disable pipe stall interrupt
|
||||
#define Host_disable_stall_interrupt() (UPIENX &= ~(1<<RXSTALLE))
|
||||
|
||||
//! Enable pipe error interrupt
|
||||
#define Host_enable_error_interrupt() (UPIENX |= (1<<PERRE))
|
||||
//! Disable pipe error interrupt
|
||||
#define Host_disable_error_interrupt() (UPIENX &= ~(1<<PERRE))
|
||||
|
||||
//! Enable pipe NAK interrupt
|
||||
#define Host_enable_nak_interrupt() (UPIENX |= (1<<NAKEDE))
|
||||
//! Disable pipe NAK interrupt
|
||||
#define Host_disable_nak_interrupt() (UPIENX &= ~(1<<NAKEDE))
|
||||
|
||||
#define Get_pipe_token(x) ((x & (0x80)) ? TOKEN_IN : TOKEN_OUT)
|
||||
|
||||
//! @}
|
||||
|
||||
//! wSWAP
|
||||
//! This macro swaps the U8 order in words.
|
||||
//!
|
||||
//! @param x (U16) the 16 bit word to swap
|
||||
//!
|
||||
//! @return (U16) the 16 bit word x with the 2 bytes swaped
|
||||
|
||||
#define wSWAP(x) \
|
||||
( (((x)>>8)&0x00FF) \
|
||||
| (((x)<<8)&0xFF00) \
|
||||
)
|
||||
|
||||
|
||||
//! Usb_write_word_enum_struc
|
||||
//! This macro help to fill the U16 fill in USB enumeration struct.
|
||||
//! Depending on the CPU architecture, the macro swap or not the nibbles
|
||||
//!
|
||||
//! @param x (U16) the 16 bit word to be written
|
||||
//!
|
||||
//! @return (U16) the 16 bit word written
|
||||
#if !defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)
|
||||
#error YOU MUST Define the Endian Type of target: LITTLE_ENDIAN or BIG_ENDIAN
|
||||
#endif
|
||||
#ifdef LITTLE_ENDIAN
|
||||
#define Usb_write_word_enum_struc(x) (x)
|
||||
#else //BIG_ENDIAN
|
||||
#define Usb_write_word_enum_struc(x) (wSWAP(x))
|
||||
#endif
|
||||
|
||||
|
||||
//_____ D E C L A R A T I O N ______________________________________________
|
||||
|
||||
U8 usb_config_ep (U8, U8);
|
||||
U8 usb_select_enpoint_interrupt (void);
|
||||
U8 usb_send_packet (U8 , U8*, U8);
|
||||
U8 usb_read_packet (U8 , U8*, U8);
|
||||
void usb_halt_endpoint (U8);
|
||||
U8 usb_init_device (void);
|
||||
|
||||
U8 host_config_pipe (U8, U8);
|
||||
U8 host_determine_pipe_size (U16);
|
||||
void host_disable_all_pipe (void);
|
||||
U8 usb_get_nb_pipe_interrupt (void);
|
||||
|
||||
#endif // _USB_DRV_H_
|
||||
|
||||
/** @} */
|
360
cpu/avr/dev/usb/usb_specific_request.c
Normal file
360
cpu/avr/dev/usb/usb_specific_request.c
Normal file
|
@ -0,0 +1,360 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file *********************************************************************
|
||||
*
|
||||
* \brief
|
||||
* USB Protocol-Specific Requests
|
||||
*
|
||||
* \addtogroup usbtask
|
||||
*
|
||||
* \author
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 Colin O'Flynn
|
||||
Copyright (c) Atmel Corporation 2008
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
#include "radio.h"
|
||||
#include "contiki.h"
|
||||
#include "config.h"
|
||||
#include "usb_drv.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "usb_specific_request.h"
|
||||
#include "rndis/rndis_protocol.h"
|
||||
#include "serial/uart_usb_lib.h"
|
||||
#include "storage/ctrl_access.h"
|
||||
#include "uip.h"
|
||||
#include <avr/pgmspace.h>
|
||||
#include <string.h>
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
//_____ D E F I N I T I O N ________________________________________________
|
||||
bit ms_multiple_drive;
|
||||
//_____ P R I V A T E D E C L A R A T I O N ______________________________
|
||||
|
||||
extern PGM_VOID_P pbuffer;
|
||||
extern U8 data_to_transfer;
|
||||
|
||||
//_____ D E C L A R A T I O N ______________________________________________
|
||||
|
||||
|
||||
|
||||
//! This function is called by the standard usb read request function when
|
||||
//! the Usb request is not supported. This function returns TRUE when the
|
||||
//! request is processed. This function returns FALSE if the request is not
|
||||
//! supported. In this case, a STALL handshake will be automatically
|
||||
//! sent by the standard usb read request function.
|
||||
//!
|
||||
//! @param type Not used
|
||||
//! @param request Read request type
|
||||
//!
|
||||
//! @retval FALSE if unknown read type
|
||||
//! @retval TRUE if request type is processed
|
||||
//!
|
||||
Bool usb_user_read_request(U8 type, U8 request)
|
||||
{
|
||||
U16 wLength;
|
||||
|
||||
//Both protocols have two bytes we throw away
|
||||
Usb_read_byte();
|
||||
Usb_read_byte();
|
||||
|
||||
switch(request)
|
||||
{
|
||||
case SEND_ENCAPSULATED_COMMAND:
|
||||
Usb_read_byte();//wIndex LSB
|
||||
Usb_read_byte();//wIndex MSB
|
||||
|
||||
LSB(wLength) = Usb_read_byte();
|
||||
MSB(wLength) = Usb_read_byte();
|
||||
return send_encapsulated_command(wLength);
|
||||
break;
|
||||
|
||||
case GET_ENCAPSULATED_COMMAND:
|
||||
Usb_read_byte();//wIndex LSB
|
||||
Usb_read_byte();//wIndex MSB
|
||||
|
||||
LSB(wLength) = Usb_read_byte();
|
||||
MSB(wLength) = Usb_read_byte();
|
||||
return get_encapsulated_command();
|
||||
break;
|
||||
|
||||
|
||||
case MASS_STORAGE_RESET:
|
||||
Usb_ack_receive_setup();
|
||||
Usb_send_control_in();
|
||||
return TRUE;
|
||||
break;
|
||||
|
||||
|
||||
case GET_MAX_LUN:
|
||||
Usb_ack_receive_setup();
|
||||
Usb_write_byte( (get_nb_lun()-1) );
|
||||
Usb_send_control_in();
|
||||
ms_multiple_drive = 1;
|
||||
return TRUE;
|
||||
break;
|
||||
|
||||
|
||||
/* We don't have a real serial port - so these aren't applicable. We
|
||||
advertise that we support nothing, so shouldn't get them anyway */
|
||||
/* case GET_LINE_CODING:
|
||||
cdc_get_line_coding();
|
||||
return TRUE;
|
||||
break;
|
||||
|
||||
case SET_LINE_CODING:
|
||||
cdc_set_line_coding();
|
||||
return TRUE;
|
||||
break;
|
||||
|
||||
case SET_CONTROL_LINE_STATE:
|
||||
cdc_set_control_line_state();
|
||||
return TRUE;
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//! usb_user_get_descriptor.
|
||||
//!
|
||||
//! @brief This function returns the size and the pointer on a user information
|
||||
//! structure
|
||||
//!
|
||||
//! @param type descriptor type
|
||||
//! @param string descriptor ID
|
||||
//!
|
||||
//! @retval FALSE
|
||||
//!
|
||||
Bool usb_user_get_descriptor(U8 type, U8 string)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case STRING_DESCRIPTOR:
|
||||
switch (string)
|
||||
{
|
||||
case LANG_ID:
|
||||
data_to_transfer = sizeof (usb_user_language_id);
|
||||
pbuffer = &(usb_user_language_id.bLength);
|
||||
return TRUE;
|
||||
break;
|
||||
case MAN_INDEX:
|
||||
data_to_transfer = sizeof (usb_user_manufacturer_string_descriptor);
|
||||
pbuffer = &(usb_user_manufacturer_string_descriptor.bLength);
|
||||
return TRUE;
|
||||
break;
|
||||
case PROD_INDEX:
|
||||
data_to_transfer = sizeof (usb_user_product_string_descriptor);
|
||||
pbuffer = &(usb_user_product_string_descriptor.bLength);
|
||||
return TRUE;
|
||||
break;
|
||||
case SN_INDEX:
|
||||
data_to_transfer = sizeof (usb_user_serial_number);
|
||||
pbuffer = &(usb_user_serial_number.bLength);
|
||||
return TRUE;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//! usb_user_endpoint_init.
|
||||
//!
|
||||
//! @brief This function configures the endpoints.
|
||||
//!
|
||||
//! @param conf_nb Not used
|
||||
void usb_user_endpoint_init(U8 conf_nb)
|
||||
{
|
||||
|
||||
/* If we use RNDIS endpoints */
|
||||
if ((usb_mode == rndis_only) || (usb_mode == rndis_debug)) {
|
||||
|
||||
usb_configure_endpoint(INT_EP, \
|
||||
TYPE_INTERRUPT, \
|
||||
DIRECTION_IN, \
|
||||
SIZE_64, \
|
||||
ONE_BANK, \
|
||||
NYET_ENABLED);
|
||||
|
||||
usb_configure_endpoint(TX_EP, \
|
||||
TYPE_BULK, \
|
||||
DIRECTION_IN, \
|
||||
SIZE_64, \
|
||||
TWO_BANKS, \
|
||||
NYET_ENABLED);
|
||||
|
||||
usb_configure_endpoint(RX_EP, \
|
||||
TYPE_BULK, \
|
||||
DIRECTION_OUT, \
|
||||
SIZE_64, \
|
||||
TWO_BANKS, \
|
||||
NYET_ENABLED);
|
||||
|
||||
}
|
||||
|
||||
/* If we use virtual comm port (VCP) endpoints */
|
||||
if (usb_mode == rndis_debug) {
|
||||
usb_configure_endpoint(VCP_INT_EP, \
|
||||
TYPE_INTERRUPT, \
|
||||
DIRECTION_IN, \
|
||||
SIZE_32, \
|
||||
ONE_BANK, \
|
||||
NYET_ENABLED);
|
||||
|
||||
usb_configure_endpoint(VCP_TX_EP, \
|
||||
TYPE_BULK, \
|
||||
DIRECTION_IN, \
|
||||
SIZE_32, \
|
||||
TWO_BANKS, \
|
||||
NYET_ENABLED);
|
||||
|
||||
usb_configure_endpoint(VCP_RX_EP, \
|
||||
TYPE_BULK, \
|
||||
DIRECTION_OUT, \
|
||||
SIZE_32, \
|
||||
TWO_BANKS, \
|
||||
NYET_ENABLED);
|
||||
}
|
||||
|
||||
/* If we use mass storage endpoints */
|
||||
if (usb_mode == mass_storage) {
|
||||
|
||||
usb_configure_endpoint(MS_IN_EP, \
|
||||
TYPE_BULK, \
|
||||
DIRECTION_IN, \
|
||||
SIZE_64, \
|
||||
ONE_BANK, \
|
||||
NYET_ENABLED);
|
||||
|
||||
usb_configure_endpoint(MS_OUT_EP, \
|
||||
TYPE_BULK, \
|
||||
DIRECTION_OUT, \
|
||||
SIZE_64, \
|
||||
ONE_BANK, \
|
||||
NYET_ENABLED);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ((usb_mode == rndis_only) || (usb_mode == rndis_debug)) {
|
||||
Usb_reset_endpoint(INT_EP);
|
||||
Usb_reset_endpoint(TX_EP);
|
||||
Usb_reset_endpoint(RX_EP);
|
||||
}
|
||||
|
||||
if (usb_mode == rndis_debug){
|
||||
Usb_reset_endpoint(VCP_INT_EP);
|
||||
Usb_reset_endpoint(VCP_TX_EP);
|
||||
Usb_reset_endpoint(VCP_RX_EP);
|
||||
}
|
||||
|
||||
if (usb_mode == mass_storage) {
|
||||
Usb_reset_endpoint(VCP_TX_EP);
|
||||
Usb_reset_endpoint(VCP_RX_EP);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/******************** Virtual Serial Port ************************/
|
||||
|
||||
extern S_line_coding line_coding;
|
||||
|
||||
//! cdc_get_line_coding.
|
||||
//!
|
||||
//! @brief This function manages reception of line coding parameters (baudrate...).
|
||||
//!
|
||||
void cdc_get_line_coding(void)
|
||||
{
|
||||
Usb_ack_receive_setup();
|
||||
Usb_write_byte(LSB0(line_coding.dwDTERate));
|
||||
Usb_write_byte(LSB1(line_coding.dwDTERate));
|
||||
Usb_write_byte(LSB2(line_coding.dwDTERate));
|
||||
Usb_write_byte(LSB3(line_coding.dwDTERate));
|
||||
Usb_write_byte(line_coding.bCharFormat);
|
||||
Usb_write_byte(line_coding.bParityType);
|
||||
Usb_write_byte(line_coding.bDataBits);
|
||||
|
||||
Usb_send_control_in();
|
||||
while(!(Is_usb_read_control_enabled()));
|
||||
//Usb_clear_tx_complete();
|
||||
|
||||
while(!Is_usb_receive_out());
|
||||
Usb_ack_receive_out();
|
||||
}
|
||||
|
||||
|
||||
//! cdc_set_line_coding.
|
||||
//!
|
||||
//! @brief This function manages reception of line coding parameters (baudrate...).
|
||||
//!
|
||||
void cdc_set_line_coding (void)
|
||||
{
|
||||
Usb_ack_receive_setup();
|
||||
while (!(Is_usb_receive_out()));
|
||||
LSB0(line_coding.dwDTERate) = Usb_read_byte();
|
||||
LSB1(line_coding.dwDTERate) = Usb_read_byte();
|
||||
LSB2(line_coding.dwDTERate) = Usb_read_byte();
|
||||
LSB3(line_coding.dwDTERate) = Usb_read_byte();
|
||||
line_coding.bCharFormat = Usb_read_byte();
|
||||
line_coding.bParityType = Usb_read_byte();
|
||||
line_coding.bDataBits = Usb_read_byte();
|
||||
Usb_ack_receive_out();
|
||||
|
||||
Usb_send_control_in(); // send a ZLP for STATUS phase
|
||||
while(!(Is_usb_read_control_enabled()));
|
||||
}
|
||||
|
||||
//! cdc_set_control_line_state.
|
||||
//!
|
||||
//! @brief This function manages the SET_CONTROL_LINE_LINE_STATE CDC request.
|
||||
//!
|
||||
//! Note: Can manage hardware flow control here...
|
||||
//!
|
||||
void cdc_set_control_line_state (void)
|
||||
{
|
||||
Usb_ack_receive_setup();
|
||||
Usb_send_control_in();
|
||||
while(!(Is_usb_read_control_enabled()));
|
||||
}
|
||||
|
89
cpu/avr/dev/usb/usb_specific_request.h
Normal file
89
cpu/avr/dev/usb/usb_specific_request.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file *********************************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file contains the user callback functions corresponding to the
|
||||
* application.
|
||||
*
|
||||
* \addtogroup usbtask
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _USB_SPECIFIC_REQUEST_H_
|
||||
#define _USB_SPECIFIC_REQUEST_H_
|
||||
|
||||
/*_____ I N C L U D E S ____________________________________________________*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/*_____ M A C R O S ________________________________________________________*/
|
||||
|
||||
|
||||
#define SEND_ENCAPSULATED_COMMAND 0x00
|
||||
#define GET_ENCAPSULATED_COMMAND 0x01
|
||||
#define GET_LINE_CODING 0x21
|
||||
#define SET_LINE_CODING 0x20
|
||||
#define SET_CONTROL_LINE_STATE 0x22
|
||||
#define SEND_BREAK 0x23
|
||||
#define MASS_STORAGE_RESET 0xFF
|
||||
#define GET_MAX_LUN 0xFE
|
||||
|
||||
extern FLASH S_usb_device_descriptor usb_dev_desc_composite;
|
||||
extern FLASH S_usb_device_descriptor usb_dev_desc_network;
|
||||
extern FLASH S_usb_user_configuration_descriptor_composite usb_conf_desc_composite;
|
||||
extern FLASH S_usb_user_configuration_descriptor_network usb_conf_desc_network;
|
||||
extern FLASH S_usb_device_qualifier_descriptor usb_qual_desc;
|
||||
extern FLASH S_usb_manufacturer_string_descriptor usb_user_manufacturer_string_descriptor;
|
||||
extern FLASH S_usb_product_string_descriptor usb_user_product_string_descriptor;
|
||||
extern FLASH S_usb_serial_number usb_user_serial_number;
|
||||
extern FLASH S_usb_language_id usb_user_language_id;
|
||||
|
||||
|
||||
|
||||
/*_____ D E F I N I T I O N ________________________________________________*/
|
||||
Bool usb_user_read_request(U8, U8);
|
||||
Bool usb_user_get_descriptor(U8 , U8);
|
||||
void usb_user_endpoint_init(U8);
|
||||
|
||||
void cdc_get_line_coding();
|
||||
void cdc_set_line_coding();
|
||||
void cdc_set_control_line_state (void);
|
||||
|
||||
extern usb_mode_t usb_mode;
|
||||
|
||||
// ____ T Y P E D E F I N I T I O N _______________________________________
|
||||
|
||||
#endif // _USB_SPECIFIC_REQUEST_H_
|
||||
|
551
cpu/avr/dev/usb/usb_standard_request.c
Normal file
551
cpu/avr/dev/usb/usb_standard_request.c
Normal file
|
@ -0,0 +1,551 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file *********************************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file contains the USB endpoint 0 management routines corresponding to
|
||||
* the standard enumeration process (refer to chapter 9 of the USB
|
||||
* specification.
|
||||
* This file calls routines of the usb_specific_request.c file for non-standard
|
||||
* request management.
|
||||
* The enumeration parameters (descriptor tables) are contained in the
|
||||
* usb_descriptors.c file.
|
||||
*
|
||||
* \addtogroup usbdriver
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
#include "config.h"
|
||||
#include "usb_drv.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "usb_specific_request.h"
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
||||
//_____ D E F I N I T I O N ________________________________________________
|
||||
|
||||
//_____ P R I V A T E D E C L A R A T I O N ______________________________
|
||||
|
||||
static void usb_get_descriptor( void);
|
||||
static void usb_set_address( void);
|
||||
static void usb_set_configuration(void);
|
||||
static void usb_clear_feature( void);
|
||||
static void usb_set_feature( void);
|
||||
static void usb_get_status( void);
|
||||
static void usb_get_configuration(void);
|
||||
static void usb_get_interface (void);
|
||||
static void usb_set_interface (void);
|
||||
|
||||
|
||||
//_____ D E C L A R A T I O N ______________________________________________
|
||||
|
||||
static bit zlp;
|
||||
static U8 endpoint_status[NB_ENDPOINTS];
|
||||
|
||||
#ifdef AVRGCC
|
||||
PGM_VOID_P pbuffer;
|
||||
#else
|
||||
U8 FLASH *pbuffer;
|
||||
#endif
|
||||
U8 data_to_transfer;
|
||||
|
||||
U16 wInterface;
|
||||
|
||||
static U8 bmRequestType;
|
||||
|
||||
U8 usb_configuration_nb;
|
||||
|
||||
usb_mode_t usb_mode = rndis_debug;
|
||||
|
||||
extern bit usb_connected;
|
||||
extern FLASH S_usb_device_descriptor usb_user_device_descriptor_network;
|
||||
extern FLASH S_usb_user_configuration_descriptor_network usb_user_configuration_descriptor_network;
|
||||
extern FLASH S_usb_device_descriptor usb_user_device_descriptor_composite;
|
||||
extern FLASH S_usb_user_configuration_descriptor_composite usb_user_configuration_descriptor_composite;
|
||||
|
||||
//! usb_process_request.
|
||||
//!
|
||||
//! @brief This function reads the SETUP request sent to the default control endpoint
|
||||
//! and calls the appropriate function. When exiting of the usb_read_request
|
||||
//! function, the device is ready to manage the next request.
|
||||
//!
|
||||
//! @note list of supported requests:
|
||||
//! GET_DESCRIPTOR
|
||||
//! GET_CONFIGURATION
|
||||
//! SET_ADDRESS
|
||||
//! SET_CONFIGURATION
|
||||
//! CLEAR_FEATURE
|
||||
//! SET_FEATURE
|
||||
//! GET_STATUS
|
||||
//!
|
||||
void usb_process_request(void)
|
||||
{
|
||||
U8 bmRequest;
|
||||
|
||||
bmRequestType = Usb_read_byte();
|
||||
bmRequest = Usb_read_byte();
|
||||
|
||||
switch (bmRequest)
|
||||
{
|
||||
case GET_DESCRIPTOR:
|
||||
if (0x80 == bmRequestType) { usb_get_descriptor(); }
|
||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
||||
break;
|
||||
|
||||
case GET_CONFIGURATION:
|
||||
if (0x80 == bmRequestType) { usb_get_configuration(); }
|
||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
||||
break;
|
||||
|
||||
case SET_ADDRESS:
|
||||
if (0x00 == bmRequestType) { usb_set_address(); }
|
||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
||||
break;
|
||||
|
||||
case SET_CONFIGURATION:
|
||||
if (0x00 == bmRequestType) { usb_set_configuration(); }
|
||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
||||
break;
|
||||
|
||||
case CLEAR_FEATURE:
|
||||
if (0x02 >= bmRequestType) { usb_clear_feature(); }
|
||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
||||
break;
|
||||
|
||||
case SET_FEATURE:
|
||||
if (0x02 >= bmRequestType) { usb_set_feature(); }
|
||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
||||
break;
|
||||
|
||||
case GET_STATUS:
|
||||
if ((0x7F < bmRequestType) & (0x82 >= bmRequestType))
|
||||
{ usb_get_status(); }
|
||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
||||
break;
|
||||
|
||||
case GET_INTERFACE:
|
||||
if (bmRequestType == 0x81) { usb_get_interface(); }
|
||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
||||
break;
|
||||
|
||||
|
||||
case SET_INTERFACE:
|
||||
if (bmRequestType == 0x01) {usb_set_interface();}
|
||||
break;
|
||||
|
||||
case SET_DESCRIPTOR:
|
||||
case SYNCH_FRAME:
|
||||
default: //!< un-supported request => call to user read request
|
||||
if(usb_user_read_request(bmRequestType, bmRequest) == FALSE)
|
||||
{
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//! usb_set_address.
|
||||
//!
|
||||
//! This function manages the SET ADDRESS request. When complete, the device
|
||||
//! will filter the requests using the new address.
|
||||
//!
|
||||
//! @warning Code:xx bytes (function code length)
|
||||
//!
|
||||
void usb_set_address(void)
|
||||
{
|
||||
Usb_configure_address(Usb_read_byte());
|
||||
|
||||
Usb_ack_receive_setup();
|
||||
|
||||
Usb_send_control_in(); //!< send a ZLP for STATUS phase
|
||||
while(!Is_usb_in_ready()); //!< waits for status phase done
|
||||
//!< before using the new address
|
||||
Usb_enable_address();
|
||||
}
|
||||
|
||||
//! usb_set_configuration.
|
||||
//!
|
||||
//! This function manages the SET CONFIGURATION request. If the selected
|
||||
//! configuration is valid, this function call the usb_user_endpoint_init()
|
||||
//! function that will configure the endpoints following the configuration
|
||||
//! number.
|
||||
//!
|
||||
//! @warning Code:xx bytes (function code length)
|
||||
//!
|
||||
void usb_set_configuration( void )
|
||||
{
|
||||
U8 configuration_number;
|
||||
|
||||
configuration_number = Usb_read_byte();
|
||||
|
||||
if (configuration_number <= NB_CONFIGURATION)
|
||||
{
|
||||
Usb_ack_receive_setup();
|
||||
usb_configuration_nb = configuration_number;
|
||||
}
|
||||
else
|
||||
{
|
||||
//!< keep that order (set StallRq/clear RxSetup) or a
|
||||
//!< OUT request following the SETUP may be acknowledged
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
return;
|
||||
}
|
||||
|
||||
Usb_send_control_in(); //!< send a ZLP for STATUS phase
|
||||
|
||||
usb_user_endpoint_init(usb_configuration_nb); //!< endpoint configuration
|
||||
Usb_set_configuration_action();
|
||||
}
|
||||
|
||||
//! usb_get_descriptor.
|
||||
//!
|
||||
//! This function manages the GET DESCRIPTOR request. The device descriptor,
|
||||
//! the configuration descriptor and the device qualifier are supported. All
|
||||
//! other descriptors must be supported by the usb_user_get_descriptor
|
||||
//! function.
|
||||
//! Only 1 configuration is supported.
|
||||
//!
|
||||
//! @warning Code:xx bytes (function code length)
|
||||
//!
|
||||
void usb_get_descriptor(void)
|
||||
{
|
||||
U8 LSBwLength, MSBwLength;
|
||||
U8 descriptor_type ;
|
||||
U8 string_type ;
|
||||
U8 dummy;
|
||||
U8 nb_byte;
|
||||
|
||||
zlp = FALSE; /* no zero length packet */
|
||||
string_type = Usb_read_byte(); /* read LSB of wValue */
|
||||
descriptor_type = Usb_read_byte(); /* read MSB of wValue */
|
||||
|
||||
dummy = Usb_read_byte(); //!< don't care of wIndex field
|
||||
dummy = Usb_read_byte();
|
||||
LSBwLength = Usb_read_byte(); //!< read wLength
|
||||
MSBwLength = Usb_read_byte();
|
||||
|
||||
switch (descriptor_type)
|
||||
{
|
||||
case DEVICE_DESCRIPTOR:
|
||||
data_to_transfer = Usb_get_dev_desc_length(); //!< sizeof (usb_user_device_descriptor);
|
||||
pbuffer = Usb_get_dev_desc_pointer();
|
||||
break;
|
||||
case CONFIGURATION_DESCRIPTOR:
|
||||
data_to_transfer = Usb_get_conf_desc_length(); //!< sizeof (usb_user_configuration_descriptor);
|
||||
pbuffer = Usb_get_conf_desc_pointer();
|
||||
break;
|
||||
default:
|
||||
if( usb_user_get_descriptor(descriptor_type, string_type)==FALSE )
|
||||
{
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Usb_ack_receive_setup() ; //!< clear the receive setup flag
|
||||
|
||||
if ((LSBwLength > data_to_transfer) || (MSBwLength))
|
||||
{
|
||||
if ((data_to_transfer % EP_CONTROL_LENGTH) == 0) { zlp = TRUE; }
|
||||
else { zlp = FALSE; } //!< no need of zero length packet
|
||||
|
||||
LSBwLength = data_to_transfer;
|
||||
MSBwLength = 0x00;
|
||||
}
|
||||
else
|
||||
{
|
||||
data_to_transfer = LSBwLength; //!< send only requested number of data
|
||||
}
|
||||
|
||||
|
||||
while((data_to_transfer != 0) && (!Is_usb_receive_out()))
|
||||
{
|
||||
while(!Is_usb_read_control_enabled());
|
||||
|
||||
nb_byte=0;
|
||||
while(data_to_transfer != 0) //!< Send data until necessary
|
||||
{
|
||||
if(nb_byte++==EP_CONTROL_LENGTH) //!< Check endpoint 0 size
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//#ifndef AVRGCC
|
||||
// Usb_write_byte(*pbuffer++);
|
||||
//#else // AVRGCC does not support point to PGM space
|
||||
//#warning AVRGCC assumes devices descriptors are stored in the lower 64Kbytes of on-chip flash memory
|
||||
Usb_write_byte(pgm_read_byte_near((unsigned int)pbuffer++));
|
||||
//#endif
|
||||
data_to_transfer --;
|
||||
|
||||
}
|
||||
Usb_send_control_in();
|
||||
}
|
||||
|
||||
if(Is_usb_receive_out()) { Usb_ack_receive_out(); return; } //!< abort from Host
|
||||
if(zlp == TRUE)
|
||||
{
|
||||
while(!Is_usb_read_control_enabled());
|
||||
Usb_send_control_in();
|
||||
}
|
||||
|
||||
while(!Is_usb_receive_out());
|
||||
Usb_ack_receive_out();
|
||||
}
|
||||
|
||||
//! usb_get_configuration.
|
||||
//!
|
||||
//! This function manages the GET CONFIGURATION request. The current
|
||||
//! configuration number is returned.
|
||||
//!
|
||||
//! @warning Code:xx bytes (function code length)
|
||||
//!
|
||||
void usb_get_configuration(void)
|
||||
{
|
||||
Usb_ack_receive_setup();
|
||||
|
||||
Usb_write_byte(usb_configuration_nb);
|
||||
Usb_ack_in_ready();
|
||||
|
||||
while( !Is_usb_receive_out() );
|
||||
Usb_ack_receive_out();
|
||||
}
|
||||
|
||||
//! usb_get_status.
|
||||
//!
|
||||
//! This function manages the GET STATUS request. The device, interface or
|
||||
//! endpoint status is returned.
|
||||
//!
|
||||
//! @warning Code:xx bytes (function code length)
|
||||
//!
|
||||
void usb_get_status(void)
|
||||
{
|
||||
U8 wIndex;
|
||||
U8 dummy;
|
||||
|
||||
dummy = Usb_read_byte(); //!< dummy read
|
||||
dummy = Usb_read_byte(); //!< dummy read
|
||||
wIndex = Usb_read_byte();
|
||||
|
||||
switch(bmRequestType)
|
||||
{
|
||||
case REQUEST_DEVICE_STATUS: Usb_ack_receive_setup();
|
||||
Usb_write_byte(DEVICE_STATUS);
|
||||
break;
|
||||
|
||||
case REQUEST_INTERFACE_STATUS: Usb_ack_receive_setup();
|
||||
Usb_write_byte(INTERFACE_STATUS);
|
||||
break;
|
||||
|
||||
case REQUEST_ENDPOINT_STATUS: Usb_ack_receive_setup();
|
||||
wIndex = wIndex & MSK_EP_DIR;
|
||||
Usb_write_byte(endpoint_status[wIndex]);
|
||||
break;
|
||||
default:
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
return;
|
||||
}
|
||||
|
||||
Usb_write_byte(0x00);
|
||||
Usb_send_control_in();
|
||||
|
||||
while( !Is_usb_receive_out() );
|
||||
Usb_ack_receive_out();
|
||||
}
|
||||
|
||||
//! usb_set_feature.
|
||||
//!
|
||||
//! This function manages the SET FEATURE request. The USB test modes are
|
||||
//! supported by this function.
|
||||
//!
|
||||
//! @warning Code:xx bytes (function code length)
|
||||
//!
|
||||
void usb_set_feature(void)
|
||||
{
|
||||
U8 wValue;
|
||||
U8 wIndex;
|
||||
U8 dummy;
|
||||
|
||||
if (bmRequestType == INTERFACE_TYPE)
|
||||
{
|
||||
//!< keep that order (set StallRq/clear RxSetup) or a
|
||||
//!< OUT request following the SETUP may be acknowledged
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
return;
|
||||
}
|
||||
else if (bmRequestType == ENDPOINT_TYPE)
|
||||
{
|
||||
wValue = Usb_read_byte();
|
||||
dummy = Usb_read_byte(); //!< dummy read
|
||||
|
||||
if (wValue == FEATURE_ENDPOINT_HALT)
|
||||
{
|
||||
wIndex = (Usb_read_byte() & MSK_EP_DIR);
|
||||
|
||||
if (wIndex == EP_CONTROL)
|
||||
{
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
return;
|
||||
}
|
||||
|
||||
Usb_select_endpoint(wIndex);
|
||||
if(Is_usb_endpoint_enabled())
|
||||
{
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_select_endpoint(EP_CONTROL);
|
||||
endpoint_status[wIndex] = 0x01;
|
||||
Usb_ack_receive_setup();
|
||||
Usb_send_control_in();
|
||||
}
|
||||
else
|
||||
{
|
||||
Usb_select_endpoint(EP_CONTROL);
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! usb_clear_feature.
|
||||
//!
|
||||
//! This function manages the SET FEATURE request.
|
||||
//!
|
||||
//! @warning Code:xx bytes (function code length)
|
||||
//!
|
||||
void usb_clear_feature(void)
|
||||
{
|
||||
U8 wValue;
|
||||
U8 wIndex;
|
||||
U8 dummy;
|
||||
|
||||
if (bmRequestType == ZERO_TYPE)
|
||||
{
|
||||
//!< keep that order (set StallRq/clear RxSetup) or a
|
||||
//!< OUT request following the SETUP may be acknowledged
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
return;
|
||||
}
|
||||
else if (bmRequestType == INTERFACE_TYPE)
|
||||
{
|
||||
//!< keep that order (set StallRq/clear RxSetup) or a
|
||||
//!< OUT request following the SETUP may be acknowledged
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
return;
|
||||
}
|
||||
else if (bmRequestType == ENDPOINT_TYPE)
|
||||
{
|
||||
wValue = Usb_read_byte();
|
||||
dummy = Usb_read_byte(); //!< dummy read
|
||||
|
||||
if (wValue == FEATURE_ENDPOINT_HALT)
|
||||
{
|
||||
wIndex = (Usb_read_byte() & MSK_EP_DIR);
|
||||
|
||||
Usb_select_endpoint(wIndex);
|
||||
if(Is_usb_endpoint_enabled())
|
||||
{
|
||||
if(wIndex != EP_CONTROL)
|
||||
{
|
||||
Usb_disable_stall_handshake();
|
||||
Usb_reset_endpoint(wIndex);
|
||||
Usb_reset_data_toggle();
|
||||
}
|
||||
Usb_select_endpoint(EP_CONTROL);
|
||||
endpoint_status[wIndex] = 0x00;
|
||||
Usb_ack_receive_setup();
|
||||
Usb_send_control_in();
|
||||
}
|
||||
else
|
||||
{
|
||||
Usb_select_endpoint(EP_CONTROL);
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! usb_get_interface.
|
||||
//!
|
||||
//! TThis function manages the GET_INTERFACE request.
|
||||
//!
|
||||
//! @warning Code:xx bytes (function code length)
|
||||
//!
|
||||
void usb_get_interface (void)
|
||||
{
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
}
|
||||
|
||||
//! usb_set_interface.
|
||||
//!
|
||||
//! TThis function manages the SET_INTERFACE request.
|
||||
//!
|
||||
//! @warning Code:xx bytes (function code length)
|
||||
//!
|
||||
void usb_set_interface (void)
|
||||
{
|
||||
Usb_ack_receive_setup();
|
||||
Usb_send_control_in(); //!< send a ZLP for STATUS phase
|
||||
while(!Is_usb_in_ready());
|
||||
}
|
88
cpu/avr/dev/usb/usb_standard_request.h
Normal file
88
cpu/avr/dev/usb/usb_standard_request.h
Normal file
|
@ -0,0 +1,88 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file usb_standard_request.h *************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file contains the USB endpoint 0 management routines corresponding to
|
||||
* the standard enumeration process (refer to chapter 9 of the USB
|
||||
* specification.
|
||||
* This file calls routines of the usb_specific_request.c file for non-standard
|
||||
* request management.
|
||||
* The enumeration parameters (descriptor tables) are contained in the
|
||||
* usb_descriptors.c file.
|
||||
*
|
||||
* \addtogroup usbdriver
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _USB_ENUM_H_
|
||||
#define _USB_ENUM_H_
|
||||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
#include "usb_task.h"
|
||||
#include "usb_descriptors.h"
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
//_____ S T A N D A R D D E F I N I T I O N S ___________________________
|
||||
|
||||
// Device State
|
||||
#define ATTACHED 0
|
||||
#define POWERED 1
|
||||
#define DEFAULT 2
|
||||
#define ADDRESSED 3
|
||||
#define CONFIGURED 4
|
||||
#define SUSPENDED 5
|
||||
|
||||
#define USB_CONFIG_ATTRIBUTES_RESERVED 0x80
|
||||
#define USB_CONFIG_BUSPOWERED (USB_CONFIG_ATTRIBUTES_RESERVED | 0x00)
|
||||
#define USB_CONFIG_SELFPOWERED (USB_CONFIG_ATTRIBUTES_RESERVED | 0x40)
|
||||
#define USB_CONFIG_REMOTEWAKEUP (USB_CONFIG_ATTRIBUTES_RESERVED | 0x20)
|
||||
|
||||
//_____ D E C L A R A T I O N ______________________________________________
|
||||
|
||||
//! @brief Returns true when device connected and correctly enumerated with an host.
|
||||
//! The device high level application should tests this before performing any applicative requests
|
||||
#define Is_device_enumerated() ((usb_configuration_nb!=0) ? TRUE : FALSE)
|
||||
#define Is_device_not_enumerated() ((usb_configuration_nb!=0) ? FALSE : TRUE)
|
||||
|
||||
|
||||
void usb_process_request( void);
|
||||
|
||||
extern U8 usb_configuration_nb;
|
||||
|
||||
|
||||
#endif // _USB_ENUM_H_
|
||||
|
375
cpu/avr/dev/usb/usb_task.c
Normal file
375
cpu/avr/dev/usb/usb_task.c
Normal file
|
@ -0,0 +1,375 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file usb_task.c *********************************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file manages the USB task either device/host or both.
|
||||
*
|
||||
* The USB task selects the correct USB task (usb_device task or usb_host task
|
||||
* to be executed depending on the current mode available.
|
||||
*
|
||||
* According to USB_DEVICE_FEATURE and USB_HOST_FEATURE value (located in conf_usb.h file)
|
||||
* The usb_task can be configured to support USB DEVICE mode or USB Host mode or both
|
||||
* for a dual role device application.
|
||||
*
|
||||
* This module also contains the general USB interrupt subroutine. This subroutine is used
|
||||
* to detect asynchronous USB events.
|
||||
*
|
||||
* Note:
|
||||
* - The usb_task belongs to the scheduler, the usb_device_task and usb_host do not, they are called
|
||||
* from the general usb_task
|
||||
* - See conf_usb.h file for more details about the configuration of this module
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 Colin O'Flynn
|
||||
Copyright (c) 2008 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
\ingroup usbstick
|
||||
\defgroup usbtask USB Contiki Task
|
||||
@{
|
||||
*/
|
||||
|
||||
//_____ I N C L U D E S ___________________________________________________
|
||||
|
||||
#include "contiki.h"
|
||||
#include "config.h"
|
||||
#include "conf_usb.h"
|
||||
#include "usb_drv.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "pll_drv.h"
|
||||
#include "usb_task.h"
|
||||
#include "rndis/rndis_protocol.h"
|
||||
#include "rndis/rndis_task.h"
|
||||
|
||||
PROCESS(usb_process, "USB process");
|
||||
|
||||
#ifndef USE_USB_PADS_REGULATOR
|
||||
#error "USE_USB_PADS_REGULATOR" should be defined as ENABLE or DISABLE in conf_usb.h file
|
||||
#endif
|
||||
#include <avr/sleep.h>
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
#ifndef LOG_STR_CODE
|
||||
#define LOG_STR_CODE(str)
|
||||
#else
|
||||
U8 code log_device_disconnect[]="Device Disconnected";
|
||||
U8 code log_id_change[]="Pin Id Change";
|
||||
#endif
|
||||
|
||||
#define USB_EVENT 0x2F /* Contiki event number - I just made this one up?*/
|
||||
|
||||
//_____ D E F I N I T I O N S ______________________________________________
|
||||
|
||||
//!
|
||||
//! Public : U16 g_usb_event
|
||||
//! usb_connected is used to store USB events detected upon
|
||||
//! USB general interrupt subroutine
|
||||
//! Its value is managed by the following macros (See usb_task.h file)
|
||||
//! Usb_send_event(x)
|
||||
//! Usb_ack_event(x)
|
||||
//! Usb_clear_all_event()
|
||||
//! Is_usb_event(x)
|
||||
//! Is_not_usb_event(x)
|
||||
volatile uint16_t g_usb_event=0;
|
||||
|
||||
|
||||
//!
|
||||
//! Public : (bit) usb_connected
|
||||
//! usb_connected is set to TRUE when VBUS has been detected
|
||||
//! usb_connected is set to FALSE otherwise
|
||||
//! Used with USB_DEVICE_FEATURE == ENABLED only
|
||||
//!/
|
||||
bit usb_connected;
|
||||
|
||||
//!
|
||||
//! Public : (U8) usb_configuration_nb
|
||||
//! Store the number of the USB configuration used by the USB device
|
||||
//! when its value is different from zero, it means the device mode is enumerated
|
||||
//! Used with USB_DEVICE_FEATURE == ENABLED only
|
||||
//!/
|
||||
extern U8 usb_configuration_nb;
|
||||
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \brief Spare function to handle sleep mode.
|
||||
*/
|
||||
extern void suspend_action(void)
|
||||
{
|
||||
Enable_interrupt();
|
||||
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
||||
sleep_mode();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief This function initializes the USB device controller
|
||||
*
|
||||
* This function enables the USB controller and init the USB interrupts.
|
||||
* The aim is to allow the USB connection detection in order to send
|
||||
* the appropriate USB event to the operating mode manager.
|
||||
* Start device function is executed once VBUS connection has been detected
|
||||
* either by the VBUS change interrupt either by the VBUS high level
|
||||
*/
|
||||
void usb_start_device (void)
|
||||
{
|
||||
Pll_start_auto();
|
||||
Wait_pll_ready();
|
||||
Usb_unfreeze_clock();
|
||||
Usb_enable_vbus_interrupt();
|
||||
Usb_enable_reset_interrupt();
|
||||
usb_init_device(); // configure the USB controller EP0
|
||||
Usb_attach();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief USB Poll Handler
|
||||
*
|
||||
* This routine is repetively called, and deals with things such as new SETUP transfers
|
||||
* on the control endpoint
|
||||
*/
|
||||
static void pollhandler(void)
|
||||
{
|
||||
|
||||
|
||||
//RNDIS needs a delay where this isn't called, as it will switch endpoints
|
||||
//and screw up the data transfers
|
||||
if (!usb_busy) {
|
||||
|
||||
/* Check for setup packets */
|
||||
Usb_select_endpoint(EP_CONTROL);
|
||||
if (Is_usb_receive_setup()) {
|
||||
usb_process_request();
|
||||
}
|
||||
|
||||
/* The previous call might have requested we send
|
||||
out something to the RNDIS interrupt endpoint */
|
||||
if (schedule_interrupt) {
|
||||
Usb_select_endpoint(INT_EP);
|
||||
|
||||
//Linux is a bunch of lies, and won't read
|
||||
//the interrupt endpoint. Hence if this isn't ready just exit
|
||||
//while(!Is_usb_write_enabled());
|
||||
|
||||
if (Is_usb_write_enabled()) {
|
||||
|
||||
// Only valid interrupt is:
|
||||
// 0x00000001 0x00000000
|
||||
//
|
||||
Usb_write_byte(0x01);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00);
|
||||
|
||||
//Send back
|
||||
Usb_send_in();
|
||||
|
||||
schedule_interrupt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Continue polling */
|
||||
process_poll(&usb_process);
|
||||
|
||||
}
|
||||
/**
|
||||
* \brief USB Process
|
||||
*
|
||||
* The actual USB process, deals with USB events such as resets, and being plugged in
|
||||
* or unplugged. A seperate polling routine is setup, which continously checks for
|
||||
* things such as SETUP packets on the control interface. They must be responded to
|
||||
* very quickly, hence the need for a polling process.
|
||||
*/
|
||||
PROCESS_THREAD(usb_process, ev, data_proc)
|
||||
{
|
||||
|
||||
PROCESS_POLLHANDLER(pollhandler());
|
||||
|
||||
PROCESS_BEGIN();
|
||||
|
||||
|
||||
/*** USB initilization ***/
|
||||
|
||||
#if (USE_USB_PADS_REGULATOR==ENABLE) // Otherwise assume USB PADs regulator is not used
|
||||
Usb_enable_regulator();
|
||||
#endif
|
||||
|
||||
Usb_force_device_mode();
|
||||
|
||||
/* Init USB controller */
|
||||
Enable_interrupt();
|
||||
Usb_disable();
|
||||
Usb_enable();
|
||||
Usb_select_device();
|
||||
#if (USB_LOW_SPEED_DEVICE==ENABLE)
|
||||
Usb_low_speed_mode();
|
||||
#endif
|
||||
Usb_enable_vbus_interrupt();
|
||||
Enable_interrupt();
|
||||
|
||||
|
||||
/* Ensure pollhandler is called to start it off */
|
||||
process_poll(&usb_process);
|
||||
|
||||
|
||||
/*** Begin actual USB process ***/
|
||||
while(1)
|
||||
{
|
||||
|
||||
if (Is_usb_vbus_high()&& usb_connected==FALSE)
|
||||
{
|
||||
usb_connected = TRUE;
|
||||
usb_start_device();
|
||||
Usb_vbus_on_action();
|
||||
}
|
||||
|
||||
if(Is_usb_event(EVT_USB_RESET))
|
||||
{
|
||||
Usb_ack_event(EVT_USB_RESET);
|
||||
Usb_reset_endpoint(0);
|
||||
usb_configuration_nb=0;
|
||||
}
|
||||
|
||||
|
||||
PROCESS_WAIT_EVENT_UNTIL(ev == USB_EVENT);
|
||||
}//while(1)
|
||||
|
||||
PROCESS_END();
|
||||
|
||||
}
|
||||
|
||||
|
||||
//! @brief USB general interrupt subroutine
|
||||
//!
|
||||
//! This function is called each time a USB interrupt occurs.
|
||||
//! The following USB DEVICE events are taken in charge:
|
||||
//! - VBus On / Off
|
||||
//! - Start Of Frame
|
||||
//! - Suspend
|
||||
//! - Wake-Up
|
||||
//! - Resume
|
||||
//! - Reset
|
||||
//! - Start of frame
|
||||
//!
|
||||
//! For each event, the user can launch an action by completing
|
||||
//! the associate define (See conf_usb.h file to add action upon events)
|
||||
//!
|
||||
//! Note: Only interrupts events that are enabled are processed
|
||||
//!
|
||||
|
||||
ISR(USB_GEN_vect)
|
||||
{
|
||||
|
||||
process_post(&usb_process, USB_EVENT, NULL);
|
||||
|
||||
//- VBUS state detection
|
||||
if (Is_usb_vbus_transition() && Is_usb_vbus_interrupt_enabled())
|
||||
{
|
||||
Usb_ack_vbus_transition();
|
||||
if (Is_usb_vbus_high())
|
||||
{
|
||||
usb_connected = TRUE;
|
||||
Usb_vbus_on_action();
|
||||
Usb_send_event(EVT_USB_POWERED);
|
||||
Usb_enable_reset_interrupt();
|
||||
usb_start_device();
|
||||
Usb_attach();
|
||||
}
|
||||
else
|
||||
{
|
||||
Usb_vbus_off_action();
|
||||
usb_connected = FALSE;
|
||||
usb_configuration_nb = 0;
|
||||
Usb_send_event(EVT_USB_UNPOWERED);
|
||||
}
|
||||
}
|
||||
// - Device start of frame received
|
||||
if (Is_usb_sof() && Is_sof_interrupt_enabled())
|
||||
{
|
||||
Usb_ack_sof();
|
||||
Usb_sof_action();
|
||||
}
|
||||
// - Device Suspend event (no more USB activity detected)
|
||||
if (Is_usb_suspend() && Is_suspend_interrupt_enabled())
|
||||
{
|
||||
Usb_ack_suspend();
|
||||
Usb_enable_wake_up_interrupt();
|
||||
Usb_ack_wake_up(); // clear wake up to detect next event
|
||||
Usb_freeze_clock();
|
||||
Usb_send_event(EVT_USB_SUSPEND);
|
||||
Usb_suspend_action();
|
||||
}
|
||||
// - Wake up event (USB activity detected): Used to resume
|
||||
if (Is_usb_wake_up() && Is_swake_up_interrupt_enabled())
|
||||
{
|
||||
Usb_unfreeze_clock();
|
||||
Usb_ack_wake_up();
|
||||
Usb_disable_wake_up_interrupt();
|
||||
Usb_wake_up_action();
|
||||
Usb_send_event(EVT_USB_WAKE_UP);
|
||||
}
|
||||
// - Resume state bus detection
|
||||
if (Is_usb_resume() && Is_resume_interrupt_enabled())
|
||||
{
|
||||
Usb_disable_wake_up_interrupt();
|
||||
Usb_ack_resume();
|
||||
Usb_disable_resume_interrupt();
|
||||
Usb_resume_action();
|
||||
Usb_send_event(EVT_USB_RESUME);
|
||||
}
|
||||
// - USB bus reset detection
|
||||
if (Is_usb_reset()&& Is_reset_interrupt_enabled())
|
||||
{
|
||||
Usb_ack_reset();
|
||||
usb_init_device();
|
||||
Usb_reset_action();
|
||||
Usb_send_event(EVT_USB_RESET);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
195
cpu/avr/dev/usb/usb_task.h
Normal file
195
cpu/avr/dev/usb/usb_task.h
Normal file
|
@ -0,0 +1,195 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
|
||||
|
||||
/*! \file usb_task.h *********************************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file manages the USB task either device/host or both.
|
||||
*
|
||||
* The USB task selects the correct USB task (usb_device task or usb_host task
|
||||
* to be executed depending on the current mode available.
|
||||
*
|
||||
* According to USB_DEVICE_FEATURE and USB_HOST_FEATURE value (located in conf_usb.h file)
|
||||
* The usb_task can be configured to support USB DEVICE mode or USB Host mode or both
|
||||
* for a dual role device application.
|
||||
*
|
||||
* This module also contains the general USB interrupt subroutine. This subroutine is used
|
||||
* to detect asynchronous USB events.
|
||||
*
|
||||
* Note:
|
||||
* - The usb_task belongs to the scheduler, the usb_device_task and usb_host do not, they are called
|
||||
* from the general usb_task
|
||||
* - See conf_usb.h file for more details about the configuration of this module
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _USB_TASK_H_
|
||||
#define _USB_TASK_H_
|
||||
|
||||
/**
|
||||
\ingroup usbstick
|
||||
\defgroup usbdriver USB Driver
|
||||
@{
|
||||
*/
|
||||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
//! \name USB Events
|
||||
//! @{
|
||||
|
||||
//! Send event
|
||||
#define Usb_send_event(x) (g_usb_event |= (1<<x))
|
||||
//! Ack event processed
|
||||
#define Usb_ack_event(x) (g_usb_event &= ~(1<<x))
|
||||
//! Clear all events
|
||||
#define Usb_clear_all_event() (g_usb_event = 0)
|
||||
//! Check for USB event
|
||||
#define Is_usb_event(x) ((g_usb_event & (1<<x)) ? TRUE : FALSE)
|
||||
//! Check for USB event NOT occuring
|
||||
#define Is_not_usb_event(x) ((g_usb_event & (1<<x)) ? FALSE: TRUE)
|
||||
//! Check if USB is device
|
||||
#define Is_usb_device() (g_usb_mode==USB_MODE_DEVICE ? TRUE : FALSE)
|
||||
|
||||
|
||||
//! USB Event: USB plugged
|
||||
#define EVT_USB_POWERED 1
|
||||
//! USB Event: USB un-plugged
|
||||
#define EVT_USB_UNPOWERED 2
|
||||
//! USB Event: USB in device
|
||||
#define EVT_USB_DEVICE_FUNCTION 3
|
||||
//! USB Event: USB in host
|
||||
#define EVT_USB_HOST_FUNCTION 4
|
||||
//! USB Event: USB suspend
|
||||
#define EVT_USB_SUSPEND 5
|
||||
//! USB Event: USB wake up
|
||||
#define EVT_USB_WAKE_UP 6
|
||||
//! USB Event: USB resume
|
||||
#define EVT_USB_RESUME 7
|
||||
//! USB Event: USB reset
|
||||
#define EVT_USB_RESET 8
|
||||
//! USB Event: USB setup received
|
||||
#define EVT_USB_SETUP_RX 9
|
||||
//! @}
|
||||
|
||||
//! \name Standard requests defines
|
||||
//! @{
|
||||
|
||||
#define GET_STATUS 0x00
|
||||
#define GET_DEVICE 0x01
|
||||
#define CLEAR_FEATURE 0x01 //!< see FEATURES below
|
||||
#define GET_STRING 0x03
|
||||
#define SET_FEATURE 0x03 //!< see FEATURES below
|
||||
#define SET_ADDRESS 0x05
|
||||
#define GET_DESCRIPTOR 0x06
|
||||
#define SET_DESCRIPTOR 0x07
|
||||
#define GET_CONFIGURATION 0x08
|
||||
#define SET_CONFIGURATION 0x09
|
||||
#define GET_INTERFACE 0x0A
|
||||
#define SET_INTERFACE 0x0B
|
||||
#define SYNCH_FRAME 0x0C
|
||||
|
||||
#define GET_DEVICE_DESCRIPTOR 1
|
||||
#define GET_CONFIGURATION_DESCRIPTOR 4
|
||||
|
||||
#define REQUEST_DEVICE_STATUS 0x80
|
||||
#define REQUEST_INTERFACE_STATUS 0x81
|
||||
#define REQUEST_ENDPOINT_STATUS 0x82
|
||||
#define ZERO_TYPE 0x00
|
||||
#define INTERFACE_TYPE 0x01
|
||||
#define ENDPOINT_TYPE 0x02
|
||||
|
||||
// Descriptor Types
|
||||
#define DEVICE_DESCRIPTOR 0x01
|
||||
#define CONFIGURATION_DESCRIPTOR 0x02
|
||||
#define STRING_DESCRIPTOR 0x03
|
||||
#define INTERFACE_DESCRIPTOR 0x04
|
||||
#define ENDPOINT_DESCRIPTOR 0x05
|
||||
#define DEVICE_QUALIFIER_DESCRIPTOR 0x06
|
||||
#define OTHER_SPEED_CONFIGURATION_DESCRIPTOR 0x07
|
||||
|
||||
|
||||
|
||||
// Standard Features
|
||||
#define FEATURE_DEVICE_REMOTE_WAKEUP 0x01
|
||||
#define FEATURE_ENDPOINT_HALT 0x00
|
||||
|
||||
#define TEST_J 0x01
|
||||
#define TEST_K 0x02
|
||||
#define TEST_SEO_NAK 0x03
|
||||
#define TEST_PACKET 0x04
|
||||
#define TEST_FORCE_ENABLE 0x05
|
||||
|
||||
|
||||
// Device Status
|
||||
#define BUS_POWERED 0
|
||||
#define SELF_POWERED 1
|
||||
|
||||
//! @}
|
||||
|
||||
#define USB_MODE_UNDEFINED 0x00
|
||||
#define USB_MODE_HOST 0x01
|
||||
#define USB_MODE_DEVICE 0x02
|
||||
|
||||
|
||||
typedef enum {
|
||||
rndis_only,
|
||||
rndis_debug,
|
||||
mass_storage
|
||||
} usb_mode_t;
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
|
||||
extern volatile uint16_t g_usb_event;
|
||||
extern uint8_t g_usb_mode;
|
||||
|
||||
|
||||
PROCESS_NAME(usb_process);
|
||||
|
||||
extern volatile uint8_t private_sof_counter;
|
||||
|
||||
void usb_start_device (void);
|
||||
void usb_device_task (void);
|
||||
|
||||
|
||||
//! @}
|
||||
|
||||
#endif /* _USB_TASK_H_ */
|
||||
|
||||
/** @} */
|
Loading…
Reference in a new issue