[sam] USB Host stack v1 with enumeration working okay using validation example

This commit is contained in:
Thibault RICHARD 2012-06-07 16:11:26 +02:00
parent b99d525a91
commit bc62c81396
31 changed files with 3546 additions and 1912 deletions

View File

@ -193,6 +193,9 @@ extern const PinDescription g_APinDescription[] ;
#include "WMath.h"
#include "HardwareSerial.h"
#include "wiring_pulse.h"
#include "Usb.h"
#endif // __cplusplus
// Include board variant

View File

@ -540,7 +540,7 @@ uint32_t USBD_Connected(void)
//=======================================================================
//=======================================================================
USB_ USB;
//USB_ USB;
USB_::USB_()
{

View File

@ -34,6 +34,7 @@ OUTPUT_BIN = ..
# Libraries
PROJECT_BASE_PATH = ..
PROJECT_BASE_PATH_USB = ../USB
PROJECT_BASE_PATH_USB_HOST = ../../../system/USBHost
SYSTEM_PATH = ../../../system
CMSIS_ROOT_PATH = $(SYSTEM_PATH)/CMSIS
CMSIS_ARM_PATH=$(CMSIS_ROOT_PATH)/CMSIS/Include
@ -45,15 +46,16 @@ VARIANT_PATH = ../../../variants/$(VARIANT)
# Files
#-------------------------------------------------------------------------------
#vpath %.h $(PROJECT_BASE_PATH) $(PROJECT_BASE_PATH_USB) $(SYSTEM_PATH) $(VARIANT_PATH)
vpath %.c $(PROJECT_BASE_PATH) $(PROJECT_BASE_PATH_USB) $(VARIANT_PATH)
vpath %.cpp $(PROJECT_BASE_PATH) $(PROJECT_BASE_PATH_USB)
#vpath %.h $(PROJECT_BASE_PATH) $(PROJECT_BASE_PATH_USB) $(PROJECT_BASE_PATH_USB_HOST) $(SYSTEM_PATH) $(VARIANT_PATH)
vpath %.c $(PROJECT_BASE_PATH) $(PROJECT_BASE_PATH_USB) $(PROJECT_BASE_PATH_USB_HOST) $(VARIANT_PATH)
vpath %.cpp $(PROJECT_BASE_PATH) $(PROJECT_BASE_PATH_USB) $(PROJECT_BASE_PATH_USB_HOST)
VPATH+=$(PROJECT_BASE_PATH)
INCLUDES =
INCLUDES += -I$(PROJECT_BASE_PATH)
INCLUDES += -I$(PROJECT_BASE_PATH_USB)
INCLUDES += -I$(PROJECT_BASE_PATH_USB_HOST)
INCLUDES += -I$(VARIANT_PATH)
INCLUDES += -I$(CMSIS_ARM_PATH)
INCLUDES += -I$(CMSIS_ATMEL_PATH)
@ -90,7 +92,7 @@ OUTPUT_PATH=$(OUTPUT_OBJ)_$(VARIANT)
#-------------------------------------------------------------------------------
# C source files and objects
#-------------------------------------------------------------------------------
C_SRC=$(wildcard $(PROJECT_BASE_PATH)/*.c $(PROJECT_BASE_PATH_USB)/*.c)
C_SRC=$(wildcard $(PROJECT_BASE_PATH)/*.c $(PROJECT_BASE_PATH_USB)/*.c $(PROJECT_BASE_PATH_USB_HOST)/*.c)
C_OBJ_TEMP = $(patsubst %.c, %.o, $(notdir $(C_SRC)))
@ -102,7 +104,7 @@ C_OBJ=$(filter-out $(C_OBJ_FILTER), $(C_OBJ_TEMP))
#-------------------------------------------------------------------------------
# CPP source files and objects
#-------------------------------------------------------------------------------
CPP_SRC=$(wildcard $(PROJECT_BASE_PATH)/*.cpp $(PROJECT_BASE_PATH_USB)/*.cpp)
CPP_SRC=$(wildcard $(PROJECT_BASE_PATH)/*.cpp $(PROJECT_BASE_PATH_USB)/*.cpp $(PROJECT_BASE_PATH_USB_HOST)/*.cpp)
CPP_OBJ_TEMP = $(patsubst %.cpp, %.o, $(notdir $(CPP_SRC)))

View File

@ -1,418 +0,0 @@
adc.o:
00000000 T adc_configure_power_save
00000000 T adc_configure_sequence
00000000 T adc_configure_timing
00000000 T adc_configure_trigger
00000000 T adc_disable_all_channel
00000000 T adc_disable_anch
00000000 T adc_disable_channel
00000000 T adc_disable_channel_differential_input
00000000 T adc_disable_channel_input_offset
00000000 T adc_disable_interrupt
00000000 T adc_disable_tag
00000000 T adc_disable_ts
00000000 T adc_enable_all_channel
00000000 T adc_enable_anch
00000000 T adc_enable_channel
00000000 T adc_enable_channel_differential_input
00000000 T adc_enable_channel_input_offset
00000000 T adc_enable_interrupt
00000000 T adc_enable_tag
00000000 T adc_enable_ts
00000000 T adc_get_actual_adc_clock
00000000 T adc_get_channel_status
00000000 T adc_get_channel_value
00000000 T adc_get_comparison_mode
00000000 T adc_get_interrupt_mask
00000000 T adc_get_latest_value
00000000 T adc_get_overrun_status
00000000 T adc_get_pdc_base
00000000 T adc_get_status
00000000 T adc_get_tag
00000000 T adc_get_writeprotect_status
00000000 T adc_init
00000000 T adc_set_bias_current
00000000 T adc_set_channel_input_gain
00000000 T adc_set_comparison_channel
00000000 T adc_set_comparison_mode
00000000 T adc_set_comparison_window
00000000 T adc_set_resolution
00000000 T adc_set_writeprotect
00000000 T adc_start
00000000 T adc_start_sequencer
00000000 T adc_stop
00000000 T adc_stop_sequencer
adc12_sam3u.o:
interrupt_sam_nvic.o:
00000000 D g_interrupt_enabled
pio.o:
00000000 T PIO_Clear
00000000 T PIO_Configure
00000000 T PIO_DisableInterrupt
00000000 T PIO_Get
00000000 T PIO_GetOutputDataStatus
00000000 T PIO_PullUp
00000000 T PIO_Set
00000000 T PIO_SetDebounceFilter
00000000 T PIO_SetInput
00000000 T PIO_SetOutput
00000000 T PIO_SetPeripheral
pmc.o:
00000000 T pmc_clr_fast_startup_input
00000000 T pmc_disable_all_pck
00000000 T pmc_disable_all_periph_clk
00000000 T pmc_disable_interrupt
00000000 T pmc_disable_pck
00000000 T pmc_disable_periph_clk
00000000 T pmc_disable_pllack
00000000 T pmc_disable_udpck
00000000 T pmc_disable_upll_clock
00000000 T pmc_enable_all_pck
00000000 T pmc_enable_all_periph_clk
00000000 T pmc_enable_backupmode
00000000 T pmc_enable_interrupt
00000000 T pmc_enable_pck
00000000 T pmc_enable_periph_clk
00000000 T pmc_enable_pllack
00000000 T pmc_enable_sleepmode
00000000 T pmc_enable_udpck
00000000 T pmc_enable_upll_clock
00000000 T pmc_enable_waitmode
00000000 T pmc_get_interrupt_mask
00000000 T pmc_get_status
00000000 T pmc_get_writeprotect_status
00000000 T pmc_is_locked_pllack
00000000 T pmc_is_locked_upll
00000000 T pmc_is_pck_enabled
00000000 T pmc_is_periph_clk_enabled
00000000 T pmc_mck_set_prescaler
00000000 T pmc_mck_set_source
00000000 T pmc_osc_disable_fastrc
00000000 T pmc_osc_disable_xtal
00000000 T pmc_osc_enable_fastrc
00000000 T pmc_osc_is_ready_32kxtal
00000000 T pmc_osc_is_ready_mainck
00000000 T pmc_pck_set_prescaler
00000000 T pmc_pck_set_source
00000000 T pmc_set_fast_startup_input
00000000 T pmc_set_writeprotect
00000000 T pmc_switch_mainck_to_fastrc
00000000 T pmc_switch_mainck_to_xtal
00000000 T pmc_switch_mck_to_mainck
00000000 T pmc_switch_mck_to_pllack
00000000 T pmc_switch_mck_to_sclk
00000000 T pmc_switch_mck_to_upllck
00000000 T pmc_switch_pck_to_mainck
00000000 T pmc_switch_pck_to_pllack
00000000 T pmc_switch_pck_to_sclk
00000000 T pmc_switch_pck_to_upllck
00000000 T pmc_switch_sclk_to_32kxtal
00000000 T pmc_switch_udpck_to_pllack
00000000 T pmc_switch_udpck_to_upllck
pwmc.o:
00000024 r .LC0
00000000 r .LC1
0000016c r .LC10
0000019c r .LC11
000001cc r .LC12
000001fc r .LC13
00000204 r .LC14
00000014 r .LC2
00000050 r .LC3
0000007c r .LC4
000000a8 r .LC5
000000dc r .LC6
00000108 r .LC7
00000134 r .LC8
00000160 r .LC9
00000000 t FindClockConfiguration
00000000 T PWMC_ConfigureChannel
00000000 T PWMC_ConfigureChannelExt
00000000 T PWMC_ConfigureClocks
00000000 T PWMC_ConfigureComparisonUnit
00000000 T PWMC_ConfigureEventLineMode
00000000 T PWMC_ConfigureSyncChannel
00000000 T PWMC_DisableChannel
00000000 T PWMC_DisableChannelIt
00000000 T PWMC_DisableIt
00000000 T PWMC_DisableOverrideOutput
00000000 T PWMC_EnableChannel
00000000 T PWMC_EnableChannelIt
00000000 T PWMC_EnableFaultProtection
00000000 T PWMC_EnableIt
00000000 T PWMC_EnableOverrideOutput
00000000 T PWMC_FaultClear
00000000 T PWMC_SetDeadTime
00000000 T PWMC_SetDutyCycle
00000000 T PWMC_SetFaultMode
00000000 T PWMC_SetFaultProtectionValue
00000000 T PWMC_SetOverrideValue
00000000 T PWMC_SetPeriod
00000000 T PWMC_SetSyncChannelUpdatePeriod
00000000 T PWMC_SetSyncChannelUpdateUnlock
00000000 T PWMC_WriteBuffer
U __assert_func
00000000 r __func__.3192
00000000 r __func__.3203
00000000 r __func__.3218
00000000 r __func__.3229
00000000 r __func__.3240
00000000 r __func__.3247
00000000 r __func__.3331
00000000 r __func__.3337
rtc.o:
00000000 r .LC0
00000010 r .LC1
0000002c r .LC2
00000000 T RTC_ClearSCCR
00000000 T RTC_DisableIt
00000000 T RTC_EnableIt
00000000 T RTC_GetDate
00000000 T RTC_GetHourMode
00000000 T RTC_GetSR
00000000 T RTC_GetTime
00000000 T RTC_SetDate
00000000 T RTC_SetDateAlarm
00000000 T RTC_SetHourMode
00000000 T RTC_SetTime
00000000 T RTC_SetTimeAlarm
U __assert_func
00000000 r __func__.3189
00000000 r __func__.3198
00000000 r __func__.3203
rtt.o:
00000000 r .LC0
00000010 r .LC1
0000002c r .LC2
00000000 T RTT_EnableIT
00000000 T RTT_GetStatus
00000000 T RTT_GetTime
00000000 T RTT_SetAlarm
00000000 T RTT_SetPrescaler
U __assert_func
00000000 r __func__.3196
00000000 r __func__.3204
spi.o:
00000000 T SPI_Configure
00000000 T SPI_ConfigureNPCS
00000000 T SPI_Disable
00000000 T SPI_DisableIt
00000000 T SPI_Enable
00000000 T SPI_EnableIt
00000000 T SPI_GetStatus
00000000 T SPI_IsFinished
00000000 T SPI_Read
00000000 T SPI_Write
U pmc_enable_periph_clk
tc.o:
00000000 r .LC0
00000010 r .LC1
00000000 T TC_Configure
00000000 T TC_FindMckDivisor
00000000 T TC_Start
00000000 T TC_Stop
U __assert_func
00000000 r __func__.3191
00000000 r __func__.3197
00000000 r __func__.3203
timetick.o:
00000000 T GetTickCount
00000000 t NVIC_SetPriority
00000000 T Sleep
00000000 t SysTick_Config
00000000 T TimeTick_Configure
00000000 T TimeTick_Increment
00000000 T Wait
00000000 b _dwTickCount
twi.o:
00000000 r .LC0
00000010 r .LC1
00000018 r .LC2
00000024 r .LC3
00000054 r .LC4
00000064 r .LC5
0000007c r .LC6
0000009c r .LC7
000000a8 r .LC8
00000000 T TWI_ByteReceived
00000000 T TWI_ByteSent
00000000 T TWI_ConfigureMaster
00000000 T TWI_ConfigureSlave
00000000 T TWI_DisableIt
00000000 T TWI_EnableIt
00000000 T TWI_GetMaskedStatus
00000000 T TWI_GetStatus
00000000 T TWI_ReadByte
00000000 T TWI_SendSTOPCondition
00000000 T TWI_StartRead
00000000 T TWI_StartWrite
00000000 T TWI_Stop
00000000 T TWI_TransferComplete
00000000 T TWI_WriteByte
U __assert_func
00000000 r __func__.3556
00000000 r __func__.3571
00000000 r __func__.3575
00000000 r __func__.3582
00000000 r __func__.3586
00000000 r __func__.3591
00000000 r __func__.3599
00000000 r __func__.3613
00000000 r __func__.3618
00000000 r __func__.3622
00000000 r __func__.3627
00000000 r __func__.3631
udp.o:
udphs.o:
uotghs.o:
00000000 t NVIC_EnableIRQ
00000000 t NVIC_SetPriority
00000000 T UDD_Attach
00000000 T UDD_ClearIN
00000000 T UDD_ClearOUT
00000000 T UDD_ClearSetupInt
00000000 T UDD_Detach
00000000 T UDD_FifoByteCount
00000000 T UDD_GetFrameNumber
00000000 T UDD_Init
00000000 T UDD_InitEP
00000000 T UDD_InitEndpoints
00000000 T UDD_ReadWriteAllowed
00000000 T UDD_ReceivedSetupInt
00000000 T UDD_Recv
00000000 T UDD_Recv8
00000000 T UDD_ReleaseRX
00000000 T UDD_ReleaseTX
00000000 T UDD_Send
00000000 T UDD_Send8
00000000 T UDD_SetAddress
00000000 T UDD_SetStack
00000000 T UDD_Stall
00000000 T UDD_WaitForINOrOUT
00000000 T UDD_WaitIN
00000000 T UDD_WaitOUT
00000000 T UOTGHS_Handler
00000000 t cpu_irq_is_enabled_flags
00000000 t cpu_irq_restore
00000000 t cpu_irq_save
U g_interrupt_enabled
00000000 b gpf_isr
U pmc_enable_periph_clk
U pmc_enable_udpck
U pmc_enable_upll_clock
U pmc_switch_udpck_to_upllck
00000000 b ul_recv_fifo_ptr
00000000 b ul_send_fifo_ptr
usart.o:
00000000 r .LC0
00000014 r .LC1
00000000 T USART_Configure
00000000 T USART_DisableIt
00000000 T USART_EnableIt
00000000 T USART_GetChar
00000000 T USART_GetStatus
00000000 T USART_IsDataAvailable
00000000 T USART_IsRxReady
00000000 T USART_PutChar
00000000 T USART_Read
00000000 T USART_ReadBuffer
00000000 T USART_SetIrdaFilter
00000000 T USART_SetReceiverEnabled
00000000 T USART_SetTransmitterEnabled
00000000 T USART_Write
00000000 T USART_WriteBuffer
U __assert_func
00000000 r __func__.3477
wdt.o:
00000000 T WDT_Disable
00000000 T WDT_Enable
00000000 T WDT_GetPeriod
00000000 T WDT_GetStatus
00000000 T WDT_Restart
system_sam3xa.o:
00000000 D SystemCoreClock
00000000 T SystemCoreClockUpdate
00000000 T SystemInit
00000000 T system_init_flash
startup_sam3xa.o:
00000000 W ADC_Handler
00000000 W BusFault_Handler
00000000 W CAN0_Handler
00000000 W CAN1_Handler
00000000 W DACC_Handler
00000000 W DMAC_Handler
00000000 W DebugMon_Handler
00000000 T Dummy_Handler
00000000 W EFC0_Handler
00000000 W EFC1_Handler
00000000 W EMAC_Handler
00000000 W HSMCI_Handler
00000000 W HardFault_Handler
00000000 W MemManage_Handler
00000000 W NMI_Handler
00000000 W PIOA_Handler
00000000 W PIOB_Handler
00000000 W PIOC_Handler
00000000 W PIOD_Handler
00000000 W PMC_Handler
00000000 W PWM_Handler
00000000 W PendSV_Handler
00000000 W RSTC_Handler
00000000 W RTC_Handler
00000000 W RTT_Handler
00000000 T Reset_Handler
00000000 W SMC_Handler
00000000 W SPI0_Handler
00000000 W SSC_Handler
00000000 W SUPC_Handler
00000000 W SVC_Handler
00000000 W SysTick_Handler
00000000 W TC0_Handler
00000000 W TC1_Handler
00000000 W TC2_Handler
00000000 W TC3_Handler
00000000 W TC4_Handler
00000000 W TC5_Handler
00000000 W TC6_Handler
00000000 W TC7_Handler
00000000 W TC8_Handler
00000000 W TRNG_Handler
00000000 W TWI0_Handler
00000000 W TWI1_Handler
00000000 W UART_Handler
00000000 W UOTGHS_Handler
00000000 W USART0_Handler
00000000 W USART1_Handler
00000000 W USART2_Handler
00000000 W USART3_Handler
00000000 W UsageFault_Handler
00000000 W WDT_Handler
U __libc_init_array
U _erelocate
U _estack
U _etext
U _ezero
U _sfixed
U _srelocate
U _szero
00000000 R exception_table
U main

View File

@ -40,7 +40,7 @@ int main( void )
delay(1);
#if defined(USBCON)
USB.attach();
//USB.attach();
#endif
setup();

View File

@ -0,0 +1,41 @@
#
# Copyright (c) 2011 Arduino. All right reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
SUBMAKE_OPTIONS=--no-builtin-rules --no-builtin-variables
#-------------------------------------------------------------------------------
# Rules
#-------------------------------------------------------------------------------
all: test_usb_device
.PHONY: test_usb_device
test:
@echo --- Making test_usb_device
@$(MAKE) DEBUG=1 $(SUBMAKE_OPTIONS) -f test_usb_device.mk
.PHONY: clean
clean:
@echo --- Cleaning test_usb_device
@$(MAKE) DEBUG=1 $(SUBMAKE_OPTIONS) -f test_usb_device.mk $@
.PHONY: debug
debug:
@echo --- Debugging test_usb_device
@$(MAKE) DEBUG=1 $(SUBMAKE_OPTIONS) -f test_usb_device.mk $@

View File

@ -0,0 +1,25 @@
#
# Copyright (c) 2011 Arduino. All right reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# Optimization level
# -O1 Optimize
# -O2 Optimize even more
# -O3 Optimize yet more
# -O0 Reduce compilation time and make debugging produce the expected results
# -Os Optimize for size
OPTIMIZATION = -g -O0 -DDEBUG

View File

@ -0,0 +1,85 @@
#
# Copyright (c) 2011 Arduino. All right reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# Tool suffix when cross-compiling
#CROSS_COMPILE = ../../../../tools/CodeSourcery_arm/bin/arm-none-eabi-
#CROSS_COMPILE = C:/CodeSourcery_2011.03-42/bin/arm-none-eabi-
CROSS_COMPILE = $(ARM_GCC_TOOLCHAIN)/arm-none-eabi-
# Compilation tools
AR = $(CROSS_COMPILE)ar
CC = $(CROSS_COMPILE)gcc
CXX = $(CROSS_COMPILE)g++
AS = $(CROSS_COMPILE)as
GDB = $(CROSS_COMPILE)gdb
SIZE = $(CROSS_COMPILE)size
NM = $(CROSS_COMPILE)nm
OBJCOPY = $(CROSS_COMPILE)objcopy
ifeq ($(OS),Windows_NT)
RM=cs-rm -Rf
else
RM=rm -Rf
endif
SEP=\\
# ---------------------------------------------------------------------------------------
# C Flags
CFLAGS += -Wall -Wchar-subscripts -Wcomment -Wformat=2 -Wimplicit-int
CFLAGS += -Werror-implicit-function-declaration -Wmain -Wparentheses
CFLAGS += -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused
CFLAGS += -Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef
CFLAGS += -Wshadow -Wpointer-arith -Wbad-function-cast -Wwrite-strings
CFLAGS += -Wsign-compare -Waggregate-return -Wstrict-prototypes
CFLAGS += -Wmissing-prototypes -Wmissing-declarations
CFLAGS += -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations
CFLAGS += -Wpacked -Wredundant-decls -Wnested-externs -Winline -Wlong-long
CFLAGS += -Wunreachable-code
CFLAGS += -Wcast-align
CFLAGS += --param max-inline-insns-single=500 -mcpu=cortex-m3 -mthumb -mlong-calls -ffunction-sections -nostdlib -std=c99
CFLAGS += $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -D$(VARIANT)
# To reduce application size use only integer printf function.
CFLAGS += -Dprintf=iprintf
# ---------------------------------------------------------------------------------------
# CPP Flags
CPPFLAGS += -Wall -Wchar-subscripts -Wcomment -Wformat=2
CPPFLAGS += -Wmain -Wparentheses -Wcast-align -Wunreachable-code
CPPFLAGS += -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused
CPPFLAGS += -Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef
CPPFLAGS += -Wshadow -Wpointer-arith -Wwrite-strings
CPPFLAGS += -Wsign-compare -Waggregate-return -Wmissing-declarations
CPPFLAGS += -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations
CPPFLAGS += -Wpacked -Wredundant-decls -Winline -Wlong-long
#-fno-rtti -fno-exceptions
CPPFLAGS += --param max-inline-insns-single=500 -mcpu=cortex-m3 -mthumb -mlong-calls -ffunction-sections -std=c++98
CPPFLAGS += $(OPTIMIZATION) $(INCLUDES) -D$(CHIP)
# To reduce application size use only integer printf function.
CPPFLAGS += -Dprintf=iprintf
# ---------------------------------------------------------------------------------------
# ASM Flags
ASFLAGS = -mcpu=cortex-m3 -mthumb -Wall -g $(OPTIMIZATION) $(INCLUDES)

View File

@ -0,0 +1,25 @@
#
# Copyright (c) 2011 Arduino. All right reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# Optimization level
# -O1 Optimize
# -O2 Optimize even more
# -O3 Optimize yet more
# -O0 Reduce compilation time and make debugging produce the expected results
# -Os Optimize for size
OPTIMIZATION = -Os

View File

@ -0,0 +1,218 @@
#
# Copyright (c) 2011 Arduino. All right reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# Makefile for compiling libArduino
.SUFFIXES: .o .a .c .s
# putting default variant
ifeq ("$(VARIANT)", "")
#VARIANT=sam3s_ek
#VARIANT=sam3u_ek
VARIANT=arduino_due_x
endif
ifeq ("$(VARIANT)", "sam3s_ek")
CHIP=__SAM3S4C__
VARIANT_PATH = ../../../../atmel/sam/variants/$(VARIANT)
else ifeq ("$(VARIANT)", "sam3u_ek")
CHIP=__SAM3U4E__
VARIANT_PATH = ../../../../atmel/sam/variants/$(VARIANT)
else ifeq ("$(VARIANT)", "sam3x_ek")
CHIP=__SAM3X8H__
VARIANT_PATH = ../../../../atmel/sam/variants/$(VARIANT)
else ifeq ("$(VARIANT)", "arduino_due_u")
CHIP=__SAM3U4E__
VARIANT_PATH = ../../../../variants/$(VARIANT)
else ifeq ("$(VARIANT)", "arduino_due_x")
CHIP=__SAM3X8E__
VARIANT_PATH = ../../../../variants/$(VARIANT)
endif
TOOLCHAIN=gcc
#-------------------------------------------------------------------------------
# Path
#-------------------------------------------------------------------------------
# Libraries
PROJECT_BASE_PATH = ./..
SYSTEM_PATH = ../../../../system
ifeq ($(CHIP), __SAM3S4C__)
CHIP_NAME=sam3s4c
CHIP_SERIE=sam3s
else ifeq ($(CHIP), __SAM3U4E__)
CHIP_NAME=sam3u4e
CHIP_SERIE=sam3u
else ifeq ($(CHIP), __SAM3N4C__)
CHIP_NAME=sam3n4c
CHIP_SERIE=sam3n
else ifeq ($(CHIP), __SAM3X8H__)
CHIP_NAME=sam3x8h
CHIP_SERIE=sam3xa
else ifeq ($(CHIP), __SAM3X8E__)
CHIP_NAME=sam3x8e
CHIP_SERIE=sam3xa
else
endif
CMSIS_ROOT_PATH = $(SYSTEM_PATH)/CMSIS
CMSIS_ARM_PATH=$(CMSIS_ROOT_PATH)/CMSIS/Include
CMSIS_ATMEL_PATH=$(CMSIS_ROOT_PATH)/Device/ATMEL
CMSIS_CHIP_PATH=$(CMSIS_ROOT_PATH)/Device/ATMEL/$(CHIP_SERIE)
ARDUINO_CORE_PATH=$(PROJECT_BASE_PATH)/..
ARDUINO_USB_PATH=$(PROJECT_BASE_PATH)/../USB
ARDUINO_USB_HOST_PATH=$(PROJECT_BASE_PATH)/../../../system/USBHost
# Output directories
OUTPUT_PATH = debug_$(VARIANT)
#-------------------------------------------------------------------------------
# Files
#-------------------------------------------------------------------------------
vpath %.h $(PROJECT_BASE_PATH)/.. $(VARIANT_PATH) $(SYSTEM_PATH) $(CMSIS_ARM_PATH)
vpath %.cpp $(PROJECT_BASE_PATH)
VPATH+=$(PROJECT_BASE_PATH)
INCLUDES = -I$(PROJECT_BASE_PATH)/..
INCLUDES += -I$(VARIANT_PATH)
#INCLUDES += -I$(VARIANT_PATH)/..
#INCLUDES += -I$(SYSTEM_PATH)
INCLUDES += -I$(SYSTEM_PATH)/libsam
INCLUDES += -I$(CMSIS_ARM_PATH)
INCLUDES += -I$(CMSIS_ATMEL_PATH)
INCLUDES += -I$(CMSIS_CHIP_PATH)
INCLUDES += -I$(ARDUINO_USB_PATH)
INCLUDES += -I$(ARDUINO_USB_HOST_PATH)
#-------------------------------------------------------------------------------
ifdef DEBUG
include debug.mk
else
include release.mk
endif
#-------------------------------------------------------------------------------
# Tools
#-------------------------------------------------------------------------------
include $(TOOLCHAIN).mk
#-------------------------------------------------------------------------------
ifdef DEBUG
OUTPUT_OBJ=debug
LIBS_POSTFIX=dbg
else
OUTPUT_OBJ=release
LIBS_POSTFIX=rel
endif
OUTPUT_BIN=test_$(TOOLCHAIN)_$(LIBS_POSTFIX)
LIBS=-Wl,--start-group -lgcc -lc -lstdc++ -lsam_$(CHIP_NAME)_$(TOOLCHAIN)_$(LIBS_POSTFIX) -larduino_$(VARIANT)_$(TOOLCHAIN)_$(LIBS_POSTFIX) -lvariant_$(VARIANT)_$(TOOLCHAIN)_$(LIBS_POSTFIX) -Wl,--end-group
LIB_PATH =-L$(PROJECT_BASE_PATH)/..
LIB_PATH+=-L=/lib/thumb2
#LIB_PATH+=-L=/../lib/gcc/arm-none-eabi/4.5.2/thumb2
LDFLAGS= -mcpu=cortex-m3 -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols
#-------------------------------------------------------------------------------
# CPP source files and objects
#-------------------------------------------------------------------------------
CPP_SRC=$(wildcard $(PROJECT_BASE_PATH)/*.cpp)
CPP_OBJ_TEMP = $(patsubst %.cpp, %.o, $(notdir $(CPP_SRC)))
# during development, remove some files
CPP_OBJ_FILTER=
CPP_OBJ=$(filter-out $(CPP_OBJ_FILTER), $(CPP_OBJ_TEMP))
#-------------------------------------------------------------------------------
# Rules
#-------------------------------------------------------------------------------
all: test
test: create_output libsam_$(CHIP_NAME)_$(TOOLCHAIN)_$(LIBS_POSTFIX).a libarduino_$(VARIANT)_$(TOOLCHAIN)_$(LIBS_POSTFIX).a libvariant_$(VARIANT)_$(TOOLCHAIN)_$(LIBS_POSTFIX).a $(OUTPUT_BIN)
.PHONY: create_output
create_output:
@echo --- Preparing $(VARIANT) files in $(OUTPUT_PATH) $(OUTPUT_BIN)
# @echo -------------------------
# @echo *$(INCLUDES)
# @echo -------------------------
# @echo *$(C_SRC)
# @echo -------------------------
# @echo *$(C_OBJ)
# @echo -------------------------
# @echo *$(addprefix $(OUTPUT_PATH)/, $(C_OBJ))
# @echo -------------------------
# @echo *$(CPP_SRC)
# @echo -------------------------
# @echo *$(CPP_OBJ)
# @echo -------------------------
# @echo *$(addprefix $(OUTPUT_PATH)/, $(CPP_OBJ))
# @echo -------------------------
# @echo *$(A_SRC)
# @echo -------------------------
-@mkdir $(OUTPUT_PATH) 1>NUL 2>&1
$(addprefix $(OUTPUT_PATH)/,$(CPP_OBJ)): $(OUTPUT_PATH)/%.o: %.cpp
# @"$(CC)" -c $(CPPFLAGS) $< -o $@
@"$(CXX)" -c $(CPPFLAGS) $< -o $@
# @"$(CXX)" -v -c $(CPPFLAGS) $< -o $@
$(OUTPUT_BIN): $(addprefix $(OUTPUT_PATH)/, $(C_OBJ)) $(addprefix $(OUTPUT_PATH)/, $(CPP_OBJ)) $(addprefix $(OUTPUT_PATH)/, $(A_OBJ))
@"$(CC)" $(LIB_PATH) $(LDFLAGS) -T"$(VARIANT_PATH)/linker_scripts/gcc/flash.ld" -Wl,-Map,$(OUTPUT_PATH)/$@.map -o $(OUTPUT_PATH)/$@.elf $^ $(LIBS)
# @"$(CC)" $(LIB_PATH) $(LDFLAGS) -T"$(VARIANT_PATH)/linker_scripts/gcc/sram.ld" -Wl,-Map,$(OUTPUT_PATH)/$@.map -o $(OUTPUT_PATH)/$@.elf $^ $(LIBS)
@"$(NM)" $(OUTPUT_PATH)/$@.elf >$(OUTPUT_PATH)/$@.elf.txt
@"$(OBJCOPY)" -O binary $(OUTPUT_PATH)/$@.elf $(OUTPUT_PATH)/$@.bin
$(SIZE) $^ $(OUTPUT_PATH)/$@.elf
.PHONY: clean
clean:
@echo --- Cleaning test files
-@$(RM) $(OUTPUT_PATH) 1>NUL 2>&1
# -$(RM) $(OUTPUT_PATH)/test.o
# -$(RM) $(OUTPUT_PATH)/$(OUTPUT_BIN).elf
# -$(RM) $(OUTPUT_PATH)/$(OUTPUT_BIN).elf.txt
# -$(RM) $(OUTPUT_PATH)/$(OUTPUT_BIN).bin
# -$(RM) $(OUTPUT_PATH)/$(OUTPUT_BIN).map
debug: test
@"$(GDB)" -x "$(VARIANT_PATH)/debug_scripts/gcc/$(VARIANT)_flash.gdb" -ex "reset" -readnow -se $(OUTPUT_PATH)/$(OUTPUT_BIN).elf
# @"$(GDB)" -w -x "$(VARIANT_PATH)/debug_scripts/gcc/$(VARIANT)_sram.gdb" -ex "reset" -readnow -se $(OUTPUT_PATH)/$(OUTPUT_BIN).elf
libsam_$(CHIP_NAME)_$(TOOLCHAIN)_$(LIBS_POSTFIX).a:
@echo Building $@
@$(MAKE) -C $(SYSTEM_PATH)/libsam/build_gcc -f Makefile $@
libarduino_$(VARIANT)_$(TOOLCHAIN)_$(LIBS_POSTFIX).a:
@echo Building $@
$(MAKE) -C $(ARDUINO_CORE_PATH)/build_gcc -f Makefile $(VARIANT)
libvariant_$(VARIANT)_$(TOOLCHAIN)_$(LIBS_POSTFIX).a:
@echo Building $@
$(MAKE) -C $(VARIANT_PATH)/build_gcc -f Makefile $(VARIANT)

View File

@ -0,0 +1,288 @@
#ifndef _DESCRIPTOR_PARSER_
#define _DESCRIPTOR_PARSER_
typedef void (*PARSE)( uint8_t* buffer, uint8_t pkt_size );
/* Common Messages */
const char descr_len[] = "Descriptor Length:\t";
const char descr_type[] = "Descriptor type:\t";
const char class_str[] = "Class:\t\t\t";
const char subclass_str[] = "Subclass:\t\t";
const char protocol_str[] = "Protocol:\t\t";
const char maxpktsize_str[] = "Max.packet size:\t";
const char unk_msg[] = " Unknown";
const char reserved_msg[] = "Reserved";
const char rcode_error_msg[] = "\r\nRequest error. Return code: ";
/* Endpoint attributes */
const char control_tr[] = "Control";
const char iso_tr[] = "Isochronous";
const char bulk_tr[] = "Bulk";
const char int_tr[] = "Interrupt";
const char* transfer_types[] =
{
control_tr,
iso_tr,
bulk_tr,
int_tr
};
const char nosync_type[] = "No Synchronization";
const char async_type[] = "Asynchronous";
const char adaptive_type[] = "Adaptive";
const char sync_type[] = "Synchronous";
const char* sync_types[] =
{
nosync_type,
async_type,
adaptive_type,
sync_type
};
const char data_usage[] = "Data";
const char feedback_usage[] = "Feedback";
const char implicit_usage[] = "Implicit Feedback Data";
const char reserved_usage[] = "Reserved";
const char* usage_types[] =
{
data_usage,
feedback_usage,
implicit_usage,
reserved_usage
};
/* HID Country Codes */
const char notsupported_cc[] = "Not Supported";
const char arabic_cc[] = "Arabic";
const char belgian_cc[] = "Belgian";
const char canadianbi_cc[] = "Canadian-Bilingual";
const char canadianfr_cc[] = "Canadian-French";
const char czech_cc[] = "Czech Republic";
const char danish_cc[] = "Danish";
const char finnish_cc[] = "Finnish";
const char french_cc[] = "French";
const char german_cc[] = "German";
const char greek_cc[] = "Greek";
const char hebrew_cc[] = "Hebrew";
const char hungary_cc[] = "Hungary";
const char intl_cc[] = "International (ISO)";
const char italian_cc[] = "Italian";
const char japan_cc[] = "Japan (Katakana)";
const char korean_cc[] = "Korean";
const char latam_cc[] = "Latin American";
const char dutch_cc[] = "Netherlands/Dutch";
const char norwegian_cc[] = "Norwegian";
const char persian_cc[] = "Persian (Farsi)";
const char poland_cc[] = "Poland";
const char portuguese_cc[] = "Portuguese";
const char russia_cc[] = "Russia";
const char slovakia_cc[] = "Slovakia";
const char spanish_cc[] = "Spanish";
const char swedish_cc[] = "Swedish";
const char swiss_fr_cc[] = "Swiss/French";
const char swiss_ger_cc[] = "Swiss/German";
const char swiss_cc[] = "Switzerland";
const char taiwan_cc[] = "Taiwan";
const char turkish_q_cc[] = "Turkish-Q";
const char uk_cc[] = "UK";
const char us_cc[] = "US";
const char yugo_cc[] = "Yugoslavia";
const char turkish_f_cc[] = "Turkish-F";
const char* HID_Country_Codes[] =
{
notsupported_cc,
arabic_cc,
belgian_cc,
canadianbi_cc,
canadianfr_cc,
czech_cc,
danish_cc,
finnish_cc,
french_cc,
german_cc,
greek_cc,
hebrew_cc,
hungary_cc,
intl_cc,
italian_cc,
japan_cc,
korean_cc,
latam_cc,
dutch_cc,
norwegian_cc,
persian_cc,
poland_cc,
portuguese_cc,
russia_cc,
slovakia_cc,
spanish_cc,
swedish_cc,
swiss_fr_cc,
swiss_ger_cc,
swiss_cc,
taiwan_cc,
turkish_q_cc,
uk_cc,
us_cc,
yugo_cc,
turkish_f_cc
};
/* HID report descriptor parser string definitions */
/* Item type strings */
const char btype_main[] = "Main";
const char btype_global[] = "Global";
const char btype_local[] = "Local";
const char btype_reserved[] = "Reserved";
/* Item types strings array. Array index corresponds to bType */
const char* btypes[] =
{
btype_main,
btype_global,
btype_local,
btype_reserved
};
/* Main Item Tag Strings */
const char main_tag_input[] = "Input ";
const char main_tag_output[] = "Output ";
const char main_tag_collection[] = "Collection ";
const char main_tag_feature[] = "Feature ";
const char main_tag_endcoll[] = "End Collection\r\n";
/* Main Item Tags Strings Array */
const char* maintags[] =
{
main_tag_input,
main_tag_output,
main_tag_collection,
main_tag_feature,
main_tag_endcoll
};
/* Global Item Tag Strings */
const char global_tag_usagepage[] = "Usage Page ";
const char global_tag_logmin[] = "Logical Minimum ";
const char global_tag_logmax[] = "Logical Maximum ";
const char global_tag_physmin[] = "Physical Minimum ";
const char global_tag_physmax[] = "Physical Maximum ";
const char global_tag_unitexp[] = "Unit Exponent ";
const char global_tag_unit[] = "Unit ";
const char global_tag_repsize[] = "Report Size ";
const char global_tag_repid[] = "Report ID ";
const char global_tag_repcount[] = "Report Count ";
const char global_tag_push[] = "Push";
const char global_tag_pop[] = "Pop";
/* Global Item Tag Strings Array */
const char* globaltags[] =
{
global_tag_usagepage,
global_tag_logmin,
global_tag_logmax,
global_tag_physmin,
global_tag_physmax,
global_tag_unitexp,
global_tag_unit,
global_tag_repsize,
global_tag_repid,
global_tag_repcount,
global_tag_push,
global_tag_pop
};
/* Local Item Tag Strings */
const char local_tag_usage[] = "Usage ";
const char local_tag_usagemin[] = "Usage Minimum ";
const char local_tag_usagemax[] = "Usage Maximum ";
const char local_tag_desidx[] = "Designator Index ";
const char local_tag_desmin[] = "Designator Minimum ";
const char local_tag_desmax[] = "Designator Maximum ";
const char local_tag_stridx[] = "String Index ";
const char local_tag_strmin[] = "String Minimum ";
const char local_tag_strmax[] = "String Maximum ";
const char local_tag_delimiter[] = "Delimiter ";
/* Local Item Tag Strings Array */
const char* localtags[] =
{
local_tag_usage,
local_tag_usagemin,
local_tag_usagemax,
local_tag_desidx,
local_tag_desmin,
local_tag_desmax,
local_tag_stridx,
local_tag_strmin,
local_tag_strmax,
local_tag_delimiter
};
/* Collection Types Strings */
const char coll_phy[] = "Physical (group of axes)";
const char coll_app[] = "Application (mouse, keyboard)";
const char coll_log[] = "Logical (interrelated data)";
const char coll_rep[] = "Report";
const char coll_arr[] = "Named Array";
const char coll_usw[] = "Usage Switch";
const char coll_umod[] = "Usage Modifier";
/* Collection Types Strings Array */
const char* collections[] =
{
coll_phy,
coll_app,
coll_log,
coll_rep,
coll_arr,
coll_usw,
coll_umod
};
/* Usage Pages Strings */
const char up_undef[] = "Undefined";
const char up_gendesk[] = "Generic Desktop Controls";
const char up_sim[] = "Simulation Controls";
const char up_vr[] = "VR Controls";
const char up_sport[] = "Sport Controls";
const char up_game[] = "Game Controls";
const char up_gendev[] = "Generic Device Controls";
const char up_kbd[] = "Keyboard/Keypad";
const char up_led[] = "LEDs";
const char up_button[] = "Button";
const char up_ord[] = "Ordinal";
const char up_tele[] = "Telephony";
const char up_cons[] = "Consumer";
const char up_dig[] = "Digitizer";
//const char up_res[] = "Reserved";
const char up_pid[] = "PID Page";
const char up_uni[] = "Unicode";
/* Usage Pages Strings Array */
const char * usage_pages[] =
{
up_undef,
up_gendesk,
up_sim,
up_vr,
up_sport,
up_game,
up_gendev,
up_kbd,
up_led,
up_button,
up_ord,
up_tele,
up_cons,
up_dig,
reserved_msg,
up_pid,
up_uni
};
#endif //_DESCRIPTOR_PARSER_

View File

@ -0,0 +1,780 @@
/*
Copyright (c) 2012 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "variant.h"
#include <stdio.h>
#include "descriptor_parser.h"
#define LOBYTE(x) ((char*)(&(x)))[0]
#define HIBYTE(x) ((char*)(&(x)))[1]
#define BUFSIZE 256
#define DEVADDR 1
#define getReportDescr(addr, ep, nbytes, buf) Usb.ctrlReq(addr, ep, bmREQ_HIDREPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00, HID_DESCRIPTOR_REPORT, 0x0000, nbytes, buf)
USBHost Usb;
/* Forward declarations */
void HIDreport_parse(uint8_t* buffer, uint8_t pkt_size);
void print_mainbitfield(uint8_t byte_toparse);
void printunkdescr(uint8_t* descr_ptr);
void printhid_descr(uint8_t* descr_ptr);
void printepdescr(uint8_t* descr_ptr);
void printintfdescr(uint8_t* descr_ptr);
void printconfdescr(uint8_t* descr_ptr);
uint32_t getconfdescr(uint32_t addr, uint32_t conf);
void classname_parse(byte class_number);
uint32_t getstrdescr(uint32_t addr, uint32_t idx);
uint32_t getdevdescr(uint32_t addr);
_Pragma("pack(1)")
typedef struct
{
uint8_t bDescriptorType;
uint16_t wDescriptorLength;
} HID_CLASS_DESCRIPTOR;
_Pragma("pack()")
void setup()
{
cpu_irq_enable();
printf("\r\nProgram started:\r\n");
delay(200);
}
void loop()
{
uint8_t tmpbyte = 0;
Usb.Task();
// If state configuring or higher
if (Usb.getUsbTaskState() >= USB_STATE_CONFIGURING)
{
// Printing device descriptor
printf("\r\nDevice addressed...\r\n");
printf("Requesting device descriptor.\r\n");
// Number of configurations, 0 if error
tmpbyte = getdevdescr(DEVADDR);
if (tmpbyte == 0)
{
printf("\r\nDevice descriptor cannot be retrieved. Program Halted!\r\n");
while (1)
;
}
// Print configuration descriptors for all configurations
for (uint8_t i = 0; i < tmpbyte; i++)
{
getconfdescr(DEVADDR, i);
}
while (1)
;
}
}
/**
* Get device descriptor.
* Return number of configurations or zero on error.
*/
uint32_t getdevdescr(uint32_t addr)
{
USB_DEVICE_DESCRIPTOR buf;
uint32_t rcode;
rcode = Usb.getDevDescr(addr, 0, 0x12, (uint8_t*)&buf);
if (rcode)
{
printf("\r\n%s %lu\r\n", rcode_error_msg, rcode);
return 0;
}
printf("\r\nDevice descriptor: \r\n");
// Descriptor length
printf("%s0x%x\r\n", descr_len, buf.bLength);
// Descriptor type
printf("%s0x%x\r\n", descr_type, buf.bDescriptorType);
// USB Version
printf("USB version:\t\t0x%x\r\n", buf.bcdUSB);
// Device class
printf("%s0x%x", class_str, buf.bDeviceClass);
classname_parse(buf.bDeviceClass);
printf("\r\n");
// Device Subclass
printf("%s0x%x\r\n", subclass_str, buf.bDeviceSubClass);
// Device Protocol
printf("%s0x%x\r\n", protocol_str, buf.bDeviceProtocol);
// Max.packet size
printf("%s0x%x\r\n", maxpktsize_str, buf.bMaxPacketSize0);
// VID
printf("Vendor ID:\t\t0x%x\r\n", buf.idVendor);
// PID
printf("Product ID:\t\t0x%x\r\n", buf.idProduct);
// Revision
printf("Revision ID:\t\t0x%x\r\n", buf.bcdDevice);
// Mfg.string
printf("Mfg.string index:\t0x%x", buf.iManufacturer);
getstrdescr(addr, buf.iManufacturer);
// Prod.string
printf("Prod.string index:\t0x%x", buf.iProduct);
getstrdescr(addr, buf.iProduct);
// Serial number string
printf("Serial number index:\t0x%x", buf.iSerialNumber);
getstrdescr(addr, buf.iSerialNumber);
// Number of configurations
printf("Number of conf.:\t0x%x\r\n", buf.bNumConfigurations);
return buf.bNumConfigurations;
}
/**
* Get string descriptor.
* Takes device address and string index.
*/
uint32_t getstrdescr(uint32_t addr, uint32_t idx)
{
uint8_t buf[BUFSIZE];
uint32_t rcode;
uint32_t length;
uint32_t i;
uint16_t langid;
if (idx == 0)
{
// Don't try to get index zero
printf("\r\n");
return 0;
}
rcode = Usb.getStrDescr(addr, 0, 1, 0, 0, buf);
// Get language table length
if (rcode)
{
printf("\r\nError retrieving LangID table length!\r\n");
return rcode;
}
// Length is the first byte
length = buf[0];
// Get language table
rcode = Usb.getStrDescr(addr, 0, length, 0, 0, buf);
if (rcode)
{
printf("\r\nError retrieving LangID table!\r\n");
return rcode;
}
// Get first langid
langid = buf[3] << 8;
// Bytes are swapped to account for endiannes
langid |= (buf[2] & 0xff);
rcode = Usb.getStrDescr(addr, 0, 1, idx, langid, buf);
if (rcode)
{
printf("\r\nError retrieving string length!\r\n");
return rcode;
}
length = (buf[0] < 254 ? buf[0] : 254);
printf(" Length: %lu", length);
rcode = Usb.getStrDescr(addr, 0, length, idx, langid, buf);
if (rcode)
{
printf("\r\nError retrieving string!\r\n");
return rcode;
}
printf(" Contents: ");
for (i = 2; i < length; i += 2)
{
printf("%c", buf[i]);
}
printf("\r\n");
return idx;
}
/**
* Returns string to class name
*/
void classname_parse(uint8_t class_number)
{
switch(class_number) {
case 0x00:
printf(" Use class information in the Interface Descriptor");
break;
case 0x01:
printf(" Audio");
break;
case 0x02:
printf(" Communications and CDC Control");
break;
case 0x03:
printf(" HID (Human Interface Device)");
break;
case 0x05:
printf(" Physical");
break;
case 0x06:
printf(" Image");
break;
case 0x07:
printf(" Printer");
break;
case 0x08:
printf(" Mass Storage");
break;
case 0x09:
printf(" Hub");
break;
case 0x0a:
printf(" CDC-Data");
break;
case 0x0b:
printf(" Smart Card");
break;
case 0x0d:
printf(" Content Security");
break;
case 0x0e:
printf(" Video");
break;
case 0x0f:
printf(" Personal Healthcare");
break;
case 0xdc:
printf("Diagnostic Device");
break;
case 0xe0:
printf(" Wireless Controller");
break;
case 0xef:
printf(" Miscellaneous");
break;
case 0xfe:
printf(" Application Specific");
break;
case 0xff:
printf(" Vendor Specific");
break;
default:
break;
}
}
/**
* Print configuration descriptor.
*/
uint32_t getconfdescr(uint32_t addr, uint32_t conf)
{
uint8_t buf[BUFSIZE];
uint8_t* buf_ptr = buf;
uint32_t rcode = 0;
uint8_t confdescr_length = 0;
uint8_t confdescr_type = 0;
uint32_t total_length = 0;
printf("\r\nConfiguration number %lu:\r\n", conf);
rcode = Usb.getConfDescr(addr, 0, 4, conf, buf); //get total length
if (rcode)
{
printf("\r\nError retrieving configuration length. Error code %lu\r\n", rcode);
return(0);
}
total_length = buf[3] << 8;
total_length |= (buf[2] & 0xff);
if (total_length > BUFSIZE)
{
// Check if total length is larger than buffer
printf("Total length truncated to %d bytes\r\n", BUFSIZE);
total_length = BUFSIZE;
}
// Get the whole descriptor
rcode = Usb.getConfDescr(addr, 0, total_length, conf, buf);
while (buf_ptr < buf + total_length)
{
// Parsing descriptors
confdescr_length = *(buf_ptr);
confdescr_type = *(buf_ptr + 1);
switch (confdescr_type)
{
case(USB_DESCRIPTOR_CONFIGURATION):
printconfdescr(buf_ptr);
break;
case(USB_DESCRIPTOR_INTERFACE):
printintfdescr(buf_ptr);
break;
case(USB_DESCRIPTOR_ENDPOINT):
printepdescr(buf_ptr);
break;
case(HID_DESCRIPTOR_HID):
printhid_descr(buf_ptr);
break;
default:
printunkdescr(buf_ptr);
break;
}
// Advance buffer pointer
buf_ptr = (buf_ptr + confdescr_length);
}
return 0;
}
/**
* Print configuration descriptor.
*/
void printconfdescr(uint8_t* descr_ptr)
{
USB_CONFIGURATION_DESCRIPTOR* conf_ptr = (USB_CONFIGURATION_DESCRIPTOR*)descr_ptr;
uint8_t tmpbyte = 0;
printf("\r\n\nConfiguration descriptor:\r\n");
printf("Total length:\t\t%d\r\n", conf_ptr->wTotalLength);
printf("\r\nNumber of interfaces:\t%d\r\n", conf_ptr->bNumInterfaces);
printf("Configuration value:\t%d\r\n", conf_ptr->bConfigurationValue);
printf("Configuration string:\t");
tmpbyte = conf_ptr->iConfiguration;
printf("0x%x", tmpbyte);
getstrdescr(DEVADDR, tmpbyte);
printf("Attributes:\t\t");
tmpbyte = conf_ptr->bmAttributes;
printf("0x%x", tmpbyte);
if (tmpbyte & 0x40)
{
// D6
printf(" Self-powered\r\n");
}
if (tmpbyte & 0x20)
{
// D5
printf(" Remote Wakeup\r\n");
}
printf("Max.power:\t\t");
tmpbyte = conf_ptr->bMaxPower;
printf("0x%x", tmpbyte);
printf(" ");
printf("%d", (tmpbyte * 2));
printf("ma\r\n");
}
/**
* Print interface descriptor.
*/
void printintfdescr(uint8_t* descr_ptr)
{
USB_INTERFACE_DESCRIPTOR* intf_ptr = (USB_INTERFACE_DESCRIPTOR*)descr_ptr;
uint8_t tmpbyte = 0;
printf("\r\nInterface descriptor:\r\n");
printf("Interface number:\t%d\r\n", intf_ptr->bInterfaceNumber);
printf("Alternate setting:\t%d\r\n", intf_ptr->bAlternateSetting);
printf("Endpoints:\t\t%d\r\n", intf_ptr->bNumEndpoints);
printf("%s", class_str);
tmpbyte = intf_ptr->bInterfaceClass;
printf("0x%x", tmpbyte);
classname_parse(tmpbyte);
printf("\r\n");
printf("%s%d\r\n", subclass_str, intf_ptr->bInterfaceSubClass);
printf("%s%d\r\n", protocol_str, intf_ptr->bInterfaceProtocol);
printf("Interface string:\t");
tmpbyte = intf_ptr->iInterface;
printf("0x%x", tmpbyte);
getstrdescr(DEVADDR, tmpbyte);
}
/**
* Print endpoint descriptor.
*/
void printepdescr(uint8_t* descr_ptr)
{
USB_ENDPOINT_DESCRIPTOR* ep_ptr = (USB_ENDPOINT_DESCRIPTOR*)descr_ptr;
uint8_t tmpbyte = 0;
printf("\r\nEndpoint descriptor:\r\n");
printf("Endpoint address:\t");
tmpbyte = ep_ptr->bEndpointAddress;
printf("0x%x", tmpbyte & 0x0f);
printf(" Direction: ");
(tmpbyte & 0x80) ? printf("IN\r\n") : printf("OUT\r\n");
printf("Attributes:\t\t");
tmpbyte = ep_ptr->bmAttributes;
printf("0x%x", tmpbyte);
printf(" Transfer type: %s", transfer_types[(tmpbyte & 0x03)]);
if ((tmpbyte & 0x03) == 1)
{
// Isochronous Transfer
printf(", Sync Type: ");
printf("%s", sync_types[(tmpbyte & 0x0c)]);
printf(", Usage Type: ");
printf("%s", usage_types[(tmpbyte & 0x30)]);
}
printf("\r\n");
printf("%s%d\r\n", maxpktsize_str, ep_ptr->wMaxPacketSize);
printf("Polling interval:\t");
tmpbyte = ep_ptr->bInterval;
printf("0x%x", tmpbyte);
printf(" ");
printf("%d", tmpbyte);
printf(" ms\r\n");
}
/**
* Print HID descriptor.
*/
void printhid_descr(uint8_t* descr_ptr)
{
//PARSE pf = HIDreport_parse;
USB_HID_DESCRIPTOR* hid_ptr = (USB_HID_DESCRIPTOR*)descr_ptr;
uint8_t tmpbyte = 0;
printf("\r\nHID descriptor:\r\n");
printf("Descriptor length:\t");
tmpbyte = hid_ptr->bLength;
printf("0x%x %d bytes\r\n", tmpbyte, tmpbyte);
printf("HID version:\t\t0x%x\r\n", hid_ptr->bcdHID);
tmpbyte = hid_ptr->bCountryCode;
printf("Country Code:\t\t%d ", tmpbyte);
(tmpbyte > 35) ? printf("Reserved\r\n") : printf("%s\r\n", HID_Country_Codes[tmpbyte]);
tmpbyte = hid_ptr->bNumDescriptors;
printf("Class Descriptors:\t%d\r\n", tmpbyte);
// Printing class descriptors
// Advance buffer pointer
descr_ptr += 6;
for (uint8_t i = 0; i < tmpbyte; i++)
{
uint8_t tmpdata = 0;
HID_CLASS_DESCRIPTOR* hidclass_ptr = (HID_CLASS_DESCRIPTOR*)descr_ptr;
tmpdata = hidclass_ptr->bDescriptorType;
printf("Class Descriptor Type:\t0x%x", tmpdata);
if ((tmpdata < 0x21) || (tmpdata > 0x2f))
{
printf(" Invalid");
}
switch(tmpdata)
{
case 0x21:
printf(" HID\r\n");
break;
case 0x22:
printf(" Report\r\n");
break;
case 0x23:
printf(" Physical\r\n");
break;
default:
printf(" Reserved\r\n");
break;
}
printf("Class Descriptor Size: %d bytes\r\n", hidclass_ptr->wDescriptorLength);
printf("\r\nHID report descriptor:\r\n");
uint8_t buf[hidclass_ptr->wDescriptorLength];
getReportDescr(DEVADDR, 0 , hidclass_ptr->wDescriptorLength, (uint8_t*)&buf);
HIDreport_parse(buf, hidclass_ptr->wDescriptorLength);
// Advance to the next record
descr_ptr += 3;
}
printf("\r\n");
}
/**
* Print unknown descriptor.
*/
void printunkdescr(uint8_t* descr_ptr)
{
uint8_t length = *descr_ptr;
uint32_t i = 0;
printf("\r\nUnknown descriptor:\r\n");
printf("Length:\t\t%d\r\n", *descr_ptr);
printf("Type:\t\t %d\r\n", *(descr_ptr + 1));
printf("Contents:\t");
descr_ptr += 2;
for (i = 0; i < length; i++)
{
printf("%d", *descr_ptr);
descr_ptr++;
}
printf("\r\n");
}
/**
* Print bitfields in main items.
*/
void print_mainbitfield(uint8_t byte_toparse)
{
(byte_toparse & 0x01) ? printf("Constant,") : printf("Data,"); //bit 0
(byte_toparse & 0x02) ? printf("Variable,") : printf("Array,"); //bit 1
(byte_toparse & 0x04) ? printf("Relative,") : printf("Absolute,"); //...
(byte_toparse & 0x08) ? printf("Wrap,") : printf("No Wrap,");
(byte_toparse & 0x10) ? printf("Non Linear,") : printf("Linear,");
(byte_toparse & 0x20) ? printf("No preferred,") : printf("Preferred State,");
(byte_toparse & 0x40) ? printf("Null State,") : printf("No Null Position,"); //bit 6
(byte_toparse & 0x40) ? printf("Volatile(ignore for Input),") : printf("Non-volatile(Ignore for Input),"); //bit 7
}
/**
* HID Report Desriptor Parser Callback.
* Called repeatedly from Control transfer function.
*/
void HIDreport_parse(uint8_t* buffer, uint8_t pkt_size)
{
#define B_SIZE 0x03 //bSize bitmask
#define B_TYPE 0x0c //bType bitmask
#define B_TAG 0xf0 //bTag bitmask
// Parser states
enum STATE { ITEM_START, DATA_PARSE };
static STATE state = ITEM_START;
static uint8_t databytes_left = 0;
static uint8_t databytes_left2 = 0;
static uint8_t prefix; //item prefix - type and tag
uint8_t byte_toparse;
uint8_t bType;
uint8_t tmpbyte;
uint32_t i = 0, j = 0;
while (1)
{
if (i < pkt_size)
{
i = i + 1;
byte_toparse = buffer[i];
}
else
{
return;
}
switch(state)
{
// Start of the record
case ITEM_START:
// Store prefix for databyte parsing
prefix = byte_toparse >> 2;
tmpbyte = byte_toparse & B_SIZE;
// Get item length
(tmpbyte == 0x03) ? databytes_left = 4 : databytes_left = tmpbyte;
if (databytes_left)
{
// Read bytes after prefix
state = DATA_PARSE;
}
printf("bSize: %d", databytes_left);
databytes_left2 = databytes_left;
// Get item type
bType = (byte_toparse & B_TYPE) >> 2;
printf(" bType: %s", btypes[bType]);
// Get item tag
printf("\t\tbTag: ");
tmpbyte = (byte_toparse & B_TAG) >> 4 ;
switch(bType)
{
case 0: // Main
if (tmpbyte < 0x08)
{
printf("Invalid Tag");
}
else if (tmpbyte > 0x0c)
{
printf("%s", reserved_msg);
}
else
{
printf("%s", maintags[tmpbyte - 8]);
}
break;
case 1: // Global
(tmpbyte > 0x0b) ? printf("%s", reserved_msg) : printf("%s", globaltags[tmpbyte]);
break;
case 2: // Local
(tmpbyte > 0x0a) ? printf("%s", reserved_msg) : printf("%s", localtags[tmpbyte]);
break;
default:
break;
}
break;
case DATA_PARSE:
switch(prefix)
{
case 0x20: // Main Input
case 0x24: // Main Output
case 0x2c: // Main Feature
// TODO: add parsing 8th bit
print_mainbitfield(byte_toparse);
break;
case 0x28: //Main Collection
if ((byte_toparse > 0x06) && (byte_toparse < 0x80))
{
printf("%s", reserved_msg);
}
else if ((byte_toparse > 0x7f) && (byte_toparse <= 0xff))
{
printf("Vendor-defined");
}
else
{
printf("%s", collections[byte_toparse]);
}
break;
//case 0x30: //Main End Collection
case 0x01: //Global Usage Page
switch(byte_toparse)
{
// See HID Usage Tables doc v.1.12 page 14
case 0x00:
case 0x01:
case 0x02:
case 0x03:
case 0x04:
case 0x05:
case 0x06:
case 0x07:
case 0x08:
case 0x09:
case 0x0a:
case 0x0b:
case 0x0c:
case 0x0d:
case 0x0e:
case 0x0f:
case 0x10:
printf("%s", usage_pages[byte_toparse]);
break;
case 0x14:
printf("Alphanumeric Display");
break;
case 0x40:
printf("Medical Instruments");
break;
case 0x80:
case 0x81:
case 0x82:
case 0x83:
printf("Monitor page");
break;
case 0x84:
case 0x85:
case 0x86:
case 0x87:
printf("Power page");
break;
case 0x8c:
printf("Bar Code Scanner page");
break;
case 0x8d:
printf("Scale page");
break;
case 0x8e:
printf("Magnetic Stripe Reading (MSR) Devices");
break;
case 0x8f:
printf("Reserved Point of Sale pages");
break;
case 0x90:
printf("Camera Control Page");
break;
case 0x91:
printf("Arcade Page");
break;
default:
break;
}
}
databytes_left--;
if (!databytes_left)
{
printf(" (data=0x");
for (j = 0; j < databytes_left2; ++j)
printf("%02x", buffer[i - j]);
printf(")\r\n");
state = ITEM_START;
}
break;
}
}
}

View File

@ -2,9 +2,9 @@ set Path=%ARM_GCC_TOOLCHAIN%
export Path
start "libsam" /d"system\libsam\build_gcc" /max "cd"
start "libarduino" /d"cores\sam\build_gcc" /max "cd"
start "libarduino" /d"cores\arduino\build_gcc" /max "cd"
rem start "libvariant Arduino Due U" /d"variants\arduino_due_u\build_gcc" /max "cd"
start "libvariant Arduino Due X" /d"variants\arduino_due_x\build_gcc" /max "cd"
start "libvariant ADK2" /d"..\..\google\sam\variants\adk2\build_gcc" /max "cd"
start "libvariant SAM3X-EK" /d"..\..\atmel\sam\variants\sam3x_ek\build_gcc" /max "cd"
start "test" /d"cores\sam\validation\build_gcc" /max "cd"
rem start "libvariant ADK2" /d"..\..\google\sam\variants\adk2\build_gcc" /max "cd"
rem start "libvariant SAM3X-EK" /d"..\..\atmel\sam\variants\sam3x_ek\build_gcc" /max "cd"
start "test" /d"cores\arduino\validation_usb_host\build_gcc" /max "cd"

View File

@ -1,295 +0,0 @@
/* Copyright 2009-2011 Oleg Mazurov, Circuits At Home, http://www.circuitsathome.com */
/* MAX3421E USB host controller support */
#include "Max3421e.h"
// #include "Max3421e_constants.h"
static byte vbusState;
/* Functions */
/* Constructor */
MAX3421E::MAX3421E()
{
spi_init();
#if !defined(TARGET_MEGA_ADK)
pinMode( MAX_INT, INPUT);
pinMode( MAX_GPX, INPUT );
#else
// "Internal" pins so can't use Arduino helper functions.
INT_DDR &= ~_BV(INT);
GPX_DDR &= ~_BV(GPX);
#endif
pinMode( MAX_SS, OUTPUT );
digitalWrite(MAX_SS,HIGH);
#if !defined(TARGET_MEGA_ADK)
pinMode( MAX_RESET, OUTPUT );
digitalWrite( MAX_RESET, HIGH ); //release MAX3421E from reset
#else
// "Internal" pins so can't use Arduino helper functions.
RST_DDR |= _BV(RST);
RST_PORT |= _BV(RST); // Equivalent to setRST(HIGH) from old code.
#endif
}
byte MAX3421E::getVbusState( void )
{
return( vbusState );
}
/* initialization */
//void MAX3421E::init()
//{
// /* setup pins */
// pinMode( MAX_INT, INPUT);
// pinMode( MAX_GPX, INPUT );
// pinMode( MAX_SS, OUTPUT );
// //pinMode( BPNT_0, OUTPUT );
// //pinMode( BPNT_1, OUTPUT );
// //digitalWrite( BPNT_0, LOW );
// //digitalWrite( BPNT_1, LOW );
// Deselect_MAX3421E;
// pinMode( MAX_RESET, OUTPUT );
// digitalWrite( MAX_RESET, HIGH ); //release MAX3421E from reset
//}
//byte MAX3421E::getVbusState( void )
//{
// return( vbusState );
//}
//void MAX3421E::toggle( byte pin )
//{
// digitalWrite( pin, HIGH );
// digitalWrite( pin, LOW );
//}
/* Single host register write */
void MAX3421E::regWr( byte reg, byte val)
{
digitalWrite(MAX_SS,LOW);
SPDR = ( reg | 0x02 );
while(!( SPSR & ( 1 << SPIF )));
SPDR = val;
while(!( SPSR & ( 1 << SPIF )));
digitalWrite(MAX_SS,HIGH);
return;
}
/* multiple-byte write */
/* returns a pointer to a memory position after last written */
char * MAX3421E::bytesWr( byte reg, byte nbytes, char * data )
{
digitalWrite(MAX_SS,LOW);
SPDR = ( reg | 0x02 );
while( nbytes-- ) {
while(!( SPSR & ( 1 << SPIF ))); //check if previous byte was sent
SPDR = ( *data ); // send next data byte
data++; // advance data pointer
}
while(!( SPSR & ( 1 << SPIF )));
digitalWrite(MAX_SS,HIGH);
return( data );
}
/* GPIO write. GPIO byte is split between 2 registers, so two writes are needed to write one byte */
/* GPOUT bits are in the low nibble. 0-3 in IOPINS1, 4-7 in IOPINS2 */
/* upper 4 bits of IOPINS1, IOPINS2 are read-only, so no masking is necessary */
void MAX3421E::gpioWr( byte val )
{
regWr( rIOPINS1, val );
val = val >>4;
regWr( rIOPINS2, val );
return;
}
/* Single host register read */
byte MAX3421E::regRd( byte reg )
{
byte tmp;
digitalWrite(MAX_SS,LOW);
SPDR = reg;
while(!( SPSR & ( 1 << SPIF )));
SPDR = 0; //send empty byte
while(!( SPSR & ( 1 << SPIF )));
digitalWrite(MAX_SS,HIGH);
return( SPDR );
}
/* multiple-bytes register read */
/* returns a pointer to a memory position after last read */
char * MAX3421E::bytesRd ( byte reg, byte nbytes, char * data )
{
digitalWrite(MAX_SS,LOW);
SPDR = reg;
while(!( SPSR & ( 1 << SPIF ))); //wait
while( nbytes ) {
SPDR = 0; //send empty byte
nbytes--;
while(!( SPSR & ( 1 << SPIF )));
*data = SPDR;
data++;
}
digitalWrite(MAX_SS,HIGH);
return( data );
}
/* GPIO read. See gpioWr for explanation */
/* GPIN pins are in high nibbles of IOPINS1, IOPINS2 */
byte MAX3421E::gpioRd( void )
{
byte tmpbyte = 0;
tmpbyte = regRd( rIOPINS2 ); //pins 4-7
tmpbyte &= 0xf0; //clean lower nibble
tmpbyte |= ( regRd( rIOPINS1 ) >>4 ) ; //shift low bits and OR with upper from previous operation. Upper nibble zeroes during shift, at least with this compiler
return( tmpbyte );
}
/* reset MAX3421E using chip reset bit. SPI configuration is not affected */
boolean MAX3421E::reset()
{
unsigned short tmp = 0;
regWr( rUSBCTL, bmCHIPRES ); //Chip reset. This stops the oscillator
regWr( rUSBCTL, 0x00 ); //Remove the reset
while(!(regRd( rUSBIRQ ) & bmOSCOKIRQ )) { //wait until the PLL is stable
tmp++; //timeout after 256 attempts
if( tmp == 0 ) {
return( false );
}
}
return( true );
}
/* turn USB power on/off */
/* does nothing, returns TRUE. Left for compatibility with old sketches */
/* will be deleted eventually */
///* ON pin of VBUS switch (MAX4793 or similar) is connected to GPOUT7 */
///* OVERLOAD pin of Vbus switch is connected to GPIN7 */
///* OVERLOAD state low. NO OVERLOAD or VBUS OFF state high. */
boolean MAX3421E::vbusPwr ( boolean action )
{
// byte tmp;
// tmp = regRd( rIOPINS2 ); //copy of IOPINS2
// if( action ) { //turn on by setting GPOUT7
// tmp |= bmGPOUT7;
// }
// else { //turn off by clearing GPOUT7
// tmp &= ~bmGPOUT7;
// }
// regWr( rIOPINS2, tmp ); //send GPOUT7
// if( action ) {
// delay( 60 );
// }
// if (( regRd( rIOPINS2 ) & bmGPIN7 ) == 0 ) { // check if overload is present. MAX4793 /FLAG ( pin 4 ) goes low if overload
// return( false );
// }
return( true ); // power on/off successful
}
/* probe bus to determine device presense and speed and switch host to this speed */
void MAX3421E::busprobe( void )
{
byte bus_sample;
bus_sample = regRd( rHRSL ); //Get J,K status
bus_sample &= ( bmJSTATUS|bmKSTATUS ); //zero the rest of the byte
switch( bus_sample ) { //start full-speed or low-speed host
case( bmJSTATUS ):
if(( regRd( rMODE ) & bmLOWSPEED ) == 0 ) {
regWr( rMODE, MODE_FS_HOST ); //start full-speed host
vbusState = FSHOST;
}
else {
regWr( rMODE, MODE_LS_HOST); //start low-speed host
vbusState = LSHOST;
}
break;
case( bmKSTATUS ):
if(( regRd( rMODE ) & bmLOWSPEED ) == 0 ) {
regWr( rMODE, MODE_LS_HOST ); //start low-speed host
vbusState = LSHOST;
}
else {
regWr( rMODE, MODE_FS_HOST ); //start full-speed host
vbusState = FSHOST;
}
break;
case( bmSE1 ): //illegal state
vbusState = SE1;
break;
case( bmSE0 ): //disconnected state
regWr( rMODE, bmDPPULLDN|bmDMPULLDN|bmHOST|bmSEPIRQ);
vbusState = SE0;
break;
}//end switch( bus_sample )
}
/* MAX3421E initialization after power-on */
void MAX3421E::powerOn()
{
/* Configure full-duplex SPI, interrupt pulse */
regWr( rPINCTL,( bmFDUPSPI + bmINTLEVEL + bmGPXB )); //Full-duplex SPI, level interrupt, GPX
if( reset() == false ) { //stop/start the oscillator
Serial.println("Error: OSCOKIRQ failed to assert");
}
/* configure host operation */
regWr( rMODE, bmDPPULLDN|bmDMPULLDN|bmHOST|bmSEPIRQ ); // set pull-downs, Host, Separate GPIN IRQ on GPX
regWr( rHIEN, bmCONDETIE|bmFRAMEIE ); //connection detection
/* check if device is connected */
regWr( rHCTL,bmSAMPLEBUS ); // sample USB bus
while(!(regRd( rHCTL ) & bmSAMPLEBUS )); //wait for sample operation to finish
busprobe(); //check if anything is connected
regWr( rHIRQ, bmCONDETIRQ ); //clear connection detect interrupt
regWr( rCPUCTL, 0x01 ); //enable interrupt pin
}
/* MAX3421 state change task and interrupt handler */
byte MAX3421E::Task( void )
{
byte rcode = 0;
byte pinvalue;
//Serial.print("Vbus state: ");
//Serial.println( vbusState, HEX );
#if !defined(TARGET_MEGA_ADK)
pinvalue = digitalRead( MAX_INT );
#else
// "Internal" pin so can't use Arduino helper functions.
pinvalue = INT_PIN & _BV(INT) ? HIGH : LOW; // from old `readINT()`
#endif
if( pinvalue == LOW ) {
rcode = IntHandler();
}
#if !defined(TARGET_MEGA_ADK)
pinvalue = digitalRead( MAX_GPX );
#else
// "Internal" pin so can't use Arduino helper functions.
pinvalue = GPX_PIN & _BV(GPX) ? HIGH : LOW; // from old `readGPX()`
#endif
if( pinvalue == LOW ) {
GpxHandler();
}
// usbSM(); //USB state machine
return( rcode );
}
byte MAX3421E::IntHandler()
{
byte HIRQ;
byte HIRQ_sendback = 0x00;
HIRQ = regRd( rHIRQ ); //determine interrupt source
//if( HIRQ & bmFRAMEIRQ ) { //->1ms SOF interrupt handler
// HIRQ_sendback |= bmFRAMEIRQ;
//}//end FRAMEIRQ handling
if( HIRQ & bmCONDETIRQ ) {
busprobe();
HIRQ_sendback |= bmCONDETIRQ;
}
/* End HIRQ interrupts handling, clear serviced IRQs */
regWr( rHIRQ, HIRQ_sendback );
return( HIRQ_sendback );
}
byte MAX3421E::GpxHandler()
{
byte GPINIRQ = regRd( rGPINIRQ ); //read GPIN IRQ register
// if( GPINIRQ & bmGPINIRQ7 ) { //vbus overload
// vbusPwr( OFF ); //attempt powercycle
// delay( 1000 );
// vbusPwr( ON );
// regWr( rGPINIRQ, bmGPINIRQ7 );
// }
return( GPINIRQ );
}
//void MAX3421E::usbSM( void ) //USB state machine
//{
//
//
//}

View File

@ -1,54 +0,0 @@
/* Copyright 2009-2011 Oleg Mazurov, Circuits At Home, http://www.circuitsathome.com */
/* MAX3421E functions */
#ifndef _MAX3421E_H_
#define _MAX3421E_H_
//#include <Spi.h>
//#include <WProgram.h>
#include "Arduino.h"
#include "Max3421e_constants.h"
class MAX3421E /* : public SPI */ {
// byte vbusState;
public:
MAX3421E( void );
byte getVbusState( void );
// void toggle( byte pin );
static void regWr( byte, byte );
char * bytesWr( byte, byte, char * );
static void gpioWr( byte );
byte regRd( byte );
char * bytesRd( byte, byte, char * );
byte gpioRd( void );
boolean reset();
boolean vbusPwr ( boolean );
void busprobe( void );
void powerOn();
byte IntHandler();
byte GpxHandler();
byte Task();
private:
static void spi_init() {
uint8_t tmp;
// initialize SPI pins
pinMode(SCK_PIN, OUTPUT);
pinMode(MOSI_PIN, OUTPUT);
pinMode(MISO_PIN, INPUT);
pinMode(SS_PIN, OUTPUT);
digitalWrite( SS_PIN, HIGH );
/* mode 00 (CPOL=0, CPHA=0) master, fclk/2. Mode 11 (CPOL=11, CPHA=11) is also supported by MAX3421E */
SPCR = 0x50;
SPSR = 0x01;
/**/
tmp = SPSR;
tmp = SPDR;
}
// void init();
friend class Max_LCD;
};
#endif //_MAX3421E_H_

View File

@ -1,273 +0,0 @@
/* Copyright 2009-2011 Oleg Mazurov, Circuits At Home, http://www.circuitsathome.com */
/* MAX3421E register/bit names and bitmasks */
#ifndef _MAX3421Econstants_h_
#define _MAX3421Econstants_h_
/* SPI pins for diffrent Arduinos */
#define MEGA256_IS_ADK // Undefine this if you're using a non-ADK Mega256
// TODO: Check if the 2560 check should use `defined` too.
#if defined(__AVR_ATmega1280__) || (__AVR_ATmega2560__)
#define SCK_PIN 52
#define MISO_PIN 50
#define MOSI_PIN 51
#if defined(__AVR_ATmega2560__) && defined(MEGA256_IS_ADK)
#define TARGET_MEGA_ADK
#define SS_PIN 53 // TODO: Handle this as an internal pin.
#else
// TODO: Test with Mega + shield combination
#define SS_PIN 53
#endif
#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
#define SCK_PIN 13
#define MISO_PIN 12
#define MOSI_PIN 11
#define SS_PIN 10
#else
#error The currently selected board needs to have its SPI pin definitions added to this file.
#endif
#if !defined(TARGET_MEGA_ADK)
#define MAX_SS SS_PIN
#define MAX_INT 9
#define MAX_GPX 8
#define MAX_RESET 7
#else
// Because the Arduino Mega ADK board uses "internal" pins (i.e. ones that
// are not broken out to headers, are not in `pins_arduino.h` and can't
// be used with functions like `pinMode()` & `digitalWrite()`) they need
// to be defined by the low-level AVR approach.
// These definitions and the code to use them comes from an older version
// of the `Max3421e.cpp` file.
// TODO: Add these internal pins to `pins_arduino.h` for the Mega ADK so
// we can usual the standard Arduino functions & not special-case this?
#define INT PE6
#define INT_PORT PORTE
#define INT_DDR DDRE
#define INT_PIN PINE
#define RST PJ2
#define RST_PORT PORTJ
#define RST_DDR DDRJ
#define RST_PIN PINJ
#define GPX PJ3
#define GPX_PORT PORTJ
#define GPX_DDR DDRJ
#define GPX_PIN PINJ
#define MAX_SS SS_PIN // TODO: Handle this as an internal pin.
#endif
/* "Breakpoint" pins for debugging */
//#define BPNT_0 3
//#define BPNT_1 2
//#define Select_MAX3421E digitalWrite(MAX_SS,LOW)
//#define Deselect_MAX3421E digitalWrite(MAX_SS,HIGH)
/* */
#define ON true
#define OFF false
/* VBUS states */
#define SE0 0
#define SE1 1
#define FSHOST 2
#define LSHOST 3
/* MAX3421E command byte format: rrrrr0wa where 'r' is register number */
//
// MAX3421E Registers in HOST mode.
//
#define rRCVFIFO 0x08 //1<<3
#define rSNDFIFO 0x10 //2<<3
#define rSUDFIFO 0x20 //4<<3
#define rRCVBC 0x30 //6<<3
#define rSNDBC 0x38 //7<<3
#define rUSBIRQ 0x68 //13<<3
/* USBIRQ Bits */
#define bmVBUSIRQ 0x40 //b6
#define bmNOVBUSIRQ 0x20 //b5
#define bmOSCOKIRQ 0x01 //b0
#define rUSBIEN 0x70 //14<<3
/* USBIEN Bits */
#define bmVBUSIE 0x40 //b6
#define bmNOVBUSIE 0x20 //b5
#define bmOSCOKIE 0x01 //b0
#define rUSBCTL 0x78 //15<<3
/* USBCTL Bits */
#define bmCHIPRES 0x20 //b5
#define bmPWRDOWN 0x10 //b4
#define rCPUCTL 0x80 //16<<3
/* CPUCTL Bits */
#define bmPUSLEWID1 0x80 //b7
#define bmPULSEWID0 0x40 //b6
#define bmIE 0x01 //b0
#define rPINCTL 0x88 //17<<3
/* PINCTL Bits */
#define bmFDUPSPI 0x10 //b4
#define bmINTLEVEL 0x08 //b3
#define bmPOSINT 0x04 //b2
#define bmGPXB 0x02 //b1
#define bmGPXA 0x01 //b0
// GPX pin selections
#define GPX_OPERATE 0x00
#define GPX_VBDET 0x01
#define GPX_BUSACT 0x02
#define GPX_SOF 0x03
#define rREVISION 0x90 //18<<3
#define rIOPINS1 0xa0 //20<<3
/* IOPINS1 Bits */
#define bmGPOUT0 0x01
#define bmGPOUT1 0x02
#define bmGPOUT2 0x04
#define bmGPOUT3 0x08
#define bmGPIN0 0x10
#define bmGPIN1 0x20
#define bmGPIN2 0x40
#define bmGPIN3 0x80
#define rIOPINS2 0xa8 //21<<3
/* IOPINS2 Bits */
#define bmGPOUT4 0x01
#define bmGPOUT5 0x02
#define bmGPOUT6 0x04
#define bmGPOUT7 0x08
#define bmGPIN4 0x10
#define bmGPIN5 0x20
#define bmGPIN6 0x40
#define bmGPIN7 0x80
#define rGPINIRQ 0xb0 //22<<3
/* GPINIRQ Bits */
#define bmGPINIRQ0 0x01
#define bmGPINIRQ1 0x02
#define bmGPINIRQ2 0x04
#define bmGPINIRQ3 0x08
#define bmGPINIRQ4 0x10
#define bmGPINIRQ5 0x20
#define bmGPINIRQ6 0x40
#define bmGPINIRQ7 0x80
#define rGPINIEN 0xb8 //23<<3
/* GPINIEN Bits */
#define bmGPINIEN0 0x01
#define bmGPINIEN1 0x02
#define bmGPINIEN2 0x04
#define bmGPINIEN3 0x08
#define bmGPINIEN4 0x10
#define bmGPINIEN5 0x20
#define bmGPINIEN6 0x40
#define bmGPINIEN7 0x80
#define rGPINPOL 0xc0 //24<<3
/* GPINPOL Bits */
#define bmGPINPOL0 0x01
#define bmGPINPOL1 0x02
#define bmGPINPOL2 0x04
#define bmGPINPOL3 0x08
#define bmGPINPOL4 0x10
#define bmGPINPOL5 0x20
#define bmGPINPOL6 0x40
#define bmGPINPOL7 0x80
#define rHIRQ 0xc8 //25<<3
/* HIRQ Bits */
#define bmBUSEVENTIRQ 0x01 // indicates BUS Reset Done or BUS Resume
#define bmRWUIRQ 0x02
#define bmRCVDAVIRQ 0x04
#define bmSNDBAVIRQ 0x08
#define bmSUSDNIRQ 0x10
#define bmCONDETIRQ 0x20
#define bmFRAMEIRQ 0x40
#define bmHXFRDNIRQ 0x80
#define rHIEN 0xd0 //26<<3
/* HIEN Bits */
#define bmBUSEVENTIE 0x01
#define bmRWUIE 0x02
#define bmRCVDAVIE 0x04
#define bmSNDBAVIE 0x08
#define bmSUSDNIE 0x10
#define bmCONDETIE 0x20
#define bmFRAMEIE 0x40
#define bmHXFRDNIE 0x80
#define rMODE 0xd8 //27<<3
/* MODE Bits */
#define bmHOST 0x01
#define bmLOWSPEED 0x02
#define bmHUBPRE 0x04
#define bmSOFKAENAB 0x08
#define bmSEPIRQ 0x10
#define bmDELAYISO 0x20
#define bmDMPULLDN 0x40
#define bmDPPULLDN 0x80
#define rPERADDR 0xe0 //28<<3
#define rHCTL 0xe8 //29<<3
/* HCTL Bits */
#define bmBUSRST 0x01
#define bmFRMRST 0x02
#define bmSAMPLEBUS 0x04
#define bmSIGRSM 0x08
#define bmRCVTOG0 0x10
#define bmRCVTOG1 0x20
#define bmSNDTOG0 0x40
#define bmSNDTOG1 0x80
#define rHXFR 0xf0 //30<<3
/* Host transfer token values for writing the HXFR register (R30) */
/* OR this bit field with the endpoint number in bits 3:0 */
#define tokSETUP 0x10 // HS=0, ISO=0, OUTNIN=0, SETUP=1
#define tokIN 0x00 // HS=0, ISO=0, OUTNIN=0, SETUP=0
#define tokOUT 0x20 // HS=0, ISO=0, OUTNIN=1, SETUP=0
#define tokINHS 0x80 // HS=1, ISO=0, OUTNIN=0, SETUP=0
#define tokOUTHS 0xA0 // HS=1, ISO=0, OUTNIN=1, SETUP=0
#define tokISOIN 0x40 // HS=0, ISO=1, OUTNIN=0, SETUP=0
#define tokISOOUT 0x60 // HS=0, ISO=1, OUTNIN=1, SETUP=0
#define rHRSL 0xf8 //31<<3
/* HRSL Bits */
#define bmRCVTOGRD 0x10
#define bmSNDTOGRD 0x20
#define bmKSTATUS 0x40
#define bmJSTATUS 0x80
#define bmSE0 0x00 //SE0 - disconnect state
#define bmSE1 0xc0 //SE1 - illegal state
/* Host error result codes, the 4 LSB's in the HRSL register */
#define hrSUCCESS 0x00
#define hrBUSY 0x01
#define hrBADREQ 0x02
#define hrUNDEF 0x03
#define hrNAK 0x04
#define hrSTALL 0x05
#define hrTOGERR 0x06
#define hrWRONGPID 0x07
#define hrBADBC 0x08
#define hrPIDERR 0x09
#define hrPKTERR 0x0A
#define hrCRCERR 0x0B
#define hrKERR 0x0C
#define hrJERR 0x0D
#define hrTIMEOUT 0x0E
#define hrBABBLE 0x0F
#define MODE_FS_HOST (bmDPPULLDN|bmDMPULLDN|bmHOST|bmSOFKAENAB)
#define MODE_LS_HOST (bmDPPULLDN|bmDMPULLDN|bmHOST|bmLOWSPEED|bmSOFKAENAB)
#endif //_MAX3421Econstants_h_

File diff suppressed because it is too large Load Diff

View File

@ -1,38 +1,36 @@
/* Copyright 2009-2011 Oleg Mazurov, Circuits At Home, http://www.circuitsathome.com */
/* USB functions */
#ifndef _usb_h_
#define _usb_h_
#ifndef USB_H_INCLUDED
#define USB_H_INCLUDED
#include <Max3421e.h>
#include <stdint.h>
#include "ch9.h"
/* Common setup data constant combinations */
#define bmREQ_GET_DESCR USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_DEVICE //get descriptor request type
#define bmREQ_SET USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_DEVICE //set request type for all but 'set feature' and 'set interface'
#define bmREQ_CL_GET_INTF USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE //get interface request type
#define bmREQ_GET_DESCR USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_DEVICE // Get descriptor request type
#define bmREQ_SET USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_DEVICE // Set request type for all but 'set feature' and 'set interface'
#define bmREQ_CL_GET_INTF USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE // Get interface request type
/* HID requests */
#define bmREQ_HIDOUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
#define bmREQ_HIDIN USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
#define bmREQ_HIDIN USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
#define bmREQ_HIDREPORT USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_INTERFACE
#define USB_XFER_TIMEOUT 5000 //USB transfer timeout in milliseconds, per section 9.2.6.1 of USB 2.0 spec
#define USB_NAK_LIMIT 32000 //NAK limit for a transfer. o meand NAKs are not counted
#define USB_RETRY_LIMIT 3 //retry limit for a transfer
#define USB_SETTLE_DELAY 200 //settle delay in milliseconds
#define USB_NAK_NOWAIT 1 //used in Richard's PS2/Wiimote code
#define USB_XFER_TIMEOUT 5000 // USB transfer timeout in milliseconds, per section 9.2.6.1 of USB 2.0 spec
#define USB_NAK_LIMIT 32000 // NAK limit for a transfer. o means NAKs are not counted
#define USB_RETRY_LIMIT 3 // Retry limit for a transfer
#define USB_SETTLE_DELAY 200 // Settle delay in milliseconds
#define USB_NAK_NOWAIT 1 // Used in Richard's PS2/Wiimote code
#define USB_NUMDEVICES 2 //number of USB devices
#define USB_NUMDEVICES 2 // Number of USB devices
/* USB state machine states */
#define USB_STATE_MASK 0xf0
#define USB_STATE_DETACHED 0x10
#define USB_DETACHED_SUBSTATE_INITIALIZE 0x11
#define USB_DETACHED_SUBSTATE_INITIALIZE 0x11
#define USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE 0x12
#define USB_DETACHED_SUBSTATE_ILLEGAL 0x13
#define USB_ATTACHED_SUBSTATE_SETTLE 0x20
#define USB_ATTACHED_SUBSTATE_RESET_DEVICE 0x30
#define USB_ATTACHED_SUBSTATE_RESET_DEVICE 0x30
#define USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE 0x40
#define USB_ATTACHED_SUBSTATE_WAIT_SOF 0x50
#define USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE 0x60
@ -40,137 +38,166 @@
#define USB_STATE_CONFIGURING 0x80
#define USB_STATE_RUNNING 0x90
#define USB_STATE_ERROR 0xa0
// byte usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE
#define USB_STATE_MASK 0xf0
/* USB Setup Packet Structure */
typedef struct {
union { // offset description
byte bmRequestType; // 0 Bit-map of request type
struct {
byte recipient: 5; // Recipient of the request
byte type: 2; // Type of request
byte direction: 1; // Direction of data X-fer
typedef struct
{
union
{ // offset description
uint8_t bmRequestType; // 0 Bit-map of request type
struct
{
uint8_t recipient: 5; // Recipient of the request
uint8_t type: 2; // Type of request
uint8_t direction: 1; // Direction of data X-fer
};
}ReqType_u;
byte bRequest; // 1 Request
union {
unsigned int wValue; // 2 Depends on bRequest
struct {
byte wValueLo;
byte wValueHi;
} ReqType_u;
uint8_t bRequest; // 1 Request
union
{
uint16_t wValue; // 2 Depends on bRequest
struct
{
uint8_t wValueLo;
uint8_t wValueHi;
};
}wVal_u;
unsigned int wIndex; // 4 Depends on bRequest
unsigned int wLength; // 6 Depends on bRequest
} wVal_u;
uint16_t wIndex; // 4 Depends on bRequest
uint16_t wLength; // 6 Depends on bRequest
} SETUP_PKT, *PSETUP_PKT;
/* Endpoint information structure */
/* bToggle of endpoint 0 initialized to 0xff */
/* during enumeration bToggle is set to 00 */
typedef struct {
byte epAddr; //copy from endpoint descriptor. Bit 7 indicates direction ( ignored for control endpoints )
byte Attr; // Endpoint transfer type.
unsigned int MaxPktSize; // Maximum packet size.
byte Interval; // Polling interval in frames.
byte sndToggle; //last toggle value, bitmask for HCTL toggle bits
byte rcvToggle; //last toggle value, bitmask for HCTL toggle bits
typedef struct
{
uint32_t epAddr; // Copy from endpoint descriptor. Bit 7 indicates direction (ignored for control endpoints)
uint8_t Attr; // Endpoint transfer type.
uint16_t MaxPktSize; // Maximum packet size.
uint8_t Interval; // Polling interval in frames.
uint8_t sndToggle; // Last toggle value, bitmask for HCTL toggle bits
uint8_t rcvToggle; // Last toggle value, bitmask for HCTL toggle bits
/* not sure if both are necessary */
} EP_RECORD;
/* device record structure */
typedef struct {
EP_RECORD* epinfo; //device endpoint information
byte devclass; //device class
/* Device record structure */
typedef struct
{
EP_RECORD* epinfo; // Device endpoint information
uint8_t devclass; // Device class
} DEV_RECORD;
class USB : public MAX3421E {
//data structures
/* device table. Filled during enumeration */
/* index corresponds to device address */
/* each entry contains pointer to endpoint structure */
/* and device class to use in various places */
//DEV_RECORD devtable[ USB_NUMDEVICES + 1 ];
//EP_RECORD dev0ep; //Endpoint data structure used during enumeration for uninitialized device
//byte usb_task_state;
/**
* USBHost Class
* The device table is filled during enumeration.
* Index corresponds to device address and each entry contains pointer to endpoint structure and device class to use.
*/
class USBHost
{
public:
USB( void );
byte getUsbTaskState( void );
void setUsbTaskState( byte state );
EP_RECORD* getDevTableEntry( byte addr, byte ep );
void setDevTableEntry( byte addr, EP_RECORD* eprecord_ptr );
byte ctrlReq( byte addr, byte ep, byte bmReqType, byte bRequest, byte wValLo, byte wValHi, unsigned int wInd, unsigned int nbytes, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
/* Control requests */
byte getDevDescr( byte addr, byte ep, unsigned int nbytes, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
byte getConfDescr( byte addr, byte ep, unsigned int nbytes, byte conf, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
byte getStrDescr( byte addr, byte ep, unsigned int nbytes, byte index, unsigned int langid, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
byte setAddr( byte oldaddr, byte ep, byte newaddr, unsigned int nak_limit = USB_NAK_LIMIT );
byte setConf( byte addr, byte ep, byte conf_value, unsigned int nak_limit = USB_NAK_LIMIT );
/**/
byte setProto( byte addr, byte ep, byte interface, byte protocol, unsigned int nak_limit = USB_NAK_LIMIT );
byte getProto( byte addr, byte ep, byte interface, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
byte getReportDescr( byte addr, byte ep, unsigned int nbytes, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
byte setReport( byte addr, byte ep, unsigned int nbytes, byte interface, byte report_type, byte report_id, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
byte getReport( byte addr, byte ep, unsigned int nbytes, byte interface, byte report_type, byte report_id, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
byte getIdle( byte addr, byte ep, byte interface, byte reportID, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
byte setIdle( byte addr, byte ep, byte interface, byte reportID, byte duration, unsigned int nak_limit = USB_NAK_LIMIT );
/**/
byte ctrlData( byte addr, byte ep, unsigned int nbytes, char* dataptr, boolean direction, unsigned int nak_limit = USB_NAK_LIMIT );
byte ctrlStatus( byte ep, boolean direction, unsigned int nak_limit = USB_NAK_LIMIT );
byte inTransfer( byte addr, byte ep, unsigned int nbytes, char* data, unsigned int nak_limit = USB_NAK_LIMIT );
int newInTransfer( byte addr, byte ep, unsigned int nbytes, char* data, unsigned int nak_limit = USB_NAK_LIMIT);
byte outTransfer( byte addr, byte ep, unsigned int nbytes, char* data, unsigned int nak_limit = USB_NAK_LIMIT );
byte dispatchPkt( byte token, byte ep, unsigned int nak_limit = USB_NAK_LIMIT );
void Task( void );
USBHost(void);
uint32_t getUsbTaskState(void);
void setUsbTaskState(uint32_t state);
EP_RECORD* getDevTableEntry(uint32_t addr, uint32_t ep);
void setDevTableEntry(uint32_t addr, EP_RECORD* eprecord_ptr);
uint32_t ctrlReq(uint32_t addr, uint32_t ep, uint8_t bmReqType, uint8_t bRequest, uint8_t wValLo, uint8_t wValHi, uint16_t wInd, uint32_t nbytes, uint8_t* dataptr, uint32_t nak_limit = USB_NAK_LIMIT);
/* Control requests */
uint32_t getDevDescr(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t* dataptr, uint32_t nak_limit = USB_NAK_LIMIT);
uint32_t getConfDescr(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t conf, uint8_t* dataptr, uint32_t nak_limit = USB_NAK_LIMIT);
uint32_t getStrDescr(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t index, uint16_t langid, uint8_t* dataptr, uint32_t nak_limit = USB_NAK_LIMIT);
uint32_t setAddr(uint32_t oldaddr, uint32_t ep, uint32_t newaddr, uint32_t nak_limit = USB_NAK_LIMIT);
uint32_t setConf(uint32_t addr, uint32_t ep, uint8_t conf_value, uint32_t nak_limit = USB_NAK_LIMIT);
/* Status requests */
uint32_t setProto(uint32_t addr, uint32_t ep, uint8_t interface, uint8_t protocol, uint32_t nak_limit = USB_NAK_LIMIT);
uint32_t getProto(uint32_t addr, uint32_t ep, uint8_t interface, uint8_t* dataptr, uint32_t nak_limit = USB_NAK_LIMIT);
uint32_t getReportDescr(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t* dataptr, uint32_t nak_limit = USB_NAK_LIMIT);
uint32_t setReport(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t interface, uint8_t report_type, uint8_t report_id, uint8_t* dataptr, uint32_t nak_limit = USB_NAK_LIMIT);
uint32_t getReport(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t interface, uint8_t report_type, uint8_t report_id, uint8_t* dataptr, uint32_t nak_limit = USB_NAK_LIMIT);
uint32_t getIdle(uint32_t addr, uint32_t ep, uint8_t interface, uint8_t reportID, uint8_t* dataptr, uint32_t nak_limit = USB_NAK_LIMIT);
uint32_t setIdle(uint32_t addr, uint32_t ep, uint8_t interface, uint8_t reportID, uint8_t duration, uint32_t nak_limit = USB_NAK_LIMIT);
/* Transfer requests */
uint32_t ctrlData(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t* dataptr, uint32_t direction, uint32_t nak_limit = USB_NAK_LIMIT);
uint32_t ctrlStatus(uint32_t ep, uint32_t direction, uint32_t nak_limit = USB_NAK_LIMIT);
uint32_t inTransfer(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t* data, uint32_t nak_limit = USB_NAK_LIMIT);
int32_t newInTransfer(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t* data, uint32_t nak_limit = USB_NAK_LIMIT);
uint32_t outTransfer(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t* data, uint32_t nak_limit = USB_NAK_LIMIT);
uint32_t dispatchPkt(uint32_t token, uint32_t ep, uint32_t nak_limit = USB_NAK_LIMIT);
void Task(void);
private:
void init();
};
//get device descriptor
inline byte USB::getDevDescr( byte addr, byte ep, unsigned int nbytes, char* dataptr, unsigned int nak_limit ) {
return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, dataptr, nak_limit ));
// Get device descriptor
inline uint32_t USBHost::getDevDescr(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t* dataptr, uint32_t nak_limit)
{
return (ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, dataptr, nak_limit));
}
//get configuration descriptor
inline byte USB::getConfDescr( byte addr, byte ep, unsigned int nbytes, byte conf, char* dataptr, unsigned int nak_limit ) {
return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, dataptr, nak_limit ));
// Get configuration descriptor
inline uint32_t USBHost::getConfDescr(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t conf, uint8_t* dataptr, uint32_t nak_limit)
{
return (ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, dataptr, nak_limit));
}
//get string descriptor
inline byte USB::getStrDescr( byte addr, byte ep, unsigned int nbytes, byte index, unsigned int langid, char* dataptr, unsigned int nak_limit ) {
return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, nbytes, dataptr, nak_limit ));
// Get string descriptor
inline uint32_t USBHost::getStrDescr(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t index, uint16_t langid, uint8_t* dataptr, uint32_t nak_limit)
{
return (ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, nbytes, dataptr, nak_limit));
}
//set address
inline byte USB::setAddr( byte oldaddr, byte ep, byte newaddr, unsigned int nak_limit ) {
return( ctrlReq( oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, NULL, nak_limit ));
// Set address
inline uint32_t USBHost::setAddr(uint32_t oldaddr, uint32_t ep, uint32_t newaddr, uint32_t nak_limit)
{
return (ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, 0, nak_limit));
}
//set configuration
inline byte USB::setConf( byte addr, byte ep, byte conf_value, unsigned int nak_limit ) {
return( ctrlReq( addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, NULL, nak_limit ));
// Set configuration
inline uint32_t USBHost::setConf(uint32_t addr, uint32_t ep, uint8_t conf_value, uint32_t nak_limit)
{
return (ctrlReq(addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, 0, nak_limit));
}
//class requests
inline byte USB::setProto( byte addr, byte ep, byte interface, byte protocol, unsigned int nak_limit ) {
return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_PROTOCOL, protocol, 0x00, interface, 0x0000, NULL, nak_limit ));
// Class requests
inline uint32_t USBHost::setProto(uint32_t addr, uint32_t ep, uint8_t interface, uint8_t protocol, uint32_t nak_limit)
{
return (ctrlReq(addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_PROTOCOL, protocol, 0x00, interface, 0x0000, 0, nak_limit));
}
inline byte USB::getProto( byte addr, byte ep, byte interface, char* dataptr, unsigned int nak_limit ) {
return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_PROTOCOL, 0x00, 0x00, interface, 0x0001, dataptr, nak_limit ));
inline uint32_t USBHost::getProto(uint32_t addr, uint32_t ep, uint8_t interface, uint8_t* dataptr, uint32_t nak_limit)
{
return (ctrlReq(addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_PROTOCOL, 0x00, 0x00, interface, 0x0001, dataptr, nak_limit));
}
//get HID report descriptor
inline byte USB::getReportDescr( byte addr, byte ep, unsigned int nbytes, char* dataptr, unsigned int nak_limit ) {
return( ctrlReq( addr, ep, bmREQ_HIDREPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00, HID_DESCRIPTOR_REPORT, 0x0000, nbytes, dataptr, nak_limit ));
// Get HID report descriptor
inline uint32_t USBHost::getReportDescr(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t* dataptr, uint32_t nak_limit)
{
return (ctrlReq(addr, ep, bmREQ_HIDREPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00, HID_DESCRIPTOR_REPORT, 0x0000, nbytes, dataptr, nak_limit));
}
inline byte USB::setReport( byte addr, byte ep, unsigned int nbytes, byte interface, byte report_type, byte report_id, char* dataptr, unsigned int nak_limit ) {
return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_REPORT, report_id, report_type, interface, nbytes, dataptr, nak_limit ));
inline uint32_t USBHost::setReport(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t interface, uint8_t report_type, uint8_t report_id, uint8_t* dataptr, uint32_t nak_limit)
{
return (ctrlReq(addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_REPORT, report_id, report_type, interface, nbytes, dataptr, nak_limit));
}
inline byte USB::getReport( byte addr, byte ep, unsigned int nbytes, byte interface, byte report_type, byte report_id, char* dataptr, unsigned int nak_limit ) { // ** RI 04/11/09
return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_REPORT, report_id, report_type, interface, nbytes, dataptr, nak_limit ));
inline uint32_t USBHost::getReport(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t interface, uint8_t report_type, uint8_t report_id, uint8_t* dataptr, uint32_t nak_limit)
{
return (ctrlReq(addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_REPORT, report_id, report_type, interface, nbytes, dataptr, nak_limit));
}
/* returns one byte of data in dataptr */
inline byte USB::getIdle( byte addr, byte ep, byte interface, byte reportID, char* dataptr, unsigned int nak_limit ) {
return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_IDLE, reportID, 0, interface, 0x0001, dataptr, nak_limit ));
/* returns one uint8_t of data in dataptr */
inline uint32_t USBHost::getIdle(uint32_t addr, uint32_t ep, uint8_t interface, uint8_t reportID, uint8_t* dataptr, uint32_t nak_limit)
{
return (ctrlReq(addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_IDLE, reportID, 0, interface, 0x0001, dataptr, nak_limit));
}
inline byte USB::setIdle( byte addr, byte ep, byte interface, byte reportID, byte duration, unsigned int nak_limit ) {
return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_IDLE, reportID, duration, interface, 0x0000, NULL, nak_limit ));
}
#endif //_usb_h_
inline uint32_t USBHost::setIdle(uint32_t addr, uint32_t ep, uint8_t interface, uint8_t reportID, uint8_t duration, uint32_t nak_limit)
{
return (ctrlReq(addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_IDLE, reportID, duration, interface, 0x0000, 0, nak_limit));
}
#endif /* USB_H_INCLUDED */

View File

@ -3,6 +3,8 @@
#ifndef _ch9_h_
#define _ch9_h_
#include <stdint.h>
/* Misc.USB constants */
#define DEV_DESCR_LEN 18 //device descriptor length
#define CONF_DESCR_LEN 9 //configuration descriptor length
@ -96,73 +98,77 @@
#define HID_PROTOCOL_MOUSE 0x02
_Pragma("pack(1)")
/* descriptor data structures */
/* Device descriptor structure */
typedef struct {
byte bLength; // Length of this descriptor.
byte bDescriptorType; // DEVICE descriptor type (USB_DESCRIPTOR_DEVICE).
unsigned int bcdUSB; // USB Spec Release Number (BCD).
byte bDeviceClass; // Class code (assigned by the USB-IF). 0xFF-Vendor specific.
byte bDeviceSubClass; // Subclass code (assigned by the USB-IF).
byte bDeviceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific.
byte bMaxPacketSize0; // Maximum packet size for endpoint 0.
unsigned int idVendor; // Vendor ID (assigned by the USB-IF).
unsigned int idProduct; // Product ID (assigned by the manufacturer).
unsigned int bcdDevice; // Device release number (BCD).
byte iManufacturer; // Index of String Descriptor describing the manufacturer.
byte iProduct; // Index of String Descriptor describing the product.
byte iSerialNumber; // Index of String Descriptor with the device's serial number.
byte bNumConfigurations; // Number of possible configurations.
uint8_t bLength; // Length of this descriptor.
uint8_t bDescriptorType; // DEVICE descriptor type (USB_DESCRIPTOR_DEVICE).
uint16_t bcdUSB; // USB Spec Release Number (BCD).
uint8_t bDeviceClass; // Class code (assigned by the USB-IF). 0xFF-Vendor specific.
uint8_t bDeviceSubClass; // Subclass code (assigned by the USB-IF).
uint8_t bDeviceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific.
uint8_t bMaxPacketSize0; // Maximum packet size for endpoint 0.
uint16_t idVendor; // Vendor ID (assigned by the USB-IF).
uint16_t idProduct; // Product ID (assigned by the manufacturer).
uint16_t bcdDevice; // Device release number (BCD).
uint8_t iManufacturer; // Index of String Descriptor describing the manufacturer.
uint8_t iProduct; // Index of String Descriptor describing the product.
uint8_t iSerialNumber; // Index of String Descriptor with the device's serial number.
uint8_t bNumConfigurations; // Number of possible configurations.
} USB_DEVICE_DESCRIPTOR;
/* Configuration descriptor structure */
typedef struct
{
byte bLength; // Length of this descriptor.
byte bDescriptorType; // CONFIGURATION descriptor type (USB_DESCRIPTOR_CONFIGURATION).
unsigned int wTotalLength; // Total length of all descriptors for this configuration.
byte bNumInterfaces; // Number of interfaces in this configuration.
byte bConfigurationValue; // Value of this configuration (1 based).
byte iConfiguration; // Index of String Descriptor describing the configuration.
byte bmAttributes; // Configuration characteristics.
byte bMaxPower; // Maximum power consumed by this configuration.
uint8_t bLength; // Length of this descriptor.
uint8_t bDescriptorType; // CONFIGURATION descriptor type (USB_DESCRIPTOR_CONFIGURATION).
uint16_t wTotalLength; // Total length of all descriptors for this configuration.
uint8_t bNumInterfaces; // Number of interfaces in this configuration.
uint8_t bConfigurationValue; // Value of this configuration (1 based).
uint8_t iConfiguration; // Index of String Descriptor describing the configuration.
uint8_t bmAttributes; // Configuration characteristics.
uint8_t bMaxPower; // Maximum power consumed by this configuration.
} USB_CONFIGURATION_DESCRIPTOR;
/* Interface descriptor structure */
typedef struct
{
byte bLength; // Length of this descriptor.
byte bDescriptorType; // INTERFACE descriptor type (USB_DESCRIPTOR_INTERFACE).
byte bInterfaceNumber; // Number of this interface (0 based).
byte bAlternateSetting; // Value of this alternate interface setting.
byte bNumEndpoints; // Number of endpoints in this interface.
byte bInterfaceClass; // Class code (assigned by the USB-IF). 0xFF-Vendor specific.
byte bInterfaceSubClass; // Subclass code (assigned by the USB-IF).
byte bInterfaceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific.
byte iInterface; // Index of String Descriptor describing the interface.
uint8_t bLength; // Length of this descriptor.
uint8_t bDescriptorType; // INTERFACE descriptor type (USB_DESCRIPTOR_INTERFACE).
uint8_t bInterfaceNumber; // Number of this interface (0 based).
uint8_t bAlternateSetting; // Value of this alternate interface setting.
uint8_t bNumEndpoints; // Number of endpoints in this interface.
uint8_t bInterfaceClass; // Class code (assigned by the USB-IF). 0xFF-Vendor specific.
uint8_t bInterfaceSubClass; // Subclass code (assigned by the USB-IF).
uint8_t bInterfaceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific.
uint8_t iInterface; // Index of String Descriptor describing the interface.
} USB_INTERFACE_DESCRIPTOR;
/* Endpoint descriptor structure */
typedef struct
{
byte bLength; // Length of this descriptor.
byte bDescriptorType; // ENDPOINT descriptor type (USB_DESCRIPTOR_ENDPOINT).
byte bEndpointAddress; // Endpoint address. Bit 7 indicates direction (0=OUT, 1=IN).
byte bmAttributes; // Endpoint transfer type.
unsigned int wMaxPacketSize; // Maximum packet size.
byte bInterval; // Polling interval in frames.
uint8_t bLength; // Length of this descriptor.
uint8_t bDescriptorType; // ENDPOINT descriptor type (USB_DESCRIPTOR_ENDPOINT).
uint8_t bEndpointAddress; // Endpoint address. Bit 7 indicates direction (0=OUT, 1=IN).
uint8_t bmAttributes; // Endpoint transfer type.
uint16_t wMaxPacketSize; // Maximum packet size.
uint8_t bInterval; // Polling interval in frames.
} USB_ENDPOINT_DESCRIPTOR;
/* HID descriptor */
typedef struct {
byte bLength;
byte bDescriptorType;
unsigned int bcdHID;
byte bCountryCode;
byte bNumDescriptors;
byte bDescrType;
unsigned int wDescriptorLength;
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdHID;
uint8_t bCountryCode;
uint8_t bNumDescriptors;
uint8_t bDescrType;
uint16_t wDescriptorLength;
} USB_HID_DESCRIPTOR;
_Pragma("pack()")
#endif // _ch9_h_

View File

@ -56,9 +56,11 @@
#include "include/timetick.h"
#include "include/USB_device.h"
#include "include/USB_host.h"
#if SAM3XA_SERIES
#include "include/uotghs.h"
#include "include/uotghs_device.h"
#include "include/uotghs_host.h"
#endif /* SAM3XA_SERIES */
#endif /* _LIB_SAM_ */

View File

@ -16,8 +16,8 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _USB_DRIVER_
#define _USB_DRIVER_
#ifndef USB_DEVICE_H_INCLUDED
#define USB_DEVICE_H_INCLUDED
#include <stdint.h>
@ -403,4 +403,4 @@ typedef uint32_t iram_size_t;
//! @}
#endif /* _USB_DRIVER_*/
#endif /* USB_DEVICE_H_INCLUDED */

View File

@ -0,0 +1,59 @@
/*
Copyright (c) 2011 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef USB_HOST_H_INCLUDED
#define USB_HOST_H_INCLUDED
#include <stdint.h>
#define tokSETUP UOTGHS_HSTPIPCFG_PTOKEN_SETUP
#define tokIN UOTGHS_HSTPIPCFG_PTOKEN_IN
#define tokOUT UOTGHS_HSTPIPCFG_PTOKEN_OUT
#define tokINHS UOTGHS_HSTPIPCFG_PTOKEN_IN
#define tokOUTHS UOTGHS_HSTPIPCFG_PTOKEN_OUT
//! \brief Device speed
/*typedef enum {
UHD_SPEED_LOW = 0,
UHD_SPEED_FULL = 1,
UHD_SPEED_HIGH = 2,
} uhd_speed_t;*/
//! States of USBB interface
typedef enum {
UHD_STATE_NO_VBUS = 0,
UHD_STATE_DISCONNECTED = 1,
UHD_STATE_CONNECTED = 2,
UHD_STATE_ERROR = 3,
} uhd_vbus_state_t;
//extern uhd_speed_t uhd_get_speed(void);
extern void UHD_SetStack(void (*pf_isr)(void));
extern void UHD_Init(void);
extern void UHD_BusReset(void);
extern uhd_vbus_state_t UHD_GetVBUSState(void);
extern uint32_t UHD_EP0_Alloc(uint32_t ul_add, uint32_t ul_ep_size);
extern void UHD_EP_Free(uint32_t add, uint32_t endp);
extern uint32_t UHD_EP_Read(uint32_t ul_ep, uint32_t ul_size, uint8_t* data);
extern void UHD_EP_Write(uint32_t ul_ep, uint32_t ul_size, uint8_t* data);
extern void UHD_EP_Send(uint32_t ul_ep, uint32_t ul_token_type);
extern uint32_t UHD_EP_Is_Transfer_Complete(uint32_t ul_ep, uint32_t ul_token_type);
#endif /* USB_HOST_H_INCLUDED */

View File

@ -16,8 +16,8 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef UOTGHS_H_INCLUDED
#define UOTGHS_H_INCLUDED
#ifndef UOTGHS_DEVICE_H_INCLUDED
#define UOTGHS_DEVICE_H_INCLUDED
#define MAX_ENDPOINTS 10
@ -737,4 +737,4 @@
//! @}
#endif /* UOTGHS_H_INCLUDED */
#endif /* UOTGHS_DEVICE_H_INCLUDED */

View File

@ -0,0 +1,378 @@
/*
Copyright (c) 2012 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef UOTGHS_HOST_H_INCLUDED
#define UOTGHS_HOST_H_INCLUDED
//! \ingroup usb_host_group
//! \defgroup uhd_group USB Host Driver (UHD)
//! UOTGHS low-level driver for USB host mode
//!
//! @{
//! @name UOTGHS Host IP properties
//!
//! @{
//! Get maximal number of endpoints
#define uhd_get_pipe_max_nbr() (9)
#define UOTGHS_EPT_NUM (uhd_get_pipe_max_nbr()+1)
//! @}
//! @name Host Vbus line control
//!
//! VBOF is an optional output pin which allows to enable or disable
//! the external VBus generator.
//!
//! @{
//! Enables hardware control of USB_VBOF output pin when a Vbus error occur
#define uhd_enable_vbus_error_hw_control() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSHWC))
//! Disables hardware control of USB_VBOF output pin when a Vbus error occur
#define uhd_disable_vbus_error_hw_control() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSHWC))
//! Pin and function for USB_VBOF according to configuration from USB_VBOF
#define USB_VBOF_PIN USB_VBOF_GPIO
#define USB_VBOF_FUNCTION USB_VBOF_FLAGS
//! Output USB_VBOF onto its pin
#define uhd_output_vbof_pin() do {\
pio_configure_pin(USB_VBOF_PIN, USB_VBOF_FUNCTION); \
} while (0)
//! Set USB_VBOF output pin polarity
#define uhd_set_vbof_active_high() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSPO))
#define uhd_set_vbof_active_low() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSPO))
//! Requests VBus activation
#define uhd_enable_vbus() (Set_bits(UOTGHS->UOTGHS_SFR, UOTGHS_SR_VBUSRQ))
//! Requests VBus deactivation
#define uhd_disable_vbus() (Set_bits(UOTGHS->UOTGHS_SCR, UOTGHS_SR_VBUSRQ))
//! Tests if VBus activation has been requested
#define Is_uhd_vbus_enabled() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_VBUSRQ))
//! @}
//! @name Host Vbus line monitoring
//!
//! The VBus level is always checked by USBC hardware.
//!
//! @{
#define uhd_enable_vbus_error_interrupt() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBERRE))
#define uhd_disable_vbus_error_interrupt() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBERRE))
#define Is_uhd_vbus_error_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBERRE))
#define uhd_ack_vbus_error_interrupt() (Set_bits(UOTGHS->UOTGHS_SCR, UOTGHS_SCR_VBERRIC))
#define Is_uhd_vbus_error_interrupt() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_VBERRI))
//! @}
#define uhd_ack_errors_interrupt() (UOTGHS->UOTGHS_SCR = (UOTGHS_SCR_VBERRIC|UOTGHS_SCR_BCERRIC|UOTGHS_SCR_HNPERRIC|UOTGHS_SCR_STOIC))
#define Is_uhd_errors_interrupt() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBERRE|UOTGHS_CTRL_BCERRE|UOTGHS_CTRL_HNPERRE|UOTGHS_CTRL_STOE))
#define uhd_enable_suspend_error_interrupt()
#define uhd_enable_hnp_error_interrupt()
#define uhd_enable_bconn_error_interrupt()
//! @name USB device connection/disconnection monitoring
//! @{
#define uhd_enable_connection_int() (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_DCONNIES)
#define uhd_disable_connection_int() (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_DCONNIEC)
#define Is_uhd_connection_int_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_DCONNIE))
#define uhd_ack_connection() (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_DCONNIC)
#define Is_uhd_connection() (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_DCONNI))
#define uhd_enable_disconnection_int() (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_DDISCIES)
#define uhd_disable_disconnection_int() (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_DDISCIEC)
#define Is_uhd_disconnection_int_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_DDISCIE))
#define uhd_ack_disconnection() (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_DDISCIC)
#define Is_uhd_disconnection() (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_DDISCI))
//! @}
//! @name USB device speed control
//! @{
#define uhd_get_speed_mode() (Rd_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_SPEED_Msk))
#define Is_uhd_low_speed_mode() (uhd_get_speed_mode() == UOTGHS_SR_SPEED_LOW_SPEED)
#define Is_uhd_full_speed_mode() (uhd_get_speed_mode() == UOTGHS_SR_SPEED_FULL_SPEED)
#define Is_uhd_high_speed_mode() (uhd_get_speed_mode() == UOTGHS_SR_SPEED_HIGH_SPEED)
//! Enable high speed mode
# define uhd_enable_high_speed_mode() (Wr_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_SPDCONF_Msk, UOTGHS_HSTCTRL_SPDCONF_HIGH_SPEED))
//! Disable high speed mode
# define uhd_disable_high_speed_mode() (Wr_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_SPDCONF_Msk, UOTGHS_HSTCTRL_SPDCONF_FORCED_FS))
//! @}
//! @name Bus events control
//! These macros manage the bus events: reset, SOF, resume, wakeup.
//! @{
//! Initiates a reset event
//! @{
#define uhd_start_reset() (Set_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_RESET))
#define Is_uhd_starting_reset() (Tst_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_RESET))
#define uhd_stop_reset() (Clr_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_RESET))
#define uhd_enable_reset_sent_interrupt() (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_RSTIES)
#define uhd_disable_reset_sent_interrupt() (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_RSTIEC)
#define Is_uhd_reset_sent_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_RSTIE))
#define uhd_ack_reset_sent() (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_RSTIC)
#define Is_uhd_reset_sent() (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_RSTI))
//! @}
//! Initiates a SOF events
//! @{
#define uhd_enable_sof() (Set_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_SOFE))
#define uhd_disable_sof() (Clr_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_SOFE))
#define Is_uhd_sof_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_SOFE))
#define uhd_get_sof_number() ((UOTGHS->UOTGHS_HSTFNUM&UOTGHS_HSTFNUM_FNUM_Msk)>>UOTGHS_HSTFNUM_FNUM_Pos)
#define uhd_get_microsof_number() ((UOTGHS->UOTGHS_HSTFNUM&UOTGHS_HSTFNUM_MFNUM_Msk)>>UOTGHS_HSTFNUM_MFNUM_Pos)
#define uhd_get_frame_position() (Rd_bits(UOTGHS->UOTGHS_HSTFNUM, UOTGHS_HSTFNUM_FLENHIGH_Msk))
#define uhd_enable_sof_interrupt() (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_HSOFIES)
#define uhd_disable_sof_interrupt() (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_HSOFIEC)
#define Is_uhd_sof_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_HSOFIE))
#define uhd_ack_sof() (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_HSOFIC)
#define Is_uhd_sof() (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_HSOFI))
//! @}
//! Initiates a resume event
//! It is called downstream resume event.
//! @{
#define uhd_send_resume() (Set_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_RESUME))
#define Is_uhd_sending_resume() (Tst_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_RESUME))
#define uhd_enable_downstream_resume_interrupt() (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_RSMEDIES)
#define uhd_disable_downstream_resume_interrupt() (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_RSMEDIEC)
#define Is_uhd_downstream_resume_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_RSMEDIE))
#define uhd_ack_downstream_resume() (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_RSMEDIC)
#define Is_uhd_downstream_resume() (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_RSMEDI))
//! @}
//! Detection of a wake-up event
//! A wake-up event is received when the host controller is in the suspend mode:
//! - and an upstream resume from the peripheral is detected.
//! - and a peripheral disconnection is detected.
//! @{
#define uhd_enable_wakeup_interrupt() (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_HWUPIES)
#define uhd_disable_wakeup_interrupt() (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_HWUPIEC)
#define Is_uhd_wakeup_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_HWUPIE))
#define uhd_ack_wakeup() (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_HWUPIC)
#define Is_uhd_wakeup() (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_HWUPI))
#define uhd_enable_upstream_resume_interrupt() (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_RXRSMIES)
#define uhd_disable_upstream_resume_interrupt() (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_RXRSMIEC)
#define Is_uhd_upstream_resume_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_RXRSMIE))
#define uhd_ack_upstream_resume() (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_RXRSMIC)
#define Is_uhd_upstream_resume() (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_RXRSMI))
//! @}
//! @}
//! @name Pipes management
//! @{
//! USB address of pipes
//! @{
#define uhd_configure_address(p, addr) \
(Wr_bitfield((&UOTGHS->UOTGHS_HSTADDR1)[(p)>>2], \
UOTGHS_HSTADDR1_HSTADDRP0_Msk << (((p)&0x03)<<3), addr))
#define uhd_get_configured_address(p) \
(Rd_bitfield((&UOTGHS->UOTGHS_HSTADDR1)[(p)>>2], \
UOTGHS_HSTADDR1_HSTADDRP0_Msk << (((p)&0x03)<<3)))
//! @}
//! Pipe enable
//! Enable, disable, reset, freeze
//! @{
#define uhd_enable_pipe(p) \
(Set_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p)))
#define uhd_disable_pipe(p) \
(Clr_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p)))
#define Is_uhd_pipe_enabled(p) \
(Tst_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p)))
#define uhd_reset_pipe(p) \
(Set_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p))); \
(Clr_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p)))
#define Is_uhd_resetting_pipe(p) \
(Tst_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p)))
#define uhd_freeze_pipe(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_PFREEZES)
#define uhd_unfreeze_pipe(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_PFREEZEC)
#define Is_uhd_pipe_frozen(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_PFREEZE))
#define uhd_reset_data_toggle(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_RSTDTS)
#define Is_uhd_data_toggle_reset(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_RSTDT))
//! @}
//! Pipe configuration
//! @{
#define uhd_configure_pipe_int_req_freq(p,freq) (Wr_bitfield(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_INTFRQ_Msk, (freq)))
#define uhd_get_pipe_int_req_freq(p) (Rd_bitfield(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_INTFRQ_Msk))
#define uhd_configure_pipe_endpoint_number(p,ep) (Wr_bitfield(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PEPNUM_Msk, (ep)))
#define uhd_get_pipe_endpoint_address(p) \
(uhd_is_pipe_in(p) ?\
(uhd_get_pipe_endpoint_number(p) | USB_EP_DIR_IN) :\
(uhd_get_pipe_endpoint_number(p) | USB_EP_DIR_OUT))
#define uhd_get_pipe_endpoint_number(p) (Rd_bitfield(UOTGHS->UOTGHS_HSTPIPCFG[p], (UOTGHS_HSTPIPCFG_PEPNUM_Msk)))
#define uhd_configure_pipe_type(p, type) (Wr_bitfield(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PTYPE_Msk, type))
#define uhd_get_pipe_type(p) (Rd_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PTYPE_Msk))
#define uhd_enable_pipe_bank_autoswitch(p) (Set_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_AUTOSW))
#define uhd_disable_pipe_bank_autoswitch(p) (Clr_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_AUTOSW))
#define Is_uhd_pipe_bank_autoswitch_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_AUTOSW))
#define uhd_configure_pipe_token(p, token) (Wr_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PTOKEN_Msk, token))
#define uhd_get_pipe_token(p) (Rd_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PTOKEN_Msk))
#define uhd_is_pipe_in(p) (UOTGHS_HSTPIPCFG_PTOKEN_IN==uhd_get_pipe_token(p))
#define uhd_is_pipe_out(p) (UOTGHS_HSTPIPCFG_PTOKEN_OUT==uhd_get_pipe_token(p))
//! Bounds given integer size to allowed range and rounds it up to the nearest
//! available greater size, then applies register format of UOTGHS controller
//! for pipe size bit-field.
#define uhd_format_pipe_size(size) \
(32 - clz(((uint32_t)min(max(size, 8), 1024) << 1) - 1) - 1 - 3)
#define uhd_configure_pipe_size(p,size) \
(Wr_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PSIZE_Msk, uhd_format_pipe_size(size)))
#define uhd_get_pipe_size(p) (8<<((Rd_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], (UOTGHS_HSTPIPCFG_PSIZE_Msk)))>> UOTGHS_HSTPIPCFG_PSIZE_Pos))
#define uhd_configure_pipe_bank(p,bank) (Wr_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PBK_Msk, (bank)))
#define uhd_get_pipe_bank(p) (Rd_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PBK_Msk))
#define uhd_allocate_memory(p) (Set_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_ALLOC))
#define uhd_unallocate_memory(p) (Clr_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_ALLOC))
#define Is_uhd_memory_allocated(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_ALLOC))
//! Enable PING management only available in HS mode
# define uhd_enable_ping(p) (Set_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PINGEN))
//#endif
#define uhd_configure_pipe(p, freq, ep_num, type, token, size, bank, bank_switch) \
(Set_bits(UOTGHS->UOTGHS_HSTPIPCFG[p],\
(bank)|\
((uhd_format_pipe_size(size)<<UOTGHS_HSTPIPCFG_PSIZE_Pos)&UOTGHS_HSTPIPCFG_PSIZE_Msk)|\
(((token)<<UOTGHS_HSTPIPCFG_PTOKEN_Pos)&UOTGHS_HSTPIPCFG_PTOKEN_Msk)|\
(((type)<<UOTGHS_HSTPIPCFG_PTYPE_Pos)&UOTGHS_HSTPIPCFG_PTYPE_Msk)|\
(((ep_num)<<UOTGHS_HSTPIPCFG_PEPNUM_Pos)&UOTGHS_HSTPIPCFG_PEPNUM_Msk)|\
bank_switch |\
(((freq)<<UOTGHS_HSTPIPCFG_INTFRQ_Pos)&UOTGHS_HSTPIPCFG_INTFRQ_Msk)))
#define Is_uhd_pipe_configured(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_CFGOK))
//! @}
//! Pipe main interrupts management
//! @{
#define uhd_enable_pipe_interrupt(p) (UOTGHS->UOTGHS_HSTIER = (UOTGHS_HSTIER_PEP_0 << (p)))
#define uhd_disable_pipe_interrupt(p) (UOTGHS->UOTGHS_HSTIDR = (UOTGHS_HSTIDR_PEP_0 << (p)))
#define Is_uhd_pipe_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_PEP_0 << (p)))
#define Is_uhd_pipe_interrupt(p) (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_PEP_0 << (p)))
//! returns the lowest pipe number generating a pipe interrupt or UOTGHS_EPT_NUM if none
#define uhd_get_interrupt_pipe_number() \
(ctz(((UOTGHS->UOTGHS_HSTISR >> 8) & (UOTGHS->UOTGHS_HSTIMR >> 8)) | (1 << UOTGHS_EPT_NUM)))
//! @}
//! Pipe overflow and underflow for isochronous and interrupt endpoints
//! @{
#define uhd_enable_overflow_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_OVERFIES)
#define uhd_disable_overflow_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_OVERFIEC)
#define Is_uhd_overflow_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_OVERFIE))
#define uhd_ack_overflow_interrupt(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_OVERFIC)
#define Is_uhd_overflow(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_OVERFI))
#define uhd_enable_underflow_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_UNDERFIES)
#define uhd_disable_underflow_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_UNDERFIEC)
#define Is_uhd_underflow_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_UNDERFIE))
#define uhd_ack_underflow_interrupt(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_UNDERFIC)
#define Is_uhd_underflow(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_UNDERFI))
//! @}
//! USB packet errors management
//! @{
#define uhd_enable_stall_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_RXSTALLDES)
#define uhd_disable_stall_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_RXSTALLDEC)
#define Is_uhd_stall_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_RXSTALLDE))
#define uhd_ack_stall(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_RXSTALLDIC)
#define Is_uhd_stall(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_RXSTALLDI))
#define uhd_enable_pipe_error_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_PERRES)
#define uhd_disable_pipe_error_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_PERREC)
#define Is_uhd_pipe_error_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_PERRE))
#define uhd_ack_all_errors(p) (UOTGHS->UOTGHS_HSTPIPERR[p] = 0UL)
#define Is_uhd_pipe_error(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_PERRI))
#define uhd_error_status(p) (UOTGHS->UOTGHS_HSTPIPERR[p])
#define Is_uhd_bad_data_toggle(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_DATATGL))
#define Is_uhd_data_pid_error(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_DATAPID))
#define Is_uhd_pid_error(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_PID))
#define Is_uhd_timeout_error(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_TIMEOUT))
#define Is_uhd_crc16_error(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_CRC16))
#define uhd_get_error_counter(p) (Rd_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_COUNTER))
//! @}
//! Pipe data management
//! @{
#define uhd_data_toggle(p) (Rd_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_DTSEQ))
#define uhd_enable_bank_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_NBUSYBKES)
#define uhd_disable_bank_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_NBUSYBKEC)
#define Is_uhd_bank_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_NBUSYBKE))
#define uhd_nb_busy_bank(p) (Rd_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_NBUSYBK_Msk))
#define uhd_current_bank(p) (Rd_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_CURRBK_Msk ))
#define uhd_enable_short_packet_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_SHORTPACKETES)
#define uhd_disable_short_packet_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_SHORTPACKETIEC)
#define Is_uhd_short_packet_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_SHORTPACKETIE)) )
#define uhd_ack_short_packet(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_SHORTPACKETIC)
#define Is_uhd_short_packet(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_SHORTPACKETI))
#define uhd_byte_count(p) (Rd_bitfield(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_PBYCT_Msk))
#define Is_uhd_fifocon(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_FIFOCON))
#define uhd_ack_fifocon(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_FIFOCONC)
#define uhd_enable_setup_ready_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_TXSTPES)
#define uhd_disable_setup_ready_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_TXSTPEC)
#define Is_uhd_setup_ready_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_TXSTPE))
#define uhd_ack_setup_ready(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_TXSTPIC)
#define Is_uhd_setup_ready(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_TXSTPI))
#define uhd_enable_in_received_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_RXINES)
#define uhd_disable_in_received_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_RXINEC)
#define Is_uhd_in_received_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_RXINE))
#define uhd_ack_in_received(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_RXINIC)
#define Is_uhd_in_received(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_RXINI))
#define uhd_enable_out_ready_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_TXOUTES)
#define uhd_disable_out_ready_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_TXOUTEC)
#define Is_uhd_out_ready_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_TXOUTE))
#define uhd_ack_out_ready(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_TXOUTIC)
#define Is_uhd_out_ready(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_TXOUTI))
#define uhd_raise_out_ready(p) (UOTGHS->UOTGHS_HSTPIPIFR[p] = UOTGHS_HSTPIPIFR_TXOUTIS)
#define uhd_enable_nak_received_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_NAKEDES)
#define uhd_disable_nak_received_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_NAKEDEC)
#define Is_uhd_nak_received_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_NAKEDE))
#define uhd_ack_nak_received(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_NAKEDIC)
#define Is_uhd_nak_received(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_NAKEDI))
#define Is_uhd_read_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_RWALL))
#define Is_uhd_write_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_RWALL ))
#define uhd_enable_continuous_in_mode(p) (Set_bits(UOTGHS->UOTGHS_HSTPIPINRQ[p], UOTGHS_HSTPIPINRQ_INMODE))
#define uhd_disable_continuous_in_mode(p) (Clr_bits(UOTGHS->UOTGHS_HSTPIPINRQ[p], UOTGHS_HSTPIPINRQ_INMODE))
#define Is_uhd_continuous_in_mode_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPINRQ[p], UOTGHS_HSTPIPINRQ_INMODE))
#define uhd_in_request_number(p, in_num) (Set_bits(UOTGHS->UOTGHS_HSTPIPINRQ[p], (in_num)-1))
#define uhd_get_in_request_number(p) (((Rd_bits(UOTGHS->UOTGHS_HSTPIPINRQ[p], UOTGHS_HSTPIPINRQ_INRQ_Msk))>>UOTGHS_HSTPIPINRQ_INRQ_Pos)+1)
//! @}
//! Maximum transfer size on USB DMA
#define UHD_PIPE_MAX_TRANS 0x8000
//! Get 64-, 32-, 16- or 8-bit access to FIFO data register of selected pipe.
//! @param p Target Pipe number
//! @param scale Data scale in bits: 64, 32, 16 or 8
//! @return Volatile 64-, 32-, 16- or 8-bit data pointer to FIFO data register
//! @warning It is up to the user of this macro to make sure that all accesses
//! are aligned with their natural boundaries except 64-bit accesses which
//! require only 32-bit alignment.
//! @warning It is up to the user of this macro to make sure that used HSB
//! addresses are identical to the DPRAM internal pointer modulo 32 bits.
#define uhd_get_pipe_fifo_access(p, scale) \
(((volatile TPASTE2(U, scale) (*)[UHD_PIPE_MAX_TRANS / ((scale) / 8)])UOTGHS_RAM_ADDR)[(p)])
#endif /* UOTGHS_HOST_H_INCLUDED */

View File

@ -17,22 +17,10 @@
*/
#include "chip.h"
#include <stdio.h>
#if SAM3XA_SERIES
//#define TRACE_UOTGHS(x) x
#define TRACE_UOTGHS(x)
static void (*gpf_isr)(void) = (0UL);
static volatile uint32_t ul_send_fifo_ptr[MAX_ENDPOINTS];
static volatile uint32_t ul_recv_fifo_ptr[MAX_ENDPOINTS];
void UDD_SetStack(void (*pf_isr)(void))
{
gpf_isr = pf_isr;
}
void (*gpf_isr)(void) = (0UL);
void UOTGHS_Handler( void )
{
@ -40,291 +28,4 @@ void UOTGHS_Handler( void )
gpf_isr();
}
uint32_t UDD_Init(void)
{
uint32_t i;
for (i = 0; i < MAX_ENDPOINTS; ++i)
{
ul_send_fifo_ptr[i] = 0;
ul_recv_fifo_ptr[i] = 0;
}
// Enables the USB Clock
pmc_enable_periph_clk(ID_UOTGHS);
pmc_enable_upll_clock();
pmc_switch_udpck_to_upllck(0); // div=0+1
pmc_enable_udpck();
// Configure interrupts
NVIC_SetPriority((IRQn_Type) ID_UOTGHS, 0UL);
NVIC_EnableIRQ((IRQn_Type) ID_UOTGHS);
// Always authorize asynchrone USB interrupts to exit from sleep mode
// for SAM3 USB wake up device except BACKUP mode
//pmc_set_fast_startup_input(PMC_FSMR_USBAL);
// ID pin not used then force device mode
otg_disable_id_pin();
otg_force_device_mode();
// Enable USB hardware
otg_disable_pad();
otg_enable_pad();
otg_enable();
otg_unfreeze_clock();
// Check USB clock
//while (!Is_otg_clock_usable())
// ;
udd_low_speed_disable();
udd_high_speed_disable();
//otg_ack_vbus_transition();
// Force Vbus interrupt in case of Vbus always with a high level
// This is possible with a short timing between a Host mode stop/start.
/*if (Is_otg_vbus_high()) {
otg_raise_vbus_transition();
}
otg_enable_vbus_interrupt();*/
otg_freeze_clock();
return 0UL ;
}
void UDD_Attach(void)
{
irqflags_t flags = cpu_irq_save();
TRACE_UOTGHS(printf("=> UDD_Attach\r\n");)
otg_unfreeze_clock();
// Check USB clock because the source can be a PLL
while (!Is_otg_clock_usable());
// Authorize attach if Vbus is present
udd_attach_device();
// Enable USB line events
udd_enable_reset_interrupt();
//udd_enable_sof_interrupt();
cpu_irq_restore(flags);
}
void UDD_Detach(void)
{
TRACE_UOTGHS(printf("=> UDD_Detach\r\n");)
UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_DETACH;
}
void UDD_InitEP( uint32_t ul_ep_nb, uint32_t ul_ep_cfg )
{
ul_ep_nb = ul_ep_nb & 0xF; // EP range is 0..9, hence mask is 0xF.
TRACE_UOTGHS(printf("=> UDD_InitEP : init EP %d\r\n", ul_ep_nb);)
// Configure EP
UOTGHS->UOTGHS_DEVEPTCFG[ul_ep_nb] = ul_ep_cfg;
// Enable EP
udd_enable_endpoint(ul_ep_nb);
if (!Is_udd_endpoint_configured(ul_ep_nb)) {
TRACE_UOTGHS(printf("=> UDD_InitEP : ERROR FAILED TO INIT EP %d\r\n", ul_ep_nb);)
}
}
void UDD_InitEndpoints(const uint32_t* eps_table, const uint32_t ul_eps_table_size)
{
uint32_t ul_ep_nb ;
for (ul_ep_nb = 1; ul_ep_nb < ul_eps_table_size; ul_ep_nb++)
{
// Configure EP
UOTGHS->UOTGHS_DEVEPTCFG[ul_ep_nb] = eps_table[ul_ep_nb];
// Enable EP
udd_enable_endpoint(ul_ep_nb);
if (!Is_udd_endpoint_configured(ul_ep_nb)) {
TRACE_UOTGHS(printf("=> UDD_InitEP : ERROR FAILED TO INIT EP %d\r\n", ul_ep_nb);)
}
}
}
// Wait until ready to accept IN packet.
void UDD_WaitIN(void)
{
while (!(UOTGHS->UOTGHS_DEVEPTISR[EP0] & UOTGHS_DEVEPTISR_TXINI))
;
}
void UDD_WaitOUT(void)
{
while (!(UOTGHS->UOTGHS_DEVEPTISR[EP0] & UOTGHS_DEVEPTISR_RXOUTI))
;
}
// Send packet.
void UDD_ClearIN(void)
{
TRACE_UOTGHS(printf("=> UDD_ClearIN: sent %d bytes\r\n", ul_send_fifo_ptr[EP0]);)
UOTGHS->UOTGHS_DEVEPTICR[EP0] = UOTGHS_DEVEPTICR_TXINIC;
ul_send_fifo_ptr[EP0] = 0;
}
void UDD_ClearOUT(void)
{
UOTGHS->UOTGHS_DEVEPTICR[EP0] = UOTGHS_DEVEPTICR_RXOUTIC;
ul_recv_fifo_ptr[EP0] = 0;
}
// Wait for IN FIFO to be ready to accept data or OUT FIFO to receive data.
// Return true if new IN FIFO buffer available.
uint32_t UDD_WaitForINOrOUT(void)
{
while (!(UOTGHS->UOTGHS_DEVEPTISR[EP0] & (UOTGHS_DEVEPTISR_TXINI | UOTGHS_DEVEPTISR_RXOUTI)))
;
return ((UOTGHS->UOTGHS_DEVEPTISR[EP0] & UOTGHS_DEVEPTISR_RXOUTI) == 0);
}
uint32_t UDD_ReceivedSetupInt(void)
{
return UOTGHS->UOTGHS_DEVEPTISR[EP0] & UOTGHS_DEVEPTISR_RXSTPI;
}
void UDD_ClearSetupInt(void)
{
UOTGHS->UOTGHS_DEVEPTICR[EP0] = (UOTGHS_DEVEPTICR_RXSTPIC);
}
uint32_t UDD_Send(uint32_t ep, const void* data, uint32_t len)
{
const uint8_t *ptr_src = data;
uint8_t *ptr_dest = (uint8_t *) &udd_get_endpoint_fifo_access8(ep);
uint32_t i;
TRACE_UOTGHS(printf("=> UDD_Send (1): ep=%d ul_send_fifo_ptr=%d len=%d\r\n", ep, ul_send_fifo_ptr[ep], len);)
if (ep == EP0)
{
if (ul_send_fifo_ptr[ep] + len > EP0_SIZE)
len = EP0_SIZE - ul_send_fifo_ptr[ep];
}
else
{
if (ul_send_fifo_ptr[ep] + len > EPX_SIZE)
len = EPX_SIZE - ul_send_fifo_ptr[ep];
}
for (i = 0, ptr_dest += ul_send_fifo_ptr[ep]; i < len; ++i)
*ptr_dest++ = *ptr_src++;
ul_send_fifo_ptr[ep] += i;
if (ep == EP0)
{
TRACE_UOTGHS(printf("=> UDD_Send (2): ep=%d ptr_dest=%d maxlen=%d\r\n", ep, ul_send_fifo_ptr[ep], EP0_SIZE);)
if (ul_send_fifo_ptr[ep] == EP0_SIZE)
{
UDD_ClearIN(); // Fifo is full, release this packet
UDD_WaitIN(); // Wait for new FIFO buffer to be ready
}
}
else
{
if (ul_send_fifo_ptr[ep] == EPX_SIZE)
{
UDD_ClearIN(); // Fifo is full, release this packet
UDD_WaitIN(); // Wait for new FIFO buffer to be ready
}
}
return len;
}
void UDD_Send8(uint32_t ep, uint8_t data )
{
uint8_t *ptr_dest = (uint8_t *) &udd_get_endpoint_fifo_access8(ep);
TRACE_UOTGHS(printf("=> UDD_Send8 : ul_send_fifo_ptr=%d data=0x%x\r\n", ul_send_fifo_ptr[ep], data);)
ptr_dest[ul_send_fifo_ptr[ep]] = data;
ul_send_fifo_ptr[ep] += 1;
}
uint8_t UDD_Recv8(uint32_t ep)
{
uint8_t *ptr_dest = (uint8_t *) &udd_get_endpoint_fifo_access8(ep);
uint8_t data = ptr_dest[ul_recv_fifo_ptr[ep]];
TRACE_UOTGHS(printf("=> UDD_Recv8 : ul_recv_fifo_ptr=%d\r\n", ul_recv_fifo_ptr[ep]);)
ul_recv_fifo_ptr[ep] += 1;
return data;
}
void UDD_Recv(uint32_t ep, uint8_t* data, uint32_t len)
{
uint8_t *ptr_src = (uint8_t *) &udd_get_endpoint_fifo_access8(ep);
uint8_t *ptr_dest = data;
uint32_t i;
for (i = 0, ptr_src += ul_recv_fifo_ptr[ep]; i < len; ++i)
*ptr_dest++ = *ptr_src++;
ul_recv_fifo_ptr[ep] += i;
}
void UDD_Stall(void)
{
UOTGHS->UOTGHS_DEVEPT = (UOTGHS_DEVEPT_EPEN0 << EP0);
UOTGHS->UOTGHS_DEVEPTIER[EP0] = UOTGHS_DEVEPTIER_STALLRQS;
}
uint32_t UDD_FifoByteCount(uint32_t ep)
{
return ((UOTGHS->UOTGHS_DEVEPTISR[ep] & UOTGHS_DEVEPTISR_BYCT_Msk) >> UOTGHS_DEVEPTISR_BYCT_Pos);
}
void UDD_ReleaseRX(uint32_t ep)
{
TRACE_UOTGHS(puts("=> UDD_ReleaseRX\r\n");)
UOTGHS->UOTGHS_DEVEPTICR[ep] = (UOTGHS_DEVEPTICR_NAKOUTIC | UOTGHS_DEVEPTICR_RXOUTIC);
UOTGHS->UOTGHS_DEVEPTIDR[ep] = UOTGHS_DEVEPTIDR_FIFOCONC;
ul_recv_fifo_ptr[ep] = 0;
}
void UDD_ReleaseTX(uint32_t ep)
{
TRACE_UOTGHS(printf("=> UDD_ReleaseTX ep=%d\r\n", ep);)
UOTGHS->UOTGHS_DEVEPTICR[ep] = (UOTGHS_DEVEPTICR_NAKINIC | UOTGHS_DEVEPTICR_RXOUTIC | UOTGHS_DEVEPTICR_TXINIC);
UOTGHS->UOTGHS_DEVEPTIDR[ep] = UOTGHS_DEVEPTIDR_FIFOCONC;
ul_send_fifo_ptr[ep] = 0;
}
// Return true if the current bank is not full.
uint32_t UDD_ReadWriteAllowed(uint32_t ep)
{
return (UOTGHS->UOTGHS_DEVEPTISR[ep] & UOTGHS_DEVEPTISR_RWALL);
}
void UDD_SetAddress(uint32_t addr)
{
TRACE_UOTGHS(printf("=> UDD_SetAddress : setting address to %d\r\n", addr);)
udd_configure_address(addr);
udd_enable_address();
}
uint32_t UDD_GetFrameNumber(void)
{
return udd_frame_number();
}
#endif /* SAM3XA_SERIES */

View File

@ -0,0 +1,324 @@
/*
Copyright (c) 2012 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "chip.h"
#include <stdio.h>
#if SAM3XA_SERIES
//#define TRACE_UOTGHS(x) x
#define TRACE_UOTGHS(x)
extern void (*gpf_isr)(void);
static volatile uint32_t ul_send_fifo_ptr[MAX_ENDPOINTS];
static volatile uint32_t ul_recv_fifo_ptr[MAX_ENDPOINTS];
void UDD_SetStack(void (*pf_isr)(void))
{
gpf_isr = pf_isr;
}
uint32_t UDD_Init(void)
{
uint32_t i;
for (i = 0; i < MAX_ENDPOINTS; ++i)
{
ul_send_fifo_ptr[i] = 0;
ul_recv_fifo_ptr[i] = 0;
}
// Enables the USB Clock
pmc_enable_periph_clk(ID_UOTGHS);
pmc_enable_upll_clock();
pmc_switch_udpck_to_upllck(0); // div=0+1
pmc_enable_udpck();
// Configure interrupts
NVIC_SetPriority((IRQn_Type) ID_UOTGHS, 0UL);
NVIC_EnableIRQ((IRQn_Type) ID_UOTGHS);
// Always authorize asynchrone USB interrupts to exit from sleep mode
// for SAM3 USB wake up device except BACKUP mode
//pmc_set_fast_startup_input(PMC_FSMR_USBAL);
// ID pin not used then force device mode
otg_disable_id_pin();
otg_force_device_mode();
// Enable USB hardware
otg_disable_pad();
otg_enable_pad();
otg_enable();
otg_unfreeze_clock();
// Check USB clock
//while (!Is_otg_clock_usable())
// ;
udd_low_speed_disable();
udd_high_speed_disable();
//otg_ack_vbus_transition();
// Force Vbus interrupt in case of Vbus always with a high level
// This is possible with a short timing between a Host mode stop/start.
/*if (Is_otg_vbus_high()) {
otg_raise_vbus_transition();
}
otg_enable_vbus_interrupt();*/
otg_freeze_clock();
return 0UL ;
}
void UDD_Attach(void)
{
irqflags_t flags = cpu_irq_save();
TRACE_UOTGHS(printf("=> UDD_Attach\r\n");)
otg_unfreeze_clock();
// Check USB clock because the source can be a PLL
while (!Is_otg_clock_usable());
// Authorize attach if Vbus is present
udd_attach_device();
// Enable USB line events
udd_enable_reset_interrupt();
//udd_enable_sof_interrupt();
cpu_irq_restore(flags);
}
void UDD_Detach(void)
{
TRACE_UOTGHS(printf("=> UDD_Detach\r\n");)
UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_DETACH;
}
void UDD_InitEP( uint32_t ul_ep_nb, uint32_t ul_ep_cfg )
{
ul_ep_nb = ul_ep_nb & 0xF; // EP range is 0..9, hence mask is 0xF.
TRACE_UOTGHS(printf("=> UDD_InitEP : init EP %d\r\n", ul_ep_nb);)
// Configure EP
UOTGHS->UOTGHS_DEVEPTCFG[ul_ep_nb] = ul_ep_cfg;
// Enable EP
udd_enable_endpoint(ul_ep_nb);
if (!Is_udd_endpoint_configured(ul_ep_nb)) {
TRACE_UOTGHS(printf("=> UDD_InitEP : ERROR FAILED TO INIT EP %d\r\n", ul_ep_nb);)
}
}
void UDD_InitEndpoints(const uint32_t* eps_table, const uint32_t ul_eps_table_size)
{
uint32_t ul_ep_nb ;
for (ul_ep_nb = 1; ul_ep_nb < ul_eps_table_size; ul_ep_nb++)
{
// Configure EP
UOTGHS->UOTGHS_DEVEPTCFG[ul_ep_nb] = eps_table[ul_ep_nb];
// Enable EP
udd_enable_endpoint(ul_ep_nb);
if (!Is_udd_endpoint_configured(ul_ep_nb)) {
TRACE_UOTGHS(printf("=> UDD_InitEP : ERROR FAILED TO INIT EP %d\r\n", ul_ep_nb);)
}
}
}
// Wait until ready to accept IN packet.
void UDD_WaitIN(void)
{
while (!(UOTGHS->UOTGHS_DEVEPTISR[EP0] & UOTGHS_DEVEPTISR_TXINI))
;
}
void UDD_WaitOUT(void)
{
while (!(UOTGHS->UOTGHS_DEVEPTISR[EP0] & UOTGHS_DEVEPTISR_RXOUTI))
;
}
// Send packet.
void UDD_ClearIN(void)
{
TRACE_UOTGHS(printf("=> UDD_ClearIN: sent %d bytes\r\n", ul_send_fifo_ptr[EP0]);)
UOTGHS->UOTGHS_DEVEPTICR[EP0] = UOTGHS_DEVEPTICR_TXINIC;
ul_send_fifo_ptr[EP0] = 0;
}
void UDD_ClearOUT(void)
{
UOTGHS->UOTGHS_DEVEPTICR[EP0] = UOTGHS_DEVEPTICR_RXOUTIC;
ul_recv_fifo_ptr[EP0] = 0;
}
// Wait for IN FIFO to be ready to accept data or OUT FIFO to receive data.
// Return true if new IN FIFO buffer available.
uint32_t UDD_WaitForINOrOUT(void)
{
while (!(UOTGHS->UOTGHS_DEVEPTISR[EP0] & (UOTGHS_DEVEPTISR_TXINI | UOTGHS_DEVEPTISR_RXOUTI)))
;
return ((UOTGHS->UOTGHS_DEVEPTISR[EP0] & UOTGHS_DEVEPTISR_RXOUTI) == 0);
}
uint32_t UDD_ReceivedSetupInt(void)
{
return UOTGHS->UOTGHS_DEVEPTISR[EP0] & UOTGHS_DEVEPTISR_RXSTPI;
}
void UDD_ClearSetupInt(void)
{
UOTGHS->UOTGHS_DEVEPTICR[EP0] = (UOTGHS_DEVEPTICR_RXSTPIC);
}
uint32_t UDD_Send(uint32_t ep, const void* data, uint32_t len)
{
const uint8_t *ptr_src = data;
uint8_t *ptr_dest = (uint8_t *) &udd_get_endpoint_fifo_access8(ep);
uint32_t i;
TRACE_UOTGHS(printf("=> UDD_Send (1): ep=%d ul_send_fifo_ptr=%d len=%d\r\n", ep, ul_send_fifo_ptr[ep], len);)
if (ep == EP0)
{
if (ul_send_fifo_ptr[ep] + len > EP0_SIZE)
len = EP0_SIZE - ul_send_fifo_ptr[ep];
}
else
{
if (ul_send_fifo_ptr[ep] + len > EPX_SIZE)
len = EPX_SIZE - ul_send_fifo_ptr[ep];
}
for (i = 0, ptr_dest += ul_send_fifo_ptr[ep]; i < len; ++i)
*ptr_dest++ = *ptr_src++;
ul_send_fifo_ptr[ep] += i;
if (ep == EP0)
{
TRACE_UOTGHS(printf("=> UDD_Send (2): ep=%d ptr_dest=%d maxlen=%d\r\n", ep, ul_send_fifo_ptr[ep], EP0_SIZE);)
if (ul_send_fifo_ptr[ep] == EP0_SIZE)
{
UDD_ClearIN(); // Fifo is full, release this packet
UDD_WaitIN(); // Wait for new FIFO buffer to be ready
}
}
else
{
if (ul_send_fifo_ptr[ep] == EPX_SIZE)
{
UDD_ClearIN(); // Fifo is full, release this packet
UDD_WaitIN(); // Wait for new FIFO buffer to be ready
}
}
return len;
}
void UDD_Send8(uint32_t ep, uint8_t data )
{
uint8_t *ptr_dest = (uint8_t *) &udd_get_endpoint_fifo_access8(ep);
TRACE_UOTGHS(printf("=> UDD_Send8 : ul_send_fifo_ptr=%d data=0x%x\r\n", ul_send_fifo_ptr[ep], data);)
ptr_dest[ul_send_fifo_ptr[ep]] = data;
ul_send_fifo_ptr[ep] += 1;
}
uint8_t UDD_Recv8(uint32_t ep)
{
uint8_t *ptr_dest = (uint8_t *) &udd_get_endpoint_fifo_access8(ep);
uint8_t data = ptr_dest[ul_recv_fifo_ptr[ep]];
TRACE_UOTGHS(printf("=> UDD_Recv8 : ul_recv_fifo_ptr=%d\r\n", ul_recv_fifo_ptr[ep]);)
ul_recv_fifo_ptr[ep] += 1;
return data;
}
void UDD_Recv(uint32_t ep, uint8_t* data, uint32_t len)
{
uint8_t *ptr_src = (uint8_t *) &udd_get_endpoint_fifo_access8(ep);
uint8_t *ptr_dest = data;
uint32_t i;
for (i = 0, ptr_src += ul_recv_fifo_ptr[ep]; i < len; ++i)
*ptr_dest++ = *ptr_src++;
ul_recv_fifo_ptr[ep] += i;
}
void UDD_Stall(void)
{
UOTGHS->UOTGHS_DEVEPT = (UOTGHS_DEVEPT_EPEN0 << EP0);
UOTGHS->UOTGHS_DEVEPTIER[EP0] = UOTGHS_DEVEPTIER_STALLRQS;
}
uint32_t UDD_FifoByteCount(uint32_t ep)
{
return ((UOTGHS->UOTGHS_DEVEPTISR[ep] & UOTGHS_DEVEPTISR_BYCT_Msk) >> UOTGHS_DEVEPTISR_BYCT_Pos);
}
void UDD_ReleaseRX(uint32_t ep)
{
TRACE_UOTGHS(puts("=> UDD_ReleaseRX\r\n");)
UOTGHS->UOTGHS_DEVEPTICR[ep] = (UOTGHS_DEVEPTICR_NAKOUTIC | UOTGHS_DEVEPTICR_RXOUTIC);
UOTGHS->UOTGHS_DEVEPTIDR[ep] = UOTGHS_DEVEPTIDR_FIFOCONC;
ul_recv_fifo_ptr[ep] = 0;
}
void UDD_ReleaseTX(uint32_t ep)
{
TRACE_UOTGHS(printf("=> UDD_ReleaseTX ep=%d\r\n", ep);)
UOTGHS->UOTGHS_DEVEPTICR[ep] = (UOTGHS_DEVEPTICR_NAKINIC | UOTGHS_DEVEPTICR_RXOUTIC | UOTGHS_DEVEPTICR_TXINIC);
UOTGHS->UOTGHS_DEVEPTIDR[ep] = UOTGHS_DEVEPTIDR_FIFOCONC;
ul_send_fifo_ptr[ep] = 0;
}
// Return true if the current bank is not full.
uint32_t UDD_ReadWriteAllowed(uint32_t ep)
{
return (UOTGHS->UOTGHS_DEVEPTISR[ep] & UOTGHS_DEVEPTISR_RWALL);
}
void UDD_SetAddress(uint32_t addr)
{
TRACE_UOTGHS(printf("=> UDD_SetAddress : setting address to %d\r\n", addr);)
udd_configure_address(addr);
udd_enable_address();
}
uint32_t UDD_GetFrameNumber(void)
{
return udd_frame_number();
}
#endif /* SAM3XA_SERIES */

View File

@ -0,0 +1,404 @@
/*
Copyright (c) 2012 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "chip.h"
#include <stdio.h>
#if SAM3XA_SERIES
#define TRACE_UOTGHS(x) x
//#define TRACE_UOTGHS(x)
extern void (*gpf_isr)(void);
static uhd_vbus_state_t uhd_state = UHD_STATE_NO_VBUS;
static void UHD_ISR(void)
{
// Manage dis/connection event
if (Is_uhd_disconnection() && Is_uhd_disconnection_int_enabled()) {
printf(">>> UHD_ISR : Disconnection INT\r\n");
uhd_ack_disconnection();
uhd_disable_disconnection_int();
// Stop reset signal, in case of disconnection during reset
uhd_stop_reset();
// Disable wakeup/resumes interrupts,
// in case of disconnection during suspend mode
//UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_HWUPIEC
// | UOTGHS_HSTIDR_RSMEDIEC
// | UOTGHS_HSTIDR_RXRSMIEC;
uhd_ack_connection();
uhd_enable_connection_int();
uhd_state = UHD_STATE_DISCONNECTED;
return;
}
if (Is_uhd_connection() && Is_uhd_connection_int_enabled()) {
printf(">>> UHD_ISR : Connection INT\r\n");
uhd_ack_connection();
uhd_disable_connection_int();
uhd_ack_disconnection();
uhd_enable_disconnection_int();
//uhd_enable_sof();
uhd_state = UHD_STATE_CONNECTED;
return;
}
// Manage Vbus error
if (Is_uhd_vbus_error_interrupt())
{
printf(">>> UHD_ISR : VBUS error INT\r\n");
uhd_ack_vbus_error_interrupt();
uhd_state = UHD_STATE_ERROR;
return;
}
// Check USB clock ready after asynchronous interrupt
while (!Is_otg_clock_usable())
;
otg_unfreeze_clock();
// Manage Vbus state change
if (Is_otg_vbus_transition())
{
otg_ack_vbus_transition();
if (Is_otg_vbus_high())
{
printf(">>> UHD_ISR : VBUS transition INT : UHD_STATE_DISCONNECT\r\n");
uhd_state = UHD_STATE_DISCONNECTED;
}
else
{
printf(">>> UHD_ISR : VBUS transition INT : UHD_STATE_NO_VBUS\r\n");
otg_freeze_clock();
uhd_state = UHD_STATE_NO_VBUS;
}
printf(">>> UHD_ISR : VBUS transition INT : done.\r\n");
return;
}
// Other errors
if (Is_uhd_errors_interrupt())
{
printf(">>> UHD_ISR : Other error INT\r\n");
uhd_ack_errors_interrupt();
return;
}
}
void UHD_SetStack(void (*pf_isr)(void))
{
gpf_isr = pf_isr;
}
void UHD_Init(void)
{
irqflags_t flags;
// To avoid USB interrupt before end of initialization
flags = cpu_irq_save();
// Setup USB Host interrupt callback
UHD_SetStack(&UHD_ISR);
// Enables the USB Clock
pmc_enable_upll_clock();
pmc_switch_udpck_to_upllck(0); // div=0+1
pmc_enable_udpck();
pmc_enable_periph_clk(ID_UOTGHS);
// Always authorize asynchronous USB interrupts to exit of sleep mode
// For SAM3 USB wake up device except BACKUP mode
NVIC_SetPriority((IRQn_Type) ID_UOTGHS, 0);
NVIC_EnableIRQ((IRQn_Type) ID_UOTGHS);
// ID pin not used then force host mode
otg_disable_id_pin();
otg_force_host_mode();
// Signal is active low (because all SAM3X Pins are high after startup)
// Hence VBOF must be low after connection request to power up the remote device
uhd_set_vbof_active_low();
otg_enable_pad();
otg_enable();
otg_unfreeze_clock();
// Check USB clock
while (!Is_otg_clock_usable())
;
// Clear all interrupts that may have been set by a previous host mode
UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_DCONNIC | UOTGHS_HSTICR_DDISCIC
| UOTGHS_HSTICR_HSOFIC | UOTGHS_HSTICR_HWUPIC
| UOTGHS_HSTICR_RSMEDIC | UOTGHS_HSTICR_RSTIC
| UOTGHS_HSTICR_RXRSMIC;
otg_ack_vbus_transition();
// Enable Vbus change and error interrupts
// Disable automatic Vbus control after Vbus error
Set_bits(UOTGHS->UOTGHS_CTRL,
UOTGHS_CTRL_VBUSHWC | UOTGHS_CTRL_VBUSTE | UOTGHS_CTRL_VBERRE);
uhd_enable_vbus();
// Force Vbus interrupt when Vbus is always high
// This is possible due to a short timing between a Host mode stop/start.
if (Is_otg_vbus_high())
{
otg_raise_vbus_transition();
}
// Enable main control interrupt
// Connection, SOF and reset
UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTICR_DCONNIC;// | UOTGHS_HSTICR_RSTIC;// | UOTGHS_HSTICR_HSOFIC;
otg_freeze_clock();
uhd_state = UHD_STATE_NO_VBUS;
cpu_irq_restore(flags);
}
void UHD_BusReset(void)
{
uhd_start_reset();
}
uhd_vbus_state_t UHD_GetVBUSState(void)
{
return uhd_state;
}
/*uhd_speed_t uhd_get_speed(void)
{
switch (uhd_get_speed_mode())
{
case UOTGHS_SR_SPEED_HIGH_SPEED:
return UHD_SPEED_HIGH;
case UOTGHS_SR_SPEED_FULL_SPEED:
return UHD_SPEED_FULL;
case UOTGHS_SR_SPEED_LOW_SPEED:
return UHD_SPEED_LOW;
default:
return UHD_SPEED_LOW;
}
}*/
/**
* \brief Allocate FIFO for pipe 0.
*
* \param ul_add Address of remote device for pipe 0.
* \param ul_ep_size Actual size of the FIFO in bytes.
*
* \retval 0 success.
* \retval 1 error.
*/
uint32_t UHD_EP0_Alloc(uint32_t ul_add, uint32_t ul_ep_size)
{
if (ul_ep_size < 8)
{
TRACE_UOTGHS(printf("/!\\ UHD_EP0_Alloc : incorrect pipe size!\r\n");)
return 1;
}
if (Is_uhd_pipe_enabled(0))
{
// Pipe is already allocated
return 0;
}
uhd_enable_pipe(0);
uhd_configure_pipe(0, // Pipe 0
0, // No frequency
0, // Enpoint 0
UOTGHS_HSTPIPCFG_PTYPE_CTRL,
UOTGHS_HSTPIPCFG_PTOKEN_SETUP,
ul_ep_size,
UOTGHS_HSTPIPCFG_PBK_1_BANK, 0);
uhd_allocate_memory(0);
if (!Is_uhd_pipe_configured(0))
{
TRACE_UOTGHS(printf("/!\\ UHD_EP0_Alloc : incorrect pipe settings!\r\n");)
uhd_disable_pipe(0);
return 1;
}
uhd_configure_address(0, ul_add);
// Always enable stall and error interrupts of control endpoint
/*uhd_enable_stall_interrupt(0);
uhd_enable_pipe_error_interrupt(0);
uhd_enable_pipe_interrupt(0);*/
return 0;
}
void UHD_EP_Free(uint32_t add, uint32_t endp)
{
// Search endpoint(s) in all pipes
for (uint8_t pipe = 0; pipe < UOTGHS_EPT_NUM; pipe++)
{
if (!Is_uhd_pipe_enabled(pipe))
{
continue;
}
if (add != uhd_get_configured_address(pipe))
{
continue;
}
/* if (endp != 0xFF)
{
// Disable specific endpoint number
if (endp != uhd_get_pipe_endpoint_address(pipe))
{
continue; // Mismatch
}
}
*/
// Unalloc pipe
uhd_disable_pipe(pipe);
uhd_unallocate_memory(pipe);
uhd_reset_pipe(pipe);
}
}
uint32_t UHD_EP_Read(uint32_t ul_ep, uint32_t ul_size, uint8_t* data)
{
uint8_t *ptr_ep_data = 0;
uint8_t nb_byte_received = 0;
uint32_t ul_nb_trans = 0;
// Get information to read data
nb_byte_received = uhd_byte_count(ul_ep);
ptr_ep_data = (uint8_t *) & uhd_get_pipe_fifo_access(ul_ep, 8);
// Copy data from pipe to payload buffer
while (ul_size && nb_byte_received) {
*data++ = *ptr_ep_data++;
ul_nb_trans++;
ul_size--;
nb_byte_received--;
}
return ul_nb_trans;
}
void UHD_EP_Write(uint32_t ul_ep, uint32_t ul_size, uint8_t* data)
{
volatile uint8_t *ptr_ep_data = 0;
uint32_t i = 0;
// Check pipe
if (!Is_uhd_pipe_enabled(ul_ep))
{
// Endpoint not valid
TRACE_UOTGHS(printf("/!\\ UHD_EP_Send : pipe is not enabled!\r\n");)
return;
}
ptr_ep_data = (volatile uint8_t *)&uhd_get_pipe_fifo_access(ul_ep, 8);
for (i = 0; i < ul_size; ++i)
*ptr_ep_data++ = *data++;
}
void UHD_EP_Send(uint32_t ul_ep, uint32_t ul_token_type)
{
// Check pipe
if (!Is_uhd_pipe_enabled(ul_ep))
{
// Endpoint not valid
TRACE_UOTGHS(printf("/!\\ UHD_EP_Send : pipe is not enabled!\r\n");)
return;
}
// Set token type
uhd_configure_pipe_token(ul_ep, ul_token_type);
// Clear interrupt flags
uhd_ack_setup_ready(ul_ep);
uhd_ack_in_received(ul_ep);
uhd_ack_out_ready(ul_ep);
uhd_ack_short_packet(ul_ep);
// Send actual packet
uhd_ack_fifocon(ul_ep);
uhd_unfreeze_pipe(ul_ep);
}
/**
* \brief Check is transfer is complete.
*
* \param ul_add Address of remote device for pipe 0.
* \param ul_ep_size Actual size of the FIFO in bytes.
*
* \retval 0 transfer is not complete.
* \retval 1 transfer is complete.
*/
uint32_t UHD_EP_Is_Transfer_Complete(uint32_t ul_ep, uint32_t ul_token_type)
{
// Check for transfer completion depending on token type
switch (ul_token_type)
{
case UOTGHS_HSTPIPCFG_PTOKEN_SETUP:
if (Is_uhd_setup_ready(ul_ep))
{
uhd_freeze_pipe(ul_ep);
uhd_ack_setup_ready(ul_ep);
return 1;
}
case UOTGHS_HSTPIPCFG_PTOKEN_IN:
if (Is_uhd_in_received(ul_ep))
{
// In case of low USB speed and with a high CPU frequency,
// a ACK from host can be always running on USB line
// then wait end of ACK on IN pipe.
while(!Is_uhd_pipe_frozen(ul_ep))
;
// IN packet received
uhd_ack_in_received(ul_ep);
return 1;
}
case UOTGHS_HSTPIPCFG_PTOKEN_OUT:
if (Is_uhd_out_ready(ul_ep))
{
// OUT packet sent
uhd_freeze_pipe(ul_ep);
uhd_ack_out_ready(ul_ep);
return 1;
}
}
// Nothing to report
return 0;
}
#endif /* SAM3XA_SERIES */

View File

@ -58,6 +58,7 @@ INCLUDES += -I$(ARDUINO_PATH)
INCLUDES += -I$(ARDUINO_PATH)/USB
INCLUDES += -I$(SYSTEM_PATH)
INCLUDES += -I$(SYSTEM_PATH)/libsam
INCLUDES += -I$(SYSTEM_PATH)/USBHost
INCLUDES += -I$(VARIANT_BASE_PATH)
INCLUDES += -I$(VARIANT_PATH)
INCLUDES += -I$(CMSIS_ARM_PATH)

View File

@ -99,14 +99,14 @@ pwmc.o:
00000000 T PWMC_SetSyncChannelUpdateUnlock
00000000 T PWMC_WriteBuffer
U __assert_func
00000000 r __func__.3192
00000000 r __func__.3203
00000000 r __func__.3218
00000000 r __func__.3229
00000000 r __func__.3240
00000000 r __func__.3247
00000000 r __func__.3331
00000000 r __func__.3337
00000000 r __func__.3227
00000000 r __func__.3238
00000000 r __func__.3253
00000000 r __func__.3264
00000000 r __func__.3275
00000000 r __func__.3282
00000000 r __func__.3366
00000000 r __func__.3372
rtc.o:
00000000 T RTC_ClearSCCR
@ -122,9 +122,9 @@ rtc.o:
00000000 T RTC_SetTime
00000000 T RTC_SetTimeAlarm
U __assert_func
00000000 r __func__.3189
00000000 r __func__.3198
00000000 r __func__.3203
00000000 r __func__.3224
00000000 r __func__.3233
00000000 r __func__.3238
rtt.o:
00000000 T RTT_EnableIT
@ -133,8 +133,8 @@ rtt.o:
00000000 T RTT_SetAlarm
00000000 T RTT_SetPrescaler
U __assert_func
00000000 r __func__.3196
00000000 r __func__.3204
00000000 r __func__.3231
00000000 r __func__.3239
spi.o:
00000000 T SPI_Configure
@ -155,9 +155,9 @@ tc.o:
00000000 T TC_Start
00000000 T TC_Stop
U __assert_func
00000000 r __func__.3191
00000000 r __func__.3197
00000000 r __func__.3203
00000000 r __func__.3226
00000000 r __func__.3232
00000000 r __func__.3238
timetick.o:
00000000 T GetTickCount
@ -184,18 +184,18 @@ twi.o:
00000000 T TWI_TransferComplete
00000000 T TWI_WriteByte
U __assert_func
00000000 r __func__.3556
00000000 r __func__.3571
00000000 r __func__.3575
00000000 r __func__.3582
00000000 r __func__.3586
00000000 r __func__.3591
00000000 r __func__.3599
00000000 r __func__.3613
00000000 r __func__.3618
00000000 r __func__.3622
00000000 r __func__.3627
00000000 r __func__.3631
00000000 r __func__.3606
00000000 r __func__.3610
00000000 r __func__.3617
00000000 r __func__.3621
00000000 r __func__.3626
00000000 r __func__.3634
00000000 r __func__.3648
00000000 r __func__.3653
00000000 r __func__.3657
00000000 r __func__.3662
00000000 r __func__.3666
usart.o:
00000000 T USART_Configure
@ -214,7 +214,7 @@ usart.o:
00000000 T USART_Write
00000000 T USART_WriteBuffer
U __assert_func
00000000 r __func__.3477
00000000 r __func__.3512
wdt.o:
00000000 T WDT_Disable
@ -343,6 +343,13 @@ udp.o:
udphs.o:
uotghs.o:
00000000 T UOTGHS_Handler
00000000 B gpf_isr
interrupt_sam_nvic.o:
00000000 D g_interrupt_enabled
uotghs_device.o:
00000000 T UDD_Attach
00000000 T UDD_ClearIN
00000000 T UDD_ClearOUT
@ -367,9 +374,8 @@ uotghs.o:
00000000 T UDD_WaitForINOrOUT
00000000 T UDD_WaitIN
00000000 T UDD_WaitOUT
00000000 T UOTGHS_Handler
U g_interrupt_enabled
00000000 b gpf_isr
U gpf_isr
U pmc_enable_periph_clk
U pmc_enable_udpck
U pmc_enable_upll_clock
@ -377,5 +383,23 @@ uotghs.o:
00000000 b ul_recv_fifo_ptr
00000000 b ul_send_fifo_ptr
interrupt_sam_nvic.o:
00000000 D g_interrupt_enabled
uotghs_host.o:
00000000 T UHD_BusReset
00000000 T UHD_EP0_Alloc
00000000 T UHD_EP_Free
00000000 T UHD_EP_Is_Transfer_Complete
00000000 T UHD_EP_Read
00000000 T UHD_EP_Send
00000000 T UHD_EP_Write
00000000 T UHD_GetVBUSState
00000000 t UHD_ISR
00000000 T UHD_Init
00000000 T UHD_SetStack
U g_interrupt_enabled
U gpf_isr
U iprintf
U pmc_enable_periph_clk
U pmc_enable_udpck
U pmc_enable_upll_clock
U pmc_switch_udpck_to_upllck
00000000 b uhd_state