tags/v2.9dc0e46e
Rename LUFA to LUFA-git3bfa7fa
Remove LUFA-120730215b764
Merge commit 'afa0f22a9299686fd88f58ce09c5b521ac917e8f' as 'protocol/lufa/LUFA'afa0f22
Squashed 'protocol/lufa/LUFA/' content from commitdef7fca
c0c42fa
Remove submodule of LUFA30f897d
Merge commit '87ced33feb74e79c3281dda36eb6d6d153399b41' as 'protocol/usb_hid/USB_Host_Shield_2.0'87ced33
Squashed 'protocol/usb_hid/USB_Host_Shield_2.0/' content from commitaab4a69
14f6d49
Remove submodule of USB_Host_Shield_2.0 git-subtree-dir: tmk_core git-subtree-split:dc0e46eaa4
@@ -1,6 +0,0 @@ | |||
[submodule "protocol/lufa/LUFA-git"] | |||
path = protocol/lufa/LUFA-git | |||
url = https://github.com/abcminiuser/lufa.git | |||
[submodule "protocol/usb_hid/USB_Host_Shield_2.0"] | |||
path = protocol/usb_hid/USB_Host_Shield_2.0 | |||
url = https://github.com/felis/USB_Host_Shield_2.0.git |
@@ -1,11 +1,7 @@ | |||
LUFA_DIR = protocol/lufa | |||
# Path to the LUFA library | |||
ifeq (, $(wildcard $(TMK_DIR)/$(LUFA_DIR)/LUFA-git/LUFA/Version.h)) | |||
LUFA_PATH ?= $(LUFA_DIR)/LUFA-120730 | |||
else | |||
LUFA_PATH ?= $(LUFA_DIR)/LUFA-git | |||
endif | |||
LUFA_PATH ?= $(LUFA_DIR)/LUFA-git | |||
# Create the LUFA source path variables by including the LUFA makefile |
@@ -1,116 +0,0 @@ | |||
# | |||
# LUFA Library | |||
# Copyright (C) Dean Camera, 2012. | |||
# | |||
# dean [at] fourwalledcubicle [dot] com | |||
# www.lufa-lib.org | |||
# | |||
LUFA_BUILD_MODULES += SOURCES | |||
LUFA_BUILD_TARGETS += | |||
LUFA_BUILD_MANDATORY_VARS += LUFA_PATH ARCH | |||
LUFA_BUILD_OPTIONAL_VARS += | |||
LUFA_BUILD_PROVIDED_VARS += LUFA_SRC_USB LUFA_SRC_USBCLASS LUFA_SRC_TEMPERATURE LUFA_SRC_SERIAL LUFA_SRC_TWI LUFA_SRC_PLATFORM | |||
LUFA_BUILD_PROVIDED_MACROS += | |||
# ----------------------------------------------------------------------------- | |||
# LUFA Sources Buildsystem Makefile Module. | |||
# ----------------------------------------------------------------------------- | |||
# DESCRIPTION: | |||
# Provides a set of makefile variables for the various LUFA module sources. | |||
# Once included, the sources required to use a given LUFA module will become | |||
# available using the makefile variable names listed in the LUFA project | |||
# documentation. | |||
# ----------------------------------------------------------------------------- | |||
# TARGETS: | |||
# | |||
# (None) | |||
# | |||
# MANDATORY PARAMETERS: | |||
# | |||
# LUFA_PATH - Path to the LUFA library core | |||
# ARCH - Device architecture name | |||
# | |||
# OPTIONAL PARAMETERS: | |||
# | |||
# (None) | |||
# | |||
# PROVIDED VARIABLES: | |||
# | |||
# LUFA_SRC_USB - List of LUFA USB driver source files | |||
# LUFA_SRC_USBCLASS - List of LUFA USB Class driver source files | |||
# LUFA_SRC_TEMPERATURE - List of LUFA temperature sensor driver source | |||
# files | |||
# LUFA_SRC_SERIAL - List of LUFA Serial U(S)ART driver source files | |||
# LUFA_SRC_TWI - List of LUFA TWI driver source files | |||
# LUFA_SRC_PLATFORM - List of LUFA architecture specific platform | |||
# management source files | |||
# | |||
# PROVIDED MACROS: | |||
# | |||
# (None) | |||
# | |||
# ----------------------------------------------------------------------------- | |||
SHELL = /bin/sh | |||
ERROR_IF_UNSET ?= $(if $(filter undefined, $(origin $(strip $(1)))), $(error Makefile $(strip $(1)) value not set)) | |||
ERROR_IF_EMPTY ?= $(if $(strip $($(strip $(1)))), , $(error Makefile $(strip $(1)) option cannot be blank)) | |||
ERROR_IF_NONBOOL ?= $(if $(filter Y N, $($(strip $(1)))), , $(error Makefile $(strip $(1)) option must be Y or N)) | |||
# Sanity check user supplied values | |||
$(foreach MANDATORY_VAR, $(LUFA_BUILD_MANDATORY_VARS), $(call ERROR_IF_UNSET, $(MANDATORY_VAR))) | |||
$(call ERROR_IF_EMPTY, LUFA_PATH) | |||
$(call ERROR_IF_EMPTY, ARCH) | |||
# Allow LUFA_ROOT_PATH to be overridden elsewhere to support legacy LUFA makefiles | |||
LUFA_ROOT_PATH ?= $(patsubst %/,%,$(LUFA_PATH)) | |||
# Construct LUFA module source variables | |||
LUFA_SRC_USB := $(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/Device_$(ARCH).c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/Endpoint_$(ARCH).c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/Host_$(ARCH).c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/Pipe_$(ARCH).c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/USBController_$(ARCH).c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/USBInterrupt_$(ARCH).c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/EndpointStream_$(ARCH).c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/PipeStream_$(ARCH).c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Core/ConfigDescriptors.c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Core/DeviceStandardReq.c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Core/Events.c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Core/HostStandardReq.c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Core/USBTask.c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Class/Common/HIDParser.c | |||
LUFA_SRC_USBCLASS := $(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/AudioClassDevice.c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/CDCClassDevice.c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/HIDClassDevice.c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/MassStorageClassDevice.c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/MIDIClassDevice.c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/RNDISClassDevice.c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/AudioClassHost.c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/CDCClassHost.c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/HIDClassHost.c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/MassStorageClassHost.c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/MIDIClassHost.c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/PrinterClassHost.c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/RNDISClassHost.c \ | |||
$(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/StillImageClassHost.c | |||
LUFA_SRC_TEMPERATURE := $(LUFA_ROOT_PATH)/Drivers/Board/Temperature.c | |||
LUFA_SRC_SERIAL := $(LUFA_ROOT_PATH)/Drivers/Peripheral/$(ARCH)/Serial_$(ARCH).c | |||
LUFA_SRC_TWI := $(LUFA_ROOT_PATH)/Drivers/Peripheral/$(ARCH)/TWI_$(ARCH).c | |||
ifeq ($(ARCH), UC3) | |||
LUFA_SRC_PLATFORM := $(LUFA_ROOT_PATH)/Platform/UC3/Exception.S \ | |||
$(LUFA_ROOT_PATH)/Platform/UC3/InterruptManagement.c | |||
else | |||
LUFA_SRC_PLATFORM := | |||
endif | |||
# Build a list of all available module sources | |||
LUFA_SRC_ALL_FILES := $(LUFA_SRC_USB) \ | |||
$(LUFA_SRC_USBCLASS) \ | |||
$(LUFA_SRC_TEMPERATURE) \ | |||
$(LUFA_SRC_SERIAL) \ | |||
$(LUFA_SRC_TWI) \ | |||
$(LUFA_SRC_PLATFORM) |
@@ -1,223 +0,0 @@ | |||
/** \file | |||
* | |||
* This file contains special DoxyGen information for the generation of the main page and other special | |||
* documentation pages. It is not a project source file. | |||
*/ | |||
/** \page Page_TokenSummary Summary of Compile Tokens | |||
* | |||
* The following lists all the possible tokens which can be defined in a project makefile, and passed to the | |||
* compiler via the -D switch, to alter the LUFA library code. These tokens may alter the library behaviour, | |||
* or remove features unused by a given application in order to save flash space. | |||
* | |||
* \note If the \c USE_LUFA_CONFIG_HEADER token is defined, the library will include a header file named \c LUFAConfig.h located | |||
* in the user directory where the below compile time tokens may be defined. This allows for an alternative to makefile | |||
* defined tokens for configuring the library. | |||
* | |||
* \section Sec_SummaryNonUSBTokens Non USB Related Tokens | |||
* This section describes compile tokens which affect non-USB sections of the LUFA library. | |||
* | |||
* - <b>DISABLE_TERMINAL_CODES</b> - (\ref Group_Terminal) - <i>All Architectures</i> \n | |||
* If an application contains ANSI terminal control codes listed in TerminalCodes.h, it might be desired to remove them | |||
* at compile time for use with a terminal which is non-ANSI control code aware, without modifying the source code. If | |||
* this token is defined, all ANSI control codes in the application code from the TerminalCodes.h header are removed from | |||
* the source code at compile time. | |||
* | |||
* | |||
* \section Sec_SummaryUSBClassTokens USB Class Driver Related Tokens | |||
* This section describes compile tokens which affect USB class-specific drivers in the LUFA library. | |||
* | |||
* - <b>HID_HOST_BOOT_PROTOCOL_ONLY</b> - (\ref Group_USBClassHIDHost) - <i>All Architectures</i> \n | |||
* By default, the USB HID Host class driver is designed to work with HID devices using either the Boot or Report HID | |||
* communication protocols. On devices where the Report protocol is not used (i.e. in applications where only basic | |||
* Mouse or Keyboard operation is desired, using boot compatible devices), the code responsible for the Report protocol | |||
* mode can be removed to save space in the compiled application by defining this token. When defined, it is still necessary | |||
* to explicitly put the attached device into Boot protocol mode via a call to \ref HID_Host_SetBootProtocol(). | |||
* | |||
* - <b>HID_STATETABLE_STACK_DEPTH</b>=<i>x</i> - (\ref Group_HIDParser) - <i>All Architectures</i> \n | |||
* HID reports may contain PUSH and POP elements, to store and retrieve the current HID state table onto a stack. This | |||
* allows for reports to save the state table before modifying it slightly for a data item, and then restore the previous | |||
* state table in a compact manner. This token may be defined to a non-zero 8-bit value to give the maximum depth of the state | |||
* table stack. If not defined, this defaults to the value indicated in the HID.h file documentation. | |||
* | |||
* - <b>HID_USAGE_STACK_DEPTH</b>=<i>x</i> - (\ref Group_HIDParser) - <i>All Architectures</i> \n | |||
* HID reports generally contain many USAGE elements, which are assigned to INPUT, OUTPUT and FEATURE items in succession | |||
* when multiple items are defined at once (via REPORT COUNT elements). This allows for several items to be defined with | |||
* different usages in a compact manner. This token may be defined to a non-zero 8-bit value to set the maximum depth of the | |||
* usage stack, indicating the maximum number of USAGE items which can be stored temporarily until the next INPUT, OUTPUT | |||
* and FEATURE item. If not defined, this defaults to the value indicated in the HID.h file documentation. | |||
* | |||
* - <b>HID_MAX_COLLECTIONS</b>=<i>x</i> - (\ref Group_HIDParser) - <i>All Architectures</i> \n | |||
* HID reports generally contain several COLLECTION elements, used to group related data items together. Collection information | |||
* is stored separately in the processed usage structure (and referred to by the data elements in the structure) to save space. | |||
* This token may be defined to a non-zero 8-bit value to set the maximum number of COLLECTION items which can be processed by the | |||
* parser into the resultant processed report structure. If not defined, this defaults to the value indicated in the HID.h file | |||
* documentation. | |||
* | |||
* - <b>HID_MAX_REPORTITEMS</b>=<i>x</i> - (\ref Group_HIDParser) - <i>All Architectures</i> \n | |||
* All HID reports contain one or more INPUT, OUTPUT and/or FEATURE items describing the data which can be sent to and from the HID | |||
* device. Each item has associated usages, bit offsets in the item reports and other associated data indicating the manner in which | |||
* the report data should be interpreted by the host. This token may be defined to a non-zero 8-bit value to set the maximum number of | |||
* data elements which can be stored in the processed HID report structure, including INPUT, OUTPUT and (if enabled) FEATURE items. | |||
* If a item has a multiple count (i.e. a REPORT COUNT of more than 1), each item in the report count is placed separately in the | |||
* processed HID report table. If not defined, this defaults to the value indicated in the HID.h file documentation. | |||
* | |||
* - <b>HID_MAX_REPORT_IDS</b>=<i>x</i> - (\ref Group_HIDParser) - <i>All Architectures</i> \n | |||
* HID reports may contain several report IDs, to logically distinguish grouped device data from one another - for example, a combination | |||
* keyboard and mouse might use report IDs to separate the keyboard reports from the mouse reports. In order to determine the size of each | |||
* report, and thus know how many bytes must be read or written, the size of each report (IN, OUT and FEATURE) must be calculated and | |||
* stored. This token may be defined to a non-zero 8-bit value to set the maximum number of report IDs in a device which can be processed | |||
* and their sizes calculated/stored into the resultant processed report structure. If not defined, this defaults to the value indicated in | |||
* the HID.h file documentation. | |||
* | |||
* - <b>NO_CLASS_DRIVER_AUTOFLUSH</b> - (\ref Group_USBClassDrivers) - <i>All Architectures</i> \n | |||
* Many of the device and host mode class drivers automatically flush any data waiting to be written to an interface, when the corresponding | |||
* USB management task is executed. This is usually desirable to ensure that any queued data is sent as soon as possible once and new data is | |||
* constructed in the main program loop. However, if flushing is to be controlled manually by the user application via the *_Flush() commands, | |||
* the compile time token may be defined in the application's makefile to disable automatic flushing during calls to the class driver USB | |||
* management tasks. | |||
* | |||
* | |||
* \section Sec_SummaryUSBTokens General USB Driver Related Tokens | |||
* This section describes compile tokens which affect USB driver stack as a whole in the LUFA library. | |||
* | |||
* - <b>ORDERED_EP_CONFIG</b> - (\ref Group_EndpointManagement , \ref Group_PipeManagement) - <i>AVR8, UC3</i> \n | |||
* The USB AVRs do not allow for Endpoints and Pipes to be configured out of order; they <i>must</i> be configured in an ascending order to | |||
* prevent data corruption issues. However, by default LUFA employs a workaround to allow for unordered Endpoint/Pipe initialization. This compile | |||
* time token may be used to restrict the initialization order to ascending indexes only in exchange for a smaller compiled binary size. Use | |||
* caution when applied to applications using the library USB Class drivers; the user application must ensure that all endpoints and pipes are | |||
* allocated sequentially. | |||
* | |||
* - <b>USE_STATIC_OPTIONS</b>=<i>x</i> - (\ref Group_USBManagement) - <i>All Architectures</i> \n | |||
* By default, the USB_Init() function accepts dynamic options at runtime to alter the library behaviour, including whether the USB pad | |||
* voltage regulator is enabled, and the device speed when in device mode. By defining this token to a mask comprised of the USB options | |||
* mask defines usually passed as the Options parameter to USB_Init(), the resulting compiled binary can be decreased in size by removing | |||
* the dynamic options code, and replacing it with the statically set options. When defined, the USB_Init() function no longer accepts an | |||
* Options parameter. | |||
* | |||
* - <b>USB_DEVICE_ONLY</b> - (\ref Group_USBManagement) - <i>All Architectures</i> \n | |||
* For the USB AVR models supporting both device and host USB modes, the USB_Init() function contains a Mode parameter which specifies the | |||
* mode the library should be initialized to. If only device mode is required, the code for USB host mode can be removed from the binary to | |||
* save space. When defined, the USB_Init() function no longer accepts a Mode parameter. This define is irrelevant on smaller USB AVRs which | |||
* do not support host mode. | |||
* | |||
* - <b>USB_HOST_ONLY</b> - (\ref Group_USBManagement) - <i>All Architectures</i> \n | |||
* Same as USB_DEVICE_ONLY, except the library is fixed to USB host mode rather than USB device mode. Not available on some USB AVR models. | |||
* | |||
* - <b>USB_STREAM_TIMEOUT_MS</b>=<i>x</i> - (\ref Group_USBManagement) - <i>All Architectures</i> \n | |||
* When endpoint and/or pipe stream functions are used, by default there is a timeout between each transfer which the connected device or host | |||
* must satisfy, or the stream function aborts the remaining data transfer. This token may be defined to a non-zero 16-bit value to set the timeout | |||
* period for stream transfers, specified in milliseconds. If not defined, the default value specified in LowLevel.h is used instead. | |||
* | |||
* - <b>NO_LIMITED_CONTROLLER_CONNECT</b> - (\ref Group_Events) - <i>AVR8 Only</i> \n | |||
* On the smaller USB AVRs, the USB controller lacks VBUS events to determine the physical connection state of the USB bus to a host. In lieu of | |||
* VBUS events, the library attempts to determine the connection state via the bus suspension and wake up events instead. This however may be | |||
* slightly inaccurate due to the possibility of the host suspending the bus while the device is still connected. If accurate connection status is | |||
* required, the VBUS line of the USB connector should be routed to an AVR pin to detect its level, so that the USB_DeviceState global | |||
* can be accurately set and the \ref EVENT_USB_Device_Connect() and \ref EVENT_USB_Device_Disconnect() events manually raised by the RAISE_EVENT macro. | |||
* When defined, this token disables the library's auto-detection of the connection state by the aforementioned suspension and wake up events. | |||
* | |||
* - <b>NO_SOF_EVENTS</b> - (\ref Group_Events) - <i>All Architectures</i> \n | |||
* By default, there exists a LUFA application event for the start of each USB frame while the USB bus is not suspended in either host or device mode. | |||
* This event can be selectively enabled or disabled by calling the appropriate device or host mode function. When this compile time token is defined, | |||
* the ability to receive USB Start of Frame events via the \ref EVENT_USB_Device_StartOfFrame() or \ref EVENT_USB_Host_StartOfFrame() events is removed, | |||
* reducing the compiled program's binary size. | |||
* | |||
* | |||
* \section Sec_SummaryUSBDeviceTokens USB Device Mode Driver Related Tokens | |||
* This section describes compile tokens which affect USB driver stack of the LUFA library when used in Device mode. | |||
* | |||
* - <b>USE_RAM_DESCRIPTORS</b> - (\ref Group_StdDescriptors) - <i>AVR8 Only</i> \n | |||
* Define this token to indicate to the USB driver that all device descriptors are stored in RAM, rather than being located in any one | |||
* of the AVR's memory spaces. RAM descriptors may be desirable in applications where the descriptors need to be modified at runtime. | |||
* | |||
* - <b>USE_FLASH_DESCRIPTORS</b> - (\ref Group_StdDescriptors) - <i>AVR8 Only</i> \n | |||
* Similar to USE_RAM_DESCRIPTORS, but all descriptors are stored in the AVR's FLASH memory rather than RAM. | |||
* | |||
* - <b>USE_EEPROM_DESCRIPTORS</b> - (\ref Group_StdDescriptors) - <i>AVR8 Only</i> \n | |||
* Similar to USE_RAM_DESCRIPTORS, but all descriptors are stored in the AVR's EEPROM memory rather than RAM. | |||
* | |||
* - <b>NO_INTERNAL_SERIAL</b> - (\ref Group_StdDescriptors) - <i>All Architectures</i> \n | |||
* Some AVR models contain a unique serial number which can be used as the device serial number, while in device mode. This allows | |||
* the host to uniquely identify the device regardless of if it is moved between USB ports on the same computer, allowing allocated | |||
* resources (such as drivers, COM Port number allocations) to be preserved. This is not needed in many apps, and so the code that | |||
* performs this task can be disabled by defining this option and passing it to the compiler via the -D switch. | |||
* | |||
* - <b>FIXED_CONTROL_ENDPOINT_SIZE</b>=<i>x</i> - (\ref Group_EndpointManagement) - <i>All Architectures</i> \n | |||
* By default, the library determines the size of the control endpoint (when in device mode) by reading the device descriptor. | |||
* Normally this reduces the amount of configuration required for the library, allows the value to change dynamically (if | |||
* descriptors are stored in EEPROM or RAM rather than flash memory) and reduces code maintenance. However, this token can be | |||
* defined to a non-zero value instead to give the size in bytes of the control endpoint, to reduce the size of the compiled | |||
* binary. | |||
* | |||
* - <b>DEVICE_STATE_AS_GPIOR</b> - (\ref Group_Device) - <i>AVR8 Only</i> \n | |||
* One of the most frequently used global variables in the stack is the USB_DeviceState global, which indicates the current state of | |||
* the Device State Machine. To reduce the amount of code and time required to access and modify this global in an application, this token | |||
* may be defined to a value between 0 and 2 to fix the state variable into one of the three general purpose IO registers inside the AVR | |||
* reserved for application use. When defined, the corresponding GPIOR register should not be used within the user application except | |||
* implicitly via the library APIs. | |||
* | |||
* - <b>FIXED_NUM_CONFIGURATIONS</b>=<i>x</i> - (\ref Group_Device) - <i>All Architectures</i> \n | |||
* By default, the library determines the number of configurations a USB device supports by reading the device descriptor. This reduces | |||
* the amount of configuration required to set up the library, and allows the value to change dynamically (if descriptors are stored in | |||
* EEPROM or RAM rather than flash memory) and reduces code maintenance. However, this value may be fixed via this token in the project | |||
* makefile to reduce the compiled size of the binary at the expense of flexibility. | |||
* | |||
* - <b>CONTROL_ONLY_DEVICE</b> - (\ref Group_Device) - <i>All Architectures</i> \n | |||
* In some limited USB device applications, there are no device endpoints other than the control endpoint; i.e. all device communication | |||
* is through control endpoint requests. Defining this token will remove several features related to the selection and control of device | |||
* endpoints internally, saving space. Generally, this is usually only useful in (some) bootloaders and is best avoided. | |||
* | |||
* - <b>MAX_ENDPOINT_INDEX</b> - (\ref Group_Device) - <i>XMEGA Only</i> \n | |||
* Defining this value to the highest index (not address - this excludes the direction flag) endpoint within the device will restrict the | |||
* number of FIFOs created internally for the endpoint buffers, reducing the total RAM usage. | |||
* | |||
* - <b>INTERRUPT_CONTROL_ENDPOINT</b> - (\ref Group_USBManagement) - <i>All Architectures</i> \n | |||
* Some applications prefer to not call the USB_USBTask() management task regularly while in device mode, as it can complicate code significantly. | |||
* Instead, when device mode is used this token can be passed to the library via the -D switch to allow the library to manage the USB control | |||
* endpoint entirely via USB controller interrupts asynchronously to the user application. When defined, USB_USBTask() does not need to be called | |||
* when in USB device mode. | |||
* | |||
* - <b>NO_DEVICE_REMOTE_WAKEUP</b> - (\ref Group_Device) - <i>All Architectures</i> \n | |||
* Many devices do not require the use of the Remote Wakeup features of USB, used to wake up the USB host when suspended. On these devices, | |||
* the code required to manage device Remote Wakeup can be disabled by defining this token and passing it to the library via the -D switch. | |||
* | |||
* - <b>NO_DEVICE_SELF_POWER</b> - (\ref Group_Device) - <i>All Architectures</i> \n | |||
* USB devices may be bus powered, self powered, or a combination of both. When a device can be both bus powered and self powered, the host may | |||
* query the device to determine the current power source, via \ref USB_Device_CurrentlySelfPowered. For solely bus powered devices, this global | |||
* and the code required to manage it may be disabled by passing this token to the library via the -D switch. | |||
* | |||
* | |||
* \section Sec_SummaryUSBHostTokens USB Host Mode Driver Related Tokens | |||
* | |||
* This section describes compile tokens which affect USB driver stack of the LUFA library when used in Host mode. | |||
* | |||
* - <b>HOST_STATE_AS_GPIOR</b> - (\ref Group_Host) - <i>AVR8 Only</i> \n | |||
* One of the most frequently used global variables in the stack is the USB_HostState global, which indicates the current state of | |||
* the Host State Machine. To reduce the amount of code and time required to access and modify this global in an application, this token | |||
* may be defined to a value between 0 and 2 to fix the state variable into one of the three general purpose IO registers inside the AVR | |||
* reserved for application use. When defined, the corresponding GPIOR register should not be used within the user application except | |||
* implicitly via the library APIs. | |||
* | |||
* - <b>USB_HOST_TIMEOUT_MS</b>=<i>x</i> - (\ref Group_Host) - <i>All Architectures</i> \n | |||
* When a control transfer is initiated in host mode to an attached device, a timeout is used to abort the transfer if the attached | |||
* device fails to respond within the timeout period. This token may be defined to a non-zero 16-bit value to set the timeout period for | |||
* control transfers, specified in milliseconds. If not defined, the default value specified in Host.h is used instead. | |||
* | |||
* - <b>HOST_DEVICE_SETTLE_DELAY_MS</b>=<i>x</i> - (\ref Group_Host) - <i>All Architectures</i> \n | |||
* Some devices require a delay of up to 5 seconds after they are connected to VBUS before the enumeration process can be started, or | |||
* they will fail to enumerate correctly. By placing a delay before the enumeration process, it can be ensured that the bus has settled | |||
* back to a known idle state before communications occur with the device. This token may be defined to a 16-bit value to set the device | |||
* settle period, specified in milliseconds. If not defined, the default value specified in Host.h is used instead. | |||
* | |||
* - <b>INVERTED_VBUS_ENABLE_LINE</b> - (\ref Group_Host) - <i>All Architectures</i> \n | |||
* If enabled, this will indicate that the USB target VBUS line polarity is inverted; i.e. it should be pulled low to enable VBUS to the | |||
* target, and pulled high to stop the target VBUS generation. | |||
* | |||
* \attention On AVR8 architecture devices, this compile time option requires \c NO_AUTO_VBUS_MANAGEMENT to be set. | |||
* | |||
* - <b>NO_AUTO_VBUS_MANAGEMENT</b> - (\ref Group_Host) - <i>All Architectures</i> \n | |||
* Disables the automatic management of VBUS to the target, i.e. automatic shut down in the even of an overcurrent situation. When enabled, VBUS | |||
* is enabled while the USB controller is initialized in USB Host mode. | |||
*/ | |||
@@ -1,44 +0,0 @@ | |||
/** \file | |||
* | |||
* This file contains special DoxyGen information for the generation of the main page and other special | |||
* documentation pages. It is not a project source file. | |||
*/ | |||
/** \page Page_KnownIssues Known Issues | |||
* The following are known issues present in each official LUFA release. This list should contain all known | |||
* issues in the library. Most of these issues should be corrected in the future release - see | |||
* \ref Page_FutureChanges for a list of planned changes in future releases. | |||
* | |||
* \section Sec_KnownIssues120730 Version 120730 | |||
* - AVR8 Architecture | |||
* - No known issues. | |||
* - UC3 Architecture | |||
* \warning The UC3 device support is currently <b>experimental</b> (incomplete and/or non-functional), and is included for preview purposes only. \n | |||
* | |||
* - No demos, bootloaders or projects have been ported for the UC3 devices in the current release, | |||
* although the architecture is supported in the LUFA core library. | |||
* - DMA transfers to and from the USB controller are not yet implemented for this release. | |||
* - The UC3C, UC3D and UC3L sub-families of UC3 are not currently supported by the library due to their | |||
* altered USB controller design. | |||
* - The various \c CreateStream() functions for creating standard \c <stdio.h> compatible virtual file | |||
* streams are not available on the UC3 architecture, due to a lack of suitable library support. | |||
* - XMEGA Architecture | |||
* \warning The XMEGA device support is currently <b>experimental</b> (incomplete and/or non-functional), and is included for preview purposes only. | |||
* | |||
* - No demos, bootloaders or projects have been ported for the XMEGA devices in the current release, | |||
* although the architecture is supported in the LUFA core library. | |||
* - Endpoints of more than 64 bytes are not currently supported in this release. | |||
* - Isochronous endpoints are not currently supported in this release. As a result, the audio class | |||
* cannot be used on XMEGA devices. | |||
* - Multiple-bank endpoints are not currently supported in this release. | |||
* - Early revisions of the ATXMEGA128A1U are incompatible with LUFA, due to their various errata | |||
* relating to the USB controller. | |||
* - Architecture Independent | |||
* - The HID parser fails for array type elements that have a MIN and MAX usage applied; each element | |||
* in the array will receive a unique incrementing usage from the MIN value, up to MAX. | |||
* - The LUFA library is not watchdog aware, and thus timeouts are possible if short periods are used | |||
* and a lengthy USB operation is initiated. | |||
* - Build System | |||
* - No known issues. | |||
*/ | |||
@@ -1,22 +0,0 @@ | |||
/** \file | |||
* | |||
* This file contains special DoxyGen information for the generation of the main page and other special | |||
* documentation pages. It is not a project source file. | |||
*/ | |||
/** | |||
* \page Page_LicenseInfo Source Code License | |||
* | |||
* The LUFA library is currently released under the MIT license, included below. | |||
* | |||
* Commercial entities can opt out of the public disclosure clause in this license | |||
* for a one-time US$1500 payment. This provides a non-exclusive modified MIT licensed which | |||
* allows for the free use of the LUFA library, bootloaders and (where the sole copyright | |||
* is attributed to Dean Camera) demos without public disclosure within an organization, in | |||
* addition to three free hours of consultation with the library author, and priority support. | |||
* Please visit the Commercial License link on \ref Page_Resources for more information on | |||
* ordering a commercial license for your company. | |||
* | |||
* \verbinclude License.txt | |||
*/ | |||
@@ -1,424 +0,0 @@ | |||
/** \file | |||
* | |||
* This file contains special DoxyGen information for the generation of the main page and other special | |||
* documentation pages. It is not a project source file. | |||
*/ | |||
/** \page Page_VIDPID VID and PID values | |||
* | |||
* \section Sec_VIDPID_Allocations VID and PID Allocations | |||
* The LUFA library uses VID/PID combinations generously donated by Atmel. The following VID/PID combinations | |||
* are used within the LUFA demos, and thus may be re-used by derivations of each demo. Free PID values may be | |||
* used by future LUFA demo projects. | |||
* | |||
* <b>These VID/PID values should not be used in commercial designs under any circumstances.</b> Private projects | |||
* may use the following values freely, but must accept any collisions due to other LUFA derived private projects | |||
* sharing identical values. It is suggested that private projects using interfaces compatible with existing | |||
* demos share the same VID/PID value. | |||
* | |||
* <table> | |||
* | |||
* <tr> | |||
* <td> | |||
* <b>VID</b> | |||
* </td> | |||
* <td> | |||
* <b>PID</b> | |||
* </td> | |||
* <td> | |||
* <b>Usage</b> | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x2040 | |||
* </td> | |||
* <td> | |||
* Test VID/PID (See below) | |||
* </td> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x2041 | |||
* </td> | |||
* <td> | |||
* Mouse Demo Application | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x2042 | |||
* </td> | |||
* <td> | |||
* Keyboard Demo Application | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x2043 | |||
* </td> | |||
* <td> | |||
* Joystick Demo Application | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x2044 | |||
* </td> | |||
* <td> | |||
* CDC Demo Application | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x2045 | |||
* </td> | |||
* <td> | |||
* Mass Storage Demo Application | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x2046 | |||
* </td> | |||
* <td> | |||
* Audio Output Demo Application | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x2047 | |||
* </td> | |||
* <td> | |||
* Audio Input Demo Application | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x2048 | |||
* </td> | |||
* <td> | |||
* MIDI Demo Application | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x2049 | |||
* </td> | |||
* <td> | |||
* MagStripe Project | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x204A | |||
* </td> | |||
* <td> | |||
* CDC Bootloader | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x204B | |||
* </td> | |||
* <td> | |||
* USB to Serial Demo Application | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x204C | |||
* </td> | |||
* <td> | |||
* RNDIS Demo Application | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x204D | |||
* </td> | |||
* <td> | |||
* Combined Keyboard and Mouse Demo Application | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x204E | |||
* </td> | |||
* <td> | |||
* Dual CDC Demo Application | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x204F | |||
* </td> | |||
* <td> | |||
* Generic HID Demo Application | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x2060 | |||
* </td> | |||
* <td> | |||
* Benito Programmer Project | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x2061 | |||
* </td> | |||
* <td> | |||
* Combined Mass Storage and Keyboard Demo | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x2062 | |||
* </td> | |||
* <td> | |||
* Combined CDC and Mouse Demo | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x2063 | |||
* </td> | |||
* <td> | |||
* Mass Storage/HID Interface Datalogger Project | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x2064 | |||
* </td> | |||
* <td> | |||
* Interfaceless Control-Only LUFA Devices | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x2065 | |||
* </td> | |||
* <td> | |||
* Test and Measurement Demo | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x2066 | |||
* </td> | |||
* <td> | |||
* Multiple Report Keyboard/Mouse HID Demo | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x2067 | |||
* </td> | |||
* <td> | |||
* HID Class Bootloader | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x2068 | |||
* </td> | |||
* <td> | |||
* Virtual Serial/Mass Storage Demo | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x2069 | |||
* </td> | |||
* <td> | |||
* Webserver Project | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x206A | |||
* </td> | |||
* <td> | |||
* Media Control Project | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x206B | |||
* </td> | |||
* <td> | |||
* <i>Currently Unallocated</i> | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x206C | |||
* </td> | |||
* <td> | |||
* <i>Currently Unallocated</i> | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x206D | |||
* </td> | |||
* <td> | |||
* <i>Currently Unallocated</i> | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x206E | |||
* </td> | |||
* <td> | |||
* <i>Currently Unallocated</i> | |||
* </td> | |||
* </tr> | |||
* | |||
* <tr> | |||
* <td> | |||
* 0x03EB | |||
* </td> | |||
* <td> | |||
* 0x206F | |||
* </td> | |||
* <td> | |||
* <i>Currently Unallocated</i> | |||
* </td> | |||
* </tr> | |||
* | |||
* </table> | |||
* | |||
* \section Sec_Test_VIDPID The Test VID/PID Combination | |||
* For use in testing of LUFA powered devices during development only, by non-commercial entities. | |||
* All devices must accept collisions on this VID/PID range (from other in-development LUFA devices) | |||
* to be resolved by using a unique release number in the Device Descriptor. No devices using this | |||
* VID/PID combination may be released to the general public. | |||
*/ | |||
@@ -1,27 +0,0 @@ | |||
/** \file | |||
* | |||
* This file contains special DoxyGen information for the generation of the main page and other special | |||
* documentation pages. It is not a project source file. | |||
*/ | |||
/** \page Page_WritingBoardDrivers Writing LUFA Board Drivers | |||
* | |||
* LUFA ships with several basic pre-made board drivers, to control hardware present on the supported board | |||
* hardware - such as Dataflash ICs, LEDs, Joysticks, or other hardware peripherals. When compiling an application | |||
* which makes use of one or more board drivers located in LUFA/Drivers/Board, you must also indicate what board | |||
* hardware you are using in your project makefile. This is done by defining the BOARD macro using the -D switch | |||
* passed to the compiler, with a constant of BOARD_{Name}. For example <b>-DBOARD=BOARD_USBKEY</b> instructs the | |||
* compiler to use the USBKEY board hardware drivers. | |||
* | |||
* If your application does not use *any* board level drivers, you can omit the definition of the BOARD macro. | |||
* However, some users may wish to write their own custom board hardware drivers which are to remain compatible | |||
* with the LUFA hardware API. To do this, the BOARD macro should be defined to the value BOARD_USER. This indicates | |||
* that the board level drivers should be located in a folder named "Board" located inside the application's folder. | |||
* | |||
* When used, the driver stub files located in the LUFA/CodeTemplates/DriverStubs folder should be copied to the user | |||
* Board/ directory, and fleshed out to include the values and code needed to control the custom board hardware. Once | |||
* done, the existing LUFA board level APIs (accessed in the regular LUFA/Drivers/Board/ folder) will redirect to the | |||
* user board drivers, maintaining code compatibility and allowing for a different board to be selected through the | |||
* project makefile with no code changes. | |||
*/ | |||
@@ -1 +0,0 @@ | |||
Subproject commit b6c18b2a7c544653efbe12a1d4e8ba65e7d83c35 |
@@ -0,0 +1,14 @@ | |||
*.o | |||
*.d | |||
*.elf | |||
*.hex | |||
*.eep | |||
*.sym | |||
*.bin | |||
*.lss | |||
*.map | |||
*.bak | |||
*.class | |||
Documentation/ | |||
LUFA/StudioIntegration/ProjectGenerator/* | |||
LUFA/StudioIntegration/DocBook/* |
@@ -0,0 +1,75 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Bootloader user application API functions. | |||
*/ | |||
#include "BootloaderAPI.h" | |||
void BootloaderAPI_ErasePage(const uint32_t Address) | |||
{ | |||
boot_page_erase_safe(Address); | |||
boot_spm_busy_wait(); | |||
boot_rww_enable(); | |||
} | |||
void BootloaderAPI_WritePage(const uint32_t Address) | |||
{ | |||
boot_page_write_safe(Address); | |||
boot_spm_busy_wait(); | |||
boot_rww_enable(); | |||
} | |||
void BootloaderAPI_FillWord(const uint32_t Address, const uint16_t Word) | |||
{ | |||
boot_page_fill_safe(Address, Word); | |||
} | |||
uint8_t BootloaderAPI_ReadSignature(const uint16_t Address) | |||
{ | |||
return boot_signature_byte_get(Address); | |||
} | |||
uint8_t BootloaderAPI_ReadFuse(const uint16_t Address) | |||
{ | |||
return boot_lock_fuse_bits_get(Address); | |||
} | |||
uint8_t BootloaderAPI_ReadLock(void) | |||
{ | |||
return boot_lock_fuse_bits_get(GET_LOCK_BITS); | |||
} | |||
void BootloaderAPI_WriteLock(const uint8_t LockBits) | |||
{ | |||
boot_lock_bits_set_safe(LockBits); | |||
} |
@@ -0,0 +1,58 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Header file for BootloaderAPI.c. | |||
*/ | |||
#ifndef _BOOTLOADER_API_H_ | |||
#define _BOOTLOADER_API_H_ | |||
/* Includes: */ | |||
#include <avr/io.h> | |||
#include <avr/boot.h> | |||
#include <stdbool.h> | |||
#include <LUFA/Common/Common.h> | |||
#include "Config/AppConfig.h" | |||
/* Function Prototypes: */ | |||
void BootloaderAPI_ErasePage(const uint32_t Address); | |||
void BootloaderAPI_WritePage(const uint32_t Address); | |||
void BootloaderAPI_FillWord(const uint32_t Address, const uint16_t Word); | |||
uint8_t BootloaderAPI_ReadSignature(const uint16_t Address); | |||
uint8_t BootloaderAPI_ReadFuse(const uint16_t Address); | |||
uint8_t BootloaderAPI_ReadLock(void); | |||
void BootloaderAPI_WriteLock(const uint8_t LockBits); | |||
#endif | |||
@@ -0,0 +1,91 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
; Trampolines to actual API implementations if the target address is outside the | |||
; range of a rjmp instruction (can happen with large bootloader sections) | |||
.section .apitable_trampolines, "ax" | |||
.global BootloaderAPI_Trampolines | |||
BootloaderAPI_Trampolines: | |||
BootloaderAPI_ErasePage_Trampoline: | |||
jmp BootloaderAPI_ErasePage | |||
BootloaderAPI_WritePage_Trampoline: | |||
jmp BootloaderAPI_WritePage | |||
BootloaderAPI_FillWord_Trampoline: | |||
jmp BootloaderAPI_FillWord | |||
BootloaderAPI_ReadSignature_Trampoline: | |||
jmp BootloaderAPI_ReadSignature | |||
BootloaderAPI_ReadFuse_Trampoline: | |||
jmp BootloaderAPI_ReadFuse | |||
BootloaderAPI_ReadLock_Trampoline: | |||
jmp BootloaderAPI_ReadLock | |||
BootloaderAPI_WriteLock_Trampoline: | |||
jmp BootloaderAPI_WriteLock | |||
BootloaderAPI_UNUSED1: | |||
ret | |||
BootloaderAPI_UNUSED2: | |||
ret | |||
BootloaderAPI_UNUSED3: | |||
ret | |||
BootloaderAPI_UNUSED4: | |||
ret | |||
BootloaderAPI_UNUSED5: | |||
ret | |||
; API function jump table | |||
.section .apitable_jumptable, "ax" | |||
.global BootloaderAPI_JumpTable | |||
BootloaderAPI_JumpTable: | |||
rjmp BootloaderAPI_ErasePage_Trampoline | |||
rjmp BootloaderAPI_WritePage_Trampoline | |||
rjmp BootloaderAPI_FillWord_Trampoline | |||
rjmp BootloaderAPI_ReadSignature_Trampoline | |||
rjmp BootloaderAPI_ReadFuse_Trampoline | |||
rjmp BootloaderAPI_ReadLock_Trampoline | |||
rjmp BootloaderAPI_WriteLock_Trampoline | |||
rjmp BootloaderAPI_UNUSED1 ; UNUSED ENTRY 1 | |||
rjmp BootloaderAPI_UNUSED2 ; UNUSED ENTRY 2 | |||
rjmp BootloaderAPI_UNUSED3 ; UNUSED ENTRY 3 | |||
rjmp BootloaderAPI_UNUSED4 ; UNUSED ENTRY 4 | |||
rjmp BootloaderAPI_UNUSED5 ; UNUSED ENTRY 5 | |||
; Bootloader table signatures and information | |||
.section .apitable_signatures, "ax" | |||
.global BootloaderAPI_Signatures | |||
BootloaderAPI_Signatures: | |||
.long BOOT_START_ADDR ; Start address of the bootloader | |||
.word 0xDF00 ; Signature for the CDC class bootloader | |||
.word 0xDCFB ; Signature for a LUFA class bootloader |
@@ -0,0 +1,641 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Main source file for the CDC class bootloader. This file contains the complete bootloader logic. | |||
*/ | |||
#define INCLUDE_FROM_BOOTLOADERCDC_C | |||
#include "BootloaderCDC.h" | |||
/** Contains the current baud rate and other settings of the first virtual serial port. This must be retained as some | |||
* operating systems will not open the port unless the settings can be set successfully. | |||
*/ | |||
static CDC_LineEncoding_t LineEncoding = { .BaudRateBPS = 0, | |||
.CharFormat = CDC_LINEENCODING_OneStopBit, | |||
.ParityType = CDC_PARITY_None, | |||
.DataBits = 8 }; | |||
/** Current address counter. This stores the current address of the FLASH or EEPROM as set by the host, | |||
* and is used when reading or writing to the AVRs memory (either FLASH or EEPROM depending on the issued | |||
* command.) | |||
*/ | |||
static uint32_t CurrAddress; | |||
/** Flag to indicate if the bootloader should be running, or should exit and allow the application code to run | |||
* via a watchdog reset. When cleared the bootloader will exit, starting the watchdog and entering an infinite | |||
* loop until the AVR restarts and the application runs. | |||
*/ | |||
static bool RunBootloader = true; | |||
/** Magic lock for forced application start. If the HWBE fuse is programmed and BOOTRST is unprogrammed, the bootloader | |||
* will start if the /HWB line of the AVR is held low and the system is reset. However, if the /HWB line is still held | |||
* low when the application attempts to start via a watchdog reset, the bootloader will re-start. If set to the value | |||
* \ref MAGIC_BOOT_KEY the special init function \ref Application_Jump_Check() will force the application to start. | |||
*/ | |||
uint16_t MagicBootKey ATTR_NO_INIT; | |||
/** Special startup routine to check if the bootloader was started via a watchdog reset, and if the magic application | |||
* start key has been loaded into \ref MagicBootKey. If the bootloader started via the watchdog and the key is valid, | |||
* this will force the user application to start via a software jump. | |||
*/ | |||
void Application_Jump_Check(void) | |||
{ | |||
bool JumpToApplication = false; | |||
#if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1)) | |||
/* Disable JTAG debugging */ | |||
JTAG_DISABLE(); | |||
/* Enable pull-up on the JTAG TCK pin so we can use it to select the mode */ | |||
PORTF |= (1 << 4); | |||
Delay_MS(10); | |||
/* If the TCK pin is not jumpered to ground, start the user application instead */ | |||
JumpToApplication |= ((PINF & (1 << 4)) != 0); | |||
/* Re-enable JTAG debugging */ | |||
JTAG_ENABLE(); | |||
#endif | |||
/* If the reset source was the bootloader and the key is correct, clear it and jump to the application */ | |||
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY)) | |||
JumpToApplication |= true; | |||
/* If a request has been made to jump to the user application, honor it */ | |||
if (JumpToApplication) | |||
{ | |||
/* Turn off the watchdog */ | |||
MCUSR &= ~(1<<WDRF); | |||
wdt_disable(); | |||
/* Clear the boot key and jump to the user application */ | |||
MagicBootKey = 0; | |||
// cppcheck-suppress constStatement | |||
((void (*)(void))0x0000)(); | |||
} | |||
} | |||
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously | |||
* runs the bootloader processing routine until instructed to soft-exit, or hard-reset via the watchdog to start | |||
* the loaded application code. | |||
*/ | |||
int main(void) | |||
{ | |||
/* Setup hardware required for the bootloader */ | |||
SetupHardware(); | |||
/* Turn on first LED on the board to indicate that the bootloader has started */ | |||
LEDs_SetAllLEDs(LEDS_LED1); | |||
/* Enable global interrupts so that the USB stack can function */ | |||
GlobalInterruptEnable(); | |||
while (RunBootloader) | |||
{ | |||
CDC_Task(); | |||
USB_USBTask(); | |||
} | |||
/* Disconnect from the host - USB interface will be reset later along with the AVR */ | |||
USB_Detach(); | |||
/* Unlock the forced application start mode of the bootloader if it is restarted */ | |||
MagicBootKey = MAGIC_BOOT_KEY; | |||
/* Enable the watchdog and force a timeout to reset the AVR */ | |||
wdt_enable(WDTO_250MS); | |||
for (;;); | |||
} | |||
/** Configures all hardware required for the bootloader. */ | |||
static void SetupHardware(void) | |||
{ | |||
/* Disable watchdog if enabled by bootloader/fuses */ | |||
MCUSR &= ~(1 << WDRF); | |||
wdt_disable(); | |||
/* Disable clock division */ | |||
clock_prescale_set(clock_div_1); | |||
/* Relocate the interrupt vector table to the bootloader section */ | |||
MCUCR = (1 << IVCE); | |||
MCUCR = (1 << IVSEL); | |||
/* Initialize the USB and other board hardware drivers */ | |||
USB_Init(); | |||
LEDs_Init(); | |||
/* Bootloader active LED toggle timer initialization */ | |||
TIMSK1 = (1 << TOIE1); | |||
TCCR1B = ((1 << CS11) | (1 << CS10)); | |||
} | |||
/** ISR to periodically toggle the LEDs on the board to indicate that the bootloader is active. */ | |||
ISR(TIMER1_OVF_vect, ISR_BLOCK) | |||
{ | |||
LEDs_ToggleLEDs(LEDS_LED1 | LEDS_LED2); | |||
} | |||
/** Event handler for the USB_ConfigurationChanged event. This configures the device's endpoints ready | |||
* to relay data to and from the attached USB host. | |||
*/ | |||
void EVENT_USB_Device_ConfigurationChanged(void) | |||
{ | |||
/* Setup CDC Notification, Rx and Tx Endpoints */ | |||
Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPADDR, EP_TYPE_INTERRUPT, | |||
CDC_NOTIFICATION_EPSIZE, 1); | |||
Endpoint_ConfigureEndpoint(CDC_TX_EPADDR, EP_TYPE_BULK, CDC_TXRX_EPSIZE, 1); | |||
Endpoint_ConfigureEndpoint(CDC_RX_EPADDR, EP_TYPE_BULK, CDC_TXRX_EPSIZE, 1); | |||
} | |||
/** Event handler for the USB_ControlRequest event. This is used to catch and process control requests sent to | |||
* the device from the USB host before passing along unhandled control requests to the library for processing | |||
* internally. | |||
*/ | |||
void EVENT_USB_Device_ControlRequest(void) | |||
{ | |||
/* Ignore any requests that aren't directed to the CDC interface */ | |||
if ((USB_ControlRequest.bmRequestType & (CONTROL_REQTYPE_TYPE | CONTROL_REQTYPE_RECIPIENT)) != | |||
(REQTYPE_CLASS | REQREC_INTERFACE)) | |||
{ | |||
return; | |||
} | |||
/* Activity - toggle indicator LEDs */ | |||
LEDs_ToggleLEDs(LEDS_LED1 | LEDS_LED2); | |||
/* Process CDC specific control requests */ | |||
switch (USB_ControlRequest.bRequest) | |||
{ | |||
case CDC_REQ_GetLineEncoding: | |||
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) | |||
{ | |||
Endpoint_ClearSETUP(); | |||
/* Write the line coding data to the control endpoint */ | |||
Endpoint_Write_Control_Stream_LE(&LineEncoding, sizeof(CDC_LineEncoding_t)); | |||
Endpoint_ClearOUT(); | |||
} | |||
break; | |||
case CDC_REQ_SetLineEncoding: | |||
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) | |||
{ | |||
Endpoint_ClearSETUP(); | |||
/* Read the line coding data in from the host into the global struct */ | |||
Endpoint_Read_Control_Stream_LE(&LineEncoding, sizeof(CDC_LineEncoding_t)); | |||
Endpoint_ClearIN(); | |||
} | |||
break; | |||
case CDC_REQ_SetControlLineState: | |||
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) | |||
{ | |||
Endpoint_ClearSETUP(); | |||
Endpoint_ClearStatusStage(); | |||
} | |||
break; | |||
} | |||
} | |||
#if !defined(NO_BLOCK_SUPPORT) | |||
/** Reads or writes a block of EEPROM or FLASH memory to or from the appropriate CDC data endpoint, depending | |||
* on the AVR109 protocol command issued. | |||
* | |||
* \param[in] Command Single character AVR109 protocol command indicating what memory operation to perform | |||
*/ | |||
static void ReadWriteMemoryBlock(const uint8_t Command) | |||
{ | |||
uint16_t BlockSize; | |||
char MemoryType; | |||
uint8_t HighByte = 0; | |||
uint8_t LowByte = 0; | |||
BlockSize = (FetchNextCommandByte() << 8); | |||
BlockSize |= FetchNextCommandByte(); | |||
MemoryType = FetchNextCommandByte(); | |||
if ((MemoryType != MEMORY_TYPE_FLASH) && (MemoryType != MEMORY_TYPE_EEPROM)) | |||
{ | |||
/* Send error byte back to the host */ | |||
WriteNextResponseByte('?'); | |||
return; | |||
} | |||
/* Check if command is to read a memory block */ | |||
if (Command == AVR109_COMMAND_BlockRead) | |||
{ | |||
/* Re-enable RWW section */ | |||
boot_rww_enable(); | |||
while (BlockSize--) | |||
{ | |||
if (MemoryType == MEMORY_TYPE_FLASH) | |||
{ | |||
/* Read the next FLASH byte from the current FLASH page */ | |||
#if (FLASHEND > 0xFFFF) | |||
WriteNextResponseByte(pgm_read_byte_far(CurrAddress | HighByte)); | |||
#else | |||
WriteNextResponseByte(pgm_read_byte(CurrAddress | HighByte)); | |||
#endif | |||
/* If both bytes in current word have been read, increment the address counter */ | |||
if (HighByte) | |||
CurrAddress += 2; | |||
HighByte = !HighByte; | |||
} | |||
else | |||
{ | |||
/* Read the next EEPROM byte into the endpoint */ | |||
WriteNextResponseByte(eeprom_read_byte((uint8_t*)(intptr_t)(CurrAddress >> 1))); | |||
/* Increment the address counter after use */ | |||
CurrAddress += 2; | |||
} | |||
} | |||
} | |||
else | |||
{ | |||
uint32_t PageStartAddress = CurrAddress; | |||
if (MemoryType == MEMORY_TYPE_FLASH) | |||
{ | |||
boot_page_erase(PageStartAddress); | |||
boot_spm_busy_wait(); | |||
} | |||
while (BlockSize--) | |||
{ | |||
if (MemoryType == MEMORY_TYPE_FLASH) | |||
{ | |||
/* If both bytes in current word have been written, increment the address counter */ | |||
if (HighByte) | |||
{ | |||
/* Write the next FLASH word to the current FLASH page */ | |||
boot_page_fill(CurrAddress, ((FetchNextCommandByte() << 8) | LowByte)); | |||
/* Increment the address counter after use */ | |||
CurrAddress += 2; | |||
} | |||
else | |||
{ | |||
LowByte = FetchNextCommandByte(); | |||
} | |||
HighByte = !HighByte; | |||
} | |||
else | |||
{ | |||
/* Write the next EEPROM byte from the endpoint */ | |||
eeprom_write_byte((uint8_t*)((intptr_t)(CurrAddress >> 1)), FetchNextCommandByte()); | |||
/* Increment the address counter after use */ | |||
CurrAddress += 2; | |||
} | |||
} | |||
/* If in FLASH programming mode, commit the page after writing */ | |||
if (MemoryType == MEMORY_TYPE_FLASH) | |||
{ | |||
/* Commit the flash page to memory */ | |||
boot_page_write(PageStartAddress); | |||
/* Wait until write operation has completed */ | |||
boot_spm_busy_wait(); | |||
} | |||
/* Send response byte back to the host */ | |||
WriteNextResponseByte('\r'); | |||
} | |||
} | |||
#endif | |||
/** Retrieves the next byte from the host in the CDC data OUT endpoint, and clears the endpoint bank if needed | |||
* to allow reception of the next data packet from the host. | |||
* | |||
* \return Next received byte from the host in the CDC data OUT endpoint | |||
*/ | |||
static uint8_t FetchNextCommandByte(void) | |||
{ | |||
/* Select the OUT endpoint so that the next data byte can be read */ | |||
Endpoint_SelectEndpoint(CDC_RX_EPADDR); | |||
/* If OUT endpoint empty, clear it and wait for the next packet from the host */ | |||
while (!(Endpoint_IsReadWriteAllowed())) | |||
{ | |||
Endpoint_ClearOUT(); | |||
while (!(Endpoint_IsOUTReceived())) | |||
{ | |||
if (USB_DeviceState == DEVICE_STATE_Unattached) | |||
return 0; | |||
} | |||
} | |||
/* Fetch the next byte from the OUT endpoint */ | |||
return Endpoint_Read_8(); | |||
} | |||
/** Writes the next response byte to the CDC data IN endpoint, and sends the endpoint back if needed to free up the | |||
* bank when full ready for the next byte in the packet to the host. | |||
* | |||
* \param[in] Response Next response byte to send to the host | |||
*/ | |||
static void WriteNextResponseByte(const uint8_t Response) | |||
{ | |||
/* Select the IN endpoint so that the next data byte can be written */ | |||
Endpoint_SelectEndpoint(CDC_TX_EPADDR); | |||
/* If IN endpoint full, clear it and wait until ready for the next packet to the host */ | |||
if (!(Endpoint_IsReadWriteAllowed())) | |||
{ | |||
Endpoint_ClearIN(); | |||
while (!(Endpoint_IsINReady())) | |||
{ | |||
if (USB_DeviceState == DEVICE_STATE_Unattached) | |||
return; | |||
} | |||
} | |||
/* Write the next byte to the IN endpoint */ | |||
Endpoint_Write_8(Response); | |||
} | |||
/** Task to read in AVR109 commands from the CDC data OUT endpoint, process them, perform the required actions | |||
* and send the appropriate response back to the host. | |||
*/ | |||
static void CDC_Task(void) | |||
{ | |||
/* Select the OUT endpoint */ | |||
Endpoint_SelectEndpoint(CDC_RX_EPADDR); | |||
/* Check if endpoint has a command in it sent from the host */ | |||
if (!(Endpoint_IsOUTReceived())) | |||
return; | |||
/* Read in the bootloader command (first byte sent from host) */ | |||
uint8_t Command = FetchNextCommandByte(); | |||
if (Command == AVR109_COMMAND_ExitBootloader) | |||
{ | |||
RunBootloader = false; | |||
/* Send confirmation byte back to the host */ | |||
WriteNextResponseByte('\r'); | |||
} | |||
else if ((Command == AVR109_COMMAND_SetLED) || (Command == AVR109_COMMAND_ClearLED) || | |||
(Command == AVR109_COMMAND_SelectDeviceType)) | |||
{ | |||
FetchNextCommandByte(); | |||
/* Send confirmation byte back to the host */ | |||
WriteNextResponseByte('\r'); | |||
} | |||
else if ((Command == AVR109_COMMAND_EnterProgrammingMode) || (Command == AVR109_COMMAND_LeaveProgrammingMode)) | |||
{ | |||
/* Send confirmation byte back to the host */ | |||
WriteNextResponseByte('\r'); | |||
} | |||
else if (Command == AVR109_COMMAND_ReadPartCode) | |||
{ | |||
/* Return ATMEGA128 part code - this is only to allow AVRProg to use the bootloader */ | |||
WriteNextResponseByte(0x44); | |||
WriteNextResponseByte(0x00); | |||
} | |||
else if (Command == AVR109_COMMAND_ReadAutoAddressIncrement) | |||
{ | |||
/* Indicate auto-address increment is supported */ | |||
WriteNextResponseByte('Y'); | |||
} | |||
else if (Command == AVR109_COMMAND_SetCurrentAddress) | |||
{ | |||
/* Set the current address to that given by the host (translate 16-bit word address to byte address) */ | |||
CurrAddress = (FetchNextCommandByte() << 9); | |||
CurrAddress |= (FetchNextCommandByte() << 1); | |||
/* Send confirmation byte back to the host */ | |||
WriteNextResponseByte('\r'); | |||
} | |||
else if (Command == AVR109_COMMAND_ReadBootloaderInterface) | |||
{ | |||
/* Indicate serial programmer back to the host */ | |||
WriteNextResponseByte('S'); | |||
} | |||
else if (Command == AVR109_COMMAND_ReadBootloaderIdentifier) | |||
{ | |||
/* Write the 7-byte software identifier to the endpoint */ | |||
for (uint8_t CurrByte = 0; CurrByte < 7; CurrByte++) | |||
WriteNextResponseByte(SOFTWARE_IDENTIFIER[CurrByte]); | |||
} | |||
else if (Command == AVR109_COMMAND_ReadBootloaderSWVersion) | |||
{ | |||
WriteNextResponseByte('0' + BOOTLOADER_VERSION_MAJOR); | |||
WriteNextResponseByte('0' + BOOTLOADER_VERSION_MINOR); | |||
} | |||
else if (Command == AVR109_COMMAND_ReadSignature) | |||
{ | |||
WriteNextResponseByte(AVR_SIGNATURE_3); | |||
WriteNextResponseByte(AVR_SIGNATURE_2); | |||
WriteNextResponseByte(AVR_SIGNATURE_1); | |||
} | |||
else if (Command == AVR109_COMMAND_EraseFLASH) | |||
{ | |||
/* Clear the application section of flash */ | |||
for (uint32_t CurrFlashAddress = 0; CurrFlashAddress < (uint32_t)BOOT_START_ADDR; CurrFlashAddress += SPM_PAGESIZE) | |||
{ | |||
boot_page_erase(CurrFlashAddress); | |||
boot_spm_busy_wait(); | |||
boot_page_write(CurrFlashAddress); | |||
boot_spm_busy_wait(); | |||
} | |||
/* Send confirmation byte back to the host */ | |||
WriteNextResponseByte('\r'); | |||
} | |||
#if !defined(NO_LOCK_BYTE_WRITE_SUPPORT) | |||
else if (Command == AVR109_COMMAND_WriteLockbits) | |||
{ | |||
/* Set the lock bits to those given by the host */ | |||
boot_lock_bits_set(FetchNextCommandByte()); | |||
/* Send confirmation byte back to the host */ | |||
WriteNextResponseByte('\r'); | |||
} | |||
#endif | |||
else if (Command == AVR109_COMMAND_ReadLockbits) | |||
{ | |||
WriteNextResponseByte(boot_lock_fuse_bits_get(GET_LOCK_BITS)); | |||
} | |||
else if (Command == AVR109_COMMAND_ReadLowFuses) | |||
{ | |||
WriteNextResponseByte(boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS)); | |||
} | |||
else if (Command == AVR109_COMMAND_ReadHighFuses) | |||
{ | |||
WriteNextResponseByte(boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS)); | |||
} | |||
else if (Command == AVR109_COMMAND_ReadExtendedFuses) | |||
{ | |||
WriteNextResponseByte(boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS)); | |||
} | |||
#if !defined(NO_BLOCK_SUPPORT) | |||
else if (Command == AVR109_COMMAND_GetBlockWriteSupport) | |||
{ | |||
WriteNextResponseByte('Y'); | |||
/* Send block size to the host */ | |||
WriteNextResponseByte(SPM_PAGESIZE >> 8); | |||
WriteNextResponseByte(SPM_PAGESIZE & 0xFF); | |||
} | |||
else if ((Command == AVR109_COMMAND_BlockWrite) || (Command == AVR109_COMMAND_BlockRead)) | |||
{ | |||
/* Delegate the block write/read to a separate function for clarity */ | |||
ReadWriteMemoryBlock(Command); | |||
} | |||
#endif | |||
#if !defined(NO_FLASH_BYTE_SUPPORT) | |||
else if (Command == AVR109_COMMAND_FillFlashPageWordHigh) | |||
{ | |||
/* Write the high byte to the current flash page */ | |||
boot_page_fill(CurrAddress, FetchNextCommandByte()); | |||
/* Send confirmation byte back to the host */ | |||
WriteNextResponseByte('\r'); | |||
} | |||
else if (Command == AVR109_COMMAND_FillFlashPageWordLow) | |||
{ | |||
/* Write the low byte to the current flash page */ | |||
boot_page_fill(CurrAddress | 0x01, FetchNextCommandByte()); | |||
/* Increment the address */ | |||
CurrAddress += 2; | |||
/* Send confirmation byte back to the host */ | |||
WriteNextResponseByte('\r'); | |||
} | |||
else if (Command == AVR109_COMMAND_WriteFlashPage) | |||
{ | |||
/* Commit the flash page to memory */ | |||
boot_page_write(CurrAddress); | |||
/* Wait until write operation has completed */ | |||
boot_spm_busy_wait(); | |||
/* Send confirmation byte back to the host */ | |||
WriteNextResponseByte('\r'); | |||
} | |||
else if (Command == AVR109_COMMAND_ReadFLASHWord) | |||
{ | |||
#if (FLASHEND > 0xFFFF) | |||
uint16_t ProgramWord = pgm_read_word_far(CurrAddress); | |||
#else | |||
uint16_t ProgramWord = pgm_read_word(CurrAddress); | |||
#endif | |||
WriteNextResponseByte(ProgramWord >> 8); | |||
WriteNextResponseByte(ProgramWord & 0xFF); | |||
} | |||
#endif | |||
#if !defined(NO_EEPROM_BYTE_SUPPORT) | |||
else if (Command == AVR109_COMMAND_WriteEEPROM) | |||
{ | |||
/* Read the byte from the endpoint and write it to the EEPROM */ | |||
eeprom_write_byte((uint8_t*)((intptr_t)(CurrAddress >> 1)), FetchNextCommandByte()); | |||
/* Increment the address after use */ | |||
CurrAddress += 2; | |||
/* Send confirmation byte back to the host */ | |||
WriteNextResponseByte('\r'); | |||
} | |||
else if (Command == AVR109_COMMAND_ReadEEPROM) | |||
{ | |||
/* Read the EEPROM byte and write it to the endpoint */ | |||
WriteNextResponseByte(eeprom_read_byte((uint8_t*)((intptr_t)(CurrAddress >> 1)))); | |||
/* Increment the address after use */ | |||
CurrAddress += 2; | |||
} | |||
#endif | |||
else if (Command != AVR109_COMMAND_Sync) | |||
{ | |||
/* Unknown (non-sync) command, return fail code */ | |||
WriteNextResponseByte('?'); | |||
} | |||
/* Select the IN endpoint */ | |||
Endpoint_SelectEndpoint(CDC_TX_EPADDR); | |||
/* Remember if the endpoint is completely full before clearing it */ | |||
bool IsEndpointFull = !(Endpoint_IsReadWriteAllowed()); | |||
/* Send the endpoint data to the host */ | |||
Endpoint_ClearIN(); | |||
/* If a full endpoint's worth of data was sent, we need to send an empty packet afterwards to signal end of transfer */ | |||
if (IsEndpointFull) | |||
{ | |||
while (!(Endpoint_IsINReady())) | |||
{ | |||
if (USB_DeviceState == DEVICE_STATE_Unattached) | |||
return; | |||
} | |||
Endpoint_ClearIN(); | |||
} | |||
/* Wait until the data has been sent to the host */ | |||
while (!(Endpoint_IsINReady())) | |||
{ | |||
if (USB_DeviceState == DEVICE_STATE_Unattached) | |||
return; | |||
} | |||
/* Select the OUT endpoint */ | |||
Endpoint_SelectEndpoint(CDC_RX_EPADDR); | |||
/* Acknowledge the command from the host */ | |||
Endpoint_ClearOUT(); | |||
} | |||
@@ -0,0 +1,144 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Header file for BootloaderCDC.c. | |||
*/ | |||
#ifndef _CDC_H_ | |||
#define _CDC_H_ | |||
/* Includes: */ | |||
#include <avr/io.h> | |||
#include <avr/wdt.h> | |||
#include <avr/boot.h> | |||
#include <avr/eeprom.h> | |||
#include <avr/power.h> | |||
#include <avr/interrupt.h> | |||
#include <stdbool.h> | |||
#include "Descriptors.h" | |||
#include "BootloaderAPI.h" | |||
#include "Config/AppConfig.h" | |||
#include <LUFA/Drivers/USB/USB.h> | |||
#include <LUFA/Drivers/Board/LEDs.h> | |||
#include <LUFA/Platform/Platform.h> | |||
/* Preprocessor Checks: */ | |||
#if !defined(__OPTIMIZE_SIZE__) | |||
#error This bootloader requires that it be optimized for size, not speed, to fit into the target device. Change optimization settings and try again. | |||
#endif | |||
/* Macros: */ | |||
/** Version major of the CDC bootloader. */ | |||
#define BOOTLOADER_VERSION_MAJOR 0x01 | |||
/** Version minor of the CDC bootloader. */ | |||
#define BOOTLOADER_VERSION_MINOR 0x00 | |||
/** Hardware version major of the CDC bootloader. */ | |||
#define BOOTLOADER_HWVERSION_MAJOR 0x01 | |||
/** Hardware version minor of the CDC bootloader. */ | |||
#define BOOTLOADER_HWVERSION_MINOR 0x00 | |||
/** Eight character bootloader firmware identifier reported to the host when requested. */ | |||
#define SOFTWARE_IDENTIFIER "LUFACDC" | |||
/** Magic bootloader key to unlock forced application start mode. */ | |||
#define MAGIC_BOOT_KEY 0xDC42 | |||
/* Enums: */ | |||
/** Possible memory types that can be addressed via the bootloader. */ | |||
enum AVR109_Memories | |||
{ | |||
MEMORY_TYPE_FLASH = 'F', | |||
MEMORY_TYPE_EEPROM = 'E', | |||
}; | |||
/** Possible commands that can be issued to the bootloader. */ | |||
enum AVR109_Commands | |||
{ | |||
AVR109_COMMAND_Sync = 27, | |||
AVR109_COMMAND_ReadEEPROM = 'd', | |||
AVR109_COMMAND_WriteEEPROM = 'D', | |||
AVR109_COMMAND_ReadFLASHWord = 'R', | |||
AVR109_COMMAND_WriteFlashPage = 'm', | |||
AVR109_COMMAND_FillFlashPageWordLow = 'c', | |||
AVR109_COMMAND_FillFlashPageWordHigh = 'C', | |||
AVR109_COMMAND_GetBlockWriteSupport = 'b', | |||
AVR109_COMMAND_BlockWrite = 'B', | |||
AVR109_COMMAND_BlockRead = 'g', | |||
AVR109_COMMAND_ReadExtendedFuses = 'Q', | |||
AVR109_COMMAND_ReadHighFuses = 'N', | |||
AVR109_COMMAND_ReadLowFuses = 'F', | |||
AVR109_COMMAND_ReadLockbits = 'r', | |||
AVR109_COMMAND_WriteLockbits = 'l', | |||
AVR109_COMMAND_EraseFLASH = 'e', | |||
AVR109_COMMAND_ReadSignature = 's', | |||
AVR109_COMMAND_ReadBootloaderSWVersion = 'V', | |||
AVR109_COMMAND_ReadBootloaderHWVersion = 'v', | |||
AVR109_COMMAND_ReadBootloaderIdentifier = 'S', | |||
AVR109_COMMAND_ReadBootloaderInterface = 'p', | |||
AVR109_COMMAND_SetCurrentAddress = 'A', | |||
AVR109_COMMAND_ReadAutoAddressIncrement = 'a', | |||
AVR109_COMMAND_ReadPartCode = 't', | |||
AVR109_COMMAND_EnterProgrammingMode = 'P', | |||
AVR109_COMMAND_LeaveProgrammingMode = 'L', | |||
AVR109_COMMAND_SelectDeviceType = 'T', | |||
AVR109_COMMAND_SetLED = 'x', | |||
AVR109_COMMAND_ClearLED = 'y', | |||
AVR109_COMMAND_ExitBootloader = 'E', | |||
}; | |||
/* Type Defines: */ | |||
/** Type define for a non-returning pointer to the start of the loaded application in flash memory. */ | |||
typedef void (*AppPtr_t)(void) ATTR_NO_RETURN; | |||
/* Function Prototypes: */ | |||
static void CDC_Task(void); | |||
static void SetupHardware(void); | |||
void Application_Jump_Check(void) ATTR_INIT_SECTION(3); | |||
void EVENT_USB_Device_ConfigurationChanged(void); | |||
#if defined(INCLUDE_FROM_BOOTLOADERCDC_C) || defined(__DOXYGEN__) | |||
#if !defined(NO_BLOCK_SUPPORT) | |||
static void ReadWriteMemoryBlock(const uint8_t Command); | |||
#endif | |||
static uint8_t FetchNextCommandByte(void); | |||
static void WriteNextResponseByte(const uint8_t Response); | |||
#endif | |||
#endif | |||
@@ -0,0 +1,240 @@ | |||
/** \file | |||
* | |||
* This file contains special DoxyGen information for the generation of the main page and other special | |||
* documentation pages. It is not a project source file. | |||
*/ | |||
/** \mainpage CDC Class USB AVR Bootloader | |||
* | |||
* \section Sec_Compat Demo Compatibility: | |||
* | |||
* The following list indicates what microcontrollers are compatible with this demo. | |||
* | |||
* \li Series 7 USB AVRs (AT90USBxxx7) | |||
* \li Series 6 USB AVRs (AT90USBxxx6) | |||
* \li Series 4 USB AVRs (ATMEGAxxU4) | |||
* \li Series 2 USB AVRs (AT90USBxx2, ATMEGAxxU2) | |||
* | |||
* \section Sec_Info USB Information: | |||
* | |||
* The following table gives a rundown of the USB utilization of this demo. | |||
* | |||
* <table> | |||
* <tr> | |||
* <td><b>USB Mode:</b></td> | |||
* <td>Device</td> | |||
* </tr> | |||
* <tr> | |||
* <td><b>USB Class:</b></td> | |||
* <td>Communications Device Class (CDC)</td> | |||
* </tr> | |||
* <tr> | |||
* <td><b>USB Subclass:</b></td> | |||
* <td>Abstract Control Model (ACM)</td> | |||
* </tr> | |||
* <tr> | |||
* <td><b>Relevant Standards:</b></td> | |||
* <td>USBIF CDC Class Standard</td> | |||
* </tr> | |||
* <tr> | |||
* <td><b>Supported USB Speeds:</b></td> | |||
* <td>Full Speed Mode</td> | |||
* </tr> | |||
* </table> | |||
* | |||
* \section Sec_Description Project Description: | |||
* | |||
* This bootloader enumerates to the host as a CDC Class device (virtual serial port), allowing for AVR109 | |||
* protocol compatible programming software to load firmware onto the AVR. | |||
* | |||
* Out of the box this bootloader builds for the AT90USB1287 with an 8KB bootloader section size, and will fit | |||
* into 4KB of bootloader space. If you wish to alter this size and/or change the AVR model, you will need to | |||
* edit the MCU, FLASH_SIZE_KB and BOOT_SECTION_SIZE_KB values in the accompanying makefile. | |||
* | |||
* When the bootloader is running, the board's LED(s) will flash at regular intervals to distinguish the | |||
* bootloader from the normal user application. | |||
* | |||
* \warning <b>THIS BOOTLOADER IS NOT SECURE.</b> Malicious entities can recover written data, even if the device | |||
* lockbits are set. | |||
* | |||
* \section Sec_Running Running the Bootloader | |||
* | |||
* This bootloader is designed to be started via the HWB mechanism of the USB AVRs; ground the HWB pin (see device | |||
* datasheet) then momentarily ground /RESET to start the bootloader. This assumes the HWBE fuse is set and the BOOTRST | |||
* fuse is cleared. | |||
* | |||
* For board specific exceptions to the above, see below. | |||
* | |||
* \subsection SSec_XPLAIN Atmel Xplain Board | |||
* Ground the USB AVR JTAG's \c TCK pin to ground when powering on the board to start the bootloader. This assumes the | |||
* \c HWBE fuse is cleared and the \c BOOTRST fuse is set as the HWBE pin is not user accessible on this board. | |||
* | |||
* \subsection SSec_Leonardo Arduino Leonardo Board | |||
* Ground \c IO13 when powering the board to start the bootloader. This assumes the \c HWBE fuse is cleared and the | |||
* \c BOOTRST fuse is set as the HWBE pin is not user accessible on this board. | |||
* | |||
* \section Sec_Installation Driver Installation | |||
* | |||
* After running this bootloader for the first time on a new computer, you will need to supply the .INF | |||
* file located in this bootloader project's directory as the device's driver when running under Windows. | |||
* This will enable Windows to use its inbuilt CDC drivers, negating the need for custom drivers for the | |||
* device. Other Operating Systems should automatically use their own inbuilt CDC-ACM drivers. | |||
* | |||
* \section Sec_HostApp Host Controller Application | |||
* | |||
* This bootloader is compatible with the open source application AVRDUDE, Atmel's AVRPROG, or other | |||
* applications implementing the AVR109 protocol, which is documented on the Atmel website as an application | |||
* note. | |||
* | |||
* \subsection SSec_AVRDude AVRDUDE (Windows, Mac, Linux) | |||
* | |||
* AVRDude is a free, cross-platform and open source command line programmer for Atmel and third party AVR | |||
* programmers. It is available on the the Windows platform as part of the "WinAVR" package, or on other systems | |||
* either from a build from the official source code, or in many distributions as a precompiled binary package. | |||
* | |||
* To load a new HEX file with AVRDude, specify "AVR109" as the programmer, with the allocated COM port. On Windows | |||
* platforms this will be a COMx port name: | |||
* \code | |||
* avrdude -c AVR109 -p at90usb1287 -P COM0 -U flash:w:Mouse.hex | |||
* \endcode | |||
* | |||
* On Linux systems, this will typically be a /dev/ttyACMx port name: | |||
* \code | |||
* avrdude -c AVR109 -p at90usb1287 -P /dev/ttyACM0 -U flash:w:Mouse.hex | |||
* \endcode | |||
* | |||
* Refer to the AVRDude project documentation for additional usage instructions. | |||
* | |||
* \section Sec_API User Application API | |||
* | |||
* Several user application functions for FLASH and other special memory area manipulations are exposed by the bootloader, | |||
* allowing the user application to call into the bootloader at runtime to read and write FLASH data. | |||
* | |||
* By default, the bootloader API jump table is located 32 bytes from the end of the device's FLASH memory, and follows the | |||
* following layout: | |||
* | |||
* \code | |||
* #define BOOTLOADER_API_TABLE_SIZE 32 | |||
* #define BOOTLOADER_API_TABLE_START ((FLASHEND + 1UL) - BOOTLOADER_API_TABLE_SIZE) | |||
* #define BOOTLOADER_API_CALL(Index) (void*)((BOOTLOADER_API_TABLE_START + (Index * 2)) / 2) | |||
* | |||
* void (*BootloaderAPI_ErasePage)(uint32_t Address) = BOOTLOADER_API_CALL(0); | |||
* void (*BootloaderAPI_WritePage)(uint32_t Address) = BOOTLOADER_API_CALL(1); | |||
* void (*BootloaderAPI_FillWord)(uint32_t Address, uint16_t Word) = BOOTLOADER_API_CALL(2); | |||
* uint8_t (*BootloaderAPI_ReadSignature)(uint16_t Address) = BOOTLOADER_API_CALL(3); | |||
* uint8_t (*BootloaderAPI_ReadFuse)(uint16_t Address) = BOOTLOADER_API_CALL(4); | |||
* uint8_t (*BootloaderAPI_ReadLock)(void) = BOOTLOADER_API_CALL(5); | |||
* void (*BootloaderAPI_WriteLock)(uint8_t LockBits) = BOOTLOADER_API_CALL(6); | |||
* | |||
* #define BOOTLOADER_MAGIC_SIGNATURE_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 2)) | |||
* #define BOOTLOADER_MAGIC_SIGNATURE 0xDCFB | |||
* | |||
* #define BOOTLOADER_CLASS_SIGNATURE_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 4)) | |||
* #define BOOTLOADER_CDC_SIGNATURE 0xDF00 | |||
* | |||
* #define BOOTLOADER_ADDRESS_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 8)) | |||
* #define BOOTLOADER_ADDRESS_LENGTH 4 | |||
* \endcode | |||
* | |||
* From the application the API support of the bootloader can be detected by reading the FLASH memory bytes located at address | |||
* \c BOOTLOADER_MAGIC_SIGNATURE_START and comparing them to the value \c BOOTLOADER_MAGIC_SIGNATURE. The class of bootloader | |||
* can be determined by reading the FLASH memory bytes located at address \c BOOTLOADER_CLASS_SIGNATURE_START and comparing them | |||
* to the value \c BOOTLOADER_CDC_SIGNATURE. The start address of the bootloader can be retrieved by reading the bytes of FLASH | |||
* memory starting from address \c BOOTLOADER_ADDRESS_START. | |||
* | |||
* \subsection SSec_API_MemLayout Device Memory Map | |||
* The following illustration indicates the final memory map of the device when loaded with the bootloader. | |||
* | |||
* \verbatim | |||
* +----------------------------+ 0x0000 | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | User Application | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* +----------------------------+ FLASHEND - BOOT_SECTION_SIZE | |||
* | | | |||
* | Bootloader Application | | |||
* | (Not User App. Accessible) | | |||
* | | | |||
* +----------------------------+ FLASHEND - 96 | |||
* | API Table Trampolines | | |||
* | (Not User App. Accessible) | | |||
* +----------------------------+ FLASHEND - 32 | |||
* | Bootloader API Table | | |||
* | (User App. Accessible) | | |||
* +----------------------------+ FLASHEND - 8 | |||
* | Bootloader ID Constants | | |||
* | (User App. Accessible) | | |||
* +----------------------------+ FLASHEND | |||
* \endverbatim | |||
* | |||
* \section Sec_KnownIssues Known Issues: | |||
* | |||
* \par On Linux machines, the CDC bootloader is unstable or inaccessible. | |||
* A change to the \c ModemManager module in many Linux distributions causes | |||
* this module to try to take control over inserted CDC devices, corrupting the | |||
* datastream. A UDEV rule is required to prevent this. | |||
* See <a href=https://groups.google.com/d/msg/lufa-support/CP9cy2bc8yo/kBqsOu-RBeMJ>here</a> for resolution steps. | |||
* If the issue still persists then uninstall modemmanager by executing <tt>sudo apt-get remove modemmanager</tt>, or | |||
* the equivalent using your chosen distribution's package manager. | |||
* | |||
* \par On Linux machines, the CDC bootloader is inaccessible. | |||
* On many Linux systems, non-root users do not have automatic access to newly | |||
* inserted CDC devices. Root privileges or a UDEV rule is required to gain | |||
* access. | |||
* See <a href=https://groups.google.com/d/msg/lufa-support/CP9cy2bc8yo/kBqsOu-RBeMJ>here</a> for resolution steps. | |||
* | |||
* \par After loading an application, it is not run automatically on startup. | |||
* Some USB AVR boards ship with the BOOTRST fuse set, causing the bootloader | |||
* to run automatically when the device is reset. In most cases, the BOOTRST | |||
* fuse should be disabled and the HWBE fuse used instead to run the bootloader | |||
* when needed. | |||
* | |||
* \section Sec_Options Project Options | |||
* | |||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value. | |||
* | |||
* <table> | |||
* <tr> | |||
* <th><b>Define Name:</b></th> | |||
* <th><b>Location:</b></th> | |||
* <th><b>Description:</b></th> | |||
* </tr> | |||
* <tr> | |||
* <td>NO_BLOCK_SUPPORT</td> | |||
* <td>AppConfig.h</td> | |||
* <td>Define to disable memory block read/write support in the bootloader, requiring all reads and writes to be made | |||
* using the byte-level commands.</td> | |||
* </tr> | |||
* <tr> | |||
* <td>NO_EEPROM_BYTE_SUPPORT</td> | |||
* <td>AppConfig.h</td> | |||
* <td>Define to disable EEPROM memory byte read/write support in the bootloader, requiring all EEPROM reads and writes | |||
* to be made using the block-level commands.</td> | |||
* </tr> | |||
* <tr> | |||
* <td>NO_FLASH_BYTE_SUPPORT</td> | |||
* <td>AppConfig.h</td> | |||
* <td>Define to disable FLASH memory byte read/write support in the bootloader, requiring all FLASH reads and writes | |||
* to be made using the block-level commands.</td> | |||
* </tr> | |||
* <tr> | |||
* <td>NO_LOCK_BYTE_WRITE_SUPPORT</td> | |||
* <td>AppConfig.h</td> | |||
* <td>Define to disable lock byte write support in the bootloader, preventing the lock bits from being set programmatically.</td> | |||
* </tr> | |||
* </table> | |||
*/ | |||
@@ -0,0 +1,50 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* \brief Application Configuration Header File | |||
* | |||
* This is a header file which is be used to configure LUFA's | |||
* compile time options, as an alternative to the compile time | |||
* constants supplied through a makefile. | |||
* | |||
* For information on what each token does, refer to the | |||
* \ref Sec_Options section of the application documentation. | |||
*/ | |||
#ifndef _APP_CONFIG_H_ | |||
#define _APP_CONFIG_H_ | |||
// #define NO_BLOCK_SUPPORT | |||
// #define NO_EEPROM_BYTE_SUPPORT | |||
// #define NO_FLASH_BYTE_SUPPORT | |||
// #define NO_LOCK_BYTE_WRITE_SUPPORT | |||
#endif |
@@ -0,0 +1,93 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* \brief LUFA Library Configuration Header File | |||
* | |||
* This header file is used to configure LUFA's compile time options, | |||
* as an alternative to the compile time constants supplied through | |||
* a makefile. | |||
* | |||
* For information on what each token does, refer to the LUFA | |||
* manual section "Summary of Compile Tokens". | |||
*/ | |||
#ifndef _LUFA_CONFIG_H_ | |||
#define _LUFA_CONFIG_H_ | |||
#if (ARCH == ARCH_AVR8) | |||
/* Non-USB Related Configuration Tokens: */ | |||
// #define DISABLE_TERMINAL_CODES | |||
/* USB Class Driver Related Tokens: */ | |||
// #define HID_HOST_BOOT_PROTOCOL_ONLY | |||
// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here} | |||
// #define HID_USAGE_STACK_DEPTH {Insert Value Here} | |||
// #define HID_MAX_COLLECTIONS {Insert Value Here} | |||
// #define HID_MAX_REPORTITEMS {Insert Value Here} | |||
// #define HID_MAX_REPORT_IDS {Insert Value Here} | |||
// #define NO_CLASS_DRIVER_AUTOFLUSH | |||
/* General USB Driver Related Tokens: */ | |||
#define ORDERED_EP_CONFIG | |||
#define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL) | |||
#define USB_DEVICE_ONLY | |||
// #define USB_HOST_ONLY | |||
// #define USB_STREAM_TIMEOUT_MS {Insert Value Here} | |||
// #define NO_LIMITED_CONTROLLER_CONNECT | |||
#define NO_SOF_EVENTS | |||
/* USB Device Mode Driver Related Tokens: */ | |||
#define USE_RAM_DESCRIPTORS | |||
// #define USE_FLASH_DESCRIPTORS | |||
// #define USE_EEPROM_DESCRIPTORS | |||
#define NO_INTERNAL_SERIAL | |||
#define FIXED_CONTROL_ENDPOINT_SIZE 8 | |||
#define DEVICE_STATE_AS_GPIOR 0 | |||
#define FIXED_NUM_CONFIGURATIONS 1 | |||
// #define CONTROL_ONLY_DEVICE | |||
// #define INTERRUPT_CONTROL_ENDPOINT | |||
#define NO_DEVICE_REMOTE_WAKEUP | |||
#define NO_DEVICE_SELF_POWER | |||
/* USB Host Mode Driver Related Tokens: */ | |||
// #define HOST_STATE_AS_GPIOR {Insert Value Here} | |||
// #define USB_HOST_TIMEOUT_MS {Insert Value Here} | |||
// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here} | |||
// #define NO_AUTO_VBUS_MANAGEMENT | |||
// #define INVERTED_VBUS_ENABLE_LINE | |||
#else | |||
#error Unsupported architecture for this LUFA configuration file. | |||
#endif | |||
#endif |
@@ -0,0 +1,244 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special | |||
* computer-readable structures which the host requests upon device enumeration, to determine | |||
* the device's capabilities and functions. | |||
*/ | |||
#include "Descriptors.h" | |||
/** Device descriptor structure. This descriptor, located in SRAM memory, describes the overall | |||
* device characteristics, including the supported USB version, control endpoint size and the | |||
* number of device configurations. The descriptor is read out by the USB host when the enumeration | |||
* process begins. | |||
*/ | |||
const USB_Descriptor_Device_t DeviceDescriptor = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, | |||
.USBSpecification = VERSION_BCD(1,1,0), | |||
.Class = CDC_CSCP_CDCClass, | |||
.SubClass = CDC_CSCP_NoSpecificSubclass, | |||
.Protocol = CDC_CSCP_NoSpecificProtocol, | |||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, | |||
.VendorID = 0x03EB, | |||
.ProductID = 0x204A, | |||
.ReleaseNumber = VERSION_BCD(1,0,0), | |||
.ManufacturerStrIndex = STRING_ID_Manufacturer, | |||
.ProductStrIndex = STRING_ID_Product, | |||
.SerialNumStrIndex = NO_DESCRIPTOR, | |||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS | |||
}; | |||
/** Configuration descriptor structure. This descriptor, located in SRAM memory, describes the usage | |||
* of the device in one of its supported configurations, including information about any device interfaces | |||
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting | |||
* a configuration so that the host may correctly communicate with the USB device. | |||
*/ | |||
const USB_Descriptor_Configuration_t ConfigurationDescriptor = | |||
{ | |||
.Config = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, | |||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), | |||
.TotalInterfaces = 2, | |||
.ConfigurationNumber = 1, | |||
.ConfigurationStrIndex = NO_DESCRIPTOR, | |||
.ConfigAttributes = USB_CONFIG_ATTR_RESERVED, | |||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100) | |||
}, | |||
.CDC_CCI_Interface = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, | |||
.InterfaceNumber = INTERFACE_ID_CDC_CCI, | |||
.AlternateSetting = 0, | |||
.TotalEndpoints = 1, | |||
.Class = CDC_CSCP_CDCClass, | |||
.SubClass = CDC_CSCP_ACMSubclass, | |||
.Protocol = CDC_CSCP_ATCommandProtocol, | |||
.InterfaceStrIndex = NO_DESCRIPTOR | |||
}, | |||
.CDC_Functional_Header = | |||
{ | |||
.Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface}, | |||
.Subtype = 0x00, | |||
.CDCSpecification = VERSION_BCD(1,1,0), | |||
}, | |||
.CDC_Functional_ACM = | |||
{ | |||
.Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface}, | |||
.Subtype = 0x02, | |||
.Capabilities = 0x02, | |||
}, | |||
.CDC_Functional_Union = | |||
{ | |||
.Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface}, | |||
.Subtype = 0x06, | |||
.MasterInterfaceNumber = INTERFACE_ID_CDC_CCI, | |||
.SlaveInterfaceNumber = INTERFACE_ID_CDC_DCI, | |||
}, | |||
.CDC_NotificationEndpoint = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, | |||
.EndpointAddress = CDC_NOTIFICATION_EPADDR, | |||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), | |||
.EndpointSize = CDC_NOTIFICATION_EPSIZE, | |||
.PollingIntervalMS = 0xFF | |||
}, | |||
.CDC_DCI_Interface = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, | |||
.InterfaceNumber = INTERFACE_ID_CDC_DCI, | |||
.AlternateSetting = 0, | |||
.TotalEndpoints = 2, | |||
.Class = CDC_CSCP_CDCDataClass, | |||
.SubClass = CDC_CSCP_NoDataSubclass, | |||
.Protocol = CDC_CSCP_NoDataProtocol, | |||
.InterfaceStrIndex = NO_DESCRIPTOR | |||
}, | |||
.CDC_DataOutEndpoint = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, | |||
.EndpointAddress = CDC_RX_EPADDR, | |||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), | |||
.EndpointSize = CDC_TXRX_EPSIZE, | |||
.PollingIntervalMS = 0x05 | |||
}, | |||
.CDC_DataInEndpoint = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, | |||
.EndpointAddress = CDC_TX_EPADDR, | |||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), | |||
.EndpointSize = CDC_TXRX_EPSIZE, | |||
.PollingIntervalMS = 0x05 | |||
} | |||
}; | |||
/** Language descriptor structure. This descriptor, located in SRAM memory, is returned when the host requests | |||
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate | |||
* via the language ID table available at USB.org what languages the device supports for its string descriptors. | |||
*/ | |||
const USB_Descriptor_String_t LanguageString = USB_STRING_DESCRIPTOR_ARRAY(LANGUAGE_ID_ENG); | |||
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable | |||
* form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device | |||
* Descriptor. | |||
*/ | |||
const USB_Descriptor_String_t ManufacturerString = USB_STRING_DESCRIPTOR(L"Dean Camera"); | |||
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form, | |||
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device | |||
* Descriptor. | |||
*/ | |||
const USB_Descriptor_String_t ProductString = USB_STRING_DESCRIPTOR(L"LUFA CDC"); | |||
/** This function is called by the library when in device mode, and must be overridden (see LUFA library "USB Descriptors" | |||
* documentation) by the application code so that the address and size of a requested descriptor can be given | |||
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function | |||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the | |||
* USB host. | |||
*/ | |||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, | |||
const uint8_t wIndex, | |||
const void** const DescriptorAddress) | |||
{ | |||
const uint8_t DescriptorType = (wValue >> 8); | |||
const uint8_t DescriptorNumber = (wValue & 0xFF); | |||
const void* Address = NULL; | |||
uint16_t Size = NO_DESCRIPTOR; | |||
switch (DescriptorType) | |||
{ | |||
case DTYPE_Device: | |||
Address = &DeviceDescriptor; | |||
Size = sizeof(USB_Descriptor_Device_t); | |||
break; | |||
case DTYPE_Configuration: | |||
Address = &ConfigurationDescriptor; | |||
Size = sizeof(USB_Descriptor_Configuration_t); | |||
break; | |||
case DTYPE_String: | |||
if (DescriptorNumber == STRING_ID_Language) | |||
{ | |||
Address = &LanguageString; | |||
Size = LanguageString.Header.Size; | |||
} | |||
else if (DescriptorNumber == STRING_ID_Manufacturer) | |||
{ | |||
Address = &ManufacturerString; | |||
Size = ManufacturerString.Header.Size; | |||
} | |||
else if (DescriptorNumber == STRING_ID_Product) | |||
{ | |||
Address = &ProductString; | |||
Size = ProductString.Header.Size; | |||
} | |||
break; | |||
} | |||
*DescriptorAddress = Address; | |||
return Size; | |||
} | |||
@@ -0,0 +1,158 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Header file for Descriptors.c. | |||
*/ | |||
#ifndef _DESCRIPTORS_H_ | |||
#define _DESCRIPTORS_H_ | |||
/* Includes: */ | |||
#include <LUFA/Drivers/USB/USB.h> | |||
#include "Config/AppConfig.h" | |||
/* Macros: */ | |||
#if defined(__AVR_AT90USB1287__) | |||
#define AVR_SIGNATURE_1 0x1E | |||
#define AVR_SIGNATURE_2 0x97 | |||
#define AVR_SIGNATURE_3 0x82 | |||
#elif defined(__AVR_AT90USB647__) | |||
#define AVR_SIGNATURE_1 0x1E | |||
#define AVR_SIGNATURE_2 0x96 | |||
#define AVR_SIGNATURE_3 0x82 | |||
#elif defined(__AVR_AT90USB1286__) | |||
#define AVR_SIGNATURE_1 0x1E | |||
#define AVR_SIGNATURE_2 0x97 | |||
#define AVR_SIGNATURE_3 0x82 | |||
#elif defined(__AVR_AT90USB646__) | |||
#define AVR_SIGNATURE_1 0x1E | |||
#define AVR_SIGNATURE_2 0x96 | |||
#define AVR_SIGNATURE_3 0x82 | |||
#elif defined(__AVR_ATmega32U4__) | |||
#define AVR_SIGNATURE_1 0x1E | |||
#define AVR_SIGNATURE_2 0x95 | |||
#define AVR_SIGNATURE_3 0x87 | |||
#elif defined(__AVR_ATmega16U4__) | |||
#define AVR_SIGNATURE_1 0x1E | |||
#define AVR_SIGNATURE_2 0x94 | |||
#define AVR_SIGNATURE_3 0x88 | |||
#elif defined(__AVR_ATmega32U2__) | |||
#define AVR_SIGNATURE_1 0x1E | |||
#define AVR_SIGNATURE_2 0x95 | |||
#define AVR_SIGNATURE_3 0x8A | |||
#elif defined(__AVR_ATmega16U2__) | |||
#define AVR_SIGNATURE_1 0x1E | |||
#define AVR_SIGNATURE_2 0x94 | |||
#define AVR_SIGNATURE_3 0x89 | |||
#elif defined(__AVR_AT90USB162__) | |||
#define AVR_SIGNATURE_1 0x1E | |||
#define AVR_SIGNATURE_2 0x94 | |||
#define AVR_SIGNATURE_3 0x82 | |||
#elif defined(__AVR_ATmega8U2__) | |||
#define AVR_SIGNATURE_1 0x1E | |||
#define AVR_SIGNATURE_2 0x93 | |||
#define AVR_SIGNATURE_3 0x89 | |||
#elif defined(__AVR_AT90USB82__) | |||
#define AVR_SIGNATURE_1 0x1E | |||
#define AVR_SIGNATURE_2 0x94 | |||
#define AVR_SIGNATURE_3 0x82 | |||
#else | |||
#error The selected AVR part is not currently supported by this bootloader. | |||
#endif | |||
/** Endpoint address for the CDC control interface event notification endpoint. */ | |||
#define CDC_NOTIFICATION_EPADDR (ENDPOINT_DIR_IN | 2) | |||
/** Endpoint address for the CDC data interface TX (data IN) endpoint. */ | |||
#define CDC_TX_EPADDR (ENDPOINT_DIR_IN | 3) | |||
/** Endpoint address for the CDC data interface RX (data OUT) endpoint. */ | |||
#define CDC_RX_EPADDR (ENDPOINT_DIR_OUT | 4) | |||
/** Size of the CDC data interface TX and RX data endpoint banks, in bytes. */ | |||
#define CDC_TXRX_EPSIZE 16 | |||
/** Size of the CDC control interface notification endpoint bank, in bytes. */ | |||
#define CDC_NOTIFICATION_EPSIZE 8 | |||
/* Type Defines: */ | |||
/** Type define for the device configuration descriptor structure. This must be defined in the | |||
* application code, as the configuration descriptor contains several sub-descriptors which | |||
* vary between devices, and which describe the device's usage to the host. | |||
*/ | |||
typedef struct | |||
{ | |||
USB_Descriptor_Configuration_Header_t Config; | |||
// CDC Control Interface | |||
USB_Descriptor_Interface_t CDC_CCI_Interface; | |||
USB_CDC_Descriptor_FunctionalHeader_t CDC_Functional_Header; | |||
USB_CDC_Descriptor_FunctionalACM_t CDC_Functional_ACM; | |||
USB_CDC_Descriptor_FunctionalUnion_t CDC_Functional_Union; | |||
USB_Descriptor_Endpoint_t CDC_NotificationEndpoint; | |||
// CDC Data Interface | |||
USB_Descriptor_Interface_t CDC_DCI_Interface; | |||
USB_Descriptor_Endpoint_t CDC_DataOutEndpoint; | |||
USB_Descriptor_Endpoint_t CDC_DataInEndpoint; | |||
} USB_Descriptor_Configuration_t; | |||
/** Enum for the device interface descriptor IDs within the device. Each interface descriptor | |||
* should have a unique ID index associated with it, which can be used to refer to the | |||
* interface from other descriptors. | |||
*/ | |||
enum InterfaceDescriptors_t | |||
{ | |||
INTERFACE_ID_CDC_CCI = 0, /**< CDC CCI interface descriptor ID */ | |||
INTERFACE_ID_CDC_DCI = 1, /**< CDC DCI interface descriptor ID */ | |||
}; | |||
/** Enum for the device string descriptor IDs within the device. Each string descriptor should | |||
* have a unique ID index associated with it, which can be used to refer to the string from | |||
* other descriptors. | |||
*/ | |||
enum StringDescriptors_t | |||
{ | |||
STRING_ID_Language = 0, /**< Supported Languages string descriptor ID (must be zero) */ | |||
STRING_ID_Manufacturer = 1, /**< Manufacturer string ID */ | |||
STRING_ID_Product = 2, /**< Product string ID */ | |||
}; | |||
/* Function Prototypes: */ | |||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, | |||
const uint8_t wIndex, | |||
const void** const DescriptorAddress) | |||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); | |||
#endif | |||
@@ -0,0 +1,66 @@ | |||
;************************************************************ | |||
; Windows USB CDC ACM Setup File | |||
; Copyright (c) 2000 Microsoft Corporation | |||
;************************************************************ | |||
[DefaultInstall] | |||
CopyINF="LUFA CDC Bootloader.inf" | |||
[Version] | |||
Signature="$Windows NT$" | |||
Class=Ports | |||
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} | |||
Provider=%MFGNAME% | |||
DriverVer=7/1/2012,10.0.0.0 | |||
[Manufacturer] | |||
%MFGNAME%=DeviceList, NTx86, NTamd64, NTia64 | |||
[SourceDisksNames] | |||
[SourceDisksFiles] | |||
[DestinationDirs] | |||
DefaultDestDir=12 | |||
[DriverInstall] | |||
Include=mdmcpq.inf | |||
CopyFiles=FakeModemCopyFileSection | |||
AddReg=DriverInstall.AddReg | |||
[DriverInstall.Services] | |||
Include=mdmcpq.inf | |||
AddService=usbser, 0x00000002, LowerFilter_Service_Inst | |||
[DriverInstall.AddReg] | |||
HKR,,EnumPropPages32,,"msports.dll,SerialPortPropPageProvider" | |||
;------------------------------------------------------------------------------ | |||
; Vendor and Product ID Definitions | |||
;------------------------------------------------------------------------------ | |||
; When developing your USB device, the VID and PID used in the PC side | |||
; application program and the firmware on the microcontroller must match. | |||
; Modify the below line to use your VID and PID. Use the format as shown below. | |||
; Note: One INF file can be used for multiple devices with different VID and PIDs. | |||
; For each supported device, append ",USB\VID_xxxx&PID_yyyy" to the end of the line. | |||
;------------------------------------------------------------------------------ | |||
[DeviceList] | |||
%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204A | |||
[DeviceList.NTx86] | |||
%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204A | |||
[DeviceList.NTamd64] | |||
%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204A | |||
[DeviceList.NTia64] | |||
%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204A | |||
;------------------------------------------------------------------------------ | |||
; String Definitions | |||
;------------------------------------------------------------------------------ | |||
;Modify these strings to customize your device | |||
;------------------------------------------------------------------------------ | |||
[Strings] | |||
MFGNAME="http://www.lufa-lib.org" | |||
DESCRIPTION="LUFA CDC Class Bootloader" |
@@ -0,0 +1,161 @@ | |||
<asf xmlversion="1.0"> | |||
<project caption="CDC Bootloader - 128KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.cdc.avr8.128_4" force-caption="true" workspace-name="lufa_cdc_128kb_4kb_"> | |||
<require idref="lufa.bootloaders.cdc"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="at90usb1287"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<config name="config.compiler.optimization.level" value="size"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0x1F000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x1F000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x1FFA0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x1FFE0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x1FFF8"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/> | |||
</project> | |||
<project caption="CDC Bootloader - 64KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.cdc.avr8.64_4" force-caption="true" workspace-name="lufa_cdc_64kb_4kb_"> | |||
<require idref="lufa.bootloaders.cdc"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="at90usb647"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<config name="config.compiler.optimization.level" value="size"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0xF000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0xF000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0xFFA0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0xFFE0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0xFFF8"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/> | |||
</project> | |||
<project caption="CDC Bootloader - 32KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.cdc.avr8.32_4" force-caption="true" workspace-name="lufa_cdc_32kb_4kb_"> | |||
<require idref="lufa.bootloaders.cdc"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="atmega32u4"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<config name="config.compiler.optimization.level" value="size"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0x7000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x7000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x7FA0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x7FE0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x7FF8"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/> | |||
</project> | |||
<project caption="CDC Bootloader - 16KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.cdc.avr8.16_4" force-caption="true" workspace-name="lufa_cdc_16kb_4kb_"> | |||
<require idref="lufa.bootloaders.cdc"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="atmega16u2"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<config name="config.compiler.optimization.level" value="size"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0x3000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x3000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x3FA0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x3FE0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x3FF8"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/> | |||
</project> | |||
<project caption="CDC Bootloader - 8KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.cdc.avr8.8_4" force-caption="true" workspace-name="lufa_cdc_8kb_4kb_"> | |||
<require idref="lufa.bootloaders.cdc"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="atmega8u2"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<config name="config.compiler.optimization.level" value="size"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0x1000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x1000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x1FA0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x1FE0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x1FF8"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/> | |||
</project> | |||
<module type="application" id="lufa.bootloaders.cdc" caption="CDC Bootloader"> | |||
<info type="description" value="summary"> | |||
CDC Class Bootloader, capable of reprogramming a device using avrdude or other AVR109 protocol compliant software when plugged into a host. | |||
</info> | |||
<info type="gui-flag" value="move-to-root"/> | |||
<info type="keyword" value="Technology"> | |||
<keyword value="Bootloaders"/> | |||
<keyword value="USB Device"/> | |||
</info> | |||
<device-support-alias value="lufa_avr8"/> | |||
<device-support-alias value="lufa_xmega"/> | |||
<device-support-alias value="lufa_uc3"/> | |||
<build type="include-path" value="."/> | |||
<build type="c-source" value="BootloaderCDC.c"/> | |||
<build type="header-file" value="BootloaderCDC.h"/> | |||
<build type="c-source" value="Descriptors.c"/> | |||
<build type="header-file" value="Descriptors.h"/> | |||
<build type="c-source" value="BootloaderAPI.c"/> | |||
<build type="header-file" value="BootloaderAPI.h"/> | |||
<build type="asm-source" value="BootloaderAPITable.S"/> | |||
<build type="module-config" subtype="path" value="Config"/> | |||
<build type="header-file" value="Config/LUFAConfig.h"/> | |||
<build type="header-file" value="Config/AppConfig.h"/> | |||
<build type="distribute" subtype="user-file" value="doxyfile"/> | |||
<build type="distribute" subtype="user-file" value="BootloaderCDC.txt"/> | |||
<build type="distribute" subtype="user-file" value="LUFA CDC Bootloader.inf"/> | |||
<require idref="lufa.common"/> | |||
<require idref="lufa.platform"/> | |||
<require idref="lufa.drivers.usb"/> | |||
<require idref="lufa.drivers.board"/> | |||
<require idref="lufa.drivers.board.leds"/> | |||
</module> | |||
</asf> |
@@ -0,0 +1,55 @@ | |||
# | |||
# LUFA Library | |||
# Copyright (C) Dean Camera, 2014. | |||
# | |||
# dean [at] fourwalledcubicle [dot] com | |||
# www.lufa-lib.org | |||
# | |||
# -------------------------------------- | |||
# LUFA Project Makefile. | |||
# -------------------------------------- | |||
# Run "make help" for target help. | |||
MCU = at90usb1287 | |||
ARCH = AVR8 | |||
BOARD = USBKEY | |||
F_CPU = 8000000 | |||
F_USB = $(F_CPU) | |||
OPTIMIZATION = s | |||
TARGET = BootloaderCDC | |||
SRC = $(TARGET).c Descriptors.c BootloaderAPI.c BootloaderAPITable.S $(LUFA_SRC_USB) | |||
LUFA_PATH = ../../LUFA | |||
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/ -DBOOT_START_ADDR=$(BOOT_START_OFFSET) | |||
LD_FLAGS = -Wl,--section-start=.text=$(BOOT_START_OFFSET) $(BOOT_API_LD_FLAGS) | |||
# Flash size and bootloader section sizes of the target, in KB. These must | |||
# match the target's total FLASH size and the bootloader size set in the | |||
# device's fuses. | |||
FLASH_SIZE_KB = 128 | |||
BOOT_SECTION_SIZE_KB = 8 | |||
# Bootloader address calculation formulas | |||
# Do not modify these macros, but rather modify the dependent values above. | |||
CALC_ADDRESS_IN_HEX = $(shell printf "0x%X" $$(( $(1) )) ) | |||
BOOT_START_OFFSET = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) - $(BOOT_SECTION_SIZE_KB)) * 1024 ) | |||
BOOT_SEC_OFFSET = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) * 1024) - ($(strip $(1))) ) | |||
# Bootloader linker section flags for relocating the API table sections to | |||
# known FLASH addresses - these should not normally be user-edited. | |||
BOOT_SECTION_LD_FLAG = -Wl,--section-start=$(strip $(1))=$(call BOOT_SEC_OFFSET, $(3)) -Wl,--undefined=$(strip $(2)) | |||
BOOT_API_LD_FLAGS = $(call BOOT_SECTION_LD_FLAG, .apitable_trampolines, BootloaderAPI_Trampolines, 96) | |||
BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .apitable_jumptable, BootloaderAPI_JumpTable, 32) | |||
BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .apitable_signatures, BootloaderAPI_Signatures, 8) | |||
# Default target | |||
all: | |||
# Include LUFA build script makefiles | |||
include $(LUFA_PATH)/Build/lufa_core.mk | |||
include $(LUFA_PATH)/Build/lufa_sources.mk | |||
include $(LUFA_PATH)/Build/lufa_build.mk | |||
include $(LUFA_PATH)/Build/lufa_cppcheck.mk | |||
include $(LUFA_PATH)/Build/lufa_doxygen.mk | |||
include $(LUFA_PATH)/Build/lufa_avrdude.mk | |||
include $(LUFA_PATH)/Build/lufa_atprogram.mk |
@@ -0,0 +1,76 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Bootloader user application API functions. | |||
*/ | |||
#include "BootloaderAPI.h" | |||
void BootloaderAPI_ErasePage(const uint32_t Address) | |||
{ | |||
boot_page_erase_safe(Address); | |||
boot_spm_busy_wait(); | |||
boot_rww_enable(); | |||
} | |||
void BootloaderAPI_WritePage(const uint32_t Address) | |||
{ | |||
boot_page_write_safe(Address); | |||
boot_spm_busy_wait(); | |||
boot_rww_enable(); | |||
} | |||
void BootloaderAPI_FillWord(const uint32_t Address, const uint16_t Word) | |||
{ | |||
boot_page_fill_safe(Address, Word); | |||
} | |||
uint8_t BootloaderAPI_ReadSignature(const uint16_t Address) | |||
{ | |||
return boot_signature_byte_get(Address); | |||
} | |||
uint8_t BootloaderAPI_ReadFuse(const uint16_t Address) | |||
{ | |||
return boot_lock_fuse_bits_get(Address); | |||
} | |||
uint8_t BootloaderAPI_ReadLock(void) | |||
{ | |||
return boot_lock_fuse_bits_get(GET_LOCK_BITS); | |||
} | |||
void BootloaderAPI_WriteLock(const uint8_t LockBits) | |||
{ | |||
boot_lock_bits_set_safe(LockBits); | |||
} | |||
@@ -0,0 +1,58 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Header file for BootloaderAPI.c. | |||
*/ | |||
#ifndef _BOOTLOADER_API_H_ | |||
#define _BOOTLOADER_API_H_ | |||
/* Includes: */ | |||
#include <avr/io.h> | |||
#include <avr/boot.h> | |||
#include <stdbool.h> | |||
#include <LUFA/Common/Common.h> | |||
#include "Config/AppConfig.h" | |||
/* Function Prototypes: */ | |||
void BootloaderAPI_ErasePage(const uint32_t Address); | |||
void BootloaderAPI_WritePage(const uint32_t Address); | |||
void BootloaderAPI_FillWord(const uint32_t Address, const uint16_t Word); | |||
uint8_t BootloaderAPI_ReadSignature(const uint16_t Address); | |||
uint8_t BootloaderAPI_ReadFuse(const uint16_t Address); | |||
uint8_t BootloaderAPI_ReadLock(void); | |||
void BootloaderAPI_WriteLock(const uint8_t LockBits); | |||
#endif | |||
@@ -0,0 +1,91 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
; Trampolines to actual API implementations if the target address is outside the | |||
; range of a rjmp instruction (can happen with large bootloader sections) | |||
.section .apitable_trampolines, "ax" | |||
.global BootloaderAPI_Trampolines | |||
BootloaderAPI_Trampolines: | |||
BootloaderAPI_ErasePage_Trampoline: | |||
jmp BootloaderAPI_ErasePage | |||
BootloaderAPI_WritePage_Trampoline: | |||
jmp BootloaderAPI_WritePage | |||
BootloaderAPI_FillWord_Trampoline: | |||
jmp BootloaderAPI_FillWord | |||
BootloaderAPI_ReadSignature_Trampoline: | |||
jmp BootloaderAPI_ReadSignature | |||
BootloaderAPI_ReadFuse_Trampoline: | |||
jmp BootloaderAPI_ReadFuse | |||
BootloaderAPI_ReadLock_Trampoline: | |||
jmp BootloaderAPI_ReadLock | |||
BootloaderAPI_WriteLock_Trampoline: | |||
jmp BootloaderAPI_WriteLock | |||
BootloaderAPI_UNUSED1: | |||
ret | |||
BootloaderAPI_UNUSED2: | |||
ret | |||
BootloaderAPI_UNUSED3: | |||
ret | |||
BootloaderAPI_UNUSED4: | |||
ret | |||
BootloaderAPI_UNUSED5: | |||
ret | |||
; API function jump table | |||
.section .apitable_jumptable, "ax" | |||
.global BootloaderAPI_JumpTable | |||
BootloaderAPI_JumpTable: | |||
rjmp BootloaderAPI_ErasePage_Trampoline | |||
rjmp BootloaderAPI_WritePage_Trampoline | |||
rjmp BootloaderAPI_FillWord_Trampoline | |||
rjmp BootloaderAPI_ReadSignature_Trampoline | |||
rjmp BootloaderAPI_ReadFuse_Trampoline | |||
rjmp BootloaderAPI_ReadLock_Trampoline | |||
rjmp BootloaderAPI_WriteLock_Trampoline | |||
rjmp BootloaderAPI_UNUSED1 ; UNUSED ENTRY 1 | |||
rjmp BootloaderAPI_UNUSED2 ; UNUSED ENTRY 2 | |||
rjmp BootloaderAPI_UNUSED3 ; UNUSED ENTRY 3 | |||
rjmp BootloaderAPI_UNUSED4 ; UNUSED ENTRY 4 | |||
rjmp BootloaderAPI_UNUSED5 ; UNUSED ENTRY 5 | |||
; Bootloader table signatures and information | |||
.section .apitable_signatures, "ax" | |||
.global BootloaderAPI_Signatures | |||
BootloaderAPI_Signatures: | |||
.long BOOT_START_ADDR ; Start address of the bootloader | |||
.word 0xDF10 ; Signature for the DFU class bootloader, V1 | |||
.word 0xDCFB ; Signature for a LUFA class bootloader |
@@ -0,0 +1,804 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Main source file for the DFU class bootloader. This file contains the complete bootloader logic. | |||
*/ | |||
#define INCLUDE_FROM_BOOTLOADER_C | |||
#include "BootloaderDFU.h" | |||
/** Flag to indicate if the bootloader is currently running in secure mode, disallowing memory operations | |||
* other than erase. This is initially set to the value set by SECURE_MODE, and cleared by the bootloader | |||
* once a memory erase has completed in a bootloader session. | |||
*/ | |||
static bool IsSecure = SECURE_MODE; | |||
/** Flag to indicate if the bootloader should be running, or should exit and allow the application code to run | |||
* via a soft reset. When cleared, the bootloader will abort, the USB interface will shut down and the application | |||
* jumped to via an indirect jump to location 0x0000 (or other location specified by the host). | |||
*/ | |||
static bool RunBootloader = true; | |||
/** Flag to indicate if the bootloader is waiting to exit. When the host requests the bootloader to exit and | |||
* jump to the application address it specifies, it sends two sequential commands which must be properly | |||
* acknowledged. Upon reception of the first the RunBootloader flag is cleared and the WaitForExit flag is set, | |||
* causing the bootloader to wait for the final exit command before shutting down. | |||
*/ | |||
static bool WaitForExit = false; | |||
/** Current DFU state machine state, one of the values in the DFU_State_t enum. */ | |||
static uint8_t DFU_State = dfuIDLE; | |||
/** Status code of the last executed DFU command. This is set to one of the values in the DFU_Status_t enum after | |||
* each operation, and returned to the host when a Get Status DFU request is issued. | |||
*/ | |||
static uint8_t DFU_Status = OK; | |||
/** Data containing the DFU command sent from the host. */ | |||
static DFU_Command_t SentCommand; | |||
/** Response to the last issued Read Data DFU command. Unlike other DFU commands, the read command | |||
* requires a single byte response from the bootloader containing the read data when the next DFU_UPLOAD command | |||
* is issued by the host. | |||
*/ | |||
static uint8_t ResponseByte; | |||
/** Pointer to the start of the user application. By default this is 0x0000 (the reset vector), however the host | |||
* may specify an alternate address when issuing the application soft-start command. | |||
*/ | |||
static AppPtr_t AppStartPtr = (AppPtr_t)0x0000; | |||
/** 64-bit flash page number. This is concatenated with the current 16-bit address on USB AVRs containing more than | |||
* 64KB of flash memory. | |||
*/ | |||
static uint8_t Flash64KBPage = 0; | |||
/** Memory start address, indicating the current address in the memory being addressed (either FLASH or EEPROM | |||
* depending on the issued command from the host). | |||
*/ | |||
static uint16_t StartAddr = 0x0000; | |||
/** Memory end address, indicating the end address to read from/write to in the memory being addressed (either FLASH | |||
* of EEPROM depending on the issued command from the host). | |||
*/ | |||
static uint16_t EndAddr = 0x0000; | |||
/** Magic lock for forced application start. If the HWBE fuse is programmed and BOOTRST is unprogrammed, the bootloader | |||
* will start if the /HWB line of the AVR is held low and the system is reset. However, if the /HWB line is still held | |||
* low when the application attempts to start via a watchdog reset, the bootloader will re-start. If set to the value | |||
* \ref MAGIC_BOOT_KEY the special init function \ref Application_Jump_Check() will force the application to start. | |||
*/ | |||
uint16_t MagicBootKey ATTR_NO_INIT; | |||
/** Special startup routine to check if the bootloader was started via a watchdog reset, and if the magic application | |||
* start key has been loaded into \ref MagicBootKey. If the bootloader started via the watchdog and the key is valid, | |||
* this will force the user application to start via a software jump. | |||
*/ | |||
void Application_Jump_Check(void) | |||
{ | |||
bool JumpToApplication = false; | |||
#if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1)) | |||
/* Disable JTAG debugging */ | |||
JTAG_DISABLE(); | |||
/* Enable pull-up on the JTAG TCK pin so we can use it to select the mode */ | |||
PORTF |= (1 << 4); | |||
Delay_MS(10); | |||
/* If the TCK pin is not jumpered to ground, start the user application instead */ | |||
JumpToApplication |= ((PINF & (1 << 4)) != 0); | |||
/* Re-enable JTAG debugging */ | |||
JTAG_ENABLE(); | |||
#endif | |||
/* If the reset source was the bootloader and the key is correct, clear it and jump to the application */ | |||
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY)) | |||
JumpToApplication |= true; | |||
/* If a request has been made to jump to the user application, honor it */ | |||
if (JumpToApplication) | |||
{ | |||
/* Turn off the watchdog */ | |||
MCUSR &= ~(1<<WDRF); | |||
wdt_disable(); | |||
/* Clear the boot key and jump to the user application */ | |||
MagicBootKey = 0; | |||
// cppcheck-suppress constStatement | |||
((void (*)(void))0x0000)(); | |||
} | |||
} | |||
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously | |||
* runs the bootloader processing routine until instructed to soft-exit, or hard-reset via the watchdog to start | |||
* the loaded application code. | |||
*/ | |||
int main(void) | |||
{ | |||
/* Configure hardware required by the bootloader */ | |||
SetupHardware(); | |||
/* Turn on first LED on the board to indicate that the bootloader has started */ | |||
LEDs_SetAllLEDs(LEDS_LED1); | |||
/* Enable global interrupts so that the USB stack can function */ | |||
GlobalInterruptEnable(); | |||
/* Run the USB management task while the bootloader is supposed to be running */ | |||
while (RunBootloader || WaitForExit) | |||
USB_USBTask(); | |||
/* Reset configured hardware back to their original states for the user application */ | |||
ResetHardware(); | |||
/* Start the user application */ | |||
AppStartPtr(); | |||
} | |||
/** Configures all hardware required for the bootloader. */ | |||
static void SetupHardware(void) | |||
{ | |||
/* Disable watchdog if enabled by bootloader/fuses */ | |||
MCUSR &= ~(1 << WDRF); | |||
wdt_disable(); | |||
/* Disable clock division */ | |||
clock_prescale_set(clock_div_1); | |||
/* Relocate the interrupt vector table to the bootloader section */ | |||
MCUCR = (1 << IVCE); | |||
MCUCR = (1 << IVSEL); | |||
/* Initialize the USB and other board hardware drivers */ | |||
USB_Init(); | |||
LEDs_Init(); | |||
/* Bootloader active LED toggle timer initialization */ | |||
TIMSK1 = (1 << TOIE1); | |||
TCCR1B = ((1 << CS11) | (1 << CS10)); | |||
} | |||
/** Resets all configured hardware required for the bootloader back to their original states. */ | |||
static void ResetHardware(void) | |||
{ | |||
/* Shut down the USB and other board hardware drivers */ | |||
USB_Disable(); | |||
LEDs_Disable(); | |||
/* Disable Bootloader active LED toggle timer */ | |||
TIMSK1 = 0; | |||
TCCR1B = 0; | |||
/* Relocate the interrupt vector table back to the application section */ | |||
MCUCR = (1 << IVCE); | |||
MCUCR = 0; | |||
} | |||
/** ISR to periodically toggle the LEDs on the board to indicate that the bootloader is active. */ | |||
ISR(TIMER1_OVF_vect, ISR_BLOCK) | |||
{ | |||
LEDs_ToggleLEDs(LEDS_LED1 | LEDS_LED2); | |||
} | |||
/** Event handler for the USB_ControlRequest event. This is used to catch and process control requests sent to | |||
* the device from the USB host before passing along unhandled control requests to the library for processing | |||
* internally. | |||
*/ | |||
void EVENT_USB_Device_ControlRequest(void) | |||
{ | |||
/* Ignore any requests that aren't directed to the DFU interface */ | |||
if ((USB_ControlRequest.bmRequestType & (CONTROL_REQTYPE_TYPE | CONTROL_REQTYPE_RECIPIENT)) != | |||
(REQTYPE_CLASS | REQREC_INTERFACE)) | |||
{ | |||
return; | |||
} | |||
/* Activity - toggle indicator LEDs */ | |||
LEDs_ToggleLEDs(LEDS_LED1 | LEDS_LED2); | |||
/* Get the size of the command and data from the wLength value */ | |||
SentCommand.DataSize = USB_ControlRequest.wLength; | |||
switch (USB_ControlRequest.bRequest) | |||
{ | |||
case DFU_REQ_DNLOAD: | |||
Endpoint_ClearSETUP(); | |||
/* Check if bootloader is waiting to terminate */ | |||
if (WaitForExit) | |||
{ | |||
/* Bootloader is terminating - process last received command */ | |||
ProcessBootloaderCommand(); | |||
/* Indicate that the last command has now been processed - free to exit bootloader */ | |||
WaitForExit = false; | |||
} | |||
/* If the request has a data stage, load it into the command struct */ | |||
if (SentCommand.DataSize) | |||
{ | |||
while (!(Endpoint_IsOUTReceived())) | |||
{ | |||
if (USB_DeviceState == DEVICE_STATE_Unattached) | |||
return; | |||
} | |||
/* First byte of the data stage is the DNLOAD request's command */ | |||
SentCommand.Command = Endpoint_Read_8(); | |||
/* One byte of the data stage is the command, so subtract it from the total data bytes */ | |||
SentCommand.DataSize--; | |||
/* Load in the rest of the data stage as command parameters */ | |||
for (uint8_t DataByte = 0; (DataByte < sizeof(SentCommand.Data)) && | |||
Endpoint_BytesInEndpoint(); DataByte++) | |||
{ | |||
SentCommand.Data[DataByte] = Endpoint_Read_8(); | |||
SentCommand.DataSize--; | |||
} | |||
/* Process the command */ | |||
ProcessBootloaderCommand(); | |||
} | |||
/* Check if currently downloading firmware */ | |||
if (DFU_State == dfuDNLOAD_IDLE) | |||
{ | |||
if (!(SentCommand.DataSize)) | |||
{ | |||
DFU_State = dfuIDLE; | |||
} | |||
else | |||
{ | |||
/* Throw away the filler bytes before the start of the firmware */ | |||
DiscardFillerBytes(DFU_FILLER_BYTES_SIZE); | |||
/* Throw away the packet alignment filler bytes before the start of the firmware */ | |||
DiscardFillerBytes(StartAddr % FIXED_CONTROL_ENDPOINT_SIZE); | |||
/* Calculate the number of bytes remaining to be written */ | |||
uint16_t BytesRemaining = ((EndAddr - StartAddr) + 1); | |||
if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x00)) // Write flash | |||
{ | |||
/* Calculate the number of words to be written from the number of bytes to be written */ | |||
uint16_t WordsRemaining = (BytesRemaining >> 1); | |||
union | |||
{ | |||
uint16_t Words[2]; | |||
uint32_t Long; | |||
} CurrFlashAddress = {.Words = {StartAddr, Flash64KBPage}}; | |||
uint32_t CurrFlashPageStartAddress = CurrFlashAddress.Long; | |||
uint8_t WordsInFlashPage = 0; | |||
while (WordsRemaining--) | |||
{ | |||
/* Check if endpoint is empty - if so clear it and wait until ready for next packet */ | |||
if (!(Endpoint_BytesInEndpoint())) | |||
{ | |||
Endpoint_ClearOUT(); | |||
while (!(Endpoint_IsOUTReceived())) | |||
{ | |||
if (USB_DeviceState == DEVICE_STATE_Unattached) | |||
return; | |||
} | |||
} | |||
/* Write the next word into the current flash page */ | |||
boot_page_fill(CurrFlashAddress.Long, Endpoint_Read_16_LE()); | |||
/* Adjust counters */ | |||
WordsInFlashPage += 1; | |||
CurrFlashAddress.Long += 2; | |||
/* See if an entire page has been written to the flash page buffer */ | |||
if ((WordsInFlashPage == (SPM_PAGESIZE >> 1)) || !(WordsRemaining)) | |||
{ | |||
/* Commit the flash page to memory */ | |||
boot_page_write(CurrFlashPageStartAddress); | |||
boot_spm_busy_wait(); | |||
/* Check if programming incomplete */ | |||
if (WordsRemaining) | |||
{ | |||
CurrFlashPageStartAddress = CurrFlashAddress.Long; | |||
WordsInFlashPage = 0; | |||
/* Erase next page's temp buffer */ | |||
boot_page_erase(CurrFlashAddress.Long); | |||
boot_spm_busy_wait(); | |||
} | |||
} | |||
} | |||
/* Once programming complete, start address equals the end address */ | |||
StartAddr = EndAddr; | |||
/* Re-enable the RWW section of flash */ | |||
boot_rww_enable(); | |||
} | |||
else // Write EEPROM | |||
{ | |||
while (BytesRemaining--) | |||
{ | |||
/* Check if endpoint is empty - if so clear it and wait until ready for next packet */ | |||
if (!(Endpoint_BytesInEndpoint())) | |||
{ | |||
Endpoint_ClearOUT(); | |||
while (!(Endpoint_IsOUTReceived())) | |||
{ | |||
if (USB_DeviceState == DEVICE_STATE_Unattached) | |||
return; | |||
} | |||
} | |||
/* Read the byte from the USB interface and write to to the EEPROM */ | |||
eeprom_write_byte((uint8_t*)StartAddr, Endpoint_Read_8()); | |||
/* Adjust counters */ | |||
StartAddr++; | |||
} | |||
} | |||
/* Throw away the currently unused DFU file suffix */ | |||
DiscardFillerBytes(DFU_FILE_SUFFIX_SIZE); | |||
} | |||
} | |||
Endpoint_ClearOUT(); | |||
Endpoint_ClearStatusStage(); | |||
break; | |||
case DFU_REQ_UPLOAD: | |||
Endpoint_ClearSETUP(); | |||
while (!(Endpoint_IsINReady())) | |||
{ | |||
if (USB_DeviceState == DEVICE_STATE_Unattached) | |||
return; | |||
} | |||
if (DFU_State != dfuUPLOAD_IDLE) | |||
{ | |||
if ((DFU_State == dfuERROR) && IS_ONEBYTE_COMMAND(SentCommand.Data, 0x01)) // Blank Check | |||
{ | |||
/* Blank checking is performed in the DFU_DNLOAD request - if we get here we've told the host | |||
that the memory isn't blank, and the host is requesting the first non-blank address */ | |||
Endpoint_Write_16_LE(StartAddr); | |||
} | |||
else | |||
{ | |||
/* Idle state upload - send response to last issued command */ | |||
Endpoint_Write_8(ResponseByte); | |||
} | |||
} | |||
else | |||
{ | |||
/* Determine the number of bytes remaining in the current block */ | |||
uint16_t BytesRemaining = ((EndAddr - StartAddr) + 1); | |||
if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x00)) // Read FLASH | |||
{ | |||
/* Calculate the number of words to be written from the number of bytes to be written */ | |||
uint16_t WordsRemaining = (BytesRemaining >> 1); | |||
union | |||
{ | |||
uint16_t Words[2]; | |||
uint32_t Long; | |||
} CurrFlashAddress = {.Words = {StartAddr, Flash64KBPage}}; | |||
while (WordsRemaining--) | |||
{ | |||
/* Check if endpoint is full - if so clear it and wait until ready for next packet */ | |||
if (Endpoint_BytesInEndpoint() == FIXED_CONTROL_ENDPOINT_SIZE) | |||
{ | |||
Endpoint_ClearIN(); | |||
while (!(Endpoint_IsINReady())) | |||
{ | |||
if (USB_DeviceState == DEVICE_STATE_Unattached) | |||
return; | |||
} | |||
} | |||
/* Read the flash word and send it via USB to the host */ | |||
#if (FLASHEND > 0xFFFF) | |||
Endpoint_Write_16_LE(pgm_read_word_far(CurrFlashAddress.Long)); | |||
#else | |||
Endpoint_Write_16_LE(pgm_read_word(CurrFlashAddress.Long)); | |||
#endif | |||
/* Adjust counters */ | |||
CurrFlashAddress.Long += 2; | |||
} | |||
/* Once reading is complete, start address equals the end address */ | |||
StartAddr = EndAddr; | |||
} | |||
else if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x02)) // Read EEPROM | |||
{ | |||
while (BytesRemaining--) | |||
{ | |||
/* Check if endpoint is full - if so clear it and wait until ready for next packet */ | |||
if (Endpoint_BytesInEndpoint() == FIXED_CONTROL_ENDPOINT_SIZE) | |||
{ | |||
Endpoint_ClearIN(); | |||
while (!(Endpoint_IsINReady())) | |||
{ | |||
if (USB_DeviceState == DEVICE_STATE_Unattached) | |||
return; | |||
} | |||
} | |||
/* Read the EEPROM byte and send it via USB to the host */ | |||
Endpoint_Write_8(eeprom_read_byte((uint8_t*)StartAddr)); | |||
/* Adjust counters */ | |||
StartAddr++; | |||
} | |||
} | |||
/* Return to idle state */ | |||
DFU_State = dfuIDLE; | |||
} | |||
Endpoint_ClearIN(); | |||
Endpoint_ClearStatusStage(); | |||
break; | |||
case DFU_REQ_GETSTATUS: | |||
Endpoint_ClearSETUP(); | |||
while (!(Endpoint_IsINReady())) | |||
{ | |||
if (USB_DeviceState == DEVICE_STATE_Unattached) | |||
return; | |||
} | |||
/* Write 8-bit status value */ | |||
Endpoint_Write_8(DFU_Status); | |||
/* Write 24-bit poll timeout value */ | |||
Endpoint_Write_8(0); | |||
Endpoint_Write_16_LE(0); | |||
/* Write 8-bit state value */ | |||
Endpoint_Write_8(DFU_State); | |||
/* Write 8-bit state string ID number */ | |||
Endpoint_Write_8(0); | |||
Endpoint_ClearIN(); | |||
Endpoint_ClearStatusStage(); | |||
break; | |||
case DFU_REQ_CLRSTATUS: | |||
Endpoint_ClearSETUP(); | |||
/* Reset the status value variable to the default OK status */ | |||
DFU_Status = OK; | |||
Endpoint_ClearStatusStage(); | |||
break; | |||
case DFU_REQ_GETSTATE: | |||
Endpoint_ClearSETUP(); | |||
while (!(Endpoint_IsINReady())) | |||
{ | |||
if (USB_DeviceState == DEVICE_STATE_Unattached) | |||
return; | |||
} | |||
/* Write the current device state to the endpoint */ | |||
Endpoint_Write_8(DFU_State); | |||
Endpoint_ClearIN(); | |||
Endpoint_ClearStatusStage(); | |||
break; | |||
case DFU_REQ_ABORT: | |||
Endpoint_ClearSETUP(); | |||
/* Reset the current state variable to the default idle state */ | |||
DFU_State = dfuIDLE; | |||
Endpoint_ClearStatusStage(); | |||
break; | |||
} | |||
} | |||
/** Routine to discard the specified number of bytes from the control endpoint stream. This is used to | |||
* discard unused bytes in the stream from the host, including the memory program block suffix. | |||
* | |||
* \param[in] NumberOfBytes Number of bytes to discard from the host from the control endpoint | |||
*/ | |||
static void DiscardFillerBytes(uint8_t NumberOfBytes) | |||
{ | |||
while (NumberOfBytes--) | |||
{ | |||
if (!(Endpoint_BytesInEndpoint())) | |||
{ | |||
Endpoint_ClearOUT(); | |||
/* Wait until next data packet received */ | |||
while (!(Endpoint_IsOUTReceived())) | |||
{ | |||
if (USB_DeviceState == DEVICE_STATE_Unattached) | |||
return; | |||
} | |||
} | |||
else | |||
{ | |||
Endpoint_Discard_8(); | |||
} | |||
} | |||
} | |||
/** Routine to process an issued command from the host, via a DFU_DNLOAD request wrapper. This routine ensures | |||
* that the command is allowed based on the current secure mode flag value, and passes the command off to the | |||
* appropriate handler function. | |||
*/ | |||
static void ProcessBootloaderCommand(void) | |||
{ | |||
/* Check if device is in secure mode */ | |||
if (IsSecure) | |||
{ | |||
/* Don't process command unless it is a READ or chip erase command */ | |||
if (!(((SentCommand.Command == COMMAND_WRITE) && | |||
IS_TWOBYTE_COMMAND(SentCommand.Data, 0x00, 0xFF)) || | |||
(SentCommand.Command == COMMAND_READ))) | |||
{ | |||
/* Set the state and status variables to indicate the error */ | |||
DFU_State = dfuERROR; | |||
DFU_Status = errWRITE; | |||
/* Stall command */ | |||
Endpoint_StallTransaction(); | |||
/* Don't process the command */ | |||
return; | |||
} | |||
} | |||
/* Dispatch the required command processing routine based on the command type */ | |||
switch (SentCommand.Command) | |||
{ | |||
case COMMAND_PROG_START: | |||
ProcessMemProgCommand(); | |||
break; | |||
case COMMAND_DISP_DATA: | |||
ProcessMemReadCommand(); | |||
break; | |||
case COMMAND_WRITE: | |||
ProcessWriteCommand(); | |||
break; | |||
case COMMAND_READ: | |||
ProcessReadCommand(); | |||
break; | |||
case COMMAND_CHANGE_BASE_ADDR: | |||
if (IS_TWOBYTE_COMMAND(SentCommand.Data, 0x03, 0x00)) // Set 64KB flash page command | |||
Flash64KBPage = SentCommand.Data[2]; | |||
break; | |||
} | |||
} | |||
/** Routine to concatenate the given pair of 16-bit memory start and end addresses from the host, and store them | |||
* in the StartAddr and EndAddr global variables. | |||
*/ | |||
static void LoadStartEndAddresses(void) | |||
{ | |||
union | |||
{ | |||
uint8_t Bytes[2]; | |||
uint16_t Word; | |||
} Address[2] = {{.Bytes = {SentCommand.Data[2], SentCommand.Data[1]}}, | |||
{.Bytes = {SentCommand.Data[4], SentCommand.Data[3]}}}; | |||
/* Load in the start and ending read addresses from the sent data packet */ | |||
StartAddr = Address[0].Word; | |||
EndAddr = Address[1].Word; | |||
} | |||
/** Handler for a Memory Program command issued by the host. This routine handles the preparations needed | |||
* to write subsequent data from the host into the specified memory. | |||
*/ | |||
static void ProcessMemProgCommand(void) | |||
{ | |||
if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x00) || // Write FLASH command | |||
IS_ONEBYTE_COMMAND(SentCommand.Data, 0x01)) // Write EEPROM command | |||
{ | |||
/* Load in the start and ending read addresses */ | |||
LoadStartEndAddresses(); | |||
/* If FLASH is being written to, we need to pre-erase the first page to write to */ | |||
if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x00)) | |||
{ | |||
union | |||
{ | |||
uint16_t Words[2]; | |||
uint32_t Long; | |||
} CurrFlashAddress = {.Words = {StartAddr, Flash64KBPage}}; | |||
/* Erase the current page's temp buffer */ | |||
boot_page_erase(CurrFlashAddress.Long); | |||
boot_spm_busy_wait(); | |||
} | |||
/* Set the state so that the next DNLOAD requests reads in the firmware */ | |||
DFU_State = dfuDNLOAD_IDLE; | |||
} | |||
} | |||
/** Handler for a Memory Read command issued by the host. This routine handles the preparations needed | |||
* to read subsequent data from the specified memory out to the host, as well as implementing the memory | |||
* blank check command. | |||
*/ | |||
static void ProcessMemReadCommand(void) | |||
{ | |||
if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x00) || // Read FLASH command | |||
IS_ONEBYTE_COMMAND(SentCommand.Data, 0x02)) // Read EEPROM command | |||
{ | |||
/* Load in the start and ending read addresses */ | |||
LoadStartEndAddresses(); | |||
/* Set the state so that the next UPLOAD requests read out the firmware */ | |||
DFU_State = dfuUPLOAD_IDLE; | |||
} | |||
else if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x01)) // Blank check FLASH command | |||
{ | |||
uint32_t CurrFlashAddress = 0; | |||
while (CurrFlashAddress < (uint32_t)BOOT_START_ADDR) | |||
{ | |||
/* Check if the current byte is not blank */ | |||
#if (FLASHEND > 0xFFFF) | |||
if (pgm_read_byte_far(CurrFlashAddress) != 0xFF) | |||
#else | |||
if (pgm_read_byte(CurrFlashAddress) != 0xFF) | |||
#endif | |||
{ | |||
/* Save the location of the first non-blank byte for response back to the host */ | |||
Flash64KBPage = (CurrFlashAddress >> 16); | |||
StartAddr = CurrFlashAddress; | |||
/* Set state and status variables to the appropriate error values */ | |||
DFU_State = dfuERROR; | |||
DFU_Status = errCHECK_ERASED; | |||
break; | |||
} | |||
CurrFlashAddress++; | |||
} | |||
} | |||
} | |||
/** Handler for a Data Write command issued by the host. This routine handles non-programming commands such as | |||
* bootloader exit (both via software jumps and hardware watchdog resets) and flash memory erasure. | |||
*/ | |||
static void ProcessWriteCommand(void) | |||
{ | |||
if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x03)) // Start application | |||
{ | |||
/* Indicate that the bootloader is terminating */ | |||
WaitForExit = true; | |||
/* Check if data supplied for the Start Program command - no data executes the program */ | |||
if (SentCommand.DataSize) | |||
{ | |||
if (SentCommand.Data[1] == 0x01) // Start via jump | |||
{ | |||
union | |||
{ | |||
uint8_t Bytes[2]; | |||
AppPtr_t FuncPtr; | |||
} Address = {.Bytes = {SentCommand.Data[4], SentCommand.Data[3]}}; | |||
/* Load in the jump address into the application start address pointer */ | |||
AppStartPtr = Address.FuncPtr; | |||
} | |||
} | |||
else | |||
{ | |||
if (SentCommand.Data[1] == 0x00) // Start via watchdog | |||
{ | |||
/* Unlock the forced application start mode of the bootloader if it is restarted */ | |||
MagicBootKey = MAGIC_BOOT_KEY; | |||
/* Start the watchdog to reset the AVR once the communications are finalized */ | |||
wdt_enable(WDTO_250MS); | |||
} | |||
else // Start via jump | |||
{ | |||
/* Set the flag to terminate the bootloader at next opportunity */ | |||
RunBootloader = false; | |||
} | |||
} | |||
} | |||
else if (IS_TWOBYTE_COMMAND(SentCommand.Data, 0x00, 0xFF)) // Erase flash | |||
{ | |||
uint32_t CurrFlashAddress = 0; | |||
/* Clear the application section of flash */ | |||
while (CurrFlashAddress < (uint32_t)BOOT_START_ADDR) | |||
{ | |||
boot_page_erase(CurrFlashAddress); | |||
boot_spm_busy_wait(); | |||
boot_page_write(CurrFlashAddress); | |||
boot_spm_busy_wait(); | |||
CurrFlashAddress += SPM_PAGESIZE; | |||
} | |||
/* Re-enable the RWW section of flash as writing to the flash locks it out */ | |||
boot_rww_enable(); | |||
/* Memory has been erased, reset the security bit so that programming/reading is allowed */ | |||
IsSecure = false; | |||
} | |||
} | |||
/** Handler for a Data Read command issued by the host. This routine handles bootloader information retrieval | |||
* commands such as device signature and bootloader version retrieval. | |||
*/ | |||
static void ProcessReadCommand(void) | |||
{ | |||
const uint8_t BootloaderInfo[3] = {BOOTLOADER_VERSION, BOOTLOADER_ID_BYTE1, BOOTLOADER_ID_BYTE2}; | |||
const uint8_t SignatureInfo[4] = {0x58, AVR_SIGNATURE_1, AVR_SIGNATURE_2, AVR_SIGNATURE_3}; | |||
uint8_t DataIndexToRead = SentCommand.Data[1]; | |||
if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x00)) // Read bootloader info | |||
{ | |||
ResponseByte = BootloaderInfo[DataIndexToRead]; | |||
} | |||
else if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x01)) // Read signature byte | |||
{ | |||
if (DataIndexToRead < 0x60) | |||
ResponseByte = SignatureInfo[DataIndexToRead - 0x30]; | |||
else | |||
ResponseByte = SignatureInfo[DataIndexToRead - 0x60 + 3]; | |||
} | |||
} | |||
@@ -0,0 +1,216 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Header file for BootloaderDFU.c. | |||
*/ | |||
#ifndef _BOOTLOADER_H_ | |||
#define _BOOTLOADER_H_ | |||
/* Includes: */ | |||
#include <avr/io.h> | |||
#include <avr/wdt.h> | |||
#include <avr/boot.h> | |||
#include <avr/pgmspace.h> | |||
#include <avr/eeprom.h> | |||
#include <avr/power.h> | |||
#include <avr/interrupt.h> | |||
#include <util/delay.h> | |||
#include <stdbool.h> | |||
#include "Descriptors.h" | |||
#include "BootloaderAPI.h" | |||
#include "Config/AppConfig.h" | |||
#include <LUFA/Drivers/USB/USB.h> | |||
#include <LUFA/Drivers/Board/LEDs.h> | |||
#include <LUFA/Platform/Platform.h> | |||
/* Preprocessor Checks: */ | |||
#if !defined(__OPTIMIZE_SIZE__) | |||
#error This bootloader requires that it be optimized for size, not speed, to fit into the target device. Change optimization settings and try again. | |||
#endif | |||
/* Macros: */ | |||
/** Major bootloader version number. */ | |||
#define BOOTLOADER_VERSION_MINOR 2 | |||
/** Minor bootloader version number. */ | |||
#define BOOTLOADER_VERSION_REV 0 | |||
/** Magic bootloader key to unlock forced application start mode. */ | |||
#define MAGIC_BOOT_KEY 0xDC42 | |||
/** Complete bootloader version number expressed as a packed byte, constructed from the | |||
* two individual bootloader version macros. | |||
*/ | |||
#define BOOTLOADER_VERSION ((BOOTLOADER_VERSION_MINOR << 4) | BOOTLOADER_VERSION_REV) | |||
/** First byte of the bootloader identification bytes, used to identify a device's bootloader. */ | |||
#define BOOTLOADER_ID_BYTE1 0xDC | |||
/** Second byte of the bootloader identification bytes, used to identify a device's bootloader. */ | |||
#define BOOTLOADER_ID_BYTE2 0xFB | |||
/** Convenience macro, used to determine if the issued command is the given one-byte long command. | |||
* | |||
* \param[in] dataarr Command byte array to check against | |||
* \param[in] cb1 First command byte to check | |||
*/ | |||
#define IS_ONEBYTE_COMMAND(dataarr, cb1) (dataarr[0] == (cb1)) | |||
/** Convenience macro, used to determine if the issued command is the given two-byte long command. | |||
* | |||
* \param[in] dataarr Command byte array to check against | |||
* \param[in] cb1 First command byte to check | |||
* \param[in] cb2 Second command byte to check | |||
*/ | |||
#define IS_TWOBYTE_COMMAND(dataarr, cb1, cb2) ((dataarr[0] == (cb1)) && (dataarr[1] == (cb2))) | |||
/** Length of the DFU file suffix block, appended to the end of each complete memory write command. | |||
* The DFU file suffix is currently unused (but is designed to give extra file information, such as | |||
* a CRC of the complete firmware for error checking) and so is discarded. | |||
*/ | |||
#define DFU_FILE_SUFFIX_SIZE 16 | |||
/** Length of the DFU file filler block, appended to the start of each complete memory write command. | |||
* Filler bytes are added to the start of each complete memory write command, and must be discarded. | |||
*/ | |||
#define DFU_FILLER_BYTES_SIZE 26 | |||
/** DFU class command request to detach from the host. */ | |||
#define DFU_REQ_DETATCH 0x00 | |||
/** DFU class command request to send data from the host to the bootloader. */ | |||
#define DFU_REQ_DNLOAD 0x01 | |||
/** DFU class command request to send data from the bootloader to the host. */ | |||
#define DFU_REQ_UPLOAD 0x02 | |||
/** DFU class command request to get the current DFU status and state from the bootloader. */ | |||
#define DFU_REQ_GETSTATUS 0x03 | |||
/** DFU class command request to reset the current DFU status and state variables to their defaults. */ | |||
#define DFU_REQ_CLRSTATUS 0x04 | |||
/** DFU class command request to get the current DFU state of the bootloader. */ | |||
#define DFU_REQ_GETSTATE 0x05 | |||
/** DFU class command request to abort the current multi-request transfer and return to the dfuIDLE state. */ | |||
#define DFU_REQ_ABORT 0x06 | |||
/** DFU command to begin programming the device's memory. */ | |||
#define COMMAND_PROG_START 0x01 | |||
/** DFU command to begin reading the device's memory. */ | |||
#define COMMAND_DISP_DATA 0x03 | |||
/** DFU command to issue a write command. */ | |||
#define COMMAND_WRITE 0x04 | |||
/** DFU command to issue a read command. */ | |||
#define COMMAND_READ 0x05 | |||
/** DFU command to issue a memory base address change command, to set the current 64KB flash page | |||
* that subsequent flash operations should use. */ | |||
#define COMMAND_CHANGE_BASE_ADDR 0x06 | |||
/* Type Defines: */ | |||
/** Type define for a non-returning function pointer to the loaded application. */ | |||
typedef void (*AppPtr_t)(void) ATTR_NO_RETURN; | |||
/** Type define for a structure containing a complete DFU command issued by the host. */ | |||
typedef struct | |||
{ | |||
uint8_t Command; /**< Single byte command to perform, one of the \c COMMAND_* macro values */ | |||
uint8_t Data[5]; /**< Command parameters */ | |||
uint16_t DataSize; /**< Size of the command parameters */ | |||
} DFU_Command_t; | |||
/* Enums: */ | |||
/** DFU bootloader states. Refer to the DFU class specification for information on each state. */ | |||
enum DFU_State_t | |||
{ | |||
appIDLE = 0, | |||
appDETACH = 1, | |||
dfuIDLE = 2, | |||
dfuDNLOAD_SYNC = 3, | |||
dfuDNBUSY = 4, | |||
dfuDNLOAD_IDLE = 5, | |||
dfuMANIFEST_SYNC = 6, | |||
dfuMANIFEST = 7, | |||
dfuMANIFEST_WAIT_RESET = 8, | |||
dfuUPLOAD_IDLE = 9, | |||
dfuERROR = 10 | |||
}; | |||
/** DFU command status error codes. Refer to the DFU class specification for information on each error code. */ | |||
enum DFU_Status_t | |||
{ | |||
OK = 0, | |||
errTARGET = 1, | |||
errFILE = 2, | |||
errWRITE = 3, | |||
errERASE = 4, | |||
errCHECK_ERASED = 5, | |||
errPROG = 6, | |||
errVERIFY = 7, | |||
errADDRESS = 8, | |||
errNOTDONE = 9, | |||
errFIRMWARE = 10, | |||
errVENDOR = 11, | |||
errUSBR = 12, | |||
errPOR = 13, | |||
errUNKNOWN = 14, | |||
errSTALLEDPKT = 15 | |||
}; | |||
/* Function Prototypes: */ | |||
static void SetupHardware(void); | |||
static void ResetHardware(void); | |||
void EVENT_USB_Device_ControlRequest(void); | |||
#if defined(INCLUDE_FROM_BOOTLOADER_C) | |||
static void DiscardFillerBytes(uint8_t NumberOfBytes); | |||
static void ProcessBootloaderCommand(void); | |||
static void LoadStartEndAddresses(void); | |||
static void ProcessMemProgCommand(void); | |||
static void ProcessMemReadCommand(void); | |||
static void ProcessWriteCommand(void); | |||
static void ProcessReadCommand(void); | |||
#endif | |||
void Application_Jump_Check(void) ATTR_INIT_SECTION(3); | |||
#endif | |||
@@ -0,0 +1,233 @@ | |||
/** \file | |||
* | |||
* This file contains special DoxyGen information for the generation of the main page and other special | |||
* documentation pages. It is not a project source file. | |||
*/ | |||
/** \mainpage DFU Class USB AVR Bootloader | |||
* | |||
* \section Sec_Compat Demo Compatibility: | |||
* | |||
* The following list indicates what microcontrollers are compatible with this demo. | |||
* | |||
* \li Series 7 USB AVRs (AT90USBxxx7) | |||
* \li Series 6 USB AVRs (AT90USBxxx6) | |||
* \li Series 4 USB AVRs (ATMEGAxxU4) - <i>See \ref SSec_Aux_Space</i> | |||
* \li Series 2 USB AVRs (AT90USBxx2, ATMEGAxxU2) - <i>See \ref SSec_Aux_Space</i> | |||
* | |||
* \section Sec_Info USB Information: | |||
* | |||
* The following table gives a rundown of the USB utilization of this demo. | |||
* | |||
* <table> | |||
* <tr> | |||
* <td><b>USB Mode:</b></td> | |||
* <td>Device</td> | |||
* </tr> | |||
* <tr> | |||
* <td><b>USB Class:</b></td> | |||
* <td>Device Firmware Update Class (DFU)</td> | |||
* </tr> | |||
* <tr> | |||
* <td><b>USB Subclass:</b></td> | |||
* <td>None</td> | |||
* </tr> | |||
* <tr> | |||
* <td><b>Relevant Standards:</b></td> | |||
* <td>USBIF DFU Class Standard, Atmel USB Bootloader Datasheet</td> | |||
* </tr> | |||
* <tr> | |||
* <td><b>Supported USB Speeds:</b></td> | |||
* <td>Low Speed Mode \n | |||
* Full Speed Mode</td> | |||
* </tr> | |||
* </table> | |||
* | |||
* \section Sec_Description Project Description: | |||
* | |||
* This bootloader enumerates to the host as a DFU Class device, allowing for DFU-compatible programming | |||
* software to load firmware onto the AVR. | |||
* | |||
* Out of the box this bootloader builds for the AT90USB1287 with an 8KB bootloader section size, and will fit | |||
* into 4KB of bootloader space. If you wish to alter this size and/or change the AVR model, you will need to | |||
* edit the MCU, FLASH_SIZE_KB and BOOT_SECTION_SIZE_KB values in the accompanying makefile. | |||
* | |||
* When the bootloader is running, the board's LED(s) will flash at regular intervals to distinguish the | |||
* bootloader from the normal user application. | |||
* | |||
* \section Sec_Running Running the Bootloader | |||
* | |||
* This bootloader is designed to be started via the HWB mechanism of the USB AVRs; ground the HWB pin (see device | |||
* datasheet) then momentarily ground /RESET to start the bootloader. This assumes the HWBE fuse is set and the BOOTRST | |||
* fuse is cleared. | |||
* | |||
* For board specific exceptions to the above, see below. | |||
* | |||
* \subsection SSec_XPLAIN Atmel Xplain Board | |||
* Ground the USB AVR JTAG's \c TCK pin to ground when powering on the board to start the bootloader. This assumes the | |||
* \c HWBE fuse is cleared and the \c BOOTRST fuse is set as the HWBE pin is not user accessible on this board. | |||
* | |||
* \subsection SSec_Leonardo Arduino Leonardo Board | |||
* Ground \c IO13 when powering the board to start the bootloader. This assumes the \c HWBE fuse is cleared and the | |||
* \c BOOTRST fuse is set as the HWBE pin is not user accessible on this board. | |||
* | |||
* \section Sec_Installation Driver Installation | |||
* | |||
* This bootloader is designed to be compatible with Atmel's provided Windows DFU class drivers. You will need to | |||
* install Atmel's DFU drivers prior to using this bootloader on Windows platforms. If you are using a 64 bit Windows | |||
* OS, you will need to either disable the driver signing requirement (see online tutorials for details) or use a | |||
* digitally signed version of the official Atmel driver provided by a third party AVR user at | |||
* <a>http://www.avrfreaks.net/index.php?module=Freaks%20Academy&func=viewItem&item_id=2196&item_type=project</a>. | |||
* | |||
* \note This device spoofs Atmel's DFU Bootloader USB VID and PID so that the Atmel DFU bootloader | |||
* drivers included with FLIP will work. If you do not wish to use Atmel's ID codes, please | |||
* manually change them in Descriptors.c and alter your driver's INF file accordingly. | |||
* | |||
* \section Sec_HostApp Host Controller Application | |||
* | |||
* This bootloader is compatible with Atmel's FLIP utility on Windows machines, and dfu-programmer on Linux machines. | |||
* | |||
* \subsection SSec_FLIP FLIP (Windows) | |||
* | |||
* FLIP (Flexible In-System Programmer) is a utility written by Atmel, and distributed for free on the Atmel website. | |||
* The FLIP utility is designed to assist in the bootloader programming of a range of Atmel devices, through several | |||
* popular physical interfaces including USB. It is written in Java, however makes use of native extensions for USB | |||
* support and thus is only offered on Windows. | |||
* | |||
* To program a device using FLIP, refer to the Atmel FLIP documentation. | |||
* | |||
* \subsection SSec_DFUProgrammer dfu-programmer (Linux) | |||
* | |||
* dfu-programmer is an open-source command line solution for the bootloader programming of Atmel devices through a | |||
* USB connection, using the DFU protocol, available for download at <a>http://sourceforge.net/projects/dfu-programmer/</a>. | |||
* | |||
* The following example loads a HEX file into the AVR's FLASH memory using dfu-programmer: | |||
* \code | |||
* dfu-programmer at90usb1287 erase flash Mouse.hex | |||
* \endcode | |||
* | |||
* \section Sec_API User Application API | |||
* | |||
* Several user application functions for FLASH and other special memory area manipulations are exposed by the bootloader, | |||
* allowing the user application to call into the bootloader at runtime to read and write FLASH data. | |||
* | |||
* \warning The APIs exposed by the DFU class bootloader are \b NOT compatible with the API exposed by the official Atmel DFU bootloader. | |||
* | |||
* By default, the bootloader API jump table is located 32 bytes from the end of the device's FLASH memory, and follows the | |||
* following layout: | |||
* | |||
* \code | |||
* #define BOOTLOADER_API_TABLE_SIZE 32 | |||
* #define BOOTLOADER_API_TABLE_START ((FLASHEND + 1UL) - BOOTLOADER_API_TABLE_SIZE) | |||
* #define BOOTLOADER_API_CALL(Index) (void*)((BOOTLOADER_API_TABLE_START + (Index * 2)) / 2) | |||
* | |||
* void (*BootloaderAPI_ErasePage)(uint32_t Address) = BOOTLOADER_API_CALL(0); | |||
* void (*BootloaderAPI_WritePage)(uint32_t Address) = BOOTLOADER_API_CALL(1); | |||
* void (*BootloaderAPI_FillWord)(uint32_t Address, uint16_t Word) = BOOTLOADER_API_CALL(2); | |||
* uint8_t (*BootloaderAPI_ReadSignature)(uint16_t Address) = BOOTLOADER_API_CALL(3); | |||
* uint8_t (*BootloaderAPI_ReadFuse)(uint16_t Address) = BOOTLOADER_API_CALL(4); | |||
* uint8_t (*BootloaderAPI_ReadLock)(void) = BOOTLOADER_API_CALL(5); | |||
* void (*BootloaderAPI_WriteLock)(uint8_t LockBits) = BOOTLOADER_API_CALL(6); | |||
* | |||
* #define BOOTLOADER_MAGIC_SIGNATURE_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 2)) | |||
* #define BOOTLOADER_MAGIC_SIGNATURE 0xDCFB | |||
* | |||
* #define BOOTLOADER_CLASS_SIGNATURE_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 4)) | |||
* #define BOOTLOADER_DFU_SIGNATURE 0xDF10 | |||
* | |||
* #define BOOTLOADER_ADDRESS_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 8)) | |||
* #define BOOTLOADER_ADDRESS_LENGTH 4 | |||
* \endcode | |||
* | |||
* From the application the API support of the bootloader can be detected by reading the FLASH memory bytes located at address | |||
* \c BOOTLOADER_MAGIC_SIGNATURE_START and comparing them to the value \c BOOTLOADER_MAGIC_SIGNATURE. The class of bootloader | |||
* can be determined by reading the FLASH memory bytes located at address \c BOOTLOADER_CLASS_SIGNATURE_START and comparing them | |||
* to the value \c BOOTLOADER_DFU_SIGNATURE. The start address of the bootloader can be retrieved by reading the bytes of FLASH | |||
* memory starting from address \c BOOTLOADER_ADDRESS_START. | |||
* | |||
* \subsection SSec_API_MemLayout Device Memory Map | |||
* The following illustration indicates the final memory map of the device when loaded with the bootloader. | |||
* | |||
* \verbatim | |||
* +----------------------------+ 0x0000 | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | User Application | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* +----------------------------+ FLASHEND - BOOT_AUX_SECTION_SIZE | |||
* | Booloader Start Trampoline | | |||
* | (Not User App. Accessible) | | |||
* +----------------------------+ FLASHEND - (BOOT_AUX_SECTION_SIZE - 4) | |||
* | | | |||
* | Auxillery Bootloader | | |||
* | Space for Smaller Devices | | |||
* | (Not User App. Accessible) | | |||
* | | | |||
* +----------------------------+ FLASHEND - BOOT_SECTION_SIZE | |||
* | | | |||
* | Bootloader Application | | |||
* | (Not User App. Accessible) | | |||
* | | | |||
* +----------------------------+ FLASHEND - 96 | |||
* | API Table Trampolines | | |||
* | (Not User App. Accessible) | | |||
* +----------------------------+ FLASHEND - 32 | |||
* | Bootloader API Table | | |||
* | (User App. Accessible) | | |||
* +----------------------------+ FLASHEND - 8 | |||
* | Bootloader ID Constants | | |||
* | (User App. Accessible) | | |||
* +----------------------------+ FLASHEND | |||
* \endverbatim | |||
* | |||
* \subsection SSec_Aux_Space Auxiliary Bootloader Section | |||
* To make the bootloader function on smaller devices (those with a physical | |||
* bootloader section of smaller than 6KB) | |||
* | |||
* \section Sec_KnownIssues Known Issues: | |||
* | |||
* \par On Linux machines, the DFU bootloader is inaccessible. | |||
* On many Linux systems, non-root users do not have automatic access to newly | |||
* inserted DFU devices. Root privileges or a UDEV rule is required to gain | |||
* access. | |||
* See <a href=https://groups.google.com/d/msg/lufa-support/CP9cy2bc8yo/kBqsOu-RBeMJ>here</a> for resolution steps. | |||
* | |||
* \par After loading an application, it is not run automatically on startup. | |||
* Some USB AVR boards ship with the BOOTRST fuse set, causing the bootloader | |||
* to run automatically when the device is reset. In most cases, the BOOTRST | |||
* fuse should be disabled and the HWBE fuse used instead to run the bootloader | |||
* when needed. | |||
* | |||
* \section Sec_Options Project Options | |||
* | |||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value. | |||
* | |||
* <table> | |||
* <tr> | |||
* <th><b>Define Name:</b></th> | |||
* <th><b>Location:</b></th> | |||
* <th><b>Description:</b></th> | |||
* </tr> | |||
* <tr> | |||
* <td>SECURE_MODE</td> | |||
* <td>AppConfig.h</td> | |||
* <td>If defined to \c true, the bootloader will not accept any memory commands other than a chip erase on start-up, until an | |||
* erase has been performed. This can be used in conjunction with the AVR's lockbits to prevent the AVRs firmware from | |||
* being dumped by unauthorized persons. When false, all memory operations are allowed at any time.</td> | |||
* </tr> | |||
* </table> | |||
*/ | |||
@@ -0,0 +1,48 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* \brief Application Configuration Header File | |||
* | |||
* This is a header file which is be used to configure some of | |||
* the application's compile time options, as an alternative to | |||
* specifying the compile time constants supplied through a | |||
* makefile or build system. | |||
* | |||
* For information on what each token does, refer to the | |||
* \ref Sec_Options section of the application documentation. | |||
*/ | |||
#ifndef _APP_CONFIG_H_ | |||
#define _APP_CONFIG_H_ | |||
#define SECURE_MODE false | |||
#endif |
@@ -0,0 +1,93 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* \brief LUFA Library Configuration Header File | |||
* | |||
* This header file is used to configure LUFA's compile time options, | |||
* as an alternative to the compile time constants supplied through | |||
* a makefile. | |||
* | |||
* For information on what each token does, refer to the LUFA | |||
* manual section "Summary of Compile Tokens". | |||
*/ | |||
#ifndef _LUFA_CONFIG_H_ | |||
#define _LUFA_CONFIG_H_ | |||
#if (ARCH == ARCH_AVR8) | |||
/* Non-USB Related Configuration Tokens: */ | |||
// #define DISABLE_TERMINAL_CODES | |||
/* USB Class Driver Related Tokens: */ | |||
// #define HID_HOST_BOOT_PROTOCOL_ONLY | |||
// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here} | |||
// #define HID_USAGE_STACK_DEPTH {Insert Value Here} | |||
// #define HID_MAX_COLLECTIONS {Insert Value Here} | |||
// #define HID_MAX_REPORTITEMS {Insert Value Here} | |||
// #define HID_MAX_REPORT_IDS {Insert Value Here} | |||
// #define NO_CLASS_DRIVER_AUTOFLUSH | |||
/* General USB Driver Related Tokens: */ | |||
// #define ORDERED_EP_CONFIG | |||
#define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL) | |||
#define USB_DEVICE_ONLY | |||
// #define USB_HOST_ONLY | |||
// #define USB_STREAM_TIMEOUT_MS {Insert Value Here} | |||
// #define NO_LIMITED_CONTROLLER_CONNECT | |||
#define NO_SOF_EVENTS | |||
/* USB Device Mode Driver Related Tokens: */ | |||
#define USE_RAM_DESCRIPTORS | |||
// #define USE_FLASH_DESCRIPTORS | |||
// #define USE_EEPROM_DESCRIPTORS | |||
#define NO_INTERNAL_SERIAL | |||
#define FIXED_CONTROL_ENDPOINT_SIZE 32 | |||
#define DEVICE_STATE_AS_GPIOR 0 | |||
#define FIXED_NUM_CONFIGURATIONS 1 | |||
#define CONTROL_ONLY_DEVICE | |||
// #define INTERRUPT_CONTROL_ENDPOINT | |||
#define NO_DEVICE_REMOTE_WAKEUP | |||
#define NO_DEVICE_SELF_POWER | |||
/* USB Host Mode Driver Related Tokens: */ | |||
// #define HOST_STATE_AS_GPIOR {Insert Value Here} | |||
// #define USB_HOST_TIMEOUT_MS {Insert Value Here} | |||
// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here} | |||
// #define NO_AUTO_VBUS_MANAGEMENT | |||
// #define INVERTED_VBUS_ENABLE_LINE | |||
#else | |||
#error Unsupported architecture for this LUFA configuration file. | |||
#endif | |||
#endif |
@@ -0,0 +1,185 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special | |||
* computer-readable structures which the host requests upon device enumeration, to determine | |||
* the device's capabilities and functions. | |||
*/ | |||
#include "Descriptors.h" | |||
/** Device descriptor structure. This descriptor, located in SRAM memory, describes the overall | |||
* device characteristics, including the supported USB version, control endpoint size and the | |||
* number of device configurations. The descriptor is read out by the USB host when the enumeration | |||
* process begins. | |||
*/ | |||
const USB_Descriptor_Device_t DeviceDescriptor = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, | |||
.USBSpecification = VERSION_BCD(1,1,0), | |||
.Class = USB_CSCP_NoDeviceClass, | |||
.SubClass = USB_CSCP_NoDeviceSubclass, | |||
.Protocol = USB_CSCP_NoDeviceProtocol, | |||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, | |||
.VendorID = 0x03EB, | |||
.ProductID = PRODUCT_ID_CODE, | |||
.ReleaseNumber = VERSION_BCD(0,0,0), | |||
.ManufacturerStrIndex = STRING_ID_Manufacturer, | |||
.ProductStrIndex = STRING_ID_Product, | |||
.SerialNumStrIndex = NO_DESCRIPTOR, | |||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS | |||
}; | |||
/** Configuration descriptor structure. This descriptor, located in SRAM memory, describes the usage | |||
* of the device in one of its supported configurations, including information about any device interfaces | |||
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting | |||
* a configuration so that the host may correctly communicate with the USB device. | |||
*/ | |||
const USB_Descriptor_Configuration_t ConfigurationDescriptor = | |||
{ | |||
.Config = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, | |||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), | |||
.TotalInterfaces = 1, | |||
.ConfigurationNumber = 1, | |||
.ConfigurationStrIndex = NO_DESCRIPTOR, | |||
.ConfigAttributes = USB_CONFIG_ATTR_RESERVED, | |||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100) | |||
}, | |||
.DFU_Interface = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, | |||
.InterfaceNumber = INTERFACE_ID_DFU, | |||
.AlternateSetting = 0, | |||
.TotalEndpoints = 0, | |||
.Class = 0xFE, | |||
.SubClass = 0x01, | |||
.Protocol = 0x02, | |||
.InterfaceStrIndex = NO_DESCRIPTOR | |||
}, | |||
.DFU_Functional = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_DFU_Functional_t), .Type = DTYPE_DFUFunctional}, | |||
.Attributes = (ATTR_CAN_UPLOAD | ATTR_CAN_DOWNLOAD), | |||
.DetachTimeout = 0x0000, | |||
.TransferSize = 0x0C00, | |||
.DFUSpecification = VERSION_BCD(1,1,0) | |||
} | |||
}; | |||
/** Language descriptor structure. This descriptor, located in SRAM memory, is returned when the host requests | |||
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate | |||
* via the language ID table available at USB.org what languages the device supports for its string descriptors. | |||
*/ | |||
const USB_Descriptor_String_t LanguageString = USB_STRING_DESCRIPTOR_ARRAY(LANGUAGE_ID_ENG); | |||
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable | |||
* form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device | |||
* Descriptor. | |||
*/ | |||
const USB_Descriptor_String_t ManufacturerString = USB_STRING_DESCRIPTOR(L"Dean Camera"); | |||
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form, | |||
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device | |||
* Descriptor. | |||
*/ | |||
const USB_Descriptor_String_t ProductString = USB_STRING_DESCRIPTOR(L"LUFA DFU"); | |||
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" | |||
* documentation) by the application code so that the address and size of a requested descriptor can be given | |||
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function | |||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the | |||
* USB host. | |||
*/ | |||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, | |||
const uint8_t wIndex, | |||
const void** const DescriptorAddress) | |||
{ | |||
const uint8_t DescriptorType = (wValue >> 8); | |||
const uint8_t DescriptorNumber = (wValue & 0xFF); | |||
const void* Address = NULL; | |||
uint16_t Size = NO_DESCRIPTOR; | |||
switch (DescriptorType) | |||
{ | |||
case DTYPE_Device: | |||
Address = &DeviceDescriptor; | |||
Size = sizeof(USB_Descriptor_Device_t); | |||
break; | |||
case DTYPE_Configuration: | |||
Address = &ConfigurationDescriptor; | |||
Size = sizeof(USB_Descriptor_Configuration_t); | |||
break; | |||
case DTYPE_String: | |||
if (DescriptorNumber == STRING_ID_Language) | |||
{ | |||
Address = &LanguageString; | |||
Size = LanguageString.Header.Size; | |||
} | |||
else if (DescriptorNumber == STRING_ID_Manufacturer) | |||
{ | |||
Address = &ManufacturerString; | |||
Size = ManufacturerString.Header.Size; | |||
} | |||
else if (DescriptorNumber == STRING_ID_Product) | |||
{ | |||
Address = &ProductString; | |||
Size = ProductString.Header.Size; | |||
} | |||
break; | |||
} | |||
*DescriptorAddress = Address; | |||
return Size; | |||
} | |||
@@ -0,0 +1,194 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Header file for Descriptors.c. | |||
*/ | |||
#ifndef _DESCRIPTORS_H_ | |||
#define _DESCRIPTORS_H_ | |||
/* Includes: */ | |||
#include <LUFA/Drivers/USB/USB.h> | |||
#include "Config/AppConfig.h" | |||
/* Macros: */ | |||
/** Descriptor type value for a DFU class functional descriptor. */ | |||
#define DTYPE_DFUFunctional 0x21 | |||
/** DFU attribute mask, indicating that the DFU device will detach and re-attach when a DFU_DETACH | |||
* command is issued, rather than the host issuing a USB Reset. | |||
*/ | |||
#define ATTR_WILL_DETATCH (1 << 3) | |||
/** DFU attribute mask, indicating that the DFU device can communicate during the manifestation phase | |||
* (memory programming phase). | |||
*/ | |||
#define ATTR_MANEFESTATION_TOLLERANT (1 << 2) | |||
/** DFU attribute mask, indicating that the DFU device can accept DFU_UPLOAD requests to send data from | |||
* the device to the host. | |||
*/ | |||
#define ATTR_CAN_UPLOAD (1 << 1) | |||
/** DFU attribute mask, indicating that the DFU device can accept DFU_DNLOAD requests to send data from | |||
* the host to the device. | |||
*/ | |||
#define ATTR_CAN_DOWNLOAD (1 << 0) | |||
#if defined(__AVR_AT90USB1287__) | |||
#define PRODUCT_ID_CODE 0x2FFB | |||
#define AVR_SIGNATURE_1 0x1E | |||
#define AVR_SIGNATURE_2 0x97 | |||
#define AVR_SIGNATURE_3 0x82 | |||
#elif defined(__AVR_AT90USB647__) | |||
#define PRODUCT_ID_CODE 0x2FF9 | |||
#define AVR_SIGNATURE_1 0x1E | |||
#define AVR_SIGNATURE_2 0x96 | |||
#define AVR_SIGNATURE_3 0x82 | |||
#elif defined(__AVR_AT90USB1286__) | |||
#define PRODUCT_ID_CODE 0x2FFB | |||
#define AVR_SIGNATURE_1 0x1E | |||
#define AVR_SIGNATURE_2 0x97 | |||
#define AVR_SIGNATURE_3 0x82 | |||
#elif defined(__AVR_AT90USB646__) | |||
#define PRODUCT_ID_CODE 0x2FF9 | |||
#define AVR_SIGNATURE_1 0x1E | |||
#define AVR_SIGNATURE_2 0x96 | |||
#define AVR_SIGNATURE_3 0x82 | |||
#elif defined(__AVR_ATmega32U4__) | |||
#define PRODUCT_ID_CODE 0x2FF4 | |||
#define AVR_SIGNATURE_1 0x1E | |||
#define AVR_SIGNATURE_2 0x95 | |||
#define AVR_SIGNATURE_3 0x87 | |||
#elif defined(__AVR_ATmega16U4__) | |||
#define PRODUCT_ID_CODE 0x2FF3 | |||
#define AVR_SIGNATURE_1 0x1E | |||
#define AVR_SIGNATURE_2 0x94 | |||
#define AVR_SIGNATURE_3 0x88 | |||
#elif defined(__AVR_ATmega32U2__) | |||
#define PRODUCT_ID_CODE 0x2FF0 | |||
#define AVR_SIGNATURE_1 0x1E | |||
#define AVR_SIGNATURE_2 0x95 | |||
#define AVR_SIGNATURE_3 0x8A | |||
#elif defined(__AVR_ATmega16U2__) | |||
#define PRODUCT_ID_CODE 0x2FEF | |||
#define AVR_SIGNATURE_1 0x1E | |||
#define AVR_SIGNATURE_2 0x94 | |||
#define AVR_SIGNATURE_3 0x89 | |||
#elif defined(__AVR_AT90USB162__) | |||
#define PRODUCT_ID_CODE 0x2FFA | |||
#define AVR_SIGNATURE_1 0x1E | |||
#define AVR_SIGNATURE_2 0x94 | |||
#define AVR_SIGNATURE_3 0x82 | |||
#elif defined(__AVR_ATmega8U2__) | |||
#define PRODUCT_ID_CODE 0x2FEE | |||
#define AVR_SIGNATURE_1 0x1E | |||
#define AVR_SIGNATURE_2 0x93 | |||
#define AVR_SIGNATURE_3 0x89 | |||
#elif defined(__AVR_AT90USB82__) | |||
#define PRODUCT_ID_CODE 0x2FF7 | |||
#define AVR_SIGNATURE_1 0x1E | |||
#define AVR_SIGNATURE_2 0x94 | |||
#define AVR_SIGNATURE_3 0x82 | |||
#else | |||
#error The selected AVR part is not currently supported by this bootloader. | |||
#endif | |||
#if !defined(PRODUCT_ID_CODE) | |||
#error Current AVR model is not supported by this bootloader. | |||
#endif | |||
/* Type Defines: */ | |||
/** Type define for a DFU class function descriptor. This descriptor gives DFU class information | |||
* to the host when read, indicating the DFU device's capabilities. | |||
*/ | |||
typedef struct | |||
{ | |||
USB_Descriptor_Header_t Header; /**< Standard descriptor header structure */ | |||
uint8_t Attributes; /**< DFU device attributes, a mask comprising of the | |||
* ATTR_* macros listed in this source file | |||
*/ | |||
uint16_t DetachTimeout; /**< Timeout in milliseconds between a USB_DETACH | |||
* command being issued and the device detaching | |||
* from the USB bus | |||
*/ | |||
uint16_t TransferSize; /**< Maximum number of bytes the DFU device can accept | |||
* from the host in a transaction | |||
*/ | |||
uint16_t DFUSpecification; /**< BCD packed DFU specification number this DFU | |||
* device complies with | |||
*/ | |||
} USB_Descriptor_DFU_Functional_t; | |||
/** Type define for the device configuration descriptor structure. This must be defined in the | |||
* application code, as the configuration descriptor contains several sub-descriptors which | |||
* vary between devices, and which describe the device's usage to the host. | |||
*/ | |||
typedef struct | |||
{ | |||
USB_Descriptor_Configuration_Header_t Config; | |||
// DFU Interface | |||
USB_Descriptor_Interface_t DFU_Interface; | |||
USB_Descriptor_DFU_Functional_t DFU_Functional; | |||
} USB_Descriptor_Configuration_t; | |||
/** Enum for the device interface descriptor IDs within the device. Each interface descriptor | |||
* should have a unique ID index associated with it, which can be used to refer to the | |||
* interface from other descriptors. | |||
*/ | |||
enum InterfaceDescriptors_t | |||
{ | |||
INTERFACE_ID_DFU = 0, /**< DFU interface descriptor ID */ | |||
}; | |||
/** Enum for the device string descriptor IDs within the device. Each string descriptor should | |||
* have a unique ID index associated with it, which can be used to refer to the string from | |||
* other descriptors. | |||
*/ | |||
enum StringDescriptors_t | |||
{ | |||
STRING_ID_Language = 0, /**< Supported Languages string descriptor ID (must be zero) */ | |||
STRING_ID_Manufacturer = 1, /**< Manufacturer string ID */ | |||
STRING_ID_Product = 2, /**< Product string ID */ | |||
}; | |||
/* Function Prototypes: */ | |||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, | |||
const uint8_t wIndex, | |||
const void** const DescriptorAddress) | |||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); | |||
#endif | |||
@@ -0,0 +1,156 @@ | |||
<asf xmlversion="1.0"> | |||
<project caption="DFU Bootloader - 128KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.dfu.avr8.128_4" force-caption="true" workspace-name="lufa_dfu_128kb_4kb_"> | |||
<require idref="lufa.bootloaders.dfu"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="at90usb1287"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<config name="config.compiler.optimization.level" value="size"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0x1F000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x1F000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x1FFA0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x1FFE0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x1FFF8"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/> | |||
</project> | |||
<project caption="DFU Bootloader - 64KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.dfu.avr8.64_4" force-caption="true" workspace-name="lufa_dfu_64kb_4kb_"> | |||
<require idref="lufa.bootloaders.dfu"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="at90usb647"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<config name="config.compiler.optimization.level" value="size"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0xF000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0xF000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0xFFA0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0xFFE0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0xFFF8"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/> | |||
</project> | |||
<project caption="DFU Bootloader - 32KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.dfu.avr8.32_4" force-caption="true" workspace-name="lufa_dfu_32kb_4kb_"> | |||
<require idref="lufa.bootloaders.dfu"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="atmega32u4"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<config name="config.compiler.optimization.level" value="size"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0x7000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x7000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x7FA0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x7FE0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x7FF8"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/> | |||
</project> | |||
<project caption="DFU Bootloader - 16KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.dfu.avr8.16_4" force-caption="true" workspace-name="lufa_dfu_16kb_4kb_"> | |||
<require idref="lufa.bootloaders.dfu"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="atmega16u2"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0x3000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x3000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x3FA0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x3FE0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x3FF8"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/> | |||
</project> | |||
<project caption="DFU Bootloader - 8KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.dfu.avr8.8_4" force-caption="true" workspace-name="lufa_dfu_8kb_4kb_"> | |||
<require idref="lufa.bootloaders.dfu"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="atmega8u2"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0x1000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x1000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x1FA0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x1FE0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x1FF8"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/> | |||
</project> | |||
<module type="application" id="lufa.bootloaders.dfu" caption="DFU Bootloader"> | |||
<info type="description" value="summary"> | |||
DFU Class Bootloader, capable of reprogramming a device using the Atmel FLIP or other AVR DFU programming software when plugged into a host. | |||
</info> | |||
<info type="gui-flag" value="move-to-root"/> | |||
<info type="keyword" value="Technology"> | |||
<keyword value="Bootloaders"/> | |||
<keyword value="USB Device"/> | |||
</info> | |||
<device-support-alias value="lufa_avr8"/> | |||
<device-support-alias value="lufa_xmega"/> | |||
<device-support-alias value="lufa_uc3"/> | |||
<build type="include-path" value="."/> | |||
<build type="c-source" value="BootloaderDFU.c"/> | |||
<build type="header-file" value="BootloaderDFU.h"/> | |||
<build type="c-source" value="Descriptors.c"/> | |||
<build type="header-file" value="Descriptors.h"/> | |||
<build type="c-source" value="BootloaderAPI.c"/> | |||
<build type="header-file" value="BootloaderAPI.h"/> | |||
<build type="asm-source" value="BootloaderAPITable.S"/> | |||
<build type="module-config" subtype="path" value="Config"/> | |||
<build type="header-file" value="Config/LUFAConfig.h"/> | |||
<build type="header-file" value="Config/AppConfig.h"/> | |||
<build type="distribute" subtype="user-file" value="doxyfile"/> | |||
<build type="distribute" subtype="user-file" value="BootloaderDFU.txt"/> | |||
<require idref="lufa.common"/> | |||
<require idref="lufa.platform"/> | |||
<require idref="lufa.drivers.usb"/> | |||
<require idref="lufa.drivers.board"/> | |||
<require idref="lufa.drivers.board.leds"/> | |||
</module> | |||
</asf> |
@@ -0,0 +1,55 @@ | |||
# | |||
# LUFA Library | |||
# Copyright (C) Dean Camera, 2014. | |||
# | |||
# dean [at] fourwalledcubicle [dot] com | |||
# www.lufa-lib.org | |||
# | |||
# -------------------------------------- | |||
# LUFA Project Makefile. | |||
# -------------------------------------- | |||
# Run "make help" for target help. | |||
MCU = at90usb1287 | |||
ARCH = AVR8 | |||
BOARD = USBKEY | |||
F_CPU = 8000000 | |||
F_USB = $(F_CPU) | |||
OPTIMIZATION = s | |||
TARGET = BootloaderDFU | |||
SRC = $(TARGET).c Descriptors.c BootloaderAPI.c BootloaderAPITable.S $(LUFA_SRC_USB) | |||
LUFA_PATH = ../../LUFA | |||
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/ -DBOOT_START_ADDR=$(BOOT_START_OFFSET) | |||
LD_FLAGS = -Wl,--section-start=.text=$(BOOT_START_OFFSET) $(BOOT_API_LD_FLAGS) | |||
# Flash size and bootloader section sizes of the target, in KB. These must | |||
# match the target's total FLASH size and the bootloader size set in the | |||
# device's fuses. | |||
FLASH_SIZE_KB = 128 | |||
BOOT_SECTION_SIZE_KB = 8 | |||
# Bootloader address calculation formulas | |||
# Do not modify these macros, but rather modify the dependent values above. | |||
CALC_ADDRESS_IN_HEX = $(shell printf "0x%X" $$(( $(1) )) ) | |||
BOOT_START_OFFSET = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) - $(BOOT_SECTION_SIZE_KB)) * 1024 ) | |||
BOOT_SEC_OFFSET = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) * 1024) - ($(strip $(1))) ) | |||
# Bootloader linker section flags for relocating the API table sections to | |||
# known FLASH addresses - these should not normally be user-edited. | |||
BOOT_SECTION_LD_FLAG = -Wl,--section-start=$(strip $(1))=$(call BOOT_SEC_OFFSET, $(3)) -Wl,--undefined=$(strip $(2)) | |||
BOOT_API_LD_FLAGS = $(call BOOT_SECTION_LD_FLAG, .apitable_trampolines, BootloaderAPI_Trampolines, 96) | |||
BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .apitable_jumptable, BootloaderAPI_JumpTable, 32) | |||
BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .apitable_signatures, BootloaderAPI_Signatures, 8) | |||
# Default target | |||
all: | |||
# Include LUFA build script makefiles | |||
include $(LUFA_PATH)/Build/lufa_core.mk | |||
include $(LUFA_PATH)/Build/lufa_sources.mk | |||
include $(LUFA_PATH)/Build/lufa_build.mk | |||
include $(LUFA_PATH)/Build/lufa_cppcheck.mk | |||
include $(LUFA_PATH)/Build/lufa_doxygen.mk | |||
include $(LUFA_PATH)/Build/lufa_avrdude.mk | |||
include $(LUFA_PATH)/Build/lufa_atprogram.mk |
@@ -0,0 +1,190 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Main source file for the HID class bootloader. This file contains the complete bootloader logic. | |||
*/ | |||
#include "BootloaderHID.h" | |||
/** Flag to indicate if the bootloader should be running, or should exit and allow the application code to run | |||
* via a soft reset. When cleared, the bootloader will abort, the USB interface will shut down and the application | |||
* started via a forced watchdog reset. | |||
*/ | |||
static bool RunBootloader = true; | |||
/** Magic lock for forced application start. If the HWBE fuse is programmed and BOOTRST is unprogrammed, the bootloader | |||
* will start if the /HWB line of the AVR is held low and the system is reset. However, if the /HWB line is still held | |||
* low when the application attempts to start via a watchdog reset, the bootloader will re-start. If set to the value | |||
* \ref MAGIC_BOOT_KEY the special init function \ref Application_Jump_Check() will force the application to start. | |||
*/ | |||
uint16_t MagicBootKey ATTR_NO_INIT; | |||
/** Special startup routine to check if the bootloader was started via a watchdog reset, and if the magic application | |||
* start key has been loaded into \ref MagicBootKey. If the bootloader started via the watchdog and the key is valid, | |||
* this will force the user application to start via a software jump. | |||
*/ | |||
void Application_Jump_Check(void) | |||
{ | |||
/* If the reset source was the bootloader and the key is correct, clear it and jump to the application */ | |||
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY)) | |||
{ | |||
MagicBootKey = 0; | |||
// cppcheck-suppress constStatement | |||
((void (*)(void))0x0000)(); | |||
} | |||
} | |||
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously | |||
* runs the bootloader processing routine until instructed to soft-exit. | |||
*/ | |||
int main(void) | |||
{ | |||
/* Setup hardware required for the bootloader */ | |||
SetupHardware(); | |||
/* Enable global interrupts so that the USB stack can function */ | |||
GlobalInterruptEnable(); | |||
while (RunBootloader) | |||
USB_USBTask(); | |||
/* Disconnect from the host - USB interface will be reset later along with the AVR */ | |||
USB_Detach(); | |||
/* Unlock the forced application start mode of the bootloader if it is restarted */ | |||
MagicBootKey = MAGIC_BOOT_KEY; | |||
/* Enable the watchdog and force a timeout to reset the AVR */ | |||
wdt_enable(WDTO_250MS); | |||
for (;;); | |||
} | |||
/** Configures all hardware required for the bootloader. */ | |||
static void SetupHardware(void) | |||
{ | |||
/* Disable watchdog if enabled by bootloader/fuses */ | |||
MCUSR &= ~(1 << WDRF); | |||
wdt_disable(); | |||
/* Relocate the interrupt vector table to the bootloader section */ | |||
MCUCR = (1 << IVCE); | |||
MCUCR = (1 << IVSEL); | |||
/* Initialize USB subsystem */ | |||
USB_Init(); | |||
} | |||
/** Event handler for the USB_ConfigurationChanged event. This configures the device's endpoints ready | |||
* to relay data to and from the attached USB host. | |||
*/ | |||
void EVENT_USB_Device_ConfigurationChanged(void) | |||
{ | |||
/* Setup HID Report Endpoint */ | |||
Endpoint_ConfigureEndpoint(HID_IN_EPADDR, EP_TYPE_INTERRUPT, HID_IN_EPSIZE, 1); | |||
} | |||
/** Event handler for the USB_ControlRequest event. This is used to catch and process control requests sent to | |||
* the device from the USB host before passing along unhandled control requests to the library for processing | |||
* internally. | |||
*/ | |||
void EVENT_USB_Device_ControlRequest(void) | |||
{ | |||
/* Ignore any requests that aren't directed to the HID interface */ | |||
if ((USB_ControlRequest.bmRequestType & (CONTROL_REQTYPE_TYPE | CONTROL_REQTYPE_RECIPIENT)) != | |||
(REQTYPE_CLASS | REQREC_INTERFACE)) | |||
{ | |||
return; | |||
} | |||
/* Process HID specific control requests */ | |||
switch (USB_ControlRequest.bRequest) | |||
{ | |||
case HID_REQ_SetReport: | |||
Endpoint_ClearSETUP(); | |||
/* Wait until the command has been sent by the host */ | |||
while (!(Endpoint_IsOUTReceived())); | |||
/* Read in the write destination address */ | |||
#if (FLASHEND > 0xFFFF) | |||
uint32_t PageAddress = ((uint32_t)Endpoint_Read_16_LE() << 8); | |||
#else | |||
uint16_t PageAddress = Endpoint_Read_16_LE(); | |||
#endif | |||
/* Check if the command is a program page command, or a start application command */ | |||
#if (FLASHEND > 0xFFFF) | |||
if ((uint16_t)(PageAddress >> 8) == COMMAND_STARTAPPLICATION) | |||
#else | |||
if (PageAddress == COMMAND_STARTAPPLICATION) | |||
#endif | |||
{ | |||
RunBootloader = false; | |||
} | |||
else | |||
{ | |||
/* Erase the given FLASH page, ready to be programmed */ | |||
boot_page_erase(PageAddress); | |||
boot_spm_busy_wait(); | |||
/* Write each of the FLASH page's bytes in sequence */ | |||
for (uint8_t PageWord = 0; PageWord < (SPM_PAGESIZE / 2); PageWord++) | |||
{ | |||
/* Check if endpoint is empty - if so clear it and wait until ready for next packet */ | |||
if (!(Endpoint_BytesInEndpoint())) | |||
{ | |||
Endpoint_ClearOUT(); | |||
while (!(Endpoint_IsOUTReceived())); | |||
} | |||
/* Write the next data word to the FLASH page */ | |||
boot_page_fill(PageAddress + ((uint16_t)PageWord << 1), Endpoint_Read_16_LE()); | |||
} | |||
/* Write the filled FLASH page to memory */ | |||
boot_page_write(PageAddress); | |||
boot_spm_busy_wait(); | |||
/* Re-enable RWW section */ | |||
boot_rww_enable(); | |||
} | |||
Endpoint_ClearOUT(); | |||
Endpoint_ClearStatusStage(); | |||
break; | |||
} | |||
} | |||
@@ -0,0 +1,73 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Header file for BootloaderHID.c. | |||
*/ | |||
#ifndef _BOOTLOADERHID_H_ | |||
#define _BOOTLOADERHID_H_ | |||
/* Includes: */ | |||
#include <avr/io.h> | |||
#include <avr/wdt.h> | |||
#include <avr/boot.h> | |||
#include <avr/power.h> | |||
#include <avr/interrupt.h> | |||
#include <stdbool.h> | |||
#include "Descriptors.h" | |||
#include <LUFA/Drivers/USB/USB.h> | |||
#include <LUFA/Platform/Platform.h> | |||
/* Preprocessor Checks: */ | |||
#if !defined(__OPTIMIZE_SIZE__) | |||
#error This bootloader requires that it be optimized for size, not speed, to fit into the target device. Change optimization settings and try again. | |||
#endif | |||
/* Macros: */ | |||
/** Bootloader special address to start the user application */ | |||
#define COMMAND_STARTAPPLICATION 0xFFFF | |||
/** Magic bootloader key to unlock forced application start mode. */ | |||
#define MAGIC_BOOT_KEY 0xDC42 | |||
/* Function Prototypes: */ | |||
static void SetupHardware(void); | |||
void Application_Jump_Check(void) ATTR_INIT_SECTION(3); | |||
void EVENT_USB_Device_ConfigurationChanged(void); | |||
void EVENT_USB_Device_UnhandledControlRequest(void); | |||
#endif | |||
@@ -0,0 +1,105 @@ | |||
/** \file | |||
* | |||
* This file contains special DoxyGen information for the generation of the main page and other special | |||
* documentation pages. It is not a project source file. | |||
*/ | |||
/** \mainpage HID Class USB AVR Bootloader | |||
* | |||
* \section SSec_Compat Demo Compatibility: | |||
* | |||
* The following list indicates what microcontrollers are compatible with this demo. | |||
* | |||
* \li Series 7 USB AVRs (AT90USBxxx7) | |||
* \li Series 6 USB AVRs (AT90USBxxx6) | |||
* \li Series 4 USB AVRs (ATMEGAxxU4) | |||
* \li Series 2 USB AVRs (AT90USBxx2, ATMEGAxxU2) | |||
* | |||
* \section SSec_Info USB Information: | |||
* | |||
* The following table gives a rundown of the USB utilization of this demo. | |||
* | |||
* <table> | |||
* <tr> | |||
* <td><b>USB Mode:</b></td> | |||
* <td>Device</td> | |||
* </tr> | |||
* <tr> | |||
* <td><b>USB Class:</b></td> | |||
* <td>Human Interface Device Class (HID)</td> | |||
* </tr> | |||
* <tr> | |||
* <td><b>USB Subclass:</b></td> | |||
* <td>N/A</td> | |||
* </tr> | |||
* <tr> | |||
* <td><b>Relevant Standards:</b></td> | |||
* <td>USBIF HID Class Standard \n | |||
* Teensy Programming Protocol Specification</td> | |||
* </tr> | |||
* <tr> | |||
* <td><b>Supported USB Speeds:</b></td> | |||
* <td>Low Speed Mode \n | |||
* Full Speed Mode</td> | |||
* </tr> | |||
* </table> | |||
* | |||
* \section SSec_Description Project Description: | |||
* | |||
* This bootloader enumerates to the host as a HID Class device, allowing for device FLASH programming through | |||
* the supplied command line software, which is a modified version of Paul's TeensyHID Command Line loader code | |||
* from PJRC (used with permission). This bootloader is deliberately non-compatible with the proprietary PJRC | |||
* HalfKay bootloader GUI; only the command line interface software accompanying this bootloader will work with it. | |||
* | |||
* Out of the box this bootloader builds for the AT90USB1287 with an 8KB bootloader section size, and will fit | |||
* into 2KB of bootloader space for the Series 2 USB AVRs (ATMEGAxxU2, AT90USBxx2) or 4KB of bootloader space for | |||
* all other models. If you wish to alter this size and/or change the AVR model, you will need to edit the MCU, | |||
* FLASH_SIZE_KB and BOOT_SECTION_SIZE_KB values in the accompanying makefile. | |||
* | |||
* \warning <b>THIS BOOTLOADER IS NOT SECURE.</b> Malicious entities can recover written data, even if the device | |||
* lockbits are set. | |||
* | |||
* \section Sec_Running Running the Bootloader | |||
* | |||
* This bootloader is designed to be started via the HWB mechanism of the USB AVRs; ground the HWB pin (see device | |||
* datasheet) then momentarily ground /RESET to start the bootloader. This assumes the HWBE fuse is set and the BOOTRST | |||
* fuse is cleared. | |||
* | |||
* \section Sec_Installation Driver Installation | |||
* | |||
* This bootloader uses the HID class driver inbuilt into all modern operating systems, thus no additional drivers | |||
* need to be supplied for correct operation. | |||
* | |||
* \section Sec_HostApp Host Controller Application | |||
* | |||
* Due to licensing issues, the supplied bootloader is compatible with the HalfKay bootloader protocol designed | |||
* by PJRC, but is non-compatible with the cross-platform loader GUI. A modified version of the open source | |||
* cross-platform TeensyLoader application is supplied, which can be compiled under most operating systems. The | |||
* command-line loader application should remain compatible with genuine Teensy boards in addition to boards using | |||
* this custom bootloader. | |||
* | |||
* Once compiled, programs can be loaded into the AVR's FLASH memory through the following example command: | |||
* \code | |||
* hid_bootloader_cli -mmcu=at90usb1287 Mouse.hex | |||
* \endcode | |||
* | |||
* \section Sec_KnownIssues Known Issues: | |||
* | |||
* \par After loading an application, it is not run automatically on startup. | |||
* Some USB AVR boards ship with the BOOTRST fuse set, causing the bootloader | |||
* to run automatically when the device is reset. In most cases, the BOOTRST | |||
* fuse should be disabled and the HWBE fuse used instead to run the bootloader | |||
* when needed. | |||
* | |||
* \section SSec_Options Project Options | |||
* | |||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value. | |||
* | |||
* <table> | |||
* <tr> | |||
* <td> | |||
* None | |||
* </td> | |||
* </tr> | |||
* </table> | |||
*/ |
@@ -0,0 +1,93 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* \brief LUFA Library Configuration Header File | |||
* | |||
* This header file is used to configure LUFA's compile time options, | |||
* as an alternative to the compile time constants supplied through | |||
* a makefile. | |||
* | |||
* For information on what each token does, refer to the LUFA | |||
* manual section "Summary of Compile Tokens". | |||
*/ | |||
#ifndef _LUFA_CONFIG_H_ | |||
#define _LUFA_CONFIG_H_ | |||
#if (ARCH == ARCH_AVR8) | |||
/* Non-USB Related Configuration Tokens: */ | |||
// #define DISABLE_TERMINAL_CODES | |||
/* USB Class Driver Related Tokens: */ | |||
// #define HID_HOST_BOOT_PROTOCOL_ONLY | |||
// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here} | |||
// #define HID_USAGE_STACK_DEPTH {Insert Value Here} | |||
// #define HID_MAX_COLLECTIONS {Insert Value Here} | |||
// #define HID_MAX_REPORTITEMS {Insert Value Here} | |||
// #define HID_MAX_REPORT_IDS {Insert Value Here} | |||
// #define NO_CLASS_DRIVER_AUTOFLUSH | |||
/* General USB Driver Related Tokens: */ | |||
#define ORDERED_EP_CONFIG | |||
#define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL) | |||
#define USB_DEVICE_ONLY | |||
// #define USB_HOST_ONLY | |||
// #define USB_STREAM_TIMEOUT_MS {Insert Value Here} | |||
// #define NO_LIMITED_CONTROLLER_CONNECT | |||
#define NO_SOF_EVENTS | |||
/* USB Device Mode Driver Related Tokens: */ | |||
#define USE_RAM_DESCRIPTORS | |||
// #define USE_FLASH_DESCRIPTORS | |||
// #define USE_EEPROM_DESCRIPTORS | |||
#define NO_INTERNAL_SERIAL | |||
#define FIXED_CONTROL_ENDPOINT_SIZE 8 | |||
#define DEVICE_STATE_AS_GPIOR 0 | |||
#define FIXED_NUM_CONFIGURATIONS 1 | |||
// #define CONTROL_ONLY_DEVICE | |||
// #define INTERRUPT_CONTROL_ENDPOINT | |||
#define NO_DEVICE_REMOTE_WAKEUP | |||
#define NO_DEVICE_SELF_POWER | |||
/* USB Host Mode Driver Related Tokens: */ | |||
// #define HOST_STATE_AS_GPIOR {Insert Value Here} | |||
// #define USB_HOST_TIMEOUT_MS {Insert Value Here} | |||
// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here} | |||
// #define NO_AUTO_VBUS_MANAGEMENT | |||
// #define INVERTED_VBUS_ENABLE_LINE | |||
#else | |||
#error Unsupported architecture for this LUFA configuration file. | |||
#endif | |||
#endif |
@@ -0,0 +1,187 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special | |||
* computer-readable structures which the host requests upon device enumeration, to determine | |||
* the device's capabilities and functions. | |||
*/ | |||
#include "Descriptors.h" | |||
/** HID class report descriptor. This is a special descriptor constructed with values from the | |||
* USBIF HID class specification to describe the reports and capabilities of the HID device. This | |||
* descriptor is parsed by the host and its contents used to determine what data (and in what encoding) | |||
* the device will send, and what it may be sent back from the host. Refer to the HID specification for | |||
* more details on HID report descriptors. | |||
*/ | |||
const USB_Descriptor_HIDReport_Datatype_t HIDReport[] = | |||
{ | |||
HID_RI_USAGE_PAGE(16, 0xFFDC), /* Vendor Page 0xDC */ | |||
HID_RI_USAGE(8, 0xFB), /* Vendor Usage 0xFB */ | |||
HID_RI_COLLECTION(8, 0x01), /* Vendor Usage 1 */ | |||
HID_RI_USAGE(8, 0x02), /* Vendor Usage 2 */ | |||
HID_RI_LOGICAL_MINIMUM(8, 0x00), | |||
HID_RI_LOGICAL_MAXIMUM(8, 0xFF), | |||
HID_RI_REPORT_SIZE(8, 0x08), | |||
HID_RI_REPORT_COUNT(16, (sizeof(uint16_t) + SPM_PAGESIZE)), | |||
HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), | |||
HID_RI_END_COLLECTION(0), | |||
}; | |||
/** Device descriptor structure. This descriptor, located in SRAM memory, describes the overall | |||
* device characteristics, including the supported USB version, control endpoint size and the | |||
* number of device configurations. The descriptor is read out by the USB host when the enumeration | |||
* process begins. | |||
*/ | |||
const USB_Descriptor_Device_t DeviceDescriptor = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, | |||
.USBSpecification = VERSION_BCD(1,1,0), | |||
.Class = USB_CSCP_NoDeviceClass, | |||
.SubClass = USB_CSCP_NoDeviceSubclass, | |||
.Protocol = USB_CSCP_NoDeviceProtocol, | |||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, | |||
.VendorID = 0x03EB, | |||
.ProductID = 0x2067, | |||
.ReleaseNumber = VERSION_BCD(0,0,1), | |||
.ManufacturerStrIndex = NO_DESCRIPTOR, | |||
.ProductStrIndex = NO_DESCRIPTOR, | |||
.SerialNumStrIndex = NO_DESCRIPTOR, | |||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS | |||
}; | |||
/** Configuration descriptor structure. This descriptor, located in SRAM memory, describes the usage | |||
* of the device in one of its supported configurations, including information about any device interfaces | |||
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting | |||
* a configuration so that the host may correctly communicate with the USB device. | |||
*/ | |||
const USB_Descriptor_Configuration_t ConfigurationDescriptor = | |||
{ | |||
.Config = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, | |||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), | |||
.TotalInterfaces = 1, | |||
.ConfigurationNumber = 1, | |||
.ConfigurationStrIndex = NO_DESCRIPTOR, | |||
.ConfigAttributes = USB_CONFIG_ATTR_RESERVED, | |||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100) | |||
}, | |||
.HID_Interface = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, | |||
.InterfaceNumber = INTERFACE_ID_Printer, | |||
.AlternateSetting = 0x00, | |||
.TotalEndpoints = 1, | |||
.Class = HID_CSCP_HIDClass, | |||
.SubClass = HID_CSCP_NonBootSubclass, | |||
.Protocol = HID_CSCP_NonBootProtocol, | |||
.InterfaceStrIndex = NO_DESCRIPTOR | |||
}, | |||
.HID_VendorHID = | |||
{ | |||
.Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, | |||
.HIDSpec = VERSION_BCD(1,1,1), | |||
.CountryCode = 0x00, | |||
.TotalReportDescriptors = 1, | |||
.HIDReportType = HID_DTYPE_Report, | |||
.HIDReportLength = sizeof(HIDReport) | |||
}, | |||
.HID_ReportINEndpoint = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, | |||
.EndpointAddress = HID_IN_EPADDR, | |||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), | |||
.EndpointSize = HID_IN_EPSIZE, | |||
.PollingIntervalMS = 0x05 | |||
}, | |||
}; | |||
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" | |||
* documentation) by the application code so that the address and size of a requested descriptor can be given | |||
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function | |||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the | |||
* USB host. | |||
*/ | |||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, | |||
const uint8_t wIndex, | |||
const void** const DescriptorAddress) | |||
{ | |||
const uint8_t DescriptorType = (wValue >> 8); | |||
const void* Address = NULL; | |||
uint16_t Size = NO_DESCRIPTOR; | |||
/* If/Else If chain compiles slightly smaller than a switch case */ | |||
if (DescriptorType == DTYPE_Device) | |||
{ | |||
Address = &DeviceDescriptor; | |||
Size = sizeof(USB_Descriptor_Device_t); | |||
} | |||
else if (DescriptorType == DTYPE_Configuration) | |||
{ | |||
Address = &ConfigurationDescriptor; | |||
Size = sizeof(USB_Descriptor_Configuration_t); | |||
} | |||
else if (DescriptorType == HID_DTYPE_HID) | |||
{ | |||
Address = &ConfigurationDescriptor.HID_VendorHID; | |||
Size = sizeof(USB_HID_Descriptor_HID_t); | |||
} | |||
else | |||
{ | |||
Address = &HIDReport; | |||
Size = sizeof(HIDReport); | |||
} | |||
*DescriptorAddress = Address; | |||
return Size; | |||
} | |||
@@ -0,0 +1,80 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Header file for Descriptors.c. | |||
*/ | |||
#ifndef _DESCRIPTORS_H_ | |||
#define _DESCRIPTORS_H_ | |||
/* Includes: */ | |||
#include <LUFA/Drivers/USB/USB.h> | |||
/* Type Defines: */ | |||
/** Type define for the device configuration descriptor structure. This must be defined in the | |||
* application code, as the configuration descriptor contains several sub-descriptors which | |||
* vary between devices, and which describe the device's usage to the host. | |||
*/ | |||
typedef struct | |||
{ | |||
USB_Descriptor_Configuration_Header_t Config; | |||
// Generic HID Interface | |||
USB_Descriptor_Interface_t HID_Interface; | |||
USB_HID_Descriptor_HID_t HID_VendorHID; | |||
USB_Descriptor_Endpoint_t HID_ReportINEndpoint; | |||
} USB_Descriptor_Configuration_t; | |||
/** Enum for the device interface descriptor IDs within the device. Each interface descriptor | |||
* should have a unique ID index associated with it, which can be used to refer to the | |||
* interface from other descriptors. | |||
*/ | |||
enum InterfaceDescriptors_t | |||
{ | |||
INTERFACE_ID_Printer = 0, /**< Printer interface descriptor ID */ | |||
}; | |||
/* Macros: */ | |||
/** Endpoint address of the HID data IN endpoint. */ | |||
#define HID_IN_EPADDR (ENDPOINT_DIR_IN | 1) | |||
/** Size in bytes of the HID reporting IN endpoint. */ | |||
#define HID_IN_EPSIZE 64 | |||
/* Function Prototypes: */ | |||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, | |||
const uint8_t wIndex, | |||
const void** const DescriptorAddress) | |||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); | |||
#endif | |||
@@ -0,0 +1,39 @@ | |||
OS ?= LINUX | |||
#OS ?= WINDOWS | |||
#OS ?= MACOSX | |||
#OS ?= BSD | |||
ifeq ($(OS), LINUX) # also works on FreeBSD | |||
CC ?= gcc | |||
CFLAGS ?= -O2 -Wall | |||
hid_bootloader_cli: hid_bootloader_cli.c | |||
$(CC) $(CFLAGS) -s -DUSE_LIBUSB -o hid_bootloader_cli hid_bootloader_cli.c -lusb | |||
else ifeq ($(OS), WINDOWS) | |||
CC = i586-mingw32msvc-gcc | |||
CFLAGS ?= -O2 -Wall | |||
hid_bootloader_cli.exe: hid_bootloader_cli.c | |||
$(CC) $(CFLAGS) -s -DUSE_WIN32 -o hid_bootloader_cli.exe hid_bootloader_cli.c -lhid -lsetupapi | |||
else ifeq ($(OS), MACOSX) | |||
CC ?= gcc | |||
SDK ?= /Developer/SDKs/MacOSX10.5.sdk | |||
CFLAGS ?= -O2 -Wall | |||
hid_bootloader_cli: hid_bootloader_cli.c | |||
$(CC) $(CFLAGS) -DUSE_APPLE_IOKIT -isysroot $(SDK) -o hid_bootloader_cli hid_bootloader_cli.c -Wl,-syslibroot,$(SDK) -framework IOKit -framework CoreFoundation | |||
else ifeq ($(OS), BSD) # works on NetBSD and OpenBSD | |||
CC ?= gcct | |||
CFLAGS ?= -O2 -Wall | |||
hid_bootloader_cli: hid_bootloader_cli.c | |||
$(CC) $(CFLAGS) -s -DUSE_UHID -o hid_bootloader_cli hid_bootloader_cli.c | |||
endif | |||
clean: | |||
rm -f hid_bootloader_cli hid_bootloader_cli.exe |
@@ -0,0 +1,21 @@ | |||
OS ?= FreeBSD | |||
#OS ?= NetBSD | |||
#OS ?= OpenBSD | |||
CFLAGS ?= -O2 -Wall | |||
CC ?= gcc | |||
.if $(OS) == "FreeBSD" | |||
CFLAGS += -DUSE_LIBUSB | |||
LIBS = -lusb | |||
.elif $(OS) == "NetBSD" || $(OS) == "OpenBSD" | |||
CFLAGS += -DUSE_UHID | |||
LIBS = | |||
.endif | |||
hid_bootloader_cli: hid_bootloader_cli.c | |||
$(CC) $(CFLAGS) -s -o hid_bootloader_cli hid_bootloader_cli.c $(LIBS) | |||
clean: | |||
rm -f hid_bootloader_cli |
@@ -0,0 +1,674 @@ | |||
GNU GENERAL PUBLIC LICENSE | |||
Version 3, 29 June 2007 | |||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> | |||
Everyone is permitted to copy and distribute verbatim copies | |||
of this license document, but changing it is not allowed. | |||
Preamble | |||
The GNU General Public License is a free, copyleft license for | |||
software and other kinds of works. | |||
The licenses for most software and other practical works are designed | |||
to take away your freedom to share and change the works. By contrast, | |||
the GNU General Public License is intended to guarantee your freedom to | |||
share and change all versions of a program--to make sure it remains free | |||
software for all its users. We, the Free Software Foundation, use the | |||
GNU General Public License for most of our software; it applies also to | |||
any other work released this way by its authors. You can apply it to | |||
your programs, too. | |||
When we speak of free software, we are referring to freedom, not | |||
price. Our General Public Licenses are designed to make sure that you | |||
have the freedom to distribute copies of free software (and charge for | |||
them if you wish), that you receive source code or can get it if you | |||
want it, that you can change the software or use pieces of it in new | |||
free programs, and that you know you can do these things. | |||
To protect your rights, we need to prevent others from denying you | |||
these rights or asking you to surrender the rights. Therefore, you have | |||
certain responsibilities if you distribute copies of the software, or if | |||
you modify it: responsibilities to respect the freedom of others. | |||
For example, if you distribute copies of such a program, whether | |||
gratis or for a fee, you must pass on to the recipients the same | |||
freedoms that you received. You must make sure that they, too, receive | |||
or can get the source code. And you must show them these terms so they | |||
know their rights. | |||
Developers that use the GNU GPL protect your rights with two steps: | |||
(1) assert copyright on the software, and (2) offer you this License | |||
giving you legal permission to copy, distribute and/or modify it. | |||
For the developers' and authors' protection, the GPL clearly explains | |||
that there is no warranty for this free software. For both users' and | |||
authors' sake, the GPL requires that modified versions be marked as | |||
changed, so that their problems will not be attributed erroneously to | |||
authors of previous versions. | |||
Some devices are designed to deny users access to install or run | |||
modified versions of the software inside them, although the manufacturer | |||
can do so. This is fundamentally incompatible with the aim of | |||
protecting users' freedom to change the software. The systematic | |||
pattern of such abuse occurs in the area of products for individuals to | |||
use, which is precisely where it is most unacceptable. Therefore, we | |||
have designed this version of the GPL to prohibit the practice for those | |||
products. If such problems arise substantially in other domains, we | |||
stand ready to extend this provision to those domains in future versions | |||
of the GPL, as needed to protect the freedom of users. | |||
Finally, every program is threatened constantly by software patents. | |||
States should not allow patents to restrict development and use of | |||
software on general-purpose computers, but in those that do, we wish to | |||
avoid the special danger that patents applied to a free program could | |||
make it effectively proprietary. To prevent this, the GPL assures that | |||
patents cannot be used to render the program non-free. | |||
The precise terms and conditions for copying, distribution and | |||
modification follow. | |||
TERMS AND CONDITIONS | |||
0. Definitions. | |||
"This License" refers to version 3 of the GNU General Public License. | |||
"Copyright" also means copyright-like laws that apply to other kinds of | |||
works, such as semiconductor masks. | |||
"The Program" refers to any copyrightable work licensed under this | |||
License. Each licensee is addressed as "you". "Licensees" and | |||
"recipients" may be individuals or organizations. | |||
To "modify" a work means to copy from or adapt all or part of the work | |||
in a fashion requiring copyright permission, other than the making of an | |||
exact copy. The resulting work is called a "modified version" of the | |||
earlier work or a work "based on" the earlier work. | |||
A "covered work" means either the unmodified Program or a work based | |||
on the Program. | |||
To "propagate" a work means to do anything with it that, without | |||
permission, would make you directly or secondarily liable for | |||
infringement under applicable copyright law, except executing it on a | |||
computer or modifying a private copy. Propagation includes copying, | |||
distribution (with or without modification), making available to the | |||
public, and in some countries other activities as well. | |||
To "convey" a work means any kind of propagation that enables other | |||
parties to make or receive copies. Mere interaction with a user through | |||
a computer network, with no transfer of a copy, is not conveying. | |||
An interactive user interface displays "Appropriate Legal Notices" | |||
to the extent that it includes a convenient and prominently visible | |||
feature that (1) displays an appropriate copyright notice, and (2) | |||
tells the user that there is no warranty for the work (except to the | |||
extent that warranties are provided), that licensees may convey the | |||
work under this License, and how to view a copy of this License. If | |||
the interface presents a list of user commands or options, such as a | |||
menu, a prominent item in the list meets this criterion. | |||
1. Source Code. | |||
The "source code" for a work means the preferred form of the work | |||
for making modifications to it. "Object code" means any non-source | |||
form of a work. | |||
A "Standard Interface" means an interface that either is an official | |||
standard defined by a recognized standards body, or, in the case of | |||
interfaces specified for a particular programming language, one that | |||
is widely used among developers working in that language. | |||
The "System Libraries" of an executable work include anything, other | |||
than the work as a whole, that (a) is included in the normal form of | |||
packaging a Major Component, but which is not part of that Major | |||
Component, and (b) serves only to enable use of the work with that | |||
Major Component, or to implement a Standard Interface for which an | |||
implementation is available to the public in source code form. A | |||
"Major Component", in this context, means a major essential component | |||
(kernel, window system, and so on) of the specific operating system | |||
(if any) on which the executable work runs, or a compiler used to | |||
produce the work, or an object code interpreter used to run it. | |||
The "Corresponding Source" for a work in object code form means all | |||
the source code needed to generate, install, and (for an executable | |||
work) run the object code and to modify the work, including scripts to | |||
control those activities. However, it does not include the work's | |||
System Libraries, or general-purpose tools or generally available free | |||
programs which are used unmodified in performing those activities but | |||
which are not part of the work. For example, Corresponding Source | |||
includes interface definition files associated with source files for | |||
the work, and the source code for shared libraries and dynamically | |||
linked subprograms that the work is specifically designed to require, | |||
such as by intimate data communication or control flow between those | |||
subprograms and other parts of the work. | |||
The Corresponding Source need not include anything that users | |||
can regenerate automatically from other parts of the Corresponding | |||
Source. | |||
The Corresponding Source for a work in source code form is that | |||
same work. | |||
2. Basic Permissions. | |||
All rights granted under this License are granted for the term of | |||
copyright on the Program, and are irrevocable provided the stated | |||
conditions are met. This License explicitly affirms your unlimited | |||
permission to run the unmodified Program. The output from running a | |||
covered work is covered by this License only if the output, given its | |||
content, constitutes a covered work. This License acknowledges your | |||
rights of fair use or other equivalent, as provided by copyright law. | |||
You may make, run and propagate covered works that you do not | |||
convey, without conditions so long as your license otherwise remains | |||
in force. You may convey covered works to others for the sole purpose | |||
of having them make modifications exclusively for you, or provide you | |||
with facilities for running those works, provided that you comply with | |||
the terms of this License in conveying all material for which you do | |||
not control copyright. Those thus making or running the covered works | |||
for you must do so exclusively on your behalf, under your direction | |||
and control, on terms that prohibit them from making any copies of | |||
your copyrighted material outside their relationship with you. | |||
Conveying under any other circumstances is permitted solely under | |||
the conditions stated below. Sublicensing is not allowed; section 10 | |||
makes it unnecessary. | |||
3. Protecting Users' Legal Rights From Anti-Circumvention Law. | |||
No covered work shall be deemed part of an effective technological | |||
measure under any applicable law fulfilling obligations under article | |||
11 of the WIPO copyright treaty adopted on 20 December 1996, or | |||
similar laws prohibiting or restricting circumvention of such | |||
measures. | |||
When you convey a covered work, you waive any legal power to forbid | |||
circumvention of technological measures to the extent such circumvention | |||
is effected by exercising rights under this License with respect to | |||
the covered work, and you disclaim any intention to limit operation or | |||
modification of the work as a means of enforcing, against the work's | |||
users, your or third parties' legal rights to forbid circumvention of | |||
technological measures. | |||
4. Conveying Verbatim Copies. | |||
You may convey verbatim copies of the Program's source code as you | |||
receive it, in any medium, provided that you conspicuously and | |||
appropriately publish on each copy an appropriate copyright notice; | |||
keep intact all notices stating that this License and any | |||
non-permissive terms added in accord with section 7 apply to the code; | |||
keep intact all notices of the absence of any warranty; and give all | |||
recipients a copy of this License along with the Program. | |||
You may charge any price or no price for each copy that you convey, | |||
and you may offer support or warranty protection for a fee. | |||
5. Conveying Modified Source Versions. | |||
You may convey a work based on the Program, or the modifications to | |||
produce it from the Program, in the form of source code under the | |||
terms of section 4, provided that you also meet all of these conditions: | |||
a) The work must carry prominent notices stating that you modified | |||
it, and giving a relevant date. | |||
b) The work must carry prominent notices stating that it is | |||
released under this License and any conditions added under section | |||
7. This requirement modifies the requirement in section 4 to | |||
"keep intact all notices". | |||
c) You must license the entire work, as a whole, under this | |||
License to anyone who comes into possession of a copy. This | |||
License will therefore apply, along with any applicable section 7 | |||
additional terms, to the whole of the work, and all its parts, | |||
regardless of how they are packaged. This License gives no | |||
permission to license the work in any other way, but it does not | |||
invalidate such permission if you have separately received it. | |||
d) If the work has interactive user interfaces, each must display | |||
Appropriate Legal Notices; however, if the Program has interactive | |||
interfaces that do not display Appropriate Legal Notices, your | |||
work need not make them do so. | |||
A compilation of a covered work with other separate and independent | |||
works, which are not by their nature extensions of the covered work, | |||
and which are not combined with it such as to form a larger program, | |||
in or on a volume of a storage or distribution medium, is called an | |||
"aggregate" if the compilation and its resulting copyright are not | |||
used to limit the access or legal rights of the compilation's users | |||
beyond what the individual works permit. Inclusion of a covered work | |||
in an aggregate does not cause this License to apply to the other | |||
parts of the aggregate. | |||
6. Conveying Non-Source Forms. | |||
You may convey a covered work in object code form under the terms | |||
of sections 4 and 5, provided that you also convey the | |||
machine-readable Corresponding Source under the terms of this License, | |||
in one of these ways: | |||
a) Convey the object code in, or embodied in, a physical product | |||
(including a physical distribution medium), accompanied by the | |||
Corresponding Source fixed on a durable physical medium | |||
customarily used for software interchange. | |||
b) Convey the object code in, or embodied in, a physical product | |||
(including a physical distribution medium), accompanied by a | |||
written offer, valid for at least three years and valid for as | |||
long as you offer spare parts or customer support for that product | |||
model, to give anyone who possesses the object code either (1) a | |||
copy of the Corresponding Source for all the software in the | |||
product that is covered by this License, on a durable physical | |||
medium customarily used for software interchange, for a price no | |||
more than your reasonable cost of physically performing this | |||
conveying of source, or (2) access to copy the | |||
Corresponding Source from a network server at no charge. | |||
c) Convey individual copies of the object code with a copy of the | |||
written offer to provide the Corresponding Source. This | |||
alternative is allowed only occasionally and noncommercially, and | |||
only if you received the object code with such an offer, in accord | |||
with subsection 6b. | |||
d) Convey the object code by offering access from a designated | |||
place (gratis or for a charge), and offer equivalent access to the | |||
Corresponding Source in the same way through the same place at no | |||
further charge. You need not require recipients to copy the | |||
Corresponding Source along with the object code. If the place to | |||
copy the object code is a network server, the Corresponding Source | |||
may be on a different server (operated by you or a third party) | |||
that supports equivalent copying facilities, provided you maintain | |||
clear directions next to the object code saying where to find the | |||
Corresponding Source. Regardless of what server hosts the | |||
Corresponding Source, you remain obligated to ensure that it is | |||
available for as long as needed to satisfy these requirements. | |||
e) Convey the object code using peer-to-peer transmission, provided | |||
you inform other peers where the object code and Corresponding | |||
Source of the work are being offered to the general public at no | |||
charge under subsection 6d. | |||
A separable portion of the object code, whose source code is excluded | |||
from the Corresponding Source as a System Library, need not be | |||
included in conveying the object code work. | |||
A "User Product" is either (1) a "consumer product", which means any | |||
tangible personal property which is normally used for personal, family, | |||
or household purposes, or (2) anything designed or sold for incorporation | |||
into a dwelling. In determining whether a product is a consumer product, | |||
doubtful cases shall be resolved in favor of coverage. For a particular | |||
product received by a particular user, "normally used" refers to a | |||
typical or common use of that class of product, regardless of the status | |||
of the particular user or of the way in which the particular user | |||
actually uses, or expects or is expected to use, the product. A product | |||
is a consumer product regardless of whether the product has substantial | |||
commercial, industrial or non-consumer uses, unless such uses represent | |||
the only significant mode of use of the product. | |||
"Installation Information" for a User Product means any methods, | |||
procedures, authorization keys, or other information required to install | |||
and execute modified versions of a covered work in that User Product from | |||
a modified version of its Corresponding Source. The information must | |||
suffice to ensure that the continued functioning of the modified object | |||
code is in no case prevented or interfered with solely because | |||
modification has been made. | |||
If you convey an object code work under this section in, or with, or | |||
specifically for use in, a User Product, and the conveying occurs as | |||
part of a transaction in which the right of possession and use of the | |||
User Product is transferred to the recipient in perpetuity or for a | |||
fixed term (regardless of how the transaction is characterized), the | |||
Corresponding Source conveyed under this section must be accompanied | |||
by the Installation Information. But this requirement does not apply | |||
if neither you nor any third party retains the ability to install | |||
modified object code on the User Product (for example, the work has | |||
been installed in ROM). | |||
The requirement to provide Installation Information does not include a | |||
requirement to continue to provide support service, warranty, or updates | |||
for a work that has been modified or installed by the recipient, or for | |||
the User Product in which it has been modified or installed. Access to a | |||
network may be denied when the modification itself materially and | |||
adversely affects the operation of the network or violates the rules and | |||
protocols for communication across the network. | |||
Corresponding Source conveyed, and Installation Information provided, | |||
in accord with this section must be in a format that is publicly | |||
documented (and with an implementation available to the public in | |||
source code form), and must require no special password or key for | |||
unpacking, reading or copying. | |||
7. Additional Terms. | |||
"Additional permissions" are terms that supplement the terms of this | |||
License by making exceptions from one or more of its conditions. | |||
Additional permissions that are applicable to the entire Program shall | |||
be treated as though they were included in this License, to the extent | |||
that they are valid under applicable law. If additional permissions | |||
apply only to part of the Program, that part may be used separately | |||
under those permissions, but the entire Program remains governed by | |||
this License without regard to the additional permissions. | |||
When you convey a copy of a covered work, you may at your option | |||
remove any additional permissions from that copy, or from any part of | |||
it. (Additional permissions may be written to require their own | |||
removal in certain cases when you modify the work.) You may place | |||
additional permissions on material, added by you to a covered work, | |||
for which you have or can give appropriate copyright permission. | |||
Notwithstanding any other provision of this License, for material you | |||
add to a covered work, you may (if authorized by the copyright holders of | |||
that material) supplement the terms of this License with terms: | |||
a) Disclaiming warranty or limiting liability differently from the | |||
terms of sections 15 and 16 of this License; or | |||
b) Requiring preservation of specified reasonable legal notices or | |||
author attributions in that material or in the Appropriate Legal | |||
Notices displayed by works containing it; or | |||
c) Prohibiting misrepresentation of the origin of that material, or | |||
requiring that modified versions of such material be marked in | |||
reasonable ways as different from the original version; or | |||
d) Limiting the use for publicity purposes of names of licensors or | |||
authors of the material; or | |||
e) Declining to grant rights under trademark law for use of some | |||
trade names, trademarks, or service marks; or | |||
f) Requiring indemnification of licensors and authors of that | |||
material by anyone who conveys the material (or modified versions of | |||
it) with contractual assumptions of liability to the recipient, for | |||
any liability that these contractual assumptions directly impose on | |||
those licensors and authors. | |||
All other non-permissive additional terms are considered "further | |||
restrictions" within the meaning of section 10. If the Program as you | |||
received it, or any part of it, contains a notice stating that it is | |||
governed by this License along with a term that is a further | |||
restriction, you may remove that term. If a license document contains | |||
a further restriction but permits relicensing or conveying under this | |||
License, you may add to a covered work material governed by the terms | |||
of that license document, provided that the further restriction does | |||
not survive such relicensing or conveying. | |||
If you add terms to a covered work in accord with this section, you | |||
must place, in the relevant source files, a statement of the | |||
additional terms that apply to those files, or a notice indicating | |||
where to find the applicable terms. | |||
Additional terms, permissive or non-permissive, may be stated in the | |||
form of a separately written license, or stated as exceptions; | |||
the above requirements apply either way. | |||
8. Termination. | |||
You may not propagate or modify a covered work except as expressly | |||
provided under this License. Any attempt otherwise to propagate or | |||
modify it is void, and will automatically terminate your rights under | |||
this License (including any patent licenses granted under the third | |||
paragraph of section 11). | |||
However, if you cease all violation of this License, then your | |||
license from a particular copyright holder is reinstated (a) | |||
provisionally, unless and until the copyright holder explicitly and | |||
finally terminates your license, and (b) permanently, if the copyright | |||
holder fails to notify you of the violation by some reasonable means | |||
prior to 60 days after the cessation. | |||
Moreover, your license from a particular copyright holder is | |||
reinstated permanently if the copyright holder notifies you of the | |||
violation by some reasonable means, this is the first time you have | |||
received notice of violation of this License (for any work) from that | |||
copyright holder, and you cure the violation prior to 30 days after | |||
your receipt of the notice. | |||
Termination of your rights under this section does not terminate the | |||
licenses of parties who have received copies or rights from you under | |||
this License. If your rights have been terminated and not permanently | |||
reinstated, you do not qualify to receive new licenses for the same | |||
material under section 10. | |||
9. Acceptance Not Required for Having Copies. | |||
You are not required to accept this License in order to receive or | |||
run a copy of the Program. Ancillary propagation of a covered work | |||
occurring solely as a consequence of using peer-to-peer transmission | |||
to receive a copy likewise does not require acceptance. However, | |||
nothing other than this License grants you permission to propagate or | |||
modify any covered work. These actions infringe copyright if you do | |||
not accept this License. Therefore, by modifying or propagating a | |||
covered work, you indicate your acceptance of this License to do so. | |||
10. Automatic Licensing of Downstream Recipients. | |||
Each time you convey a covered work, the recipient automatically | |||
receives a license from the original licensors, to run, modify and | |||
propagate that work, subject to this License. You are not responsible | |||
for enforcing compliance by third parties with this License. | |||
An "entity transaction" is a transaction transferring control of an | |||
organization, or substantially all assets of one, or subdividing an | |||
organization, or merging organizations. If propagation of a covered | |||
work results from an entity transaction, each party to that | |||
transaction who receives a copy of the work also receives whatever | |||
licenses to the work the party's predecessor in interest had or could | |||
give under the previous paragraph, plus a right to possession of the | |||
Corresponding Source of the work from the predecessor in interest, if | |||
the predecessor has it or can get it with reasonable efforts. | |||
You may not impose any further restrictions on the exercise of the | |||
rights granted or affirmed under this License. For example, you may | |||
not impose a license fee, royalty, or other charge for exercise of | |||
rights granted under this License, and you may not initiate litigation | |||
(including a cross-claim or counterclaim in a lawsuit) alleging that | |||
any patent claim is infringed by making, using, selling, offering for | |||
sale, or importing the Program or any portion of it. | |||
11. Patents. | |||
A "contributor" is a copyright holder who authorizes use under this | |||
License of the Program or a work on which the Program is based. The | |||
work thus licensed is called the contributor's "contributor version". | |||
A contributor's "essential patent claims" are all patent claims | |||
owned or controlled by the contributor, whether already acquired or | |||
hereafter acquired, that would be infringed by some manner, permitted | |||
by this License, of making, using, or selling its contributor version, | |||
but do not include claims that would be infringed only as a | |||
consequence of further modification of the contributor version. For | |||
purposes of this definition, "control" includes the right to grant | |||
patent sublicenses in a manner consistent with the requirements of | |||
this License. | |||
Each contributor grants you a non-exclusive, worldwide, royalty-free | |||
patent license under the contributor's essential patent claims, to | |||
make, use, sell, offer for sale, import and otherwise run, modify and | |||
propagate the contents of its contributor version. | |||
In the following three paragraphs, a "patent license" is any express | |||
agreement or commitment, however denominated, not to enforce a patent | |||
(such as an express permission to practice a patent or covenant not to | |||
sue for patent infringement). To "grant" such a patent license to a | |||
party means to make such an agreement or commitment not to enforce a | |||
patent against the party. | |||
If you convey a covered work, knowingly relying on a patent license, | |||
and the Corresponding Source of the work is not available for anyone | |||
to copy, free of charge and under the terms of this License, through a | |||
publicly available network server or other readily accessible means, | |||
then you must either (1) cause the Corresponding Source to be so | |||
available, or (2) arrange to deprive yourself of the benefit of the | |||
patent license for this particular work, or (3) arrange, in a manner | |||
consistent with the requirements of this License, to extend the patent | |||
license to downstream recipients. "Knowingly relying" means you have | |||
actual knowledge that, but for the patent license, your conveying the | |||
covered work in a country, or your recipient's use of the covered work | |||
in a country, would infringe one or more identifiable patents in that | |||
country that you have reason to believe are valid. | |||
If, pursuant to or in connection with a single transaction or | |||
arrangement, you convey, or propagate by procuring conveyance of, a | |||
covered work, and grant a patent license to some of the parties | |||
receiving the covered work authorizing them to use, propagate, modify | |||
or convey a specific copy of the covered work, then the patent license | |||
you grant is automatically extended to all recipients of the covered | |||
work and works based on it. | |||
A patent license is "discriminatory" if it does not include within | |||
the scope of its coverage, prohibits the exercise of, or is | |||
conditioned on the non-exercise of one or more of the rights that are | |||
specifically granted under this License. You may not convey a covered | |||
work if you are a party to an arrangement with a third party that is | |||
in the business of distributing software, under which you make payment | |||
to the third party based on the extent of your activity of conveying | |||
the work, and under which the third party grants, to any of the | |||
parties who would receive the covered work from you, a discriminatory | |||
patent license (a) in connection with copies of the covered work | |||
conveyed by you (or copies made from those copies), or (b) primarily | |||
for and in connection with specific products or compilations that | |||
contain the covered work, unless you entered into that arrangement, | |||
or that patent license was granted, prior to 28 March 2007. | |||
Nothing in this License shall be construed as excluding or limiting | |||
any implied license or other defenses to infringement that may | |||
otherwise be available to you under applicable patent law. | |||
12. No Surrender of Others' Freedom. | |||
If conditions are imposed on you (whether by court order, agreement or | |||
otherwise) that contradict the conditions of this License, they do not | |||
excuse you from the conditions of this License. If you cannot convey a | |||
covered work so as to satisfy simultaneously your obligations under this | |||
License and any other pertinent obligations, then as a consequence you may | |||
not convey it at all. For example, if you agree to terms that obligate you | |||
to collect a royalty for further conveying from those to whom you convey | |||
the Program, the only way you could satisfy both those terms and this | |||
License would be to refrain entirely from conveying the Program. | |||
13. Use with the GNU Affero General Public License. | |||
Notwithstanding any other provision of this License, you have | |||
permission to link or combine any covered work with a work licensed | |||
under version 3 of the GNU Affero General Public License into a single | |||
combined work, and to convey the resulting work. The terms of this | |||
License will continue to apply to the part which is the covered work, | |||
but the special requirements of the GNU Affero General Public License, | |||
section 13, concerning interaction through a network will apply to the | |||
combination as such. | |||
14. Revised Versions of this License. | |||
The Free Software Foundation may publish revised and/or new versions of | |||
the GNU General Public License from time to time. Such new versions will | |||
be similar in spirit to the present version, but may differ in detail to | |||
address new problems or concerns. | |||
Each version is given a distinguishing version number. If the | |||
Program specifies that a certain numbered version of the GNU General | |||
Public License "or any later version" applies to it, you have the | |||
option of following the terms and conditions either of that numbered | |||
version or of any later version published by the Free Software | |||
Foundation. If the Program does not specify a version number of the | |||
GNU General Public License, you may choose any version ever published | |||
by the Free Software Foundation. | |||
If the Program specifies that a proxy can decide which future | |||
versions of the GNU General Public License can be used, that proxy's | |||
public statement of acceptance of a version permanently authorizes you | |||
to choose that version for the Program. | |||
Later license versions may give you additional or different | |||
permissions. However, no additional obligations are imposed on any | |||
author or copyright holder as a result of your choosing to follow a | |||
later version. | |||
15. Disclaimer of Warranty. | |||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY | |||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT | |||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY | |||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, | |||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM | |||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF | |||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION. | |||
16. Limitation of Liability. | |||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | |||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS | |||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY | |||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE | |||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF | |||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD | |||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), | |||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF | |||
SUCH DAMAGES. | |||
17. Interpretation of Sections 15 and 16. | |||
If the disclaimer of warranty and limitation of liability provided | |||
above cannot be given local legal effect according to their terms, | |||
reviewing courts shall apply local law that most closely approximates | |||
an absolute waiver of all civil liability in connection with the | |||
Program, unless a warranty or assumption of liability accompanies a | |||
copy of the Program in return for a fee. | |||
END OF TERMS AND CONDITIONS | |||
How to Apply These Terms to Your New Programs | |||
If you develop a new program, and you want it to be of the greatest | |||
possible use to the public, the best way to achieve this is to make it | |||
free software which everyone can redistribute and change under these terms. | |||
To do so, attach the following notices to the program. It is safest | |||
to attach them to the start of each source file to most effectively | |||
state the exclusion of warranty; and each file should have at least | |||
the "copyright" line and a pointer to where the full notice is found. | |||
<one line to give the program's name and a brief idea of what it does.> | |||
Copyright (C) <year> <name of author> | |||
This program is free software: you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation, either version 3 of the License, or | |||
(at your option) any later version. | |||
This program 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 General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
Also add information on how to contact you by electronic and paper mail. | |||
If the program does terminal interaction, make it output a short | |||
notice like this when it starts in an interactive mode: | |||
<program> Copyright (C) <year> <name of author> | |||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | |||
This is free software, and you are welcome to redistribute it | |||
under certain conditions; type `show c' for details. | |||
The hypothetical commands `show w' and `show c' should show the appropriate | |||
parts of the General Public License. Of course, your program's commands | |||
might be different; for a GUI interface, you would use an "about box". | |||
You should also get your employer (if you work as a programmer) or school, | |||
if any, to sign a "copyright disclaimer" for the program, if necessary. | |||
For more information on this, and how to apply and follow the GNU GPL, see | |||
<http://www.gnu.org/licenses/>. | |||
The GNU General Public License does not permit incorporating your program | |||
into proprietary programs. If your program is a subroutine library, you | |||
may consider it more useful to permit linking proprietary applications with | |||
the library. If this is what you want to do, use the GNU Lesser General | |||
Public License instead of this License. But first, please read | |||
<http://www.gnu.org/philosophy/why-not-lgpl.html>. |
@@ -0,0 +1,120 @@ | |||
""" | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
""" | |||
""" | |||
Front-end programmer for the LUFA HID class bootloader. | |||
Usage: | |||
python hid_bootloader_loader.py <Device> <Input>.hex | |||
Example: | |||
python hid_bootloader_loader.py at90usb1287 Mouse.hex | |||
Requires the pywinusb (https://pypi.python.org/pypi/pywinusb/) and | |||
IntelHex (http://bialix.com/intelhex/) libraries. | |||
""" | |||
import sys | |||
from pywinusb import hid | |||
from intelhex import IntelHex | |||
# Device information table | |||
device_info_map = dict() | |||
device_info_map['at90usb1287'] = {'page_size': 256, 'flash_kb': 128} | |||
device_info_map['at90usb1286'] = {'page_size': 256, 'flash_kb': 128} | |||
device_info_map['at90usb647'] = {'page_size': 256, 'flash_kb': 64} | |||
device_info_map['at90usb646'] = {'page_size': 256, 'flash_kb': 64} | |||
device_info_map['atmega32u4'] = {'page_size': 128, 'flash_kb': 32} | |||
device_info_map['atmega32u2'] = {'page_size': 128, 'flash_kb': 32} | |||
device_info_map['atmega16u4'] = {'page_size': 128, 'flash_kb': 16} | |||
device_info_map['atmega16u2'] = {'page_size': 128, 'flash_kb': 16} | |||
device_info_map['at90usb162'] = {'page_size': 128, 'flash_kb': 16} | |||
device_info_map['atmega8u2'] = {'page_size': 128, 'flash_kb': 8} | |||
device_info_map['at90usb82'] = {'page_size': 128, 'flash_kb': 8} | |||
def get_hid_device_handle(): | |||
hid_device_filter = hid.HidDeviceFilter(vendor_id=0x03EB, | |||
product_id=0x2067) | |||
valid_hid_devices = hid_device_filter.get_devices() | |||
if len(valid_hid_devices) is 0: | |||
return None | |||
else: | |||
return valid_hid_devices[0] | |||
def send_page_data(hid_device, address, data): | |||
# Bootloader page data should be the HID Report ID (always zero) followed | |||
# by the starting address to program, then one device's flash page worth | |||
# of data | |||
output_report_data = [0] | |||
output_report_data.extend([address & 0xFF, address >> 8]) | |||
output_report_data.extend(data) | |||
hid_device.send_output_report(output_report_data) | |||
def program_device(hex_data, device_info): | |||
hid_device = get_hid_device_handle() | |||
if hid_device is None: | |||
print("No valid HID device found.") | |||
sys.exit(1) | |||
try: | |||
hid_device.open() | |||
print("Connected to bootloader.") | |||
# Program in all data from the loaded HEX file, in a number of device | |||
# page sized chunks | |||
for addr in range(0, hex_data.maxaddr(), device_info['page_size']): | |||
# Compute the address range of the current page in the device | |||
current_page_range = range(addr, addr+device_info['page_size']) | |||
# Extract the data from the hex file at the specified start page | |||
# address and convert it to a regular list of bytes | |||
page_data = [hex_data[i] for i in current_page_range] | |||
print("Writing address 0x%04X-0x%04X" % (current_page_range[0], current_page_range[-1])) | |||
# Devices with more than 64KB of flash should shift down the page | |||
# address so that it is 16-bit (page size is guaranteed to be | |||
# >= 256 bytes so no non-zero address bits are discarded) | |||
if device_info['flash_kb'] < 64: | |||
send_page_data(hid_device, addr, page_data) | |||
else: | |||
send_page_data(hid_device, addr >> 8, page_data) | |||
# Once programming is complete, start the application via a dummy page | |||
# program to the page address 0xFFFF | |||
print("Programming complete, starting application.") | |||
send_page_data(hid_device, 0xFFFF, [0] * device_info['page_size']) | |||
finally: | |||
hid_device.close() | |||
if __name__ == '__main__': | |||
# Load the specified HEX file | |||
try: | |||
hex_data = IntelHex(sys.argv[2]) | |||
except: | |||
print("Could not open the specified HEX file.") | |||
sys.exit(1) | |||
# Retrieve the device information entry for the specified device | |||
try: | |||
device_info = device_info_map[sys.argv[1]] | |||
except: | |||
print("Unknown device name specified.") | |||
sys.exit(1) | |||
program_device(hex_data, device_info) |
@@ -0,0 +1,123 @@ | |||
<asf xmlversion="1.0"> | |||
<project caption="HID Bootloader - 128KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.hid.avr8.128_4" force-caption="true" workspace-name="lufa_hid_128kb_4kb_"> | |||
<require idref="lufa.bootloaders.hid"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="at90usb1287"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<config name="config.compiler.optimization.level" value="size"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0x1F000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x1F000"/> | |||
</project> | |||
<project caption="HID Bootloader - 64KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.hid.avr8.64_4" force-caption="true" workspace-name="lufa_hid_64kb_4kb_"> | |||
<require idref="lufa.bootloaders.hid"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="at90usb647"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<config name="config.compiler.optimization.level" value="size"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0xF000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0xF000"/> | |||
</project> | |||
<project caption="HID Bootloader - 32KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.hid.avr8.32_4" force-caption="true" workspace-name="lufa_hid_32kb_4kb_"> | |||
<require idref="lufa.bootloaders.hid"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="atmega32u4"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<config name="config.compiler.optimization.level" value="size"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0x7000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x7000"/> | |||
</project> | |||
<project caption="HID Bootloader - 16KB FLASH / 2KB Boot - AVR8 Architecture" id="lufa.bootloaders.hid.avr8.16_2" force-caption="true" workspace-name="lufa_hid_16kb_2kb_"> | |||
<require idref="lufa.bootloaders.hid"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="atmega16u2"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<config name="config.compiler.optimization.level" value="size"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0x3800"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x3800"/> | |||
</project> | |||
<project caption="HID Bootloader - 8KB FLASH / 2KB Boot - AVR8 Architecture" id="lufa.bootloaders.hid.avr8.8_2" force-caption="true" workspace-name="lufa_hid_8kb_2kb_"> | |||
<require idref="lufa.bootloaders.hid"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="atmega8u2"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<config name="config.compiler.optimization.level" value="size"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0x1800"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x1800"/> | |||
</project> | |||
<module type="application" id="lufa.bootloaders.hid" caption="HID Bootloader"> | |||
<info type="description" value="summary"> | |||
HID Class Bootloader, capable of reprogramming a device via a custom cross-platform command line utility when plugged into a host. | |||
</info> | |||
<info type="gui-flag" value="move-to-root"/> | |||
<info type="keyword" value="Technology"> | |||
<keyword value="Bootloaders"/> | |||
<keyword value="USB Device"/> | |||
</info> | |||
<device-support-alias value="lufa_avr8"/> | |||
<device-support-alias value="lufa_xmega"/> | |||
<device-support-alias value="lufa_uc3"/> | |||
<build type="include-path" value="."/> | |||
<build type="c-source" value="BootloaderHID.c"/> | |||
<build type="header-file" value="BootloaderHID.h"/> | |||
<build type="c-source" value="Descriptors.c"/> | |||
<build type="header-file" value="Descriptors.h"/> | |||
<build type="module-config" subtype="path" value="Config"/> | |||
<build type="header-file" value="Config/LUFAConfig.h"/> | |||
<build type="distribute" subtype="user-file" value="doxyfile"/> | |||
<build type="distribute" subtype="user-file" value="BootloaderHID.txt"/> | |||
<build type="distribute" subtype="directory" value="HostLoaderApp"/> | |||
<build type="distribute" subtype="directory" value="HostLoaderApp_Python"/> | |||
<require idref="lufa.common"/> | |||
<require idref="lufa.platform"/> | |||
<require idref="lufa.drivers.usb"/> | |||
<require idref="lufa.drivers.board"/> | |||
<require idref="lufa.drivers.board.leds"/> | |||
</module> | |||
</asf> |
@@ -0,0 +1,48 @@ | |||
# | |||
# LUFA Library | |||
# Copyright (C) Dean Camera, 2014. | |||
# | |||
# dean [at] fourwalledcubicle [dot] com | |||
# www.lufa-lib.org | |||
# | |||
# -------------------------------------- | |||
# LUFA Project Makefile. | |||
# -------------------------------------- | |||
# Run "make help" for target help. | |||
MCU = at90usb1287 | |||
ARCH = AVR8 | |||
BOARD = USBKEY | |||
F_CPU = 8000000 | |||
F_USB = $(F_CPU) | |||
OPTIMIZATION = s | |||
TARGET = BootloaderHID | |||
SRC = $(TARGET).c Descriptors.c $(LUFA_SRC_USB) | |||
LUFA_PATH = ../../LUFA | |||
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/ | |||
LD_FLAGS = -Wl,--section-start=.text=$(BOOT_START_OFFSET) | |||
# Flash size and bootloader section sizes of the target, in KB. These must | |||
# match the target's total FLASH size and the bootloader size set in the | |||
# device's fuses. | |||
FLASH_SIZE_KB := 128 | |||
BOOT_SECTION_SIZE_KB := 8 | |||
# Bootloader address calculation formulas | |||
# Do not modify these macros, but rather modify the dependent values above. | |||
CALC_ADDRESS_IN_HEX = $(shell printf "0x%X" $$(( $(1) )) ) | |||
BOOT_START_OFFSET = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) - $(BOOT_SECTION_SIZE_KB)) * 1024 ) | |||
BOOT_SEC_OFFSET = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) * 1024) - ($(strip $(1))) ) | |||
# Default target | |||
all: | |||
# Include LUFA build script makefiles | |||
include $(LUFA_PATH)/Build/lufa_core.mk | |||
include $(LUFA_PATH)/Build/lufa_sources.mk | |||
include $(LUFA_PATH)/Build/lufa_build.mk | |||
include $(LUFA_PATH)/Build/lufa_cppcheck.mk | |||
include $(LUFA_PATH)/Build/lufa_doxygen.mk | |||
include $(LUFA_PATH)/Build/lufa_avrdude.mk | |||
include $(LUFA_PATH)/Build/lufa_atprogram.mk |
@@ -0,0 +1,76 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Bootloader user application API functions. | |||
*/ | |||
#include "BootloaderAPI.h" | |||
void BootloaderAPI_ErasePage(const uint32_t Address) | |||
{ | |||
boot_page_erase_safe(Address); | |||
boot_spm_busy_wait(); | |||
boot_rww_enable(); | |||
} | |||
void BootloaderAPI_WritePage(const uint32_t Address) | |||
{ | |||
boot_page_write_safe(Address); | |||
boot_spm_busy_wait(); | |||
boot_rww_enable(); | |||
} | |||
void BootloaderAPI_FillWord(const uint32_t Address, const uint16_t Word) | |||
{ | |||
boot_page_fill_safe(Address, Word); | |||
} | |||
uint8_t BootloaderAPI_ReadSignature(const uint16_t Address) | |||
{ | |||
return boot_signature_byte_get(Address); | |||
} | |||
uint8_t BootloaderAPI_ReadFuse(const uint16_t Address) | |||
{ | |||
return boot_lock_fuse_bits_get(Address); | |||
} | |||
uint8_t BootloaderAPI_ReadLock(void) | |||
{ | |||
return boot_lock_fuse_bits_get(GET_LOCK_BITS); | |||
} | |||
void BootloaderAPI_WriteLock(const uint8_t LockBits) | |||
{ | |||
boot_lock_bits_set_safe(LockBits); | |||
} | |||
@@ -0,0 +1,63 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Header file for BootloaderAPI.c. | |||
*/ | |||
#ifndef _BOOTLOADER_API_H_ | |||
#define _BOOTLOADER_API_H_ | |||
/* Includes: */ | |||
#include <avr/io.h> | |||
#include <avr/boot.h> | |||
#include <stdbool.h> | |||
#include <LUFA/Common/Common.h> | |||
/* Macros: */ | |||
#if AUX_BOOT_SECTION_SIZE > 0 | |||
#define AUX_BOOT_SECTION __attribute__((section(".boot_aux"))) | |||
#else | |||
#define AUX_BOOT_SECTION | |||
#endif | |||
/* Function Prototypes: */ | |||
void BootloaderAPI_ErasePage(const uint32_t Address); | |||
void BootloaderAPI_WritePage(const uint32_t Address); | |||
void BootloaderAPI_FillWord(const uint32_t Address, const uint16_t Word); | |||
uint8_t BootloaderAPI_ReadSignature(const uint16_t Address); | |||
uint8_t BootloaderAPI_ReadFuse(const uint16_t Address); | |||
uint8_t BootloaderAPI_ReadLock(void); | |||
void BootloaderAPI_WriteLock(const uint8_t LockBits); | |||
#endif | |||
@@ -0,0 +1,102 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
#if AUX_BOOT_SECTION_SIZE > 0 | |||
#warning Using a AUX bootloader section in addition to the defined bootloader space (see documentation). | |||
; Trampoline to jump over the AUX bootloader section to the start of the bootloader, | |||
; on devices where an AUX bootloader section is used. | |||
.section .boot_aux_trampoline, "ax" | |||
.global Boot_AUX_Trampoline | |||
Boot_AUX_Trampoline: | |||
jmp BOOT_START_ADDR | |||
#endif | |||
; Trampolines to actual API implementations if the target address is outside the | |||
; range of a rjmp instruction (can happen with large bootloader sections) | |||
.section .apitable_trampolines, "ax" | |||
.global BootloaderAPI_Trampolines | |||
BootloaderAPI_Trampolines: | |||
BootloaderAPI_ErasePage_Trampoline: | |||
jmp BootloaderAPI_ErasePage | |||
BootloaderAPI_WritePage_Trampoline: | |||
jmp BootloaderAPI_WritePage | |||
BootloaderAPI_FillWord_Trampoline: | |||
jmp BootloaderAPI_FillWord | |||
BootloaderAPI_ReadSignature_Trampoline: | |||
jmp BootloaderAPI_ReadSignature | |||
BootloaderAPI_ReadFuse_Trampoline: | |||
jmp BootloaderAPI_ReadFuse | |||
BootloaderAPI_ReadLock_Trampoline: | |||
jmp BootloaderAPI_ReadLock | |||
BootloaderAPI_WriteLock_Trampoline: | |||
jmp BootloaderAPI_WriteLock | |||
BootloaderAPI_UNUSED1: | |||
ret | |||
BootloaderAPI_UNUSED2: | |||
ret | |||
BootloaderAPI_UNUSED3: | |||
ret | |||
BootloaderAPI_UNUSED4: | |||
ret | |||
BootloaderAPI_UNUSED5: | |||
ret | |||
; API function jump table | |||
.section .apitable_jumptable, "ax" | |||
.global BootloaderAPI_JumpTable | |||
BootloaderAPI_JumpTable: | |||
rjmp BootloaderAPI_ErasePage_Trampoline | |||
rjmp BootloaderAPI_WritePage_Trampoline | |||
rjmp BootloaderAPI_FillWord_Trampoline | |||
rjmp BootloaderAPI_ReadSignature_Trampoline | |||
rjmp BootloaderAPI_ReadFuse_Trampoline | |||
rjmp BootloaderAPI_ReadLock_Trampoline | |||
rjmp BootloaderAPI_WriteLock_Trampoline | |||
rjmp BootloaderAPI_UNUSED1 ; UNUSED ENTRY 1 | |||
rjmp BootloaderAPI_UNUSED2 ; UNUSED ENTRY 2 | |||
rjmp BootloaderAPI_UNUSED3 ; UNUSED ENTRY 3 | |||
rjmp BootloaderAPI_UNUSED4 ; UNUSED ENTRY 4 | |||
rjmp BootloaderAPI_UNUSED5 ; UNUSED ENTRY 5 | |||
; Bootloader table signatures and information | |||
.section .apitable_signatures, "ax" | |||
.global BootloaderAPI_Signatures | |||
BootloaderAPI_Signatures: | |||
.long BOOT_START_ADDR ; Start address of the bootloader | |||
.word 0xDF30 ; Signature for the MS class bootloader, V1 | |||
.word 0xDCFB ; Signature for a LUFA class bootloader |
@@ -0,0 +1,238 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Main source file for the Mass Storage class bootloader. This file contains the complete bootloader logic. | |||
*/ | |||
#define INCLUDE_FROM_BOOTLOADER_MASSSTORAGE_C | |||
#include "BootloaderMassStorage.h" | |||
/** LUFA Mass Storage Class driver interface configuration and state information. This structure is | |||
* passed to all Mass Storage Class driver functions, so that multiple instances of the same class | |||
* within a device can be differentiated from one another. | |||
*/ | |||
USB_ClassInfo_MS_Device_t Disk_MS_Interface = | |||
{ | |||
.Config = | |||
{ | |||
.InterfaceNumber = INTERFACE_ID_MassStorage, | |||
.DataINEndpoint = | |||
{ | |||
.Address = MASS_STORAGE_IN_EPADDR, | |||
.Size = MASS_STORAGE_IO_EPSIZE, | |||
.Banks = 1, | |||
}, | |||
.DataOUTEndpoint = | |||
{ | |||
.Address = MASS_STORAGE_OUT_EPADDR, | |||
.Size = MASS_STORAGE_IO_EPSIZE, | |||
.Banks = 1, | |||
}, | |||
.TotalLUNs = 1, | |||
}, | |||
}; | |||
/** Flag to indicate if the bootloader should be running, or should exit and allow the application code to run | |||
* via a soft reset. When cleared, the bootloader will abort, the USB interface will shut down and the application | |||
* started via a forced watchdog reset. | |||
*/ | |||
bool RunBootloader = true; | |||
/** Magic lock for forced application start. If the HWBE fuse is programmed and BOOTRST is unprogrammed, the bootloader | |||
* will start if the /HWB line of the AVR is held low and the system is reset. However, if the /HWB line is still held | |||
* low when the application attempts to start via a watchdog reset, the bootloader will re-start. If set to the value | |||
* \ref MAGIC_BOOT_KEY the special init function \ref Application_Jump_Check() will force the application to start. | |||
*/ | |||
uint16_t MagicBootKey ATTR_NO_INIT; | |||
/** Indicates if the bootloader is allowed to exit immediately if \ref RunBootloader is \c false. During shutdown all | |||
* pending commands must be processed before jumping to the user-application, thus this tracks the main program loop | |||
* iterations since a SCSI command from the host was received. | |||
*/ | |||
static uint8_t TicksSinceLastCommand = 0; | |||
/** Special startup routine to check if the bootloader was started via a watchdog reset, and if the magic application | |||
* start key has been loaded into \ref MagicBootKey. If the bootloader started via the watchdog and the key is valid, | |||
* this will force the user application to start via a software jump. | |||
*/ | |||
void Application_Jump_Check(void) | |||
{ | |||
bool JumpToApplication = false; | |||
#if (BOARD == BOARD_LEONARDO) | |||
/* Enable pull-up on the IO13 pin so we can use it to select the mode */ | |||
PORTC |= (1 << 7); | |||
Delay_MS(10); | |||
/* If IO13 is not jumpered to ground, start the user application instead */ | |||
JumpToApplication |= ((PINC & (1 << 7)) != 0); | |||
/* Disable pull-up after the check has completed */ | |||
PORTC &= ~(1 << 7); | |||
#elif ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1)) | |||
/* Disable JTAG debugging */ | |||
JTAG_DISABLE(); | |||
/* Enable pull-up on the JTAG TCK pin so we can use it to select the mode */ | |||
PORTF |= (1 << 4); | |||
Delay_MS(10); | |||
/* If the TCK pin is not jumpered to ground, start the user application instead */ | |||
JumpToApplication |= ((PINF & (1 << 4)) != 0); | |||
/* Re-enable JTAG debugging */ | |||
JTAG_ENABLE(); | |||
#endif | |||
/* If the reset source was the bootloader and the key is correct, clear it and jump to the application */ | |||
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY)) | |||
{ | |||
MagicBootKey = 0; | |||
JumpToApplication = true; | |||
} | |||
if (JumpToApplication) | |||
{ | |||
// cppcheck-suppress constStatement | |||
((void (*)(void))0x0000)(); | |||
} | |||
} | |||
/** Main program entry point. This routine configures the hardware required by the application, then | |||
* enters a loop to run the application tasks in sequence. | |||
*/ | |||
int main(void) | |||
{ | |||
SetupHardware(); | |||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); | |||
GlobalInterruptEnable(); | |||
while (RunBootloader || TicksSinceLastCommand++ < 0xFF) | |||
{ | |||
MS_Device_USBTask(&Disk_MS_Interface); | |||
USB_USBTask(); | |||
} | |||
/* Disconnect from the host - USB interface will be reset later along with the AVR */ | |||
USB_Detach(); | |||
/* Unlock the forced application start mode of the bootloader if it is restarted */ | |||
MagicBootKey = MAGIC_BOOT_KEY; | |||
/* Enable the watchdog and force a timeout to reset the AVR */ | |||
wdt_enable(WDTO_250MS); | |||
for (;;); | |||
} | |||
/** Configures the board hardware and chip peripherals for the demo's functionality. */ | |||
static void SetupHardware(void) | |||
{ | |||
/* Disable watchdog if enabled by bootloader/fuses */ | |||
MCUSR &= ~(1 << WDRF); | |||
wdt_disable(); | |||
/* Disable clock division */ | |||
clock_prescale_set(clock_div_1); | |||
/* Relocate the interrupt vector table to the bootloader section */ | |||
MCUCR = (1 << IVCE); | |||
MCUCR = (1 << IVSEL); | |||
/* Hardware Initialization */ | |||
LEDs_Init(); | |||
USB_Init(); | |||
/* Bootloader active LED toggle timer initialization */ | |||
TIMSK1 = (1 << TOIE1); | |||
TCCR1B = ((1 << CS11) | (1 << CS10)); | |||
} | |||
/** ISR to periodically toggle the LEDs on the board to indicate that the bootloader is active. */ | |||
ISR(TIMER1_OVF_vect, ISR_BLOCK) | |||
{ | |||
LEDs_ToggleLEDs(LEDS_LED1 | LEDS_LED2); | |||
} | |||
/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs. */ | |||
void EVENT_USB_Device_Connect(void) | |||
{ | |||
/* Indicate USB enumerating */ | |||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); | |||
} | |||
/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via | |||
* the status LEDs and stops the Mass Storage management task. | |||
*/ | |||
void EVENT_USB_Device_Disconnect(void) | |||
{ | |||
/* Indicate USB not ready */ | |||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); | |||
} | |||
/** Event handler for the library USB Configuration Changed event. */ | |||
void EVENT_USB_Device_ConfigurationChanged(void) | |||
{ | |||
bool ConfigSuccess = true; | |||
/* Setup Mass Storage Data Endpoints */ | |||
ConfigSuccess &= MS_Device_ConfigureEndpoints(&Disk_MS_Interface); | |||
/* Indicate endpoint configuration success or failure */ | |||
LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR); | |||
} | |||
/** Event handler for the library USB Control Request reception event. */ | |||
void EVENT_USB_Device_ControlRequest(void) | |||
{ | |||
MS_Device_ProcessControlRequest(&Disk_MS_Interface); | |||
} | |||
/** Mass Storage class driver callback function the reception of SCSI commands from the host, which must be processed. | |||
* | |||
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface configuration structure being referenced | |||
*/ | |||
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) | |||
{ | |||
bool CommandSuccess; | |||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY); | |||
CommandSuccess = SCSI_DecodeSCSICommand(MSInterfaceInfo); | |||
LEDs_SetAllLEDs(LEDMASK_USB_READY); | |||
/* Signal that a command was processed, must not exit bootloader yet */ | |||
TicksSinceLastCommand = 0; | |||
return CommandSuccess; | |||
} |
@@ -0,0 +1,99 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Header file for BootloaderMassStorage.c. | |||
*/ | |||
#ifndef _BOOTLOADER_MASS_STORAGE_H_ | |||
#define _BOOTLOADER_MASS_STORAGE_H_ | |||
/* Includes: */ | |||
#include <avr/io.h> | |||
#include <avr/wdt.h> | |||
#include <avr/power.h> | |||
#include <avr/interrupt.h> | |||
#include <string.h> | |||
#include "Descriptors.h" | |||
#include "Config/AppConfig.h" | |||
#include "Lib/SCSI.h" | |||
#include <LUFA/Drivers/Board/LEDs.h> | |||
#include <LUFA/Drivers/USB/USB.h> | |||
#include <LUFA/Platform/Platform.h> | |||
/* Preprocessor Checks: */ | |||
#if !defined(__OPTIMIZE_SIZE__) | |||
#error This bootloader requires that it be optimized for size, not speed, to fit into the target device. Change optimization settings and try again. | |||
#endif | |||
/* Macros: */ | |||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */ | |||
#define LEDMASK_USB_NOTREADY LEDS_LED1 | |||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */ | |||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3) | |||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */ | |||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4) | |||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */ | |||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3) | |||
/** LED mask for the library LED driver, to indicate that the USB interface is busy. */ | |||
#define LEDMASK_USB_BUSY LEDS_LED2 | |||
/** Magic bootloader key to unlock forced application start mode. */ | |||
#define MAGIC_BOOT_KEY 0xDC42 | |||
/* Global Variables: */ | |||
extern bool RunBootloader; | |||
/* Function Prototypes: */ | |||
int main(void) AUX_BOOT_SECTION; | |||
void Application_Jump_Check(void) ATTR_INIT_SECTION(3); | |||
void EVENT_USB_Device_Connect(void) AUX_BOOT_SECTION; | |||
void EVENT_USB_Device_Disconnect(void) AUX_BOOT_SECTION; | |||
void EVENT_USB_Device_ConfigurationChanged(void) AUX_BOOT_SECTION; | |||
void EVENT_USB_Device_ControlRequest(void) AUX_BOOT_SECTION; | |||
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION; | |||
#if defined(INCLUDE_FROM_BOOTLOADER_MASSSTORAGE_C) | |||
static void SetupHardware(void) AUX_BOOT_SECTION; | |||
#endif | |||
#endif | |||
@@ -0,0 +1,225 @@ | |||
/** \file | |||
* | |||
* This file contains special DoxyGen information for the generation of the main page and other special | |||
* documentation pages. It is not a project source file. | |||
*/ | |||
/** \mainpage Mass Storage Class USB AVR Bootloader | |||
* | |||
* \section Sec_Compat Demo Compatibility: | |||
* | |||
* The following list indicates what microcontrollers are compatible with this demo. | |||
* | |||
* \li Series 7 USB AVRs (AT90USBxxx7) | |||
* \li Series 6 USB AVRs (AT90USBxxx6) | |||
* \li Series 4 USB AVRs (ATMEGAxxU4) - <i>See \ref SSec_Aux_Space</i> | |||
* \li ATMEGA32U2 - <i>See \ref SSec_Aux_Space</i> | |||
* | |||
* \section Sec_Info USB Information: | |||
* | |||
* The following table gives a rundown of the USB utilization of this demo. | |||
* | |||
* <table> | |||
* <tr> | |||
* <td><b>USB Mode:</b></td> | |||
* <td>Device</td> | |||
* </tr> | |||
* <tr> | |||
* <td><b>USB Class:</b></td> | |||
* <td>Mass Storage Device</td> | |||
* </tr> | |||
* <tr> | |||
* <td><b>USB Subclass:</b></td> | |||
* <td>Bulk-Only Transport</td> | |||
* </tr> | |||
* <tr> | |||
* <td><b>Relevant Standards:</b></td> | |||
* <td>USBIF Mass Storage Standard \n | |||
* USB Bulk-Only Transport Standard \n | |||
* SCSI Primary Commands Specification \n | |||
* SCSI Block Commands Specification</td> | |||
* </tr> | |||
* <tr> | |||
* <td><b>Supported USB Speeds:</b></td> | |||
* <td>Full Speed Mode</td> | |||
* </tr> | |||
* </table> | |||
* | |||
* \section Sec_Description Project Description: | |||
* | |||
* This bootloader enumerates to the host as a Mass Storage device, capable of reading and writing a new binary | |||
* firmware image file, to load firmware onto the AVR. | |||
* | |||
* Out of the box this bootloader builds for the AT90USB1287 with an 8KB bootloader section size, and will fit | |||
* into 6KB of bootloader space. If you wish to alter this size and/or change the AVR model, you will need to | |||
* edit the MCU, FLASH_SIZE_KB and BOOT_SECTION_SIZE_KB values in the accompanying makefile. | |||
* | |||
* When the bootloader is running, the board's LED(s) will flash at regular intervals to distinguish the | |||
* bootloader from the normal user application. | |||
* | |||
* \warning <b>THIS BOOTLOADER IS NOT SECURE.</b> Malicious entities can recover written data, even if the device | |||
* lockbits are set. | |||
* | |||
* \section Sec_Running Running the Bootloader | |||
* | |||
* This bootloader is designed to be started via the HWB mechanism of the USB AVRs; ground the HWB pin (see device | |||
* datasheet) then momentarily ground /RESET to start the bootloader. This assumes the HWBE fuse is set and the BOOTRST | |||
* fuse is cleared. | |||
* | |||
* For board specific exceptions to the above, see below. | |||
* | |||
* \subsection SSec_XPLAIN Atmel Xplain Board | |||
* Ground the USB AVR JTAG's \c TCK pin to ground when powering on the board to start the bootloader. This assumes the | |||
* \c HWBE fuse is cleared and the \c BOOTRST fuse is set as the HWBE pin is not user accessible on this board. | |||
* | |||
* \subsection SSec_Leonardo Arduino Leonardo Board | |||
* Ground \c IO13 when powering the board to start the bootloader. This assumes the \c HWBE fuse is cleared and the | |||
* \c BOOTRST fuse is set as the HWBE pin is not user accessible on this board. | |||
* | |||
* \section Sec_Installation Driver Installation | |||
* | |||
* This bootloader uses the Mass Storage drivers inbuilt into all modern operating systems, thus no additional | |||
* drivers need to be supplied for correct operation. | |||
* | |||
* \section Sec_HostApp Host Controller Application | |||
* | |||
* This bootloader is compatible with all operating systems that support the FAT12 file system format. To reprogram the | |||
* device, overwrite a file stored on the virtual FAT filesystem with a new binary (BIN format) image. Remember to safely | |||
* remove your device from the host using the host OS's ejection APIs, to ensure all data is correctly flushed to the | |||
* bootloader's virtual filesystem and not cached in the OS's file system driver. | |||
* | |||
* The current device firmware can be read from the device by reading a file from the virtual FAT filesystem. | |||
* | |||
* \warning This bootloader is currently <b>incompatible with the Apple MacOS X OS Finder GUI</b>, due to the | |||
* large amount of meta files this OS attempts to write to the disk along with the new binaries. On | |||
* this platform, firmwares must be copied to the disk via the Terminal application only to prevent | |||
* firmware corruption. | |||
* | |||
* \section Sec_API User Application API | |||
* | |||
* Several user application functions for FLASH and other special memory area manipulations are exposed by the bootloader, | |||
* allowing the user application to call into the bootloader at runtime to read and write FLASH data. | |||
* | |||
* By default, the bootloader API jump table is located 32 bytes from the end of the device's FLASH memory, and follows the | |||
* following layout: | |||
* | |||
* \code | |||
* #define BOOTLOADER_API_TABLE_SIZE 32 | |||
* #define BOOTLOADER_API_TABLE_START ((FLASHEND + 1UL) - BOOTLOADER_API_TABLE_SIZE) | |||
* #define BOOTLOADER_API_CALL(Index) (void*)((BOOTLOADER_API_TABLE_START + (Index * 2)) / 2) | |||
* | |||
* void (*BootloaderAPI_ErasePage)(uint32_t Address) = BOOTLOADER_API_CALL(0); | |||
* void (*BootloaderAPI_WritePage)(uint32_t Address) = BOOTLOADER_API_CALL(1); | |||
* void (*BootloaderAPI_FillWord)(uint32_t Address, uint16_t Word) = BOOTLOADER_API_CALL(2); | |||
* uint8_t (*BootloaderAPI_ReadSignature)(uint16_t Address) = BOOTLOADER_API_CALL(3); | |||
* uint8_t (*BootloaderAPI_ReadFuse)(uint16_t Address) = BOOTLOADER_API_CALL(4); | |||
* uint8_t (*BootloaderAPI_ReadLock)(void) = BOOTLOADER_API_CALL(5); | |||
* void (*BootloaderAPI_WriteLock)(uint8_t LockBits) = BOOTLOADER_API_CALL(6); | |||
* | |||
* #define BOOTLOADER_MAGIC_SIGNATURE_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 2)) | |||
* #define BOOTLOADER_MAGIC_SIGNATURE 0xDCFB | |||
* | |||
* #define BOOTLOADER_CLASS_SIGNATURE_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 4)) | |||
* #define BOOTLOADER_MASS_STORAGE_SIGNATURE 0xDF30 | |||
* | |||
* #define BOOTLOADER_ADDRESS_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 8)) | |||
* #define BOOTLOADER_ADDRESS_LENGTH 4 | |||
* \endcode | |||
* | |||
* From the application the API support of the bootloader can be detected by reading the FLASH memory bytes located at address | |||
* \c BOOTLOADER_MAGIC_SIGNATURE_START and comparing them to the value \c BOOTLOADER_MAGIC_SIGNATURE. The class of bootloader | |||
* can be determined by reading the FLASH memory bytes located at address \c BOOTLOADER_CLASS_SIGNATURE_START and comparing them | |||
* to the value \c BOOTLOADER_MASS_STORAGE_SIGNATURE. The start address of the bootloader can be retrieved by reading the bytes | |||
* of FLASH memory starting from address \c BOOTLOADER_ADDRESS_START. | |||
* | |||
* \subsection SSec_Aux_Space Auxiliary Bootloader Section | |||
* To make the bootloader function on smaller devices (those with a physical bootloader section of smaller than 6KB) a second | |||
* section of memory (called the <i>Auxiliary Bootloader Section</i>) is added before the start of the real bootloader section, | |||
* and is filled with a portion of the bootloader code. This allows smaller devices to run the bootloader, at the cost of an | |||
* additional portion of the device's FLASH (the bootloader section size in KB subtracted from the 6KB total size). A small | |||
* trampoline is inserted at the start of the auxiliary section so that the bootloader will run normally in the case of a blank | |||
* application section. | |||
* | |||
* On devices supporting a 8KB bootloader section size, the AUX section is not created in the final binary. | |||
* | |||
* \subsection SSec_API_MemLayout Device Memory Map | |||
* The following illustration indicates the final memory map of the device when loaded with the bootloader. | |||
* | |||
* \verbatim | |||
* +----------------------------+ 0x0000 | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | User Application | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* +----------------------------+ FLASHEND - BOOT_SECTION_SIZE - BOOT_AUX_SECTION_SIZE | |||
* | Booloader Start Trampoline | | |||
* | (Not User App. Accessible) | | |||
* +----------------------------+ FLASHEND - BOOT_SECTION_SIZE - BOOT_AUX_SECTION_SIZE + 4 | |||
* | | | |||
* | Auxiliary Bootloader | | |||
* | Space for Smaller Devices | | |||
* | (Not User App. Accessible) | | |||
* | | | |||
* +----------------------------+ FLASHEND - BOOT_SECTION_SIZE | |||
* | | | |||
* | Bootloader Application | | |||
* | (Not User App. Accessible) | | |||
* | | | |||
* +----------------------------+ FLASHEND - 96 | |||
* | API Table Trampolines | | |||
* | (Not User App. Accessible) | | |||
* +----------------------------+ FLASHEND - 32 | |||
* | Bootloader API Table | | |||
* | (User App. Accessible) | | |||
* +----------------------------+ FLASHEND - 8 | |||
* | Bootloader ID Constants | | |||
* | (User App. Accessible) | | |||
* +----------------------------+ FLASHEND | |||
* \endverbatim | |||
* | |||
* \section Sec_KnownIssues Known Issues: | |||
* | |||
* \par In some cases, the application is not fully loaded into the device. | |||
* Write-caching on some operating systems may interfere with the normal | |||
* operation of the bootloader. Write caching should be disabled when using the | |||
* Mass Storage bootloader, or the file system synced via an appropriate command | |||
* (such as the OS's normal disk ejection command) before disconnecting the device. | |||
* | |||
* \par After loading an application, it is not run automatically on startup. | |||
* Some USB AVR boards ship with the BOOTRST fuse set, causing the bootloader | |||
* to run automatically when the device is reset. In most cases, the BOOTRST | |||
* fuse should be disabled and the HWBE fuse used instead to run the bootloader | |||
* when needed. | |||
* | |||
* \section Sec_Options Project Options | |||
* | |||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value. | |||
* | |||
* <table> | |||
* <tr> | |||
* <th><b>Define Name:</b></th> | |||
* <th><b>Location:</b></th> | |||
* <th><b>Description:</b></th> | |||
* </tr> | |||
* <tr> | |||
* <td>NO_APP_START_ON_EJECT</td> | |||
* <td>AppConfig.h</td> | |||
* <td>Define to disable automatic start of the loaded application when the virtual | |||
* Mass Storage disk is ejected on the host.</td> | |||
* </tr> | |||
* </table> | |||
*/ | |||
@@ -0,0 +1,47 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* \brief Application Configuration Header File | |||
* | |||
* This is a header file which is be used to configure LUFA's | |||
* compile time options, as an alternative to the compile time | |||
* constants supplied through a makefile. | |||
* | |||
* For information on what each token does, refer to the | |||
* \ref Sec_Options section of the application documentation. | |||
*/ | |||
#ifndef _APP_CONFIG_H_ | |||
#define _APP_CONFIG_H_ | |||
// #define NO_APP_START_ON_EJECT | |||
#endif |
@@ -0,0 +1,93 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* \brief LUFA Library Configuration Header File | |||
* | |||
* This header file is used to configure LUFA's compile time options, | |||
* as an alternative to the compile time constants supplied through | |||
* a makefile. | |||
* | |||
* For information on what each token does, refer to the LUFA | |||
* manual section "Summary of Compile Tokens". | |||
*/ | |||
#ifndef _LUFA_CONFIG_H_ | |||
#define _LUFA_CONFIG_H_ | |||
#if (ARCH == ARCH_AVR8) | |||
/* Non-USB Related Configuration Tokens: */ | |||
// #define DISABLE_TERMINAL_CODES | |||
/* USB Class Driver Related Tokens: */ | |||
// #define HID_HOST_BOOT_PROTOCOL_ONLY | |||
// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here} | |||
// #define HID_USAGE_STACK_DEPTH {Insert Value Here} | |||
// #define HID_MAX_COLLECTIONS {Insert Value Here} | |||
// #define HID_MAX_REPORTITEMS {Insert Value Here} | |||
// #define HID_MAX_REPORT_IDS {Insert Value Here} | |||
// #define NO_CLASS_DRIVER_AUTOFLUSH | |||
/* General USB Driver Related Tokens: */ | |||
#define ORDERED_EP_CONFIG | |||
#define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL) | |||
#define USB_DEVICE_ONLY | |||
// #define USB_HOST_ONLY | |||
// #define USB_STREAM_TIMEOUT_MS {Insert Value Here} | |||
// #define NO_LIMITED_CONTROLLER_CONNECT | |||
#define NO_SOF_EVENTS | |||
/* USB Device Mode Driver Related Tokens: */ | |||
#define USE_RAM_DESCRIPTORS | |||
// #define USE_FLASH_DESCRIPTORS | |||
// #define USE_EEPROM_DESCRIPTORS | |||
#define NO_INTERNAL_SERIAL | |||
#define FIXED_CONTROL_ENDPOINT_SIZE 8 | |||
#define DEVICE_STATE_AS_GPIOR 0 | |||
#define FIXED_NUM_CONFIGURATIONS 1 | |||
// #define CONTROL_ONLY_DEVICE | |||
#define INTERRUPT_CONTROL_ENDPOINT | |||
#define NO_DEVICE_REMOTE_WAKEUP | |||
#define NO_DEVICE_SELF_POWER | |||
/* USB Host Mode Driver Related Tokens: */ | |||
// #define HOST_STATE_AS_GPIOR {Insert Value Here} | |||
// #define USB_HOST_TIMEOUT_MS {Insert Value Here} | |||
// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here} | |||
// #define NO_AUTO_VBUS_MANAGEMENT | |||
// #define INVERTED_VBUS_ENABLE_LINE | |||
#else | |||
#error Unsupported architecture for this LUFA configuration file. | |||
#endif | |||
#endif |
@@ -0,0 +1,157 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special | |||
* computer-readable structures which the host requests upon device enumeration, to determine | |||
* the device's capabilities and functions. | |||
*/ | |||
#include "Descriptors.h" | |||
/** Device descriptor structure. This descriptor, located in SRAM memory, describes the overall | |||
* device characteristics, including the supported USB version, control endpoint size and the | |||
* number of device configurations. The descriptor is read out by the USB host when the enumeration | |||
* process begins. | |||
*/ | |||
const USB_Descriptor_Device_t DeviceDescriptor = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, | |||
.USBSpecification = VERSION_BCD(1,1,0), | |||
.Class = USB_CSCP_NoDeviceClass, | |||
.SubClass = USB_CSCP_NoDeviceSubclass, | |||
.Protocol = USB_CSCP_NoDeviceProtocol, | |||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, | |||
.VendorID = 0x03EB, | |||
.ProductID = 0x2045, | |||
.ReleaseNumber = VERSION_BCD(0,0,1), | |||
.ManufacturerStrIndex = NO_DESCRIPTOR, | |||
.ProductStrIndex = NO_DESCRIPTOR, | |||
.SerialNumStrIndex = NO_DESCRIPTOR, | |||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS | |||
}; | |||
/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage | |||
* of the device in one of its supported configurations, including information about any device interfaces | |||
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting | |||
* a configuration so that the host may correctly communicate with the USB device. | |||
*/ | |||
const USB_Descriptor_Configuration_t ConfigurationDescriptor = | |||
{ | |||
.Config = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, | |||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), | |||
.TotalInterfaces = 1, | |||
.ConfigurationNumber = 1, | |||
.ConfigurationStrIndex = NO_DESCRIPTOR, | |||
.ConfigAttributes = USB_CONFIG_ATTR_RESERVED, | |||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100) | |||
}, | |||
.MS_Interface = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, | |||
.InterfaceNumber = INTERFACE_ID_MassStorage, | |||
.AlternateSetting = 0, | |||
.TotalEndpoints = 2, | |||
.Class = MS_CSCP_MassStorageClass, | |||
.SubClass = MS_CSCP_SCSITransparentSubclass, | |||
.Protocol = MS_CSCP_BulkOnlyTransportProtocol, | |||
.InterfaceStrIndex = NO_DESCRIPTOR | |||
}, | |||
.MS_DataInEndpoint = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, | |||
.EndpointAddress = MASS_STORAGE_IN_EPADDR, | |||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), | |||
.EndpointSize = MASS_STORAGE_IO_EPSIZE, | |||
.PollingIntervalMS = 0x05 | |||
}, | |||
.MS_DataOutEndpoint = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, | |||
.EndpointAddress = MASS_STORAGE_OUT_EPADDR, | |||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), | |||
.EndpointSize = MASS_STORAGE_IO_EPSIZE, | |||
.PollingIntervalMS = 0x05 | |||
} | |||
}; | |||
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" | |||
* documentation) by the application code so that the address and size of a requested descriptor can be given | |||
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function | |||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the | |||
* USB host. | |||
*/ | |||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, | |||
const uint8_t wIndex, | |||
const void** const DescriptorAddress) | |||
{ | |||
const uint8_t DescriptorType = (wValue >> 8); | |||
const void* Address = NULL; | |||
uint16_t Size = NO_DESCRIPTOR; | |||
/* If/Else If chain compiles slightly smaller than a switch case */ | |||
if (DescriptorType == DTYPE_Device) | |||
{ | |||
Address = &DeviceDescriptor; | |||
Size = sizeof(USB_Descriptor_Device_t); | |||
} | |||
else if (DescriptorType == DTYPE_Configuration) | |||
{ | |||
Address = &ConfigurationDescriptor; | |||
Size = sizeof(USB_Descriptor_Configuration_t); | |||
} | |||
*DescriptorAddress = Address; | |||
return Size; | |||
} | |||
@@ -0,0 +1,88 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Header file for Descriptors.c. | |||
*/ | |||
#ifndef _DESCRIPTORS_H_ | |||
#define _DESCRIPTORS_H_ | |||
/* Includes: */ | |||
#include <avr/pgmspace.h> | |||
#include <LUFA/Drivers/USB/USB.h> | |||
#include "BootloaderAPI.h" | |||
/* Macros: */ | |||
/** Endpoint address of the Mass Storage device-to-host data IN endpoint. */ | |||
#define MASS_STORAGE_IN_EPADDR (ENDPOINT_DIR_IN | 3) | |||
/** Endpoint address of the Mass Storage host-to-device data OUT endpoint. */ | |||
#define MASS_STORAGE_OUT_EPADDR (ENDPOINT_DIR_OUT | 4) | |||
/** Size in bytes of the Mass Storage data endpoints. */ | |||
#define MASS_STORAGE_IO_EPSIZE 64 | |||
/* Type Defines: */ | |||
/** Type define for the device configuration descriptor structure. This must be defined in the | |||
* application code, as the configuration descriptor contains several sub-descriptors which | |||
* vary between devices, and which describe the device's usage to the host. | |||
*/ | |||
typedef struct | |||
{ | |||
USB_Descriptor_Configuration_Header_t Config; | |||
// Mass Storage Interface | |||
USB_Descriptor_Interface_t MS_Interface; | |||
USB_Descriptor_Endpoint_t MS_DataInEndpoint; | |||
USB_Descriptor_Endpoint_t MS_DataOutEndpoint; | |||
} USB_Descriptor_Configuration_t; | |||
/** Enum for the device interface descriptor IDs within the device. Each interface descriptor | |||
* should have a unique ID index associated with it, which can be used to refer to the | |||
* interface from other descriptors. | |||
*/ | |||
enum InterfaceDescriptors_t | |||
{ | |||
INTERFACE_ID_MassStorage = 0, /**< Mass storage interface descriptor ID */ | |||
}; | |||
/* Function Prototypes: */ | |||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, | |||
const uint8_t wIndex, | |||
const void** const DescriptorAddress) | |||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3) AUX_BOOT_SECTION; | |||
#endif | |||
@@ -0,0 +1,294 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* SCSI command processing routines, for SCSI commands issued by the host. Mass Storage | |||
* devices use a thin "Bulk-Only Transport" protocol for issuing commands and status information, | |||
* which wrap around standard SCSI device commands for controlling the actual storage medium. | |||
*/ | |||
#define INCLUDE_FROM_SCSI_C | |||
#include "SCSI.h" | |||
/** Structure to hold the SCSI response data to a SCSI INQUIRY command. This gives information about the device's | |||
* features and capabilities. | |||
*/ | |||
static const SCSI_Inquiry_Response_t InquiryData = | |||
{ | |||
.DeviceType = DEVICE_TYPE_BLOCK, | |||
.PeripheralQualifier = 0, | |||
.Removable = true, | |||
.Version = 0, | |||
.ResponseDataFormat = 2, | |||
.NormACA = false, | |||
.TrmTsk = false, | |||
.AERC = false, | |||
.AdditionalLength = 0x1F, | |||
.SoftReset = false, | |||
.CmdQue = false, | |||
.Linked = false, | |||
.Sync = false, | |||
.WideBus16Bit = false, | |||
.WideBus32Bit = false, | |||
.RelAddr = false, | |||
.VendorID = "LUFA", | |||
.ProductID = "Bootloader", | |||
.RevisionID = {'0','.','0','0'}, | |||
}; | |||
/** Structure to hold the sense data for the last issued SCSI command, which is returned to the host after a SCSI REQUEST SENSE | |||
* command is issued. This gives information on exactly why the last command failed to complete. | |||
*/ | |||
static SCSI_Request_Sense_Response_t SenseData = | |||
{ | |||
.ResponseCode = 0x70, | |||
.AdditionalLength = 0x0A, | |||
}; | |||
/** Main routine to process the SCSI command located in the Command Block Wrapper read from the host. This dispatches | |||
* to the appropriate SCSI command handling routine if the issued command is supported by the device, else it returns | |||
* a command failure due to a ILLEGAL REQUEST. | |||
* | |||
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with | |||
* | |||
* \return Boolean \c true if the command completed successfully, \c false otherwise | |||
*/ | |||
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) | |||
{ | |||
bool CommandSuccess = false; | |||
/* Run the appropriate SCSI command hander function based on the passed command */ | |||
switch (MSInterfaceInfo->State.CommandBlock.SCSICommandData[0]) | |||
{ | |||
case SCSI_CMD_INQUIRY: | |||
CommandSuccess = SCSI_Command_Inquiry(MSInterfaceInfo); | |||
break; | |||
case SCSI_CMD_REQUEST_SENSE: | |||
CommandSuccess = SCSI_Command_Request_Sense(MSInterfaceInfo); | |||
break; | |||
case SCSI_CMD_READ_CAPACITY_10: | |||
CommandSuccess = SCSI_Command_Read_Capacity_10(MSInterfaceInfo); | |||
break; | |||
case SCSI_CMD_WRITE_10: | |||
CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_WRITE); | |||
break; | |||
case SCSI_CMD_READ_10: | |||
CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_READ); | |||
break; | |||
case SCSI_CMD_MODE_SENSE_6: | |||
CommandSuccess = SCSI_Command_ModeSense_6(MSInterfaceInfo); | |||
break; | |||
case SCSI_CMD_START_STOP_UNIT: | |||
#if !defined(NO_APP_START_ON_EJECT) | |||
/* If the user ejected the volume, signal bootloader exit at next opportunity. */ | |||
RunBootloader = ((MSInterfaceInfo->State.CommandBlock.SCSICommandData[4] & 0x03) != 0x02); | |||
#endif | |||
case SCSI_CMD_SEND_DIAGNOSTIC: | |||
case SCSI_CMD_TEST_UNIT_READY: | |||
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: | |||
case SCSI_CMD_VERIFY_10: | |||
/* These commands should just succeed, no handling required */ | |||
CommandSuccess = true; | |||
MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0; | |||
break; | |||
default: | |||
/* Update the SENSE key to reflect the invalid command */ | |||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST, | |||
SCSI_ASENSE_INVALID_COMMAND, | |||
SCSI_ASENSEQ_NO_QUALIFIER); | |||
break; | |||
} | |||
/* Check if command was successfully processed */ | |||
if (CommandSuccess) | |||
{ | |||
SCSI_SET_SENSE(SCSI_SENSE_KEY_GOOD, | |||
SCSI_ASENSE_NO_ADDITIONAL_INFORMATION, | |||
SCSI_ASENSEQ_NO_QUALIFIER); | |||
return true; | |||
} | |||
return false; | |||
} | |||
/** Command processing for an issued SCSI INQUIRY command. This command returns information about the device's features | |||
* and capabilities to the host. | |||
* | |||
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with | |||
* | |||
* \return Boolean \c true if the command completed successfully, \c false otherwise. | |||
*/ | |||
static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) | |||
{ | |||
uint16_t AllocationLength = SwapEndian_16(*(uint16_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[3]); | |||
uint16_t BytesTransferred = MIN(AllocationLength, sizeof(InquiryData)); | |||
/* Only the standard INQUIRY data is supported, check if any optional INQUIRY bits set */ | |||
if ((MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) || | |||
MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]) | |||
{ | |||
/* Optional but unsupported bits set - update the SENSE key and fail the request */ | |||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST, | |||
SCSI_ASENSE_INVALID_FIELD_IN_CDB, | |||
SCSI_ASENSEQ_NO_QUALIFIER); | |||
return false; | |||
} | |||
Endpoint_Write_Stream_LE(&InquiryData, BytesTransferred, NULL); | |||
/* Pad out remaining bytes with 0x00 */ | |||
Endpoint_Null_Stream((AllocationLength - BytesTransferred), NULL); | |||
/* Finalize the stream transfer to send the last packet */ | |||
Endpoint_ClearIN(); | |||
/* Succeed the command and update the bytes transferred counter */ | |||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred; | |||
return true; | |||
} | |||
/** Command processing for an issued SCSI REQUEST SENSE command. This command returns information about the last issued command, | |||
* including the error code and additional error information so that the host can determine why a command failed to complete. | |||
* | |||
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with | |||
* | |||
* \return Boolean \c true if the command completed successfully, \c false otherwise. | |||
*/ | |||
static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) | |||
{ | |||
uint8_t AllocationLength = MSInterfaceInfo->State.CommandBlock.SCSICommandData[4]; | |||
uint8_t BytesTransferred = MIN(AllocationLength, sizeof(SenseData)); | |||
Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NULL); | |||
Endpoint_Null_Stream((AllocationLength - BytesTransferred), NULL); | |||
Endpoint_ClearIN(); | |||
/* Succeed the command and update the bytes transferred counter */ | |||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred; | |||
return true; | |||
} | |||
/** Command processing for an issued SCSI READ CAPACITY (10) command. This command returns information about the device's capacity | |||
* on the selected Logical Unit (drive), as a number of OS-sized blocks. | |||
* | |||
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with | |||
* | |||
* \return Boolean \c true if the command completed successfully, \c false otherwise. | |||
*/ | |||
static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) | |||
{ | |||
Endpoint_Write_32_BE(LUN_MEDIA_BLOCKS - 1); | |||
Endpoint_Write_32_BE(SECTOR_SIZE_BYTES); | |||
Endpoint_ClearIN(); | |||
/* Succeed the command and update the bytes transferred counter */ | |||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= 8; | |||
return true; | |||
} | |||
/** Command processing for an issued SCSI READ (10) or WRITE (10) command. This command reads in the block start address | |||
* and total number of blocks to process, then calls the appropriate low-level Dataflash routine to handle the actual | |||
* reading and writing of the data. | |||
* | |||
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with | |||
* \param[in] IsDataRead Indicates if the command is a READ (10) command or WRITE (10) command (DATA_READ or DATA_WRITE) | |||
* | |||
* \return Boolean \c true if the command completed successfully, \c false otherwise. | |||
*/ | |||
static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo, | |||
const bool IsDataRead) | |||
{ | |||
uint16_t BlockAddress; | |||
uint16_t TotalBlocks; | |||
/* Load in the 32-bit block address (SCSI uses big-endian, so have to reverse the byte order) */ | |||
BlockAddress = SwapEndian_32(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]); | |||
/* Load in the 16-bit total blocks (SCSI uses big-endian, so have to reverse the byte order) */ | |||
TotalBlocks = SwapEndian_16(*(uint16_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[7]); | |||
/* Check if the block address is outside the maximum allowable value for the LUN */ | |||
if (BlockAddress >= LUN_MEDIA_BLOCKS) | |||
{ | |||
/* Block address is invalid, update SENSE key and return command fail */ | |||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST, | |||
SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, | |||
SCSI_ASENSEQ_NO_QUALIFIER); | |||
return false; | |||
} | |||
/* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */ | |||
for (uint16_t i = 0; i < TotalBlocks; i++) | |||
{ | |||
if (IsDataRead == DATA_READ) | |||
VirtualFAT_ReadBlock(BlockAddress + i); | |||
else | |||
VirtualFAT_WriteBlock(BlockAddress + i); | |||
} | |||
/* Update the bytes transferred counter and succeed the command */ | |||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * SECTOR_SIZE_BYTES); | |||
return true; | |||
} | |||
/** Command processing for an issued SCSI MODE SENSE (6) command. This command returns various informational pages about | |||
* the SCSI device, as well as the device's Write Protect status. | |||
* | |||
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with | |||
* | |||
* \return Boolean \c true if the command completed successfully, \c false otherwise. | |||
*/ | |||
static bool SCSI_Command_ModeSense_6(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) | |||
{ | |||
/* Send an empty header response indicating Write Protect flag is off */ | |||
Endpoint_Write_32_LE(0); | |||
Endpoint_ClearIN(); | |||
/* Update the bytes transferred counter and succeed the command */ | |||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= 4; | |||
return true; | |||
} | |||
@@ -0,0 +1,84 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Header file for SCSI.c. | |||
*/ | |||
#ifndef _SCSI_H_ | |||
#define _SCSI_H_ | |||
/* Includes: */ | |||
#include <avr/io.h> | |||
#include <avr/pgmspace.h> | |||
#include <LUFA/Drivers/USB/USB.h> | |||
#include "../BootloaderMassStorage.h" | |||
#include "../Descriptors.h" | |||
#include "VirtualFAT.h" | |||
/* Macros: */ | |||
/** Macro to set the current SCSI sense data to the given key, additional sense code and additional sense qualifier. This | |||
* is for convenience, as it allows for all three sense values (returned upon request to the host to give information about | |||
* the last command failure) in a quick and easy manner. | |||
* | |||
* \param[in] Key New SCSI sense key to set the sense code to | |||
* \param[in] Acode New SCSI additional sense key to set the additional sense code to | |||
* \param[in] Aqual New SCSI additional sense key qualifier to set the additional sense qualifier code to | |||
*/ | |||
#define SCSI_SET_SENSE(Key, Acode, Aqual) do { SenseData.SenseKey = (Key); \ | |||
SenseData.AdditionalSenseCode = (Acode); \ | |||
SenseData.AdditionalSenseQualifier = (Aqual); } while (0) | |||
/** Macro for the \ref SCSI_Command_ReadWrite_10() function, to indicate that data is to be read from the storage medium. */ | |||
#define DATA_READ true | |||
/** Macro for the \ref SCSI_Command_ReadWrite_10() function, to indicate that data is to be written to the storage medium. */ | |||
#define DATA_WRITE false | |||
/** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a Block Media device. */ | |||
#define DEVICE_TYPE_BLOCK 0x00 | |||
/* Function Prototypes: */ | |||
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION; | |||
#if defined(INCLUDE_FROM_SCSI_C) | |||
static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION; | |||
static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION; | |||
static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION; | |||
static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo, | |||
const bool IsDataRead) AUX_BOOT_SECTION; | |||
static bool SCSI_Command_ModeSense_6(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION; | |||
#endif | |||
#endif | |||
@@ -0,0 +1,482 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Virtualized FAT12 filesystem implementation, to perform self-programming | |||
* in response to read and write requests to the virtual filesystem by the | |||
* host PC. | |||
*/ | |||
#define INCLUDE_FROM_VIRTUAL_FAT_C | |||
#include "VirtualFAT.h" | |||
/** FAT filesystem boot sector block, must be the first sector on the physical | |||
* disk so that the host can identify the presence of a FAT filesystem. This | |||
* block is truncated; normally a large bootstrap section is located near the | |||
* end of the block for booting purposes however as this is not meant to be a | |||
* bootable disk it is omitted for space reasons. | |||
* | |||
* \note When returning the boot block to the host, the magic signature 0xAA55 | |||
* must be added to the very end of the block to identify it as a boot | |||
* block. | |||
*/ | |||
static const FATBootBlock_t BootBlock = | |||
{ | |||
.Bootstrap = {0xEB, 0x3C, 0x90}, | |||
.Description = "mkdosfs", | |||
.SectorSize = SECTOR_SIZE_BYTES, | |||
.SectorsPerCluster = SECTOR_PER_CLUSTER, | |||
.ReservedSectors = 1, | |||
.FATCopies = 2, | |||
.RootDirectoryEntries = (SECTOR_SIZE_BYTES / sizeof(FATDirectoryEntry_t)), | |||
.TotalSectors16 = LUN_MEDIA_BLOCKS, | |||
.MediaDescriptor = 0xF8, | |||
.SectorsPerFAT = 1, | |||
.SectorsPerTrack = (LUN_MEDIA_BLOCKS % 64), | |||
.Heads = (LUN_MEDIA_BLOCKS / 64), | |||
.HiddenSectors = 0, | |||
.TotalSectors32 = 0, | |||
.PhysicalDriveNum = 0, | |||
.ExtendedBootRecordSig = 0x29, | |||
.VolumeSerialNumber = 0x12345678, | |||
.VolumeLabel = "LUFA BOOT ", | |||
.FilesystemIdentifier = "FAT12 ", | |||
}; | |||
/** FAT 8.3 style directory entry, for the virtual FLASH contents file. */ | |||
static FATDirectoryEntry_t FirmwareFileEntries[] = | |||
{ | |||
/* Root volume label entry; disk label is contained in the Filename and | |||
* Extension fields (concatenated) with a special attribute flag - other | |||
* fields are ignored. Should be the same as the label in the boot block. | |||
*/ | |||
[DISK_FILE_ENTRY_VolumeID] = | |||
{ | |||
.MSDOS_Directory = | |||
{ | |||
.Name = "LUFA BOOT ", | |||
.Attributes = FAT_FLAG_VOLUME_NAME, | |||
.Reserved = {0}, | |||
.CreationTime = 0, | |||
.CreationDate = 0, | |||
.StartingCluster = 0, | |||
.Reserved2 = 0, | |||
} | |||
}, | |||
/* VFAT Long File Name entry for the virtual firmware file; required to | |||
* prevent corruption from systems that are unable to detect the device | |||
* as being a legacy MSDOS style FAT12 volume. */ | |||
[DISK_FILE_ENTRY_FLASH_LFN] = | |||
{ | |||
.VFAT_LongFileName = | |||
{ | |||
.Ordinal = 1 | FAT_ORDINAL_LAST_ENTRY, | |||
.Attribute = FAT_FLAG_LONG_FILE_NAME, | |||
.Reserved1 = 0, | |||
.Reserved2 = 0, | |||
.Checksum = FAT_CHECKSUM('F','L','A','S','H',' ',' ',' ','B','I','N'), | |||
.Unicode1 = 'F', | |||
.Unicode2 = 'L', | |||
.Unicode3 = 'A', | |||
.Unicode4 = 'S', | |||
.Unicode5 = 'H', | |||
.Unicode6 = '.', | |||
.Unicode7 = 'B', | |||
.Unicode8 = 'I', | |||
.Unicode9 = 'N', | |||
.Unicode10 = 0, | |||
.Unicode11 = 0, | |||
.Unicode12 = 0, | |||
.Unicode13 = 0, | |||
} | |||
}, | |||
/* MSDOS file entry for the virtual Firmware image. */ | |||
[DISK_FILE_ENTRY_FLASH_MSDOS] = | |||
{ | |||
.MSDOS_File = | |||
{ | |||
.Filename = "FLASH ", | |||
.Extension = "BIN", | |||
.Attributes = 0, | |||
.Reserved = {0}, | |||
.CreationTime = FAT_TIME(1, 1, 0), | |||
.CreationDate = FAT_DATE(14, 2, 1989), | |||
.StartingCluster = 2, | |||
.FileSizeBytes = FLASH_FILE_SIZE_BYTES, | |||
} | |||
}, | |||
[DISK_FILE_ENTRY_EEPROM_LFN] = | |||
{ | |||
.VFAT_LongFileName = | |||
{ | |||
.Ordinal = 1 | FAT_ORDINAL_LAST_ENTRY, | |||
.Attribute = FAT_FLAG_LONG_FILE_NAME, | |||
.Reserved1 = 0, | |||
.Reserved2 = 0, | |||
.Checksum = FAT_CHECKSUM('E','E','P','R','O','M',' ',' ','B','I','N'), | |||
.Unicode1 = 'E', | |||
.Unicode2 = 'E', | |||
.Unicode3 = 'P', | |||
.Unicode4 = 'R', | |||
.Unicode5 = 'O', | |||
.Unicode6 = 'M', | |||
.Unicode7 = '.', | |||
.Unicode8 = 'B', | |||
.Unicode9 = 'I', | |||
.Unicode10 = 'N', | |||
.Unicode11 = 0, | |||
.Unicode12 = 0, | |||
.Unicode13 = 0, | |||
} | |||
}, | |||
[DISK_FILE_ENTRY_EEPROM_MSDOS] = | |||
{ | |||
.MSDOS_File = | |||
{ | |||
.Filename = "EEPROM ", | |||
.Extension = "BIN", | |||
.Attributes = 0, | |||
.Reserved = {0}, | |||
.CreationTime = FAT_TIME(1, 1, 0), | |||
.CreationDate = FAT_DATE(14, 2, 1989), | |||
.StartingCluster = 2 + FILE_CLUSTERS(FLASH_FILE_SIZE_BYTES), | |||
.FileSizeBytes = EEPROM_FILE_SIZE_BYTES, | |||
} | |||
}, | |||
}; | |||
/** Starting cluster of the virtual FLASH.BIN file on disk, tracked so that the | |||
* offset from the start of the data sector can be determined. On Windows | |||
* systems files are usually replaced using the original file's disk clusters, | |||
* while Linux appears to overwrite with an offset which must be compensated for. | |||
*/ | |||
static const uint16_t* FLASHFileStartCluster = &FirmwareFileEntries[DISK_FILE_ENTRY_FLASH_MSDOS].MSDOS_File.StartingCluster; | |||
/** Starting cluster of the virtual EEPROM.BIN file on disk, tracked so that the | |||
* offset from the start of the data sector can be determined. On Windows | |||
* systems files are usually replaced using the original file's disk clusters, | |||
* while Linux appears to overwrite with an offset which must be compensated for. | |||
*/ | |||
static const uint16_t* EEPROMFileStartCluster = &FirmwareFileEntries[DISK_FILE_ENTRY_EEPROM_MSDOS].MSDOS_File.StartingCluster; | |||
/** Reads a byte of EEPROM out from the EEPROM memory space. | |||
* | |||
* \note This function is required as the avr-libc EEPROM functions do not cope | |||
* with linker relaxations, and a jump longer than 4K of FLASH on the | |||
* larger USB AVRs will break the linker. This function is marked as | |||
* never inlinable and placed into the normal text segment so that the | |||
* call to the EEPROM function will be short even if the AUX boot section | |||
* is used. | |||
* | |||
* \param[in] Address Address of the EEPROM location to read from | |||
* | |||
* \return Read byte of EEPROM data. | |||
*/ | |||
static uint8_t ReadEEPROMByte(const uint8_t* const Address) | |||
{ | |||
return eeprom_read_byte(Address); | |||
} | |||
/** Writes a byte of EEPROM out to the EEPROM memory space. | |||
* | |||
* \note This function is required as the avr-libc EEPROM functions do not cope | |||
* with linker relaxations, and a jump longer than 4K of FLASH on the | |||
* larger USB AVRs will break the linker. This function is marked as | |||
* never inlinable and placed into the normal text segment so that the | |||
* call to the EEPROM function will be short even if the AUX boot section | |||
* is used. | |||
* | |||
* \param[in] Address Address of the EEPROM location to write to | |||
* \param[in] Data New data to write to the EEPROM location | |||
*/ | |||
static void WriteEEPROMByte(uint8_t* const Address, | |||
const uint8_t Data) | |||
{ | |||
eeprom_update_byte(Address, Data); | |||
} | |||
/** Updates a FAT12 cluster entry in the FAT file table with the specified next | |||
* chain index. If the cluster is the last in the file chain, the magic value | |||
* \c 0xFFF should be used. | |||
* | |||
* \note FAT data cluster indexes are offset by 2, so that cluster 2 is the | |||
* first file data cluster on the disk. See the FAT specification. | |||
* | |||
* \param[out] FATTable Pointer to the FAT12 allocation table | |||
* \param[in] Index Index of the cluster entry to update | |||
* \param[in] ChainEntry Next cluster index in the file chain | |||
*/ | |||
static void UpdateFAT12ClusterEntry(uint8_t* const FATTable, | |||
const uint16_t Index, | |||
const uint16_t ChainEntry) | |||
{ | |||
/* Calculate the starting offset of the cluster entry in the FAT12 table */ | |||
uint8_t FATOffset = (Index + (Index >> 1)); | |||
bool UpperNibble = ((Index & 1) != 0); | |||
/* Check if the start of the entry is at an upper nibble of the byte, fill | |||
* out FAT12 entry as required */ | |||
if (UpperNibble) | |||
{ | |||
FATTable[FATOffset] = (FATTable[FATOffset] & 0x0F) | ((ChainEntry & 0x0F) << 4); | |||
FATTable[FATOffset + 1] = (ChainEntry >> 4); | |||
} | |||
else | |||
{ | |||
FATTable[FATOffset] = ChainEntry; | |||
FATTable[FATOffset + 1] = (FATTable[FATOffset] & 0xF0) | (ChainEntry >> 8); | |||
} | |||
} | |||
/** Updates a FAT12 cluster chain in the FAT file table with a linear chain of | |||
* the specified length. | |||
* | |||
* \note FAT data cluster indexes are offset by 2, so that cluster 2 is the | |||
* first file data cluster on the disk. See the FAT specification. | |||
* | |||
* \param[out] FATTable Pointer to the FAT12 allocation table | |||
* \param[in] Index Index of the start of the cluster chain to update | |||
* \param[in] ChainLength Length of the chain to write, in clusters | |||
*/ | |||
static void UpdateFAT12ClusterChain(uint8_t* const FATTable, | |||
const uint16_t Index, | |||
const uint8_t ChainLength) | |||
{ | |||
for (uint8_t i = 0; i < ChainLength; i++) | |||
{ | |||
uint16_t CurrentCluster = Index + i; | |||
uint16_t NextCluster = CurrentCluster + 1; | |||
/* Mark last cluster as end of file */ | |||
if (i == (ChainLength - 1)) | |||
NextCluster = 0xFFF; | |||
UpdateFAT12ClusterEntry(FATTable, CurrentCluster, NextCluster); | |||
} | |||
} | |||
/** Reads or writes a block of data from/to the physical device FLASH using a | |||
* block buffer stored in RAM, if the requested block is within the virtual | |||
* firmware file's sector ranges in the emulated FAT file system. | |||
* | |||
* \param[in] BlockNumber Physical disk block to read from/write to | |||
* \param[in,out] BlockBuffer Pointer to the start of the block buffer in RAM | |||
* \param[in] Read If \c true, the requested block is read, if | |||
* \c false, the requested block is written | |||
*/ | |||
static void ReadWriteFLASHFileBlock(const uint16_t BlockNumber, | |||
uint8_t* BlockBuffer, | |||
const bool Read) | |||
{ | |||
uint16_t FileStartBlock = DISK_BLOCK_DataStartBlock + (*FLASHFileStartCluster - 2) * SECTOR_PER_CLUSTER; | |||
uint16_t FileEndBlock = FileStartBlock + (FILE_SECTORS(FLASH_FILE_SIZE_BYTES) - 1); | |||
/* Range check the write request - abort if requested block is not within the | |||
* virtual firmware file sector range */ | |||
if (!((BlockNumber >= FileStartBlock) && (BlockNumber <= FileEndBlock))) | |||
return; | |||
#if (FLASHEND > 0xFFFF) | |||
uint32_t FlashAddress = (uint32_t)(BlockNumber - FileStartBlock) * SECTOR_SIZE_BYTES; | |||
#else | |||
uint16_t FlashAddress = (uint16_t)(BlockNumber - FileStartBlock) * SECTOR_SIZE_BYTES; | |||
#endif | |||
if (Read) | |||
{ | |||
/* Read out the mapped block of data from the device's FLASH */ | |||
for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i++) | |||
{ | |||
#if (FLASHEND > 0xFFFF) | |||
BlockBuffer[i] = pgm_read_byte_far(FlashAddress++); | |||
#else | |||
BlockBuffer[i] = pgm_read_byte(FlashAddress++); | |||
#endif | |||
} | |||
} | |||
else | |||
{ | |||
/* Write out the mapped block of data to the device's FLASH */ | |||
for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i += 2) | |||
{ | |||
if ((FlashAddress % SPM_PAGESIZE) == 0) | |||
{ | |||
/* Erase the given FLASH page, ready to be programmed */ | |||
BootloaderAPI_ErasePage(FlashAddress); | |||
} | |||
/* Write the next data word to the FLASH page */ | |||
BootloaderAPI_FillWord(FlashAddress, (BlockBuffer[i + 1] << 8) | BlockBuffer[i]); | |||
FlashAddress += 2; | |||
if ((FlashAddress % SPM_PAGESIZE) == 0) | |||
{ | |||
/* Write the filled FLASH page to memory */ | |||
BootloaderAPI_WritePage(FlashAddress - SPM_PAGESIZE); | |||
} | |||
} | |||
} | |||
} | |||
/** Reads or writes a block of data from/to the physical device EEPROM using a | |||
* block buffer stored in RAM, if the requested block is within the virtual | |||
* firmware file's sector ranges in the emulated FAT file system. | |||
* | |||
* \param[in] BlockNumber Physical disk block to read from/write to | |||
* \param[in,out] BlockBuffer Pointer to the start of the block buffer in RAM | |||
* \param[in] Read If \c true, the requested block is read, if | |||
* \c false, the requested block is written | |||
*/ | |||
static void ReadWriteEEPROMFileBlock(const uint16_t BlockNumber, | |||
uint8_t* BlockBuffer, | |||
const bool Read) | |||
{ | |||
uint16_t FileStartBlock = DISK_BLOCK_DataStartBlock + (*EEPROMFileStartCluster - 2) * SECTOR_PER_CLUSTER; | |||
uint16_t FileEndBlock = FileStartBlock + (FILE_SECTORS(EEPROM_FILE_SIZE_BYTES) - 1); | |||
/* Range check the write request - abort if requested block is not within the | |||
* virtual firmware file sector range */ | |||
if (!((BlockNumber >= FileStartBlock) && (BlockNumber <= FileEndBlock))) | |||
return; | |||
uint16_t EEPROMAddress = (uint16_t)(BlockNumber - FileStartBlock) * SECTOR_SIZE_BYTES; | |||
if (Read) | |||
{ | |||
/* Read out the mapped block of data from the device's EEPROM */ | |||
for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i++) | |||
BlockBuffer[i] = ReadEEPROMByte((uint8_t*)EEPROMAddress++); | |||
} | |||
else | |||
{ | |||
/* Write out the mapped block of data to the device's EEPROM */ | |||
for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i++) | |||
WriteEEPROMByte((uint8_t*)EEPROMAddress++, BlockBuffer[i]); | |||
} | |||
} | |||
/** Writes a block of data to the virtual FAT filesystem, from the USB Mass | |||
* Storage interface. | |||
* | |||
* \param[in] BlockNumber Index of the block to write. | |||
*/ | |||
void VirtualFAT_WriteBlock(const uint16_t BlockNumber) | |||
{ | |||
uint8_t BlockBuffer[SECTOR_SIZE_BYTES]; | |||
/* Buffer the entire block to be written from the host */ | |||
Endpoint_Read_Stream_LE(BlockBuffer, sizeof(BlockBuffer), NULL); | |||
Endpoint_ClearOUT(); | |||
switch (BlockNumber) | |||
{ | |||
case DISK_BLOCK_BootBlock: | |||
case DISK_BLOCK_FATBlock1: | |||
case DISK_BLOCK_FATBlock2: | |||
/* Ignore writes to the boot and FAT blocks */ | |||
break; | |||
case DISK_BLOCK_RootFilesBlock: | |||
/* Copy over the updated directory entries */ | |||
memcpy(FirmwareFileEntries, BlockBuffer, sizeof(FirmwareFileEntries)); | |||
break; | |||
default: | |||
ReadWriteFLASHFileBlock(BlockNumber, BlockBuffer, false); | |||
ReadWriteEEPROMFileBlock(BlockNumber, BlockBuffer, false); | |||
break; | |||
} | |||
} | |||
/** Reads a block of data from the virtual FAT filesystem, and sends it to the | |||
* host via the USB Mass Storage interface. | |||
* | |||
* \param[in] BlockNumber Index of the block to read. | |||
*/ | |||
void VirtualFAT_ReadBlock(const uint16_t BlockNumber) | |||
{ | |||
uint8_t BlockBuffer[SECTOR_SIZE_BYTES]; | |||
memset(BlockBuffer, 0x00, sizeof(BlockBuffer)); | |||
switch (BlockNumber) | |||
{ | |||
case DISK_BLOCK_BootBlock: | |||
memcpy(BlockBuffer, &BootBlock, sizeof(FATBootBlock_t)); | |||
/* Add the magic signature to the end of the block */ | |||
BlockBuffer[SECTOR_SIZE_BYTES - 2] = 0x55; | |||
BlockBuffer[SECTOR_SIZE_BYTES - 1] = 0xAA; | |||
break; | |||
case DISK_BLOCK_FATBlock1: | |||
case DISK_BLOCK_FATBlock2: | |||
/* Cluster 0: Media type/Reserved */ | |||
UpdateFAT12ClusterEntry(BlockBuffer, 0, 0xF00 | BootBlock.MediaDescriptor); | |||
/* Cluster 1: Reserved */ | |||
UpdateFAT12ClusterEntry(BlockBuffer, 1, 0xFFF); | |||
/* Cluster 2 onwards: Cluster chain of FLASH.BIN */ | |||
UpdateFAT12ClusterChain(BlockBuffer, *FLASHFileStartCluster, FILE_CLUSTERS(FLASH_FILE_SIZE_BYTES)); | |||
/* Cluster 2+n onwards: Cluster chain of EEPROM.BIN */ | |||
UpdateFAT12ClusterChain(BlockBuffer, *EEPROMFileStartCluster, FILE_CLUSTERS(EEPROM_FILE_SIZE_BYTES)); | |||
break; | |||
case DISK_BLOCK_RootFilesBlock: | |||
memcpy(BlockBuffer, FirmwareFileEntries, sizeof(FirmwareFileEntries)); | |||
break; | |||
default: | |||
ReadWriteFLASHFileBlock(BlockNumber, BlockBuffer, true); | |||
ReadWriteEEPROMFileBlock(BlockNumber, BlockBuffer, true); | |||
break; | |||
} | |||
/* Write the entire read block Buffer to the host */ | |||
Endpoint_Write_Stream_LE(BlockBuffer, sizeof(BlockBuffer), NULL); | |||
Endpoint_ClearIN(); | |||
} |
@@ -0,0 +1,302 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
#ifndef _VIRTUALFAT_H_ | |||
#define _VIRTUALFAT_H_ | |||
/* Includes: */ | |||
#include <avr/io.h> | |||
#include <avr/pgmspace.h> | |||
#include <LUFA/Drivers/USB/USB.h> | |||
#include "../BootloaderAPI.h" | |||
/* Macros: */ | |||
/** Size of the virtual FLASH.BIN file in bytes. */ | |||
#define FLASH_FILE_SIZE_BYTES (FLASHEND - (FLASHEND - BOOT_START_ADDR) - AUX_BOOT_SECTION_SIZE) | |||
/** Size of the virtual EEPROM.BIN file in bytes. */ | |||
#define EEPROM_FILE_SIZE_BYTES E2END | |||
/** Number of sectors that comprise a single logical disk cluster. */ | |||
#define SECTOR_PER_CLUSTER 4 | |||
/** Size of a single logical sector on the disk. */ | |||
#define SECTOR_SIZE_BYTES 512 | |||
/** Size of a logical cluster on the disk, in bytes */ | |||
#define CLUSTER_SIZE_BYTES (SECTOR_PER_CLUSTER * SECTOR_SIZE_BYTES) | |||
/** Number of sectors required to store a given size in bytes. | |||
* | |||
* \param[in] size Size of the data that needs to be stored | |||
* | |||
* \return Number of sectors required to store the given data on the disk. | |||
*/ | |||
#define FILE_SECTORS(size) ((size / SECTOR_SIZE_BYTES) + ((size % SECTOR_SIZE_BYTES) ? 1 : 0)) | |||
/** Number of clusters required to store a given size in bytes. | |||
* | |||
* \param[in] size Size of the data that needs to be stored | |||
* | |||
* \return Number of clusters required to store the given data on the disk. | |||
*/ | |||
#define FILE_CLUSTERS(size) ((size / CLUSTER_SIZE_BYTES) + ((size % CLUSTER_SIZE_BYTES) ? 1 : 0)) | |||
/** Total number of logical sectors/blocks on the disk. */ | |||
#define LUN_MEDIA_BLOCKS (FILE_SECTORS(FLASH_FILE_SIZE_BYTES) + FILE_SECTORS(EEPROM_FILE_SIZE_BYTES) + 32) | |||
/** Converts a given time in HH:MM:SS format to a FAT filesystem time. | |||
* | |||
* \note The minimum seconds resolution of FAT is 2, thus odd seconds | |||
* will be truncated to the previous integer multiple of 2 seconds. | |||
* | |||
* \param[in] hh Hours (0-23) | |||
* \param[in] mm Minutes (0-59) | |||
* \param[in] ss Seconds (0-59) | |||
* | |||
* \return Given time encoded as a FAT filesystem timestamp | |||
*/ | |||
#define FAT_TIME(hh, mm, ss) ((hh << 11) | (mm << 5) | (ss >> 1)) | |||
/** Converts a given date in DD/MM/YYYY format to a FAT filesystem date. | |||
* | |||
* \param[in] dd Days in the month (1-31) | |||
* \param[in] mm Months in the year (1-12) | |||
* \param[in] yyyy Year (1980 - 2107) | |||
* | |||
* \return Given date encoded as a FAT filesystem datestamp | |||
*/ | |||
#define FAT_DATE(dd, mm, yyyy) (((yyyy - 1980) << 9) | (mm << 5) | (dd << 0)) | |||
/** Bit-rotates a given 8-bit value once to the right. | |||
* | |||
* \param x Value to rotate right once | |||
* | |||
* \return Bit-rotated input value, rotated once to the right. | |||
*/ | |||
#define _ROT8(x) ((((x) & 0xFE) >> 1) | (((x) & 1) ? 0x80 : 0x00)) | |||
/** Computes the LFN entry checksum of a MSDOS 8.3 format file entry, | |||
* to associate a LFN entry with its short file entry. | |||
* | |||
* \param n0 MSDOS Filename character 1 | |||
* \param n1 MSDOS Filename character 2 | |||
* \param n2 MSDOS Filename character 3 | |||
* \param n3 MSDOS Filename character 4 | |||
* \param n4 MSDOS Filename character 5 | |||
* \param n5 MSDOS Filename character 6 | |||
* \param n6 MSDOS Filename character 7 | |||
* \param n7 MSDOS Filename character 8 | |||
* \param e0 MSDOS Extension character 1 | |||
* \param e1 MSDOS Extension character 2 | |||
* \param e2 MSDOS Extension character 3 | |||
* | |||
* \return LFN checksum of the given MSDOS 8.3 filename. | |||
*/ | |||
#define FAT_CHECKSUM(n0, n1, n2, n3, n4, n5, n6, n7, e0, e1, e2) \ | |||
(uint8_t)(_ROT8(_ROT8(_ROT8(_ROT8(_ROT8(_ROT8(_ROT8(_ROT8(_ROT8(_ROT8(n0)+n1)+n2)+n3)+n4)+n5)+n6)+n7)+e0)+e1)+e2) | |||
/** \name FAT Filesystem Flags */ | |||
//@{ | |||
/** FAT attribute flag to indicate a read-only file. */ | |||
#define FAT_FLAG_READONLY (1 << 0) | |||
/** FAT attribute flag to indicate a hidden file. */ | |||
#define FAT_FLAG_HIDDEN (1 << 1) | |||
/** FAT attribute flag to indicate a system file. */ | |||
#define FAT_FLAG_SYSTEM (1 << 2) | |||
/** FAT attribute flag to indicate a Volume name entry. */ | |||
#define FAT_FLAG_VOLUME_NAME (1 << 3) | |||
/** FAT attribute flag to indicate a directory entry. */ | |||
#define FAT_FLAG_DIRECTORY (1 << 4) | |||
/** FAT attribute flag to indicate a file ready for archiving. */ | |||
#define FAT_FLAG_ARCHIVE (1 << 5) | |||
/** FAT pseudo-attribute flag to indicate a Long File Name entry. */ | |||
#define FAT_FLAG_LONG_FILE_NAME 0x0F | |||
/** Ordinal flag marker for FAT Long File Name entries to mark the last entry. */ | |||
#define FAT_ORDINAL_LAST_ENTRY (1 << 6) | |||
//@} | |||
/* Enums: */ | |||
/** Enum for the Root FAT file entry indexes on the disk. This can be used | |||
* to retrieve the current contents of a known directory entry. | |||
*/ | |||
enum | |||
{ | |||
/** Volume ID directory entry, giving the name of the virtual disk. */ | |||
DISK_FILE_ENTRY_VolumeID = 0, | |||
/** Long File Name FAT file entry of the virtual FLASH.BIN image file. */ | |||
DISK_FILE_ENTRY_FLASH_LFN = 1, | |||
/** Legacy MSDOS FAT file entry of the virtual FLASH.BIN image file. */ | |||
DISK_FILE_ENTRY_FLASH_MSDOS = 2, | |||
/** Long File Name FAT file entry of the virtual EEPROM.BIN image file. */ | |||
DISK_FILE_ENTRY_EEPROM_LFN = 3, | |||
/** Legacy MSDOS FAT file entry of the virtual EEPROM.BIN image file. */ | |||
DISK_FILE_ENTRY_EEPROM_MSDOS = 4, | |||
}; | |||
/** Enum for the physical disk blocks of the virtual disk. */ | |||
enum | |||
{ | |||
/** Boot sector disk block. */ | |||
DISK_BLOCK_BootBlock = 0, | |||
/** First copy of the FAT table block. */ | |||
DISK_BLOCK_FATBlock1 = 1, | |||
/** Second copy of the FAT table block. */ | |||
DISK_BLOCK_FATBlock2 = 2, | |||
/** Root file and directory entries block. */ | |||
DISK_BLOCK_RootFilesBlock = 3, | |||
/** Start block of the disk data section. */ | |||
DISK_BLOCK_DataStartBlock = 4, | |||
}; | |||
/* Type Definitions: */ | |||
/** FAT boot block structure definition, used to identify the core | |||
* parameters of a FAT file system stored on a disk. | |||
* | |||
* \note This definition is truncated to save space; the magic signature | |||
* \c 0xAA55 must be appended to the very end of the block for it | |||
* to be detected by the host as a valid boot block. | |||
*/ | |||
typedef struct | |||
{ | |||
uint8_t Bootstrap[3]; | |||
uint8_t Description[8]; | |||
uint16_t SectorSize; | |||
uint8_t SectorsPerCluster; | |||
uint16_t ReservedSectors; | |||
uint8_t FATCopies; | |||
uint16_t RootDirectoryEntries; | |||
uint16_t TotalSectors16; | |||
uint8_t MediaDescriptor; | |||
uint16_t SectorsPerFAT; | |||
uint16_t SectorsPerTrack; | |||
uint16_t Heads; | |||
uint32_t HiddenSectors; | |||
uint32_t TotalSectors32; | |||
uint16_t PhysicalDriveNum; | |||
uint8_t ExtendedBootRecordSig; | |||
uint32_t VolumeSerialNumber; | |||
uint8_t VolumeLabel[11]; | |||
uint8_t FilesystemIdentifier[8]; | |||
/* uint8_t BootstrapProgram[448]; */ | |||
/* uint16_t MagicSignature; */ | |||
} FATBootBlock_t; | |||
/** FAT directory entry structure, for the various kinds of File and | |||
* directory descriptors on a FAT disk. | |||
*/ | |||
typedef union | |||
{ | |||
/** VFAT Long File Name file entry. */ | |||
struct | |||
{ | |||
uint8_t Ordinal; | |||
uint16_t Unicode1; | |||
uint16_t Unicode2; | |||
uint16_t Unicode3; | |||
uint16_t Unicode4; | |||
uint16_t Unicode5; | |||
uint8_t Attribute; | |||
uint8_t Reserved1; | |||
uint8_t Checksum; | |||
uint16_t Unicode6; | |||
uint16_t Unicode7; | |||
uint16_t Unicode8; | |||
uint16_t Unicode9; | |||
uint16_t Unicode10; | |||
uint16_t Unicode11; | |||
uint16_t Reserved2; | |||
uint16_t Unicode12; | |||
uint16_t Unicode13; | |||
} VFAT_LongFileName; | |||
/** Legacy FAT MSDOS 8.3 file entry. */ | |||
struct | |||
{ | |||
uint8_t Filename[8]; | |||
uint8_t Extension[3]; | |||
uint8_t Attributes; | |||
uint8_t Reserved[10]; | |||
uint16_t CreationTime; | |||
uint16_t CreationDate; | |||
uint16_t StartingCluster; | |||
uint32_t FileSizeBytes; | |||
} MSDOS_File; | |||
/** Legacy FAT MSDOS (sub-)directory entry. */ | |||
struct | |||
{ | |||
uint8_t Name[11]; | |||
uint8_t Attributes; | |||
uint8_t Reserved[10]; | |||
uint16_t CreationTime; | |||
uint16_t CreationDate; | |||
uint16_t StartingCluster; | |||
uint32_t Reserved2; | |||
} MSDOS_Directory; | |||
} FATDirectoryEntry_t; | |||
/* Function Prototypes: */ | |||
#if defined(INCLUDE_FROM_VIRTUAL_FAT_C) | |||
static uint8_t ReadEEPROMByte(const uint8_t* const Address) ATTR_NO_INLINE; | |||
static void WriteEEPROMByte(uint8_t* const Address, | |||
const uint8_t Data) ATTR_NO_INLINE; | |||
static void UpdateFAT12ClusterEntry(uint8_t* const FATTable, | |||
const uint16_t Index, | |||
const uint16_t ChainEntry) AUX_BOOT_SECTION; | |||
static void UpdateFAT12ClusterChain(uint8_t* const FATTable, | |||
const uint16_t StartIndex, | |||
const uint8_t ChainLength) AUX_BOOT_SECTION; | |||
static void ReadWriteFLASHFileBlock(const uint16_t BlockNumber, | |||
uint8_t* BlockBuffer, | |||
const bool Read) AUX_BOOT_SECTION; | |||
static void ReadWriteEEPROMFileBlock(const uint16_t BlockNumber, | |||
uint8_t* BlockBuffer, | |||
const bool Read) AUX_BOOT_SECTION; | |||
#endif | |||
void VirtualFAT_WriteBlock(const uint16_t BlockNumber) AUX_BOOT_SECTION; | |||
void VirtualFAT_ReadBlock(const uint16_t BlockNumber) AUX_BOOT_SECTION; | |||
#endif |
@@ -0,0 +1,156 @@ | |||
<asf xmlversion="1.0"> | |||
<project caption="Mass Storage Bootloader - 128KB FLASH / 8KB Boot - AVR8 Architecture" id="lufa.bootloaders.mass_storage.avr8.128_8" force-caption="true" workspace-name="lufa_ms_128kb_8kb_"> | |||
<require idref="lufa.bootloaders.mass_storage"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="at90usb1287"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<config name="config.compiler.optimization.level" value="size"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0x1E000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x1E000"/> | |||
<build type="define" name="AUX_BOOT_SECTION_SIZE" value="0"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x1FFA0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x1FFE0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x1FFF8"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/> | |||
</project> | |||
<project caption="Mass Storage Bootloader - 64KB FLASH / 8KB Boot - AVR8 Architecture" id="lufa.bootloaders.mass_storage.avr8.64_8" force-caption="true" workspace-name="lufa_ms_64kb_8kb_"> | |||
<require idref="lufa.bootloaders.mass_storage"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="at90usb647"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<config name="config.compiler.optimization.level" value="size"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0xE000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0xE000"/> | |||
<build type="define" name="AUX_BOOT_SECTION_SIZE" value="0"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0xFFA0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0xFFE0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0xFFF8"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/> | |||
</project> | |||
<project caption="Mass Storage Bootloader - 32KB FLASH / 4KB Boot (2KB AUX) - AVR8 Architecture" id="lufa.bootloaders.mass_storage.avr8.32_4" force-caption="true" workspace-name="lufa_ms_32kb_4kb_"> | |||
<require idref="lufa.bootloaders.mass_storage"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="atmega32u4"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<config name="config.compiler.optimization.level" value="size"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0x7000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x7000"/> | |||
<build type="define" name="AUX_BOOT_SECTION_SIZE" value="2048"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.boot_aux=0x6810"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.boot_aux_trampoline=0x6800"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=Boot_AUX_Trampoline"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x7FA0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x7FE0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x7FF8"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/> | |||
</project> | |||
<project caption="Mass Storage Bootloader - 16KB FLASH / 4KB Boot (2KB AUX) - AVR8 Architecture" id="lufa.bootloaders.mass_storage.avr8.16_4" force-caption="true" workspace-name="lufa_ms_16kb_4kb_"> | |||
<require idref="lufa.bootloaders.mass_storage"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="atmega16u2"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<config name="config.compiler.optimization.level" value="size"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0x3000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x3000"/> | |||
<build type="define" name="AUX_BOOT_SECTION_SIZE" value="2048"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.boot_aux=0x2810"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.boot_aux_trampoline=0x2800"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=Boot_AUX_Trampoline"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x3FA0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x3FE0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x3FF8"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/> | |||
</project> | |||
<module type="application" id="lufa.bootloaders.mass_storage" caption="Mass Storage Bootloader"> | |||
<info type="description" value="summary"> | |||
Mass Storage Class Bootloader, capable of reprogramming a device via binary BIN files copied to the virtual FAT12 file-system it creates when plugged into a host. | |||
</info> | |||
<info type="gui-flag" value="move-to-root"/> | |||
<info type="keyword" value="Technology"> | |||
<keyword value="Bootloaders"/> | |||
<keyword value="USB Device"/> | |||
</info> | |||
<device-support-alias value="lufa_avr8"/> | |||
<device-support-alias value="lufa_xmega"/> | |||
<device-support-alias value="lufa_uc3"/> | |||
<build type="include-path" value="."/> | |||
<build type="c-source" value="BootloaderMassStorage.c"/> | |||
<build type="header-file" value="BootloaderMassStorage.h"/> | |||
<build type="c-source" value="Descriptors.c"/> | |||
<build type="header-file" value="Descriptors.h"/> | |||
<build type="c-source" value="BootloaderAPI.c"/> | |||
<build type="header-file" value="BootloaderAPI.h"/> | |||
<build type="asm-source" value="BootloaderAPITable.S"/> | |||
<build type="module-config" subtype="path" value="Config"/> | |||
<build type="header-file" value="Config/LUFAConfig.h"/> | |||
<build type="header-file" value="Config/AppConfig.h"/> | |||
<build type="include-path" value="Lib"/> | |||
<build type="header-file" value="Lib/VirtualFAT.h"/> | |||
<build type="c-source" value="Lib/VirtualFAT.c"/> | |||
<build type="header-file" value="Lib/SCSI.h"/> | |||
<build type="c-source" value="Lib/SCSI.c"/> | |||
<build type="distribute" subtype="user-file" value="doxyfile"/> | |||
<build type="distribute" subtype="user-file" value="BootloaderMassStorage.txt"/> | |||
<require idref="lufa.common"/> | |||
<require idref="lufa.platform"/> | |||
<require idref="lufa.drivers.usb"/> | |||
<require idref="lufa.drivers.board"/> | |||
<require idref="lufa.drivers.board.leds"/> | |||
</module> | |||
</asf> |
@@ -0,0 +1,68 @@ | |||
# | |||
# LUFA Library | |||
# Copyright (C) Dean Camera, 2014. | |||
# | |||
# dean [at] fourwalledcubicle [dot] com | |||
# www.lufa-lib.org | |||
# | |||
# -------------------------------------- | |||
# LUFA Project Makefile. | |||
# -------------------------------------- | |||
# Run "make help" for target help. | |||
MCU = at90usb1287 | |||
ARCH = AVR8 | |||
BOARD = USBKEY | |||
F_CPU = 8000000 | |||
F_USB = $(F_CPU) | |||
OPTIMIZATION = s | |||
TARGET = BootloaderMassStorage | |||
SRC = $(TARGET).c Descriptors.c BootloaderAPI.c BootloaderAPITable.S Lib/SCSI.c Lib/VirtualFAT.c $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS) | |||
LUFA_PATH = ../../LUFA | |||
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/ -DBOOT_START_ADDR=$(BOOT_START_OFFSET) | |||
LD_FLAGS = -Wl,--section-start=.text=$(BOOT_START_OFFSET) $(BOOT_API_LD_FLAGS) | |||
# Flash size and bootloader section sizes of the target, in KB. These must | |||
# match the target's total FLASH size and the bootloader size set in the | |||
# device's fuses. | |||
FLASH_SIZE_KB = 128 | |||
BOOT_SECTION_SIZE_KB = 8 | |||
# Bootloader address calculation formulas | |||
# Do not modify these macros, but rather modify the dependent values above. | |||
CALC_ADDRESS_IN_HEX = $(shell printf "0x%X" $$(( $(1) )) ) | |||
BOOT_START_OFFSET = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) - $(BOOT_SECTION_SIZE_KB)) * 1024 ) | |||
BOOT_SEC_OFFSET = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) * 1024) - ($(strip $(1))) ) | |||
# Bootloader linker section flags for relocating the API table sections to | |||
# known FLASH addresses - these should not normally be user-edited. | |||
BOOT_SECTION_LD_FLAG = -Wl,--section-start=$(strip $(1))=$(call BOOT_SEC_OFFSET, $(3)) -Wl,--undefined=$(strip $(2)) | |||
BOOT_API_LD_FLAGS = $(call BOOT_SECTION_LD_FLAG, .apitable_trampolines, BootloaderAPI_Trampolines, 96) | |||
BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .apitable_jumptable, BootloaderAPI_JumpTable, 32) | |||
BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .apitable_signatures, BootloaderAPI_Signatures, 8) | |||
# Check if the bootloader needs an AUX section, located before the real bootloader section to store some of the | |||
# bootloader code. This is required for 32KB and smaller devices, where the actual bootloader is 6KB but the maximum | |||
# bootloader section size is 4KB. The actual usable application space will be reduced by 6KB for these devices. | |||
ifeq ($(BOOT_SECTION_SIZE_KB),8) | |||
CC_FLAGS += -DAUX_BOOT_SECTION_SIZE=0 | |||
else | |||
AUX_BOOT_SECTION_SIZE_KB = (6 - $(BOOT_SECTION_SIZE_KB)) | |||
CC_FLAGS += -DAUX_BOOT_SECTION_SIZE='($(AUX_BOOT_SECTION_SIZE_KB) * 1024)' | |||
LD_FLAGS += -Wl,--section-start=.boot_aux=$(call BOOT_SEC_OFFSET, (($(BOOT_SECTION_SIZE_KB) + $(AUX_BOOT_SECTION_SIZE_KB)) * 1024 - 16)) | |||
LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .boot_aux_trampoline, Boot_AUX_Trampoline, ($(BOOT_SECTION_SIZE_KB) + $(AUX_BOOT_SECTION_SIZE_KB)) * 1024) | |||
endif | |||
# Default target | |||
all: | |||
# Include LUFA build script makefiles | |||
include $(LUFA_PATH)/Build/lufa_core.mk | |||
include $(LUFA_PATH)/Build/lufa_sources.mk | |||
include $(LUFA_PATH)/Build/lufa_build.mk | |||
include $(LUFA_PATH)/Build/lufa_cppcheck.mk | |||
include $(LUFA_PATH)/Build/lufa_doxygen.mk | |||
include $(LUFA_PATH)/Build/lufa_avrdude.mk | |||
include $(LUFA_PATH)/Build/lufa_atprogram.mk |
@@ -0,0 +1,75 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Bootloader user application API functions. | |||
*/ | |||
#include "BootloaderAPI.h" | |||
void BootloaderAPI_ErasePage(const uint32_t Address) | |||
{ | |||
boot_page_erase_safe(Address); | |||
boot_spm_busy_wait(); | |||
boot_rww_enable(); | |||
} | |||
void BootloaderAPI_WritePage(const uint32_t Address) | |||
{ | |||
boot_page_write_safe(Address); | |||
boot_spm_busy_wait(); | |||
boot_rww_enable(); | |||
} | |||
void BootloaderAPI_FillWord(const uint32_t Address, const uint16_t Word) | |||
{ | |||
boot_page_fill_safe(Address, Word); | |||
} | |||
uint8_t BootloaderAPI_ReadSignature(const uint16_t Address) | |||
{ | |||
return boot_signature_byte_get(Address); | |||
} | |||
uint8_t BootloaderAPI_ReadFuse(const uint16_t Address) | |||
{ | |||
return boot_lock_fuse_bits_get(Address); | |||
} | |||
uint8_t BootloaderAPI_ReadLock(void) | |||
{ | |||
return boot_lock_fuse_bits_get(GET_LOCK_BITS); | |||
} | |||
void BootloaderAPI_WriteLock(const uint8_t LockBits) | |||
{ | |||
boot_lock_bits_set_safe(LockBits); | |||
} |
@@ -0,0 +1,56 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Header file for BootloaderAPI.c. | |||
*/ | |||
#ifndef _BOOTLOADER_API_H_ | |||
#define _BOOTLOADER_API_H_ | |||
/* Includes: */ | |||
#include <avr/io.h> | |||
#include <avr/boot.h> | |||
#include <stdbool.h> | |||
#include <LUFA/Common/Common.h> | |||
/* Function Prototypes: */ | |||
void BootloaderAPI_ErasePage(const uint32_t Address); | |||
void BootloaderAPI_WritePage(const uint32_t Address); | |||
void BootloaderAPI_FillWord(const uint32_t Address, const uint16_t Word); | |||
uint8_t BootloaderAPI_ReadSignature(const uint16_t Address); | |||
uint8_t BootloaderAPI_ReadFuse(const uint16_t Address); | |||
uint8_t BootloaderAPI_ReadLock(void); | |||
void BootloaderAPI_WriteLock(const uint8_t LockBits); | |||
#endif | |||
@@ -0,0 +1,91 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
; Trampolines to actual API implementations if the target address is outside the | |||
; range of a rjmp instruction (can happen with large bootloader sections) | |||
.section .apitable_trampolines, "ax" | |||
.global BootloaderAPI_Trampolines | |||
BootloaderAPI_Trampolines: | |||
BootloaderAPI_ErasePage_Trampoline: | |||
jmp BootloaderAPI_ErasePage | |||
BootloaderAPI_WritePage_Trampoline: | |||
jmp BootloaderAPI_WritePage | |||
BootloaderAPI_FillWord_Trampoline: | |||
jmp BootloaderAPI_FillWord | |||
BootloaderAPI_ReadSignature_Trampoline: | |||
jmp BootloaderAPI_ReadSignature | |||
BootloaderAPI_ReadFuse_Trampoline: | |||
jmp BootloaderAPI_ReadFuse | |||
BootloaderAPI_ReadLock_Trampoline: | |||
jmp BootloaderAPI_ReadLock | |||
BootloaderAPI_WriteLock_Trampoline: | |||
jmp BootloaderAPI_WriteLock | |||
BootloaderAPI_UNUSED1: | |||
ret | |||
BootloaderAPI_UNUSED2: | |||
ret | |||
BootloaderAPI_UNUSED3: | |||
ret | |||
BootloaderAPI_UNUSED4: | |||
ret | |||
BootloaderAPI_UNUSED5: | |||
ret | |||
; API function jump table | |||
.section .apitable_jumptable, "ax" | |||
.global BootloaderAPI_JumpTable | |||
BootloaderAPI_JumpTable: | |||
rjmp BootloaderAPI_ErasePage_Trampoline | |||
rjmp BootloaderAPI_WritePage_Trampoline | |||
rjmp BootloaderAPI_FillWord_Trampoline | |||
rjmp BootloaderAPI_ReadSignature_Trampoline | |||
rjmp BootloaderAPI_ReadFuse_Trampoline | |||
rjmp BootloaderAPI_ReadLock_Trampoline | |||
rjmp BootloaderAPI_WriteLock_Trampoline | |||
rjmp BootloaderAPI_UNUSED1 ; UNUSED ENTRY 1 | |||
rjmp BootloaderAPI_UNUSED2 ; UNUSED ENTRY 2 | |||
rjmp BootloaderAPI_UNUSED3 ; UNUSED ENTRY 3 | |||
rjmp BootloaderAPI_UNUSED4 ; UNUSED ENTRY 4 | |||
rjmp BootloaderAPI_UNUSED5 ; UNUSED ENTRY 5 | |||
; Bootloader table signatures and information | |||
.section .apitable_signatures, "ax" | |||
.global BootloaderAPI_Signatures | |||
BootloaderAPI_Signatures: | |||
.long BOOT_START_ADDR ; Start address of the bootloader | |||
.word 0xDF20 ; Signature for the Printer class bootloader | |||
.word 0xDCFB ; Signature for a LUFA class bootloader |
@@ -0,0 +1,431 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Main source file for the Printer class bootloader. This file contains the complete bootloader logic. | |||
*/ | |||
#include "BootloaderPrinter.h" | |||
/** LUFA Printer Class driver interface configuration and state information. This structure is | |||
* passed to all Printer Class driver functions, so that multiple instances of the same class | |||
* within a device can be differentiated from one another. | |||
*/ | |||
USB_ClassInfo_PRNT_Device_t TextOnly_Printer_Interface = | |||
{ | |||
.Config = | |||
{ | |||
.InterfaceNumber = INTERFACE_ID_Printer, | |||
.DataINEndpoint = | |||
{ | |||
.Address = PRINTER_IN_EPADDR, | |||
.Size = PRINTER_IO_EPSIZE, | |||
.Banks = 1, | |||
}, | |||
.DataOUTEndpoint = | |||
{ | |||
.Address = PRINTER_OUT_EPADDR, | |||
.Size = PRINTER_IO_EPSIZE, | |||
.Banks = 1, | |||
}, | |||
.IEEE1284String = | |||
"MFG:Generic;" | |||
"MDL:Generic_/_Text_Only;" | |||
"CMD:1284.4;" | |||
"CLS:PRINTER", | |||
}, | |||
}; | |||
/** Intel HEX parser state machine state information, to track the contents of | |||
* a HEX file streamed in as a sequence of arbitrary bytes. | |||
*/ | |||
struct | |||
{ | |||
/** Current HEX parser state machine state. */ | |||
uint8_t ParserState; | |||
/** Previously decoded numerical byte of data. */ | |||
uint8_t PrevData; | |||
/** Currently decoded numerical byte of data. */ | |||
uint8_t Data; | |||
/** Indicates if both bytes that correspond to a single decoded numerical | |||
* byte of data (HEX encodes values in ASCII HEX, two characters per byte) | |||
* have been read. | |||
*/ | |||
bool ReadMSB; | |||
/** Intel HEX record type of the current Intel HEX record. */ | |||
uint8_t RecordType; | |||
/** Numerical bytes of data remaining to be read in the current record. */ | |||
uint8_t DataRem; | |||
/** Checksum of the current record received so far. */ | |||
uint8_t Checksum; | |||
/** Starting address of the last addressed FLASH page. */ | |||
uint32_t PageStartAddress; | |||
/** Current 32-bit byte extended base address in FLASH being targeted. */ | |||
uint32_t CurrBaseAddress; | |||
/** Current 32-bit byte address in FLASH being targeted. */ | |||
uint32_t CurrAddress; | |||
} HEXParser; | |||
/** Indicates if there is data waiting to be written to a physical page of | |||
* memory in FLASH. | |||
*/ | |||
static bool PageDirty = false; | |||
/** Flag to indicate if the bootloader should be running, or should exit and allow the application code to run | |||
* via a soft reset. When cleared, the bootloader will abort, the USB interface will shut down and the application | |||
* started via a forced watchdog reset. | |||
*/ | |||
static bool RunBootloader = true; | |||
/** Magic lock for forced application start. If the HWBE fuse is programmed and BOOTRST is unprogrammed, the bootloader | |||
* will start if the /HWB line of the AVR is held low and the system is reset. However, if the /HWB line is still held | |||
* low when the application attempts to start via a watchdog reset, the bootloader will re-start. If set to the value | |||
* \ref MAGIC_BOOT_KEY the special init function \ref Application_Jump_Check() will force the application to start. | |||
*/ | |||
uint16_t MagicBootKey ATTR_NO_INIT; | |||
/** Special startup routine to check if the bootloader was started via a watchdog reset, and if the magic application | |||
* start key has been loaded into \ref MagicBootKey. If the bootloader started via the watchdog and the key is valid, | |||
* this will force the user application to start via a software jump. | |||
*/ | |||
void Application_Jump_Check(void) | |||
{ | |||
/* If the reset source was the bootloader and the key is correct, clear it and jump to the application */ | |||
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY)) | |||
{ | |||
MagicBootKey = 0; | |||
// cppcheck-suppress constStatement | |||
((void (*)(void))0x0000)(); | |||
} | |||
} | |||
/** | |||
* Converts a given input byte of data from an ASCII encoded HEX value to an integer value. | |||
* | |||
* \note Input HEX bytes are expected to be in uppercase only. | |||
* | |||
* \param[in] Byte ASCII byte of data to convert | |||
* | |||
* \return Integer converted value of the input ASCII encoded HEX byte of data, or -1 if the | |||
* input is not valid ASCII encoded HEX. | |||
*/ | |||
static int8_t HexToDecimal(const char Byte) | |||
{ | |||
if ((Byte >= 'A') && (Byte <= 'F')) | |||
return (10 + (Byte - 'A')); | |||
else if ((Byte >= '0') && (Byte <= '9')) | |||
return (Byte - '0'); | |||
return -1; | |||
} | |||
/** | |||
* Flushes a partially written page of data to physical FLASH, if a page | |||
* boundary has been crossed. | |||
* | |||
* \note If a page flush occurs the global HEX parser state is updated. | |||
*/ | |||
static void FlushPageIfRequired(void) | |||
{ | |||
/* Abort if no data has been buffered for writing to the current page */ | |||
if (!PageDirty) | |||
return; | |||
/* Flush the FLASH page to physical memory if we are crossing a page boundary */ | |||
uint32_t NewPageStartAddress = (HEXParser.CurrAddress & ~(SPM_PAGESIZE - 1)); | |||
if (HEXParser.PageStartAddress != NewPageStartAddress) | |||
{ | |||
boot_page_write(HEXParser.PageStartAddress); | |||
boot_spm_busy_wait(); | |||
HEXParser.PageStartAddress = NewPageStartAddress; | |||
PageDirty = false; | |||
} | |||
} | |||
/** | |||
* Parses an input Intel HEX formatted stream one character at a time, loading | |||
* the data contents into the device's internal FLASH memory. | |||
* | |||
* \param[in] ReadCharacter Next input ASCII byte of data to parse | |||
*/ | |||
static void ParseIntelHEXByte(const char ReadCharacter) | |||
{ | |||
/* Reset the line parser while waiting for a new line to start */ | |||
if ((HEXParser.ParserState == HEX_PARSE_STATE_WAIT_LINE) || (ReadCharacter == ':')) | |||
{ | |||
HEXParser.Checksum = 0; | |||
HEXParser.CurrAddress = HEXParser.CurrBaseAddress; | |||
HEXParser.ReadMSB = false; | |||
/* ASCII ':' indicates the start of a new HEX record */ | |||
if (ReadCharacter == ':') | |||
HEXParser.ParserState = HEX_PARSE_STATE_BYTE_COUNT; | |||
return; | |||
} | |||
/* Only allow ASCII HEX encoded digits, ignore all other characters */ | |||
int8_t ReadCharacterDec = HexToDecimal(ReadCharacter); | |||
if (ReadCharacterDec < 0) | |||
return; | |||
/* Read and convert the next nibble of data from the current character */ | |||
HEXParser.Data = (HEXParser.Data << 4) | ReadCharacterDec; | |||
HEXParser.ReadMSB = !HEXParser.ReadMSB; | |||
/* Only process further when a full byte (two nibbles) have been read */ | |||
if (HEXParser.ReadMSB) | |||
return; | |||
/* Intel HEX checksum is for all fields except starting character and the | |||
* checksum itself | |||
*/ | |||
if (HEXParser.ParserState != HEX_PARSE_STATE_CHECKSUM) | |||
HEXParser.Checksum += HEXParser.Data; | |||
switch (HEXParser.ParserState) | |||
{ | |||
case HEX_PARSE_STATE_BYTE_COUNT: | |||
HEXParser.DataRem = HEXParser.Data; | |||
HEXParser.ParserState = HEX_PARSE_STATE_ADDRESS_HIGH; | |||
break; | |||
case HEX_PARSE_STATE_ADDRESS_HIGH: | |||
HEXParser.CurrAddress += ((uint16_t)HEXParser.Data << 8); | |||
HEXParser.ParserState = HEX_PARSE_STATE_ADDRESS_LOW; | |||
break; | |||
case HEX_PARSE_STATE_ADDRESS_LOW: | |||
HEXParser.CurrAddress += HEXParser.Data; | |||
HEXParser.ParserState = HEX_PARSE_STATE_RECORD_TYPE; | |||
break; | |||
case HEX_PARSE_STATE_RECORD_TYPE: | |||
HEXParser.RecordType = HEXParser.Data; | |||
HEXParser.ParserState = (HEXParser.DataRem ? HEX_PARSE_STATE_READ_DATA : HEX_PARSE_STATE_CHECKSUM); | |||
break; | |||
case HEX_PARSE_STATE_READ_DATA: | |||
/* Track the number of read data bytes in the record */ | |||
HEXParser.DataRem--; | |||
/* Protect the bootloader against being written to */ | |||
if (HEXParser.CurrAddress >= BOOT_START_ADDR) | |||
{ | |||
HEXParser.ParserState = HEX_PARSE_STATE_WAIT_LINE; | |||
PageDirty = false; | |||
return; | |||
} | |||
/* Wait for a machine word (two bytes) of data to be read */ | |||
if (HEXParser.DataRem & 0x01) | |||
{ | |||
HEXParser.PrevData = HEXParser.Data; | |||
break; | |||
} | |||
/* Convert the last two received data bytes into a 16-bit word */ | |||
uint16_t NewDataWord = ((uint16_t)HEXParser.Data << 8) | HEXParser.PrevData; | |||
switch (HEXParser.RecordType) | |||
{ | |||
case HEX_RECORD_TYPE_Data: | |||
/* If we are writing to a new page, we need to erase it first */ | |||
if (!(PageDirty)) | |||
{ | |||
boot_page_erase(HEXParser.PageStartAddress); | |||
boot_spm_busy_wait(); | |||
PageDirty = true; | |||
} | |||
/* Fill the FLASH memory buffer with the new word of data */ | |||
boot_page_fill(HEXParser.CurrAddress, NewDataWord); | |||
HEXParser.CurrAddress += 2; | |||
/* Flush the FLASH page to physical memory if we are crossing a page boundary */ | |||
FlushPageIfRequired(); | |||
break; | |||
case HEX_RECORD_TYPE_ExtendedSegmentAddress: | |||
/* Extended address data - store the upper 12-bits of the new address */ | |||
HEXParser.CurrBaseAddress = ((uint32_t)NewDataWord << 4); | |||
break; | |||
case HEX_RECORD_TYPE_ExtendedLinearAddress: | |||
/* Extended address data - store the upper 16-bits of the new address */ | |||
HEXParser.CurrBaseAddress = ((uint32_t)NewDataWord << 16); | |||
break; | |||
} | |||
if (!HEXParser.DataRem) | |||
HEXParser.ParserState = HEX_PARSE_STATE_CHECKSUM; | |||
break; | |||
case HEX_PARSE_STATE_CHECKSUM: | |||
/* Verify checksum of the completed record */ | |||
if (HEXParser.Data != ((~HEXParser.Checksum + 1) & 0xFF)) | |||
break; | |||
/* Flush the FLASH page to physical memory if we are crossing a page boundary */ | |||
FlushPageIfRequired(); | |||
/* If end of the HEX file reached, the bootloader should exit at next opportunity */ | |||
if (HEXParser.RecordType == HEX_RECORD_TYPE_EndOfFile) | |||
RunBootloader = false; | |||
break; | |||
default: | |||
HEXParser.ParserState = HEX_PARSE_STATE_WAIT_LINE; | |||
break; | |||
} | |||
} | |||
/** Main program entry point. This routine configures the hardware required by the application, then | |||
* enters a loop to run the application tasks in sequence. | |||
*/ | |||
int main(void) | |||
{ | |||
SetupHardware(); | |||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); | |||
GlobalInterruptEnable(); | |||
while (RunBootloader) | |||
{ | |||
uint8_t BytesReceived = PRNT_Device_BytesReceived(&TextOnly_Printer_Interface); | |||
if (BytesReceived) | |||
{ | |||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY); | |||
while (BytesReceived--) | |||
{ | |||
int16_t ReceivedByte = PRNT_Device_ReceiveByte(&TextOnly_Printer_Interface); | |||
/* Feed the next byte of data to the HEX parser */ | |||
ParseIntelHEXByte(ReceivedByte); | |||
} | |||
LEDs_SetAllLEDs(LEDMASK_USB_READY); | |||
} | |||
PRNT_Device_USBTask(&TextOnly_Printer_Interface); | |||
USB_USBTask(); | |||
} | |||
/* Disconnect from the host - USB interface will be reset later along with the AVR */ | |||
USB_Detach(); | |||
/* Unlock the forced application start mode of the bootloader if it is restarted */ | |||
MagicBootKey = MAGIC_BOOT_KEY; | |||
/* Enable the watchdog and force a timeout to reset the AVR */ | |||
wdt_enable(WDTO_250MS); | |||
for (;;); | |||
} | |||
/** Configures the board hardware and chip peripherals for the demo's functionality. */ | |||
static void SetupHardware(void) | |||
{ | |||
/* Disable watchdog if enabled by bootloader/fuses */ | |||
MCUSR &= ~(1 << WDRF); | |||
wdt_disable(); | |||
/* Disable clock division */ | |||
clock_prescale_set(clock_div_1); | |||
/* Relocate the interrupt vector table to the bootloader section */ | |||
MCUCR = (1 << IVCE); | |||
MCUCR = (1 << IVSEL); | |||
/* Hardware Initialization */ | |||
LEDs_Init(); | |||
USB_Init(); | |||
/* Bootloader active LED toggle timer initialization */ | |||
TIMSK1 = (1 << TOIE1); | |||
TCCR1B = ((1 << CS11) | (1 << CS10)); | |||
} | |||
/** ISR to periodically toggle the LEDs on the board to indicate that the bootloader is active. */ | |||
ISR(TIMER1_OVF_vect, ISR_BLOCK) | |||
{ | |||
LEDs_ToggleLEDs(LEDS_LED1 | LEDS_LED2); | |||
} | |||
/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs. */ | |||
void EVENT_USB_Device_Connect(void) | |||
{ | |||
/* Indicate USB enumerating */ | |||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); | |||
} | |||
/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via | |||
* the status LEDs and stops the Printer management task. | |||
*/ | |||
void EVENT_USB_Device_Disconnect(void) | |||
{ | |||
/* Indicate USB not ready */ | |||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); | |||
} | |||
/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration | |||
* of the USB device after enumeration - the device endpoints are configured and the Mass Storage management task started. | |||
*/ | |||
void EVENT_USB_Device_ConfigurationChanged(void) | |||
{ | |||
bool ConfigSuccess = true; | |||
/* Setup Printer Data Endpoints */ | |||
ConfigSuccess &= PRNT_Device_ConfigureEndpoints(&TextOnly_Printer_Interface); | |||
/* Reset the HEX parser upon successful connection to a host */ | |||
HEXParser.ParserState = HEX_PARSE_STATE_WAIT_LINE; | |||
/* Indicate endpoint configuration success or failure */ | |||
LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR); | |||
} | |||
/** Event handler for the USB_ControlRequest event. This is used to catch and process control requests sent to | |||
* the device from the USB host before passing along unhandled control requests to the library for processing | |||
* internally. | |||
*/ | |||
void EVENT_USB_Device_ControlRequest(void) | |||
{ | |||
PRNT_Device_ProcessControlRequest(&TextOnly_Printer_Interface); | |||
} |
@@ -0,0 +1,108 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Header file for BootloaderPrinter.c. | |||
*/ | |||
#ifndef _BOOTLOADER_PRINTER_H_ | |||
#define _BOOTLOADER_PRINTER_H_ | |||
/* Includes: */ | |||
#include <avr/io.h> | |||
#include <avr/wdt.h> | |||
#include <avr/power.h> | |||
#include <avr/interrupt.h> | |||
#include "Descriptors.h" | |||
#include <LUFA/Drivers/Board/LEDs.h> | |||
#include <LUFA/Drivers/USB/USB.h> | |||
#include <LUFA/Platform/Platform.h> | |||
/* Preprocessor Checks: */ | |||
#if !defined(__OPTIMIZE_SIZE__) | |||
#error This bootloader requires that it be optimized for size, not speed, to fit into the target device. Change optimization settings and try again. | |||
#endif | |||
/* Macros: */ | |||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */ | |||
#define LEDMASK_USB_NOTREADY LEDS_LED1 | |||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */ | |||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3) | |||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */ | |||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4) | |||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */ | |||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3) | |||
/** LED mask for the library LED driver, to indicate that the USB interface is busy. */ | |||
#define LEDMASK_USB_BUSY LEDS_LED2 | |||
/** Magic bootloader key to unlock forced application start mode. */ | |||
#define MAGIC_BOOT_KEY 0xDC42 | |||
/* Enums: */ | |||
/** Intel HEX parser state machine states. */ | |||
enum HEX_Parser_States_t | |||
{ | |||
HEX_PARSE_STATE_WAIT_LINE, /**< Parser is waiting for a HEX Start of Line character. */ | |||
HEX_PARSE_STATE_BYTE_COUNT, /**< Parser is waiting for a record byte count. */ | |||
HEX_PARSE_STATE_ADDRESS_HIGH, /**< Parser is waiting for the MSB of a record address. */ | |||
HEX_PARSE_STATE_ADDRESS_LOW, /**< Parser is waiting for the LSB of a record address. */ | |||
HEX_PARSE_STATE_RECORD_TYPE, /**< Parser is waiting for the record type. */ | |||
HEX_PARSE_STATE_READ_DATA, /**< Parser is waiting for more data in the current record. */ | |||
HEX_PARSE_STATE_CHECKSUM, /**< Parser is waiting for the checksum of the current record. */ | |||
}; | |||
/** Intel HEX record types, used to indicate the type of record contained in a line of a HEX file. */ | |||
enum HEX_Record_Types_t | |||
{ | |||
HEX_RECORD_TYPE_Data = 0, /**< Record contains loadable data. */ | |||
HEX_RECORD_TYPE_EndOfFile = 1, /**< End of file record. */ | |||
HEX_RECORD_TYPE_ExtendedSegmentAddress = 2, /**< Extended segment start record. */ | |||
HEX_RECORD_TYPE_StartSegmentAddress = 3, /**< Normal segment start record. */ | |||
HEX_RECORD_TYPE_ExtendedLinearAddress = 4, /**< Extended linear address start record. */ | |||
HEX_RECORD_TYPE_StartLinearAddress = 5, /**< Linear address start record. */ | |||
}; | |||
/* Function Prototypes: */ | |||
static void SetupHardware(void); | |||
void EVENT_USB_Device_Connect(void); | |||
void EVENT_USB_Device_Disconnect(void); | |||
void EVENT_USB_Device_ConfigurationChanged(void); | |||
void EVENT_USB_Device_ControlRequest(void); | |||
#endif | |||
@@ -0,0 +1,190 @@ | |||
/** \file | |||
* | |||
* This file contains special DoxyGen information for the generation of the main page and other special | |||
* documentation pages. It is not a project source file. | |||
*/ | |||
/** \mainpage Printer Class USB AVR Bootloader | |||
* | |||
* \section Sec_Compat Demo Compatibility: | |||
* | |||
* The following list indicates what microcontrollers are compatible with this demo. | |||
* | |||
* \li Series 7 USB AVRs (AT90USBxxx7) | |||
* \li Series 6 USB AVRs (AT90USBxxx6) | |||
* \li Series 4 USB AVRs (ATMEGAxxU4) | |||
* \li Series 2 USB AVRs (AT90USBxx2, ATMEGAxxU2) | |||
* | |||
* \section Sec_Info USB Information: | |||
* | |||
* The following table gives a rundown of the USB utilization of this demo. | |||
* | |||
* <table> | |||
* <tr> | |||
* <td><b>USB Mode:</b></td> | |||
* <td>Device</td> | |||
* </tr> | |||
* <tr> | |||
* <td><b>USB Class:</b></td> | |||
* <td>Printer Class</td> | |||
* </tr> | |||
* <tr> | |||
* <td><b>USB Subclass:</b></td> | |||
* <td>Printer Subclass</td> | |||
* </tr> | |||
* <tr> | |||
* <td><b>Relevant Standards:</b></td> | |||
* <td>USBIF Printer Class Standard</td> | |||
* </tr> | |||
* <tr> | |||
* <td><b>Supported USB Speeds:</b></td> | |||
* <td>Full Speed Mode</td> | |||
* </tr> | |||
* </table> | |||
* | |||
* \section Sec_Description Project Description: | |||
* | |||
* This bootloader enumerates to the host as a Generic Text Only Printer device, capable of reading and parsing | |||
* "printed" plain-text Intel HEX files to load firmware onto the AVR. | |||
* | |||
* Out of the box this bootloader builds for the AT90USB1287 with an 8KB bootloader section size, and will fit | |||
* into 4KB of bootloader space. If you wish to alter this size and/or change the AVR model, you will need to | |||
* edit the MCU, FLASH_SIZE_KB and BOOT_SECTION_SIZE_KB values in the accompanying makefile. | |||
* | |||
* When the bootloader is running, the board's LED(s) will flash at regular intervals to distinguish the | |||
* bootloader from the normal user application. | |||
* | |||
* \section Sec_Running Running the Bootloader | |||
* | |||
* This bootloader is designed to be started via the HWB mechanism of the USB AVRs; ground the HWB pin (see device | |||
* datasheet) then momentarily ground /RESET to start the bootloader. This assumes the HWBE fuse is set and the BOOTRST | |||
* fuse is cleared. | |||
* | |||
* \section Sec_Installation Driver Installation | |||
* | |||
* This bootloader uses the Generic Text-Only printer drivers inbuilt into all modern operating systems, thus no | |||
* additional drivers need to be supplied for correct operation. | |||
* | |||
* \section Sec_HostApp Host Controller Application | |||
* | |||
* This bootloader is compatible with Notepad under Windows, and the command line \c lpr utility under Linux. | |||
* | |||
* \subsection SSec_Notepad Notepad (Windows) | |||
* | |||
* While most text applications under Windows will be compatible with the bootloader, the inbuilt Notepad utility | |||
* is recommended as it will introduce minimal formatting changes to the output stream. To program with Notepad, | |||
* open the target HEX file and print it to the Generic Text Only printer device the bootloader creates. | |||
* | |||
* \subsection SSec_LPR LPR (Linux) | |||
* | |||
* While the CUPS framework under Linux will enumerate the bootloader as a Generic Text-Only printer, many | |||
* applications will refuse to print to the device due to the lack of rich formatting options available. As a result, | |||
* under Linux HEX files must be printed via the low level \c lpr utility instead. | |||
* | |||
* \code | |||
* cat Mouse.hex | lpr | |||
* \endcode | |||
* | |||
* \section Sec_API User Application API | |||
* | |||
* Several user application functions for FLASH and other special memory area manipulations are exposed by the bootloader, | |||
* allowing the user application to call into the bootloader at runtime to read and write FLASH data. | |||
* | |||
* By default, the bootloader API jump table is located 32 bytes from the end of the device's FLASH memory, and follows the | |||
* following layout: | |||
* | |||
* \code | |||
* #define BOOTLOADER_API_TABLE_SIZE 32 | |||
* #define BOOTLOADER_API_TABLE_START ((FLASHEND + 1UL) - BOOTLOADER_API_TABLE_SIZE) | |||
* #define BOOTLOADER_API_CALL(Index) (void*)((BOOTLOADER_API_TABLE_START + (Index * 2)) / 2) | |||
* | |||
* void (*BootloaderAPI_ErasePage)(uint32_t Address) = BOOTLOADER_API_CALL(0); | |||
* void (*BootloaderAPI_WritePage)(uint32_t Address) = BOOTLOADER_API_CALL(1); | |||
* void (*BootloaderAPI_FillWord)(uint32_t Address, uint16_t Word) = BOOTLOADER_API_CALL(2); | |||
* uint8_t (*BootloaderAPI_ReadSignature)(uint16_t Address) = BOOTLOADER_API_CALL(3); | |||
* uint8_t (*BootloaderAPI_ReadFuse)(uint16_t Address) = BOOTLOADER_API_CALL(4); | |||
* uint8_t (*BootloaderAPI_ReadLock)(void) = BOOTLOADER_API_CALL(5); | |||
* void (*BootloaderAPI_WriteLock)(uint8_t LockBits) = BOOTLOADER_API_CALL(6); | |||
* | |||
* #define BOOTLOADER_MAGIC_SIGNATURE_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 2)) | |||
* #define BOOTLOADER_MAGIC_SIGNATURE 0xDCFB | |||
* | |||
* #define BOOTLOADER_CLASS_SIGNATURE_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 4)) | |||
* #define BOOTLOADER_PRINTER_SIGNATURE 0xDF20 | |||
* | |||
* #define BOOTLOADER_ADDRESS_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 8)) | |||
* #define BOOTLOADER_ADDRESS_LENGTH 4 | |||
* \endcode | |||
* | |||
* From the application the API support of the bootloader can be detected by reading the FLASH memory bytes located at address | |||
* \c BOOTLOADER_MAGIC_SIGNATURE_START and comparing them to the value \c BOOTLOADER_MAGIC_SIGNATURE. The class of bootloader | |||
* can be determined by reading the FLASH memory bytes located at address \c BOOTLOADER_CLASS_SIGNATURE_START and comparing them | |||
* to the value \c BOOTLOADER_PRINTER_SIGNATURE. The start address of the bootloader can be retrieved by reading the bytes of FLASH | |||
* memory starting from address \c BOOTLOADER_ADDRESS_START. | |||
* | |||
* \subsection SSec_API_MemLayout Device Memory Map | |||
* The following illustration indicates the final memory map of the device when loaded with the bootloader. | |||
* | |||
* \verbatim | |||
* +----------------------------+ 0x0000 | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | User Application | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* | | | |||
* +----------------------------+ FLASHEND - BOOT_SECTION_SIZE | |||
* | | | |||
* | Bootloader Application | | |||
* | (Not User App. Accessible) | | |||
* | | | |||
* +----------------------------+ FLASHEND - 96 | |||
* | API Table Trampolines | | |||
* | (Not User App. Accessible) | | |||
* +----------------------------+ FLASHEND - 32 | |||
* | Bootloader API Table | | |||
* | (User App. Accessible) | | |||
* +----------------------------+ FLASHEND - 8 | |||
* | Bootloader ID Constants | | |||
* | (User App. Accessible) | | |||
* +----------------------------+ FLASHEND | |||
* \endverbatim | |||
* | |||
* | |||
* \section Sec_KnownIssues Known Issues: | |||
* | |||
* \par On Linux machines, new firmware fails to be sent to the device via CUPS. | |||
* Only a limited subset of normal printer functionality is exposed via the | |||
* bootloader, causing CUPS to reject print requests from applications that | |||
* are unable to handle true plain-text printing. For best results, the low | |||
* level \c lpr command should be used to print new firmware to the bootloader. | |||
* | |||
* \par After loading an application, it is not run automatically on startup. | |||
* Some USB AVR boards ship with the BOOTRST fuse set, causing the bootloader | |||
* to run automatically when the device is reset. In most cases, the BOOTRST | |||
* fuse should be disabled and the HWBE fuse used instead to run the bootloader | |||
* when needed. | |||
* | |||
* \section Sec_Options Project Options | |||
* | |||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value. | |||
* | |||
* <table> | |||
* <tr> | |||
* <td> | |||
* None | |||
* </td> | |||
* </tr> | |||
* </table> | |||
*/ | |||
@@ -0,0 +1,93 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* \brief LUFA Library Configuration Header File | |||
* | |||
* This header file is used to configure LUFA's compile time options, | |||
* as an alternative to the compile time constants supplied through | |||
* a makefile. | |||
* | |||
* For information on what each token does, refer to the LUFA | |||
* manual section "Summary of Compile Tokens". | |||
*/ | |||
#ifndef _LUFA_CONFIG_H_ | |||
#define _LUFA_CONFIG_H_ | |||
#if (ARCH == ARCH_AVR8) | |||
/* Non-USB Related Configuration Tokens: */ | |||
// #define DISABLE_TERMINAL_CODES | |||
/* USB Class Driver Related Tokens: */ | |||
// #define HID_HOST_BOOT_PROTOCOL_ONLY | |||
// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here} | |||
// #define HID_USAGE_STACK_DEPTH {Insert Value Here} | |||
// #define HID_MAX_COLLECTIONS {Insert Value Here} | |||
// #define HID_MAX_REPORTITEMS {Insert Value Here} | |||
// #define HID_MAX_REPORT_IDS {Insert Value Here} | |||
// #define NO_CLASS_DRIVER_AUTOFLUSH | |||
/* General USB Driver Related Tokens: */ | |||
#define ORDERED_EP_CONFIG | |||
#define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL) | |||
#define USB_DEVICE_ONLY | |||
// #define USB_HOST_ONLY | |||
// #define USB_STREAM_TIMEOUT_MS {Insert Value Here} | |||
// #define NO_LIMITED_CONTROLLER_CONNECT | |||
#define NO_SOF_EVENTS | |||
/* USB Device Mode Driver Related Tokens: */ | |||
#define USE_RAM_DESCRIPTORS | |||
// #define USE_FLASH_DESCRIPTORS | |||
// #define USE_EEPROM_DESCRIPTORS | |||
#define NO_INTERNAL_SERIAL | |||
#define FIXED_CONTROL_ENDPOINT_SIZE 8 | |||
#define DEVICE_STATE_AS_GPIOR 0 | |||
#define FIXED_NUM_CONFIGURATIONS 1 | |||
// #define CONTROL_ONLY_DEVICE | |||
// #define INTERRUPT_CONTROL_ENDPOINT | |||
#define NO_DEVICE_REMOTE_WAKEUP | |||
#define NO_DEVICE_SELF_POWER | |||
/* USB Host Mode Driver Related Tokens: */ | |||
// #define HOST_STATE_AS_GPIOR {Insert Value Here} | |||
// #define USB_HOST_TIMEOUT_MS {Insert Value Here} | |||
// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here} | |||
// #define NO_AUTO_VBUS_MANAGEMENT | |||
// #define INVERTED_VBUS_ENABLE_LINE | |||
#else | |||
#error Unsupported architecture for this LUFA configuration file. | |||
#endif | |||
#endif |
@@ -0,0 +1,194 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special | |||
* computer-readable structures which the host requests upon device enumeration, to determine | |||
* the device's capabilities and functions. | |||
*/ | |||
#include "Descriptors.h" | |||
/** Device descriptor structure. This descriptor, located in SRAM memory, describes the overall | |||
* device characteristics, including the supported USB version, control endpoint size and the | |||
* number of device configurations. The descriptor is read out by the USB host when the enumeration | |||
* process begins. | |||
*/ | |||
const USB_Descriptor_Device_t DeviceDescriptor = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, | |||
.USBSpecification = VERSION_BCD(1,1,0), | |||
.Class = USB_CSCP_NoDeviceClass, | |||
.SubClass = USB_CSCP_NoDeviceSubclass, | |||
.Protocol = USB_CSCP_NoDeviceProtocol, | |||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, | |||
.VendorID = 0x03EB, | |||
.ProductID = 0x206B, | |||
.ReleaseNumber = VERSION_BCD(0,0,1), | |||
.ManufacturerStrIndex = STRING_ID_Manufacturer, | |||
.ProductStrIndex = STRING_ID_Product, | |||
.SerialNumStrIndex = NO_DESCRIPTOR, | |||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS | |||
}; | |||
/** Configuration descriptor structure. This descriptor, located in SRAM memory, describes the usage | |||
* of the device in one of its supported configurations, including information about any device interfaces | |||
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting | |||
* a configuration so that the host may correctly communicate with the USB device. | |||
*/ | |||
const USB_Descriptor_Configuration_t ConfigurationDescriptor = | |||
{ | |||
.Config = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, | |||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), | |||
.TotalInterfaces = 1, | |||
.ConfigurationNumber = 1, | |||
.ConfigurationStrIndex = NO_DESCRIPTOR, | |||
.ConfigAttributes = USB_CONFIG_ATTR_RESERVED, | |||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100) | |||
}, | |||
.Printer_Interface = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, | |||
.InterfaceNumber = INTERFACE_ID_Printer, | |||
.AlternateSetting = 0, | |||
.TotalEndpoints = 2, | |||
.Class = PRNT_CSCP_PrinterClass, | |||
.SubClass = PRNT_CSCP_PrinterSubclass, | |||
.Protocol = PRNT_CSCP_BidirectionalProtocol, | |||
.InterfaceStrIndex = NO_DESCRIPTOR | |||
}, | |||
.Printer_DataInEndpoint = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, | |||
.EndpointAddress = PRINTER_IN_EPADDR, | |||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), | |||
.EndpointSize = PRINTER_IO_EPSIZE, | |||
.PollingIntervalMS = 0x05 | |||
}, | |||
.Printer_DataOutEndpoint = | |||
{ | |||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, | |||
.EndpointAddress = PRINTER_OUT_EPADDR, | |||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), | |||
.EndpointSize = PRINTER_IO_EPSIZE, | |||
.PollingIntervalMS = 0x05 | |||
} | |||
}; | |||
/** Language descriptor structure. This descriptor, located in SRAM memory, is returned when the host requests | |||
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate | |||
* via the language ID table available at USB.org what languages the device supports for its string descriptors. | |||
*/ | |||
const USB_Descriptor_String_t LanguageString = USB_STRING_DESCRIPTOR_ARRAY(LANGUAGE_ID_ENG); | |||
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable | |||
* form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device | |||
* Descriptor. | |||
*/ | |||
const USB_Descriptor_String_t ManufacturerString = USB_STRING_DESCRIPTOR(L"Dean Camera"); | |||
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form, | |||
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device | |||
* Descriptor. | |||
*/ | |||
const USB_Descriptor_String_t ProductString = USB_STRING_DESCRIPTOR(L"LUFA Printer Bootloader"); | |||
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" | |||
* documentation) by the application code so that the address and size of a requested descriptor can be given | |||
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function | |||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the | |||
* USB host. | |||
*/ | |||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, | |||
const uint8_t wIndex, | |||
const void** const DescriptorAddress) | |||
{ | |||
const uint8_t DescriptorType = (wValue >> 8); | |||
const uint8_t DescriptorNumber = (wValue & 0xFF); | |||
const void* Address = NULL; | |||
uint16_t Size = NO_DESCRIPTOR; | |||
switch (DescriptorType) | |||
{ | |||
case DTYPE_Device: | |||
Address = &DeviceDescriptor; | |||
Size = sizeof(USB_Descriptor_Device_t); | |||
break; | |||
case DTYPE_Configuration: | |||
Address = &ConfigurationDescriptor; | |||
Size = sizeof(USB_Descriptor_Configuration_t); | |||
break; | |||
case DTYPE_String: | |||
switch (DescriptorNumber) | |||
{ | |||
case STRING_ID_Language: | |||
Address = &LanguageString; | |||
Size = LanguageString.Header.Size; | |||
break; | |||
case STRING_ID_Manufacturer: | |||
Address = &ManufacturerString; | |||
Size = ManufacturerString.Header.Size; | |||
break; | |||
case STRING_ID_Product: | |||
Address = &ProductString; | |||
Size = ProductString.Header.Size; | |||
break; | |||
} | |||
break; | |||
} | |||
*DescriptorAddress = Address; | |||
return Size; | |||
} | |||
@@ -0,0 +1,96 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* | |||
* Header file for Descriptors.c. | |||
*/ | |||
#ifndef _DESCRIPTORS_H_ | |||
#define _DESCRIPTORS_H_ | |||
/* Includes: */ | |||
#include <LUFA/Drivers/USB/USB.h> | |||
#include <avr/pgmspace.h> | |||
/* Macros: */ | |||
/** Endpoint address of the Printer device-to-host data IN endpoint. */ | |||
#define PRINTER_IN_EPADDR (ENDPOINT_DIR_IN | 3) | |||
/** Endpoint address of the Printer host-to-device data OUT endpoint. */ | |||
#define PRINTER_OUT_EPADDR (ENDPOINT_DIR_OUT | 4) | |||
/** Size in bytes of the Printer data endpoints. */ | |||
#define PRINTER_IO_EPSIZE 64 | |||
/* Type Defines: */ | |||
/** Type define for the device configuration descriptor structure. This must be defined in the | |||
* application code, as the configuration descriptor contains several sub-descriptors which | |||
* vary between devices, and which describe the device's usage to the host. | |||
*/ | |||
typedef struct | |||
{ | |||
USB_Descriptor_Configuration_Header_t Config; | |||
// Printer Interface | |||
USB_Descriptor_Interface_t Printer_Interface; | |||
USB_Descriptor_Endpoint_t Printer_DataInEndpoint; | |||
USB_Descriptor_Endpoint_t Printer_DataOutEndpoint; | |||
} USB_Descriptor_Configuration_t; | |||
/** Enum for the device interface descriptor IDs within the device. Each string descriptor | |||
* should have a unique ID index associated with it, which can be used to refer to the | |||
* interface from other descriptors. | |||
*/ | |||
enum InterfaceDescriptors_t | |||
{ | |||
INTERFACE_ID_Printer = 0, /**< Printer interface descriptor ID */ | |||
}; | |||
/** Enum for the device string descriptor IDs within the device. Each string descriptor should | |||
* have a unique ID index associated with it, which can be used to refer to the string from | |||
* other descriptors. | |||
*/ | |||
enum StringDescriptors_t | |||
{ | |||
STRING_ID_Language = 0, /**< Supported Languages string descriptor ID (must be zero) */ | |||
STRING_ID_Manufacturer = 1, /**< Manufacturer string ID */ | |||
STRING_ID_Product = 2, /**< Product string ID */ | |||
}; | |||
/* Function Prototypes: */ | |||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, | |||
const uint8_t wIndex, | |||
const void** const DescriptorAddress) | |||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); | |||
#endif | |||
@@ -0,0 +1,159 @@ | |||
<asf xmlversion="1.0"> | |||
<project caption="Printer Bootloader - 128KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.printer.avr8.128_4" force-caption="true" workspace-name="lufa_printer_128kb_4kb_"> | |||
<require idref="lufa.bootloaders.printer"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="at90usb1287"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<config name="config.compiler.optimization.level" value="size"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0x1F000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x1F000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x1FFA0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x1FFE0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x1FFF8"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/> | |||
</project> | |||
<project caption="Printer Bootloader - 64KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.printer.avr8.64_4" force-caption="true" workspace-name="lufa_printer_64kb_4kb_"> | |||
<require idref="lufa.bootloaders.printer"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="at90usb647"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<config name="config.compiler.optimization.level" value="size"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0xF000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0xF000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0xFFA0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0xFFE0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0xFFF8"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/> | |||
</project> | |||
<project caption="Printer Bootloader - 32KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.printer.avr8.32_4" force-caption="true" workspace-name="lufa_printer_32kb_4kb_"> | |||
<require idref="lufa.bootloaders.printer"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="atmega32u4"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<config name="config.compiler.optimization.level" value="size"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0x7000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x7000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x7FA0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x7FE0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x7FF8"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/> | |||
</project> | |||
<project caption="Printer Bootloader - 16KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.printer.avr8.16_4" force-caption="true" workspace-name="lufa_printer_16kb_4kb_"> | |||
<require idref="lufa.bootloaders.printer"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="atmega16u2"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<config name="config.compiler.optimization.level" value="size"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0x3000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x3000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x3FA0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x3FE0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x3FF8"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/> | |||
</project> | |||
<project caption="Printer Bootloader - 8KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.printer.avr8.8_4" force-caption="true" workspace-name="lufa_printer_8kb_4kb_"> | |||
<require idref="lufa.bootloaders.printer"/> | |||
<require idref="lufa.boards.dummy.avr8"/> | |||
<generator value="as5_8"/> | |||
<device-support value="atmega8u2"/> | |||
<config name="lufa.drivers.board.name" value="none"/> | |||
<config name="config.compiler.optimization.level" value="size"/> | |||
<build type="define" name="F_CPU" value="16000000UL"/> | |||
<build type="define" name="F_USB" value="16000000UL"/> | |||
<build type="define" name="BOOT_START_ADDR" value="0x1000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x1000"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x1FA0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x1FE0"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/> | |||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x1FF8"/> | |||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/> | |||
</project> | |||
<module type="application" id="lufa.bootloaders.printer" caption="Printer Bootloader"> | |||
<info type="description" value="summary"> | |||
Printer Class Bootloader, capable of reprogramming a device by "printing" new HEX files to the virtual Plain-Text printer it creates when plugged into a host. | |||
</info> | |||
<info type="gui-flag" value="move-to-root"/> | |||
<info type="keyword" value="Technology"> | |||
<keyword value="Bootloaders"/> | |||
<keyword value="USB Device"/> | |||
</info> | |||
<device-support-alias value="lufa_avr8"/> | |||
<device-support-alias value="lufa_xmega"/> | |||
<device-support-alias value="lufa_uc3"/> | |||
<build type="include-path" value="."/> | |||
<build type="c-source" value="BootloaderPrinter.c"/> | |||
<build type="header-file" value="BootloaderPrinter.h"/> | |||
<build type="c-source" value="Descriptors.c"/> | |||
<build type="header-file" value="Descriptors.h"/> | |||
<build type="c-source" value="BootloaderAPI.c"/> | |||
<build type="header-file" value="BootloaderAPI.h"/> | |||
<build type="asm-source" value="BootloaderAPITable.S"/> | |||
<build type="module-config" subtype="path" value="Config"/> | |||
<build type="header-file" value="Config/LUFAConfig.h"/> | |||
<build type="distribute" subtype="user-file" value="doxyfile"/> | |||
<build type="distribute" subtype="user-file" value="BootloaderPrinter.txt"/> | |||
<require idref="lufa.common"/> | |||
<require idref="lufa.platform"/> | |||
<require idref="lufa.drivers.usb"/> | |||
<require idref="lufa.drivers.board"/> | |||
<require idref="lufa.drivers.board.leds"/> | |||
</module> | |||
</asf> |
@@ -0,0 +1,55 @@ | |||
# | |||
# LUFA Library | |||
# Copyright (C) Dean Camera, 2014. | |||
# | |||
# dean [at] fourwalledcubicle [dot] com | |||
# www.lufa-lib.org | |||
# | |||
# -------------------------------------- | |||
# LUFA Project Makefile. | |||
# -------------------------------------- | |||
# Run "make help" for target help. | |||
MCU = at90usb1287 | |||
ARCH = AVR8 | |||
BOARD = USBKEY | |||
F_CPU = 8000000 | |||
F_USB = $(F_CPU) | |||
OPTIMIZATION = s | |||
TARGET = BootloaderPrinter | |||
SRC = $(TARGET).c Descriptors.c BootloaderAPI.c BootloaderAPITable.S $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS) | |||
LUFA_PATH = ../../LUFA | |||
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/ -DBOOT_START_ADDR=$(BOOT_START_OFFSET) | |||
LD_FLAGS = -Wl,--section-start=.text=$(BOOT_START_OFFSET) $(BOOT_API_LD_FLAGS) | |||
# Flash size and bootloader section sizes of the target, in KB. These must | |||
# match the target's total FLASH size and the bootloader size set in the | |||
# device's fuses. | |||
FLASH_SIZE_KB = 128 | |||
BOOT_SECTION_SIZE_KB = 8 | |||
# Bootloader address calculation formulas | |||
# Do not modify these macros, but rather modify the dependent values above. | |||
CALC_ADDRESS_IN_HEX = $(shell printf "0x%X" $$(( $(1) )) ) | |||
BOOT_START_OFFSET = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) - $(BOOT_SECTION_SIZE_KB)) * 1024 ) | |||
BOOT_SEC_OFFSET = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) * 1024) - ($(strip $(1))) ) | |||
# Bootloader linker section flags for relocating the API table sections to | |||
# known FLASH addresses - these should not normally be user-edited. | |||
BOOT_SECTION_LD_FLAG = -Wl,--section-start=$(strip $(1))=$(call BOOT_SEC_OFFSET, $(3)) -Wl,--undefined=$(strip $(2)) | |||
BOOT_API_LD_FLAGS = $(call BOOT_SECTION_LD_FLAG, .apitable_trampolines, BootloaderAPI_Trampolines, 96) | |||
BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .apitable_jumptable, BootloaderAPI_JumpTable, 32) | |||
BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .apitable_signatures, BootloaderAPI_Signatures, 8) | |||
# Default target | |||
all: | |||
# Include LUFA build script makefiles | |||
include $(LUFA_PATH)/Build/lufa_core.mk | |||
include $(LUFA_PATH)/Build/lufa_sources.mk | |||
include $(LUFA_PATH)/Build/lufa_build.mk | |||
include $(LUFA_PATH)/Build/lufa_cppcheck.mk | |||
include $(LUFA_PATH)/Build/lufa_doxygen.mk | |||
include $(LUFA_PATH)/Build/lufa_avrdude.mk | |||
include $(LUFA_PATH)/Build/lufa_atprogram.mk |
@@ -0,0 +1,46 @@ | |||
# | |||
# LUFA Library | |||
# Copyright (C) Dean Camera, 2014. | |||
# | |||
# dean [at] fourwalledcubicle [dot] com | |||
# www.lufa-lib.org | |||
# | |||
# Makefile to build all the LUFA USB Bootloaders. Call with "make all" to | |||
# rebuild all bootloaders. | |||
# Bootloaders are pre-cleaned before each one is built, to ensure any | |||
# custom LUFA library build options are reflected in the compiled | |||
# code. | |||
PROJECT_DIRECTORIES := $(shell ls -d */) | |||
# This makefile is potentially infinitely recursive if something really bad | |||
# happens when determining the set of project directories - hard-abort if | |||
# more than 10 levels deep to avoid angry emails. | |||
ifeq ($(MAKELEVEL), 10) | |||
$(error EMERGENCY ABORT: INFINITE RECURSION DETECTED) | |||
endif | |||
# Need to special-case building without a per-project object directory | |||
ifeq ($(OBJDIR),) | |||
# If no target specified, force "clean all" and disallow parallel build | |||
ifeq ($(MAKECMDGOALS),) | |||
MAKECMDGOALS := clean all | |||
.NOTPARALLEL: | |||
endif | |||
# If one of the targets is to build, force "clean" beforehand and disallow parallel build | |||
ifneq ($(findstring all, $(MAKECMDGOALS)),) | |||
MAKECMDGOALS := clean $(MAKECMDGOALS) | |||
.NOTPARALLEL: | |||
endif | |||
endif | |||
%: $(PROJECT_DIRECTORIES) | |||
@echo . > /dev/null | |||
$(PROJECT_DIRECTORIES): | |||
@$(MAKE) -C $@ $(MAKECMDGOALS) | |||
.PHONY: $(PROJECT_DIRECTORIES) |
@@ -0,0 +1,82 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* \brief LUFA Custom Board Hardware Information Driver (Template) | |||
* | |||
* This is a stub driver header file, for implementing custom board | |||
* layout hardware with compatible LUFA board specific drivers. If | |||
* the library is configured to use the BOARD_USER board mode, this | |||
* driver file should be completed and copied into the "/Board/" folder | |||
* inside the application's folder. | |||
* | |||
* This stub is for the board-specific component of the LUFA Board Hardware | |||
* information driver. | |||
*/ | |||
#ifndef __BOARD_USER_H__ | |||
#define __BOARD_USER_H__ | |||
/* Includes: */ | |||
// TODO: Add any required includes here | |||
/* Enable C linkage for C++ Compilers: */ | |||
#if defined(__cplusplus) | |||
extern "C" { | |||
#endif | |||
/* Preprocessor Checks: */ | |||
#if !defined(__INCLUDE_FROM_BOARD_H) | |||
#error Do not include this file directly. Include LUFA/Drivers/Board/Board.h instead. | |||
#endif | |||
/* Public Interface - May be used in end-application: */ | |||
/* Macros: */ | |||
/** Indicates the board has a hardware Buttons mounted if defined. */ | |||
// #define BOARD_HAS_BUTTONS | |||
/** Indicates the board has a hardware Dataflash mounted if defined. */ | |||
// #define BOARD_HAS_DATAFLASH | |||
/** Indicates the board has a hardware Joystick mounted if defined. */ | |||
// #define BOARD_HAS_JOYSTICK | |||
/** Indicates the board has a hardware LEDs mounted if defined. */ | |||
// #define BOARD_HAS_LEDS | |||
/* Disable C linkage for C++ Compilers: */ | |||
#if defined(__cplusplus) | |||
} | |||
#endif | |||
#endif | |||
/** @} */ | |||
@@ -0,0 +1,92 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* \brief LUFA Custom Board Button Hardware Driver (Template) | |||
* | |||
* This is a stub driver header file, for implementing custom board | |||
* layout hardware with compatible LUFA board specific drivers. If | |||
* the library is configured to use the BOARD_USER board mode, this | |||
* driver file should be completed and copied into the "/Board/" folder | |||
* inside the application's folder. | |||
* | |||
* This stub is for the board-specific component of the LUFA Buttons driver, | |||
* for the control of physical board-mounted GPIO pushbuttons. | |||
*/ | |||
#ifndef __BUTTONS_USER_H__ | |||
#define __BUTTONS_USER_H__ | |||
/* Includes: */ | |||
// TODO: Add any required includes here | |||
/* Enable C linkage for C++ Compilers: */ | |||
#if defined(__cplusplus) | |||
extern "C" { | |||
#endif | |||
/* Preprocessor Checks: */ | |||
#if !defined(__INCLUDE_FROM_BUTTONS_H) | |||
#error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. | |||
#endif | |||
#define BOARD_DUMMY_BUTTONS_IMPLEMENTATION | |||
/* Public Interface - May be used in end-application: */ | |||
/* Macros: */ | |||
/** Button mask for the first button on the board. */ | |||
#define BUTTONS_BUTTON1 (1 << 0) | |||
/* Inline Functions: */ | |||
#if !defined(__DOXYGEN__) | |||
static inline void Buttons_Init(void) | |||
{ | |||
} | |||
static inline void Buttons_Disable(void) | |||
{ | |||
} | |||
static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; | |||
static inline uint8_t Buttons_GetStatus(void) | |||
{ | |||
return 0; | |||
} | |||
#endif | |||
/* Disable C linkage for C++ Compilers: */ | |||
#if defined(__cplusplus) | |||
} | |||
#endif | |||
#endif | |||
@@ -0,0 +1,197 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* \brief LUFA Custom Board Dataflash Hardware Driver (Template) | |||
* | |||
* This is a stub driver header file, for implementing custom board | |||
* layout hardware with compatible LUFA board specific drivers. If | |||
* the library is configured to use the BOARD_USER board mode, this | |||
* driver file should be completed and copied into the "/Board/" folder | |||
* inside the application's folder. | |||
* | |||
* This stub is for the board-specific component of the LUFA Dataflash | |||
* driver. | |||
*/ | |||
#ifndef __DATAFLASH_USER_H__ | |||
#define __DATAFLASH_USER_H__ | |||
/* Includes: */ | |||
// TODO: Add any required includes here | |||
/* Preprocessor Checks: */ | |||
#if !defined(__INCLUDE_FROM_DATAFLASH_H) | |||
#error Do not include this file directly. Include LUFA/Drivers/Board/Dataflash.h instead. | |||
#endif | |||
#define BOARD_DUMMY_DATAFLASH_IMPLEMENTATION | |||
/* Private Interface - For use in library only: */ | |||
#if !defined(__DOXYGEN__) | |||
/* Macros: */ | |||
#define DATAFLASH_CHIPCS_MASK 0 | |||
#define DATAFLASH_CHIPCS_DDR 0 | |||
#define DATAFLASH_CHIPCS_PORT 0 | |||
#endif | |||
/* Public Interface - May be used in end-application: */ | |||
/* Macros: */ | |||
/** Constant indicating the total number of dataflash ICs mounted on the selected board. */ | |||
#define DATAFLASH_TOTALCHIPS 1 | |||
/** Mask for no dataflash chip selected. */ | |||
#define DATAFLASH_NO_CHIP 0 | |||
/** Mask for the first dataflash chip selected. */ | |||
#define DATAFLASH_CHIP1 0 | |||
/** Mask for the second dataflash chip selected. */ | |||
#define DATAFLASH_CHIP2 0 | |||
/** Internal main memory page size for the board's dataflash ICs. */ | |||
#define DATAFLASH_PAGE_SIZE 0 | |||
/** Total number of pages inside each of the board's dataflash ICs. */ | |||
#define DATAFLASH_PAGES 0 | |||
/* Inline Functions: */ | |||
/** Initializes the dataflash driver so that commands and data may be sent to an attached dataflash IC. | |||
* The microcontroller's SPI driver MUST be initialized before any of the dataflash commands are used. | |||
*/ | |||
static inline void Dataflash_Init(void) | |||
{ | |||
} | |||
/** Sends a byte to the currently selected dataflash IC, and returns a byte from the dataflash. | |||
* | |||
* \param[in] Byte Byte of data to send to the dataflash | |||
* | |||
* \return Last response byte from the dataflash | |||
*/ | |||
static inline uint8_t Dataflash_TransferByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; | |||
static inline uint8_t Dataflash_TransferByte(const uint8_t Byte) | |||
{ | |||
return 0; | |||
} | |||
/** Sends a byte to the currently selected dataflash IC, and ignores the next byte from the dataflash. | |||
* | |||
* \param[in] Byte Byte of data to send to the dataflash | |||
*/ | |||
static inline void Dataflash_SendByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; | |||
static inline void Dataflash_SendByte(const uint8_t Byte) | |||
{ | |||
} | |||
/** Sends a dummy byte to the currently selected dataflash IC, and returns the next byte from the dataflash. | |||
* | |||
* \return Last response byte from the dataflash | |||
*/ | |||
static inline uint8_t Dataflash_ReceiveByte(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; | |||
static inline uint8_t Dataflash_ReceiveByte(void) | |||
{ | |||
return 0; | |||
} | |||
/** Determines the currently selected dataflash chip. | |||
* | |||
* \return Mask of the currently selected Dataflash chip, either \ref DATAFLASH_NO_CHIP if no chip is selected | |||
* or a DATAFLASH_CHIPn mask (where n is the chip number). | |||
*/ | |||
static inline uint8_t Dataflash_GetSelectedChip(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; | |||
static inline uint8_t Dataflash_GetSelectedChip(void) | |||
{ | |||
return 0; | |||
} | |||
/** Selects the given dataflash chip. | |||
* | |||
* \param[in] ChipMask Mask of the Dataflash IC to select, in the form of a \c DATAFLASH_CHIPn mask (where n is | |||
* the chip number). | |||
*/ | |||
static inline void Dataflash_SelectChip(const uint8_t ChipMask) ATTR_ALWAYS_INLINE; | |||
static inline void Dataflash_SelectChip(const uint8_t ChipMask) | |||
{ | |||
} | |||
/** Deselects the current dataflash chip, so that no dataflash is selected. */ | |||
static inline void Dataflash_DeselectChip(void) ATTR_ALWAYS_INLINE; | |||
static inline void Dataflash_DeselectChip(void) | |||
{ | |||
} | |||
/** Selects a dataflash IC from the given page number, which should range from 0 to | |||
* ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one | |||
* dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside | |||
* the total number of pages contained in the boards dataflash ICs, all dataflash ICs | |||
* are deselected. | |||
* | |||
* \param[in] PageAddress Address of the page to manipulate, ranging from | |||
* 0 to ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). | |||
*/ | |||
static inline void Dataflash_SelectChipFromPage(const uint16_t PageAddress) | |||
{ | |||
} | |||
/** Toggles the select line of the currently selected dataflash IC, so that it is ready to receive | |||
* a new command. | |||
*/ | |||
static inline void Dataflash_ToggleSelectedChipCS(void) | |||
{ | |||
} | |||
/** Spin-loops while the currently selected dataflash is busy executing a command, such as a main | |||
* memory page program or main memory to buffer transfer. | |||
*/ | |||
static inline void Dataflash_WaitWhileBusy(void) | |||
{ | |||
} | |||
/** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with | |||
* dataflash commands which require a complete 24-bit address. | |||
* | |||
* \param[in] PageAddress Page address within the selected dataflash IC | |||
* \param[in] BufferByte Address within the dataflash's buffer | |||
*/ | |||
static inline void Dataflash_SendAddressBytes(uint16_t PageAddress, const uint16_t BufferByte) | |||
{ | |||
} | |||
#endif | |||
@@ -0,0 +1,104 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* \brief LUFA Custom Board Joystick Hardware Driver (Template) | |||
* | |||
* This is a stub driver header file, for implementing custom board | |||
* layout hardware with compatible LUFA board specific drivers. If | |||
* the library is configured to use the BOARD_USER board mode, this | |||
* driver file should be completed and copied into the "/Board/" folder | |||
* inside the application's folder. | |||
* | |||
* This stub is for the board-specific component of the LUFA Joystick | |||
* driver, for a digital four-way (plus button) joystick. | |||
*/ | |||
#ifndef __JOYSTICK_USER_H__ | |||
#define __JOYSTICK_USER_H__ | |||
/* Includes: */ | |||
// TODO: Add any required includes here | |||
/* Enable C linkage for C++ Compilers: */ | |||
#if defined(__cplusplus) | |||
extern "C" { | |||
#endif | |||
/* Preprocessor Checks: */ | |||
#if !defined(__INCLUDE_FROM_JOYSTICK_H) | |||
#error Do not include this file directly. Include LUFA/Drivers/Board/Joystick.h instead. | |||
#endif | |||
#define BOARD_DUMMY_JOYSTICK_IMPLEMENTATION | |||
/* Public Interface - May be used in end-application: */ | |||
/* Macros: */ | |||
/** Mask for the joystick being pushed in the left direction. */ | |||
#define JOY_LEFT 0 | |||
/** Mask for the joystick being pushed in the right direction. */ | |||
#define JOY_RIGHT 0 | |||
/** Mask for the joystick being pushed in the upward direction. */ | |||
#define JOY_UP 0 | |||
/** Mask for the joystick being pushed in the downward direction. */ | |||
#define JOY_DOWN 0 | |||
/** Mask for the joystick being pushed inward. */ | |||
#define JOY_PRESS 0 | |||
/* Inline Functions: */ | |||
#if !defined(__DOXYGEN__) | |||
static inline void Joystick_Init(void) | |||
{ | |||
} | |||
static inline void Joystick_Disable(void) | |||
{ | |||
} | |||
static inline uint8_t Joystick_GetStatus(void) ATTR_WARN_UNUSED_RESULT; | |||
static inline uint8_t Joystick_GetStatus(void) | |||
{ | |||
return 0; | |||
} | |||
#endif | |||
/* Disable C linkage for C++ Compilers: */ | |||
#if defined(__cplusplus) | |||
} | |||
#endif | |||
#endif | |||
@@ -0,0 +1,132 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
/** \file | |||
* \brief LUFA Custom Board LED Hardware Driver (Template) | |||
* | |||
* This is a stub driver header file, for implementing custom board | |||
* layout hardware with compatible LUFA board specific drivers. If | |||
* the library is configured to use the BOARD_USER board mode, this | |||
* driver file should be completed and copied into the "/Board/" folder | |||
* inside the application's folder. | |||
* | |||
* This stub is for the board-specific component of the LUFA LEDs driver, | |||
* for the LEDs (up to four) mounted on most development boards. | |||
*/ | |||
#ifndef __LEDS_USER_H__ | |||
#define __LEDS_USER_H__ | |||
/* Includes: */ | |||
// TODO: Add any required includes here | |||
/* Enable C linkage for C++ Compilers: */ | |||
#if defined(__cplusplus) | |||
extern "C" { | |||
#endif | |||
/* Preprocessor Checks: */ | |||
#if !defined(__INCLUDE_FROM_LEDS_H) | |||
#error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. | |||
#endif | |||
#define BOARD_DUMMY_LEDS_IMPLEMENTATION | |||
/* Public Interface - May be used in end-application: */ | |||
/* Macros: */ | |||
/** LED mask for the first LED on the board. */ | |||
#define LEDS_LED1 (1 << 0) | |||
/** LED mask for the second LED on the board. */ | |||
#define LEDS_LED2 (1 << 1) | |||
/** LED mask for the third LED on the board. */ | |||
#define LEDS_LED3 (1 << 2) | |||
/** LED mask for the fourth LED on the board. */ | |||
#define LEDS_LED4 (1 << 3) | |||
/** LED mask for all the LEDs on the board. */ | |||
#define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4) | |||
/** LED mask for none of the board LEDs. */ | |||
#define LEDS_NO_LEDS 0 | |||
/* Inline Functions: */ | |||
#if !defined(__DOXYGEN__) | |||
static inline void LEDs_Init(void) | |||
{ | |||
} | |||
static inline void LEDs_Disable(void) | |||
{ | |||
} | |||
static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) | |||
{ | |||
} | |||
static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) | |||
{ | |||
} | |||
static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) | |||
{ | |||
} | |||
static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, const uint8_t ActiveMask) | |||
{ | |||
} | |||
static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) | |||
{ | |||
} | |||
static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; | |||
static inline uint8_t LEDs_GetLEDs(void) | |||
{ | |||
return 0; | |||
} | |||
#endif | |||
/* Disable C linkage for C++ Compilers: */ | |||
#if defined(__cplusplus) | |||
} | |||
#endif | |||
#endif | |||
@@ -0,0 +1,87 @@ | |||
# | |||
# LUFA Library | |||
# Copyright (C) Dean Camera, 2014. | |||
# | |||
# dean [at] fourwalledcubicle [dot] com | |||
# www.lufa-lib.org | |||
# | |||
# | |||
# ============================================================================= | |||
# Board configuration map script, processed with the "BoardDriverTest" | |||
# makefile. This script file maps the possible LUFA target BOARD makefile | |||
# values in user projects to a specific architecture and device. This mapping is | |||
# then used by the makefile to build all possible drivers for that board, to | |||
# detect any missing or erroneous functions. To add a new board mapping, use | |||
# the syntax: | |||
# | |||
# BOARD DEFINE = {ARCH} : {MCU} : | |||
# | |||
# And re-run the makefile. Note that each board may have only one target. | |||
# ============================================================================= | |||
# | |||
# | |||
# ----------------- AVR8 Boards ------------------ | |||
BOARD_ADAFRUITU4 = AVR8 : atmega32u4 : | |||
BOARD_ATAVRUSBRF01 = AVR8 : at90usb1287 : | |||
BOARD_BENITO = AVR8 : at90usb162 : | |||
BOARD_BIGMULTIO = AVR8 : atmega32u4 : | |||
BOARD_BLACKCAT = AVR8 : at90usb162 : | |||
BOARD_BUI = AVR8 : at90usb646 : | |||
BOARD_BUMBLEB = AVR8 : at90usb162 : | |||
BOARD_CULV3 = AVR8 : atmega32u4 : | |||
BOARD_DUCE = AVR8 : atmega32u2 : | |||
BOARD_EVK527 = AVR8 : atmega32u4 : | |||
BOARD_JMDBU2 = AVR8 : atmega32u2 : | |||
BOARD_LEONARDO = AVR8 : atmega32u4 : | |||
BOARD_MAXIMUS = AVR8 : at90usb162 : | |||
BOARD_MICROPENDOUS_32U2 = AVR8 : atmega32u2 : | |||
BOARD_MICROPENDOUS_A = AVR8 : at90usb1287 : | |||
BOARD_MICROPENDOUS_1 = AVR8 : at90usb162 : | |||
BOARD_MICROPENDOUS_2 = AVR8 : atmega32u4 : | |||
BOARD_MICROPENDOUS_3 = AVR8 : at90usb1287 : | |||
BOARD_MICROPENDOUS_4 = AVR8 : at90usb1287 : | |||
BOARD_MICROPENDOUS_DIP = AVR8 : at90usb1287 : | |||
BOARD_MICROPENDOUS_REV1 = AVR8 : at90usb1287 : | |||
BOARD_MICROPENDOUS_REV2 = AVR8 : at90usb1287 : | |||
BOARD_MICROSIN162 = AVR8 : atmega162 : | |||
BOARD_MINIMUS = AVR8 : atmega32u2 : | |||
BOARD_MULTIO = AVR8 : at90usb162 : | |||
BOARD_NONE = AVR8 : at90usb1287 : | |||
BOARD_OLIMEX162 = AVR8 : at90usb162 : | |||
BOARD_OLIMEX32U4 = AVR8 : atmega32u4 : | |||
BOARD_OLIMEXT32U4 = AVR8 : atmega32u4 : | |||
BOARD_OLIMEXISPMK2 = AVR8 : at90usb162 : | |||
BOARD_RZUSBSTICK = AVR8 : at90usb1287 : | |||
BOARD_SPARKFUN8U2 = AVR8 : atmega8u2 : | |||
BOARD_STK525 = AVR8 : at90usb647 : | |||
BOARD_STK526 = AVR8 : at90usb162 : | |||
BOARD_TEENSY = AVR8 : at90usb162 : | |||
BOARD_TEENSY2 = AVR8 : at90usb646 : | |||
BOARD_TUL = AVR8 : atmega32u4 : | |||
BOARD_UDIP = AVR8 : atmega32u2 : | |||
BOARD_UNO = AVR8 : atmega8u2 : | |||
BOARD_USB2AX = AVR8 : atmega32u2 : | |||
BOARD_USB2AX_V3 = AVR8 : atmega32u2 : | |||
BOARD_USB2AX_V31 = AVR8 : atmega32u2 : | |||
BOARD_USBFOO = AVR8 : atmega162 : | |||
BOARD_USBKEY = AVR8 : at90usb1287 : | |||
BOARD_USBTINYMKII = AVR8 : at90usb162 : | |||
BOARD_USER = AVR8 : at90usb1287 : | |||
BOARD_XPLAIN = AVR8 : at90usb1287 : | |||
BOARD_XPLAIN_REV1 = AVR8 : at90usb1287 : | |||
BOARD_STANGE_ISP = AVR8 : at90usb162 : | |||
BOARD_U2S = AVR8 : atmega32u2 : | |||
BOARD_YUN = AVR8 : atmega32u4 : | |||
BOARD_MICRO = AVR8 : atmega32u4 : | |||
# | |||
# ----------------- XMEGA Boards ----------------- | |||
BOARD_A3BU_XPLAINED = XMEGA : atxmega256a3bu : | |||
BOARD_B1_XPLAINED = XMEGA : atxmega128b1 : | |||
BOARD_C3_XPLAINED = XMEGA : atxmega384c3 : | |||
# | |||
# ------------------ UC3 Boards ------------------ | |||
BOARD_EVK1100 = UC3 : uc3a0512 : | |||
BOARD_EVK1101 = UC3 : uc3b0256 : | |||
BOARD_EVK1104 = UC3 : uc3a3256 : | |||
BOARD_UC3A3_XPLAINED = UC3 : uc3a3256 : | |||
# |
@@ -0,0 +1,115 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
#include <LUFA/Common/Common.h> | |||
#include <LUFA/Drivers/Board/Board.h> | |||
#include <LUFA/Drivers/Board/Buttons.h> | |||
#include <LUFA/Drivers/Board/Dataflash.h> | |||
#include <LUFA/Drivers/Board/LEDs.h> | |||
#include <LUFA/Drivers/Board/Joystick.h> | |||
#if defined(BOARD_HAS_BUTTONS) == defined(BOARD_DUMMY_BUTTONS_IMPLEMENTATION) | |||
#error Mismatch between BOARD_HAS_BUTTONS and implementation. | |||
#endif | |||
#if defined(BOARD_HAS_DATAFLASH) == defined(BOARD_DUMMY_DATAFLASH_IMPLEMENTATION) | |||
#error Mismatch between BOARD_HAS_DATAFLASH and implementation. | |||
#endif | |||
#if defined(BOARD_HAS_LEDS) == defined(BOARD_DUMMY_LEDS_IMPLEMENTATION) | |||
#error Mismatch between BOARD_HAS_LEDS and implementation. | |||
#endif | |||
#if defined(BOARD_HAS_JOYSTICK) == defined(BOARD_DUMMY_JOYSTICK_IMPLEMENTATION) | |||
#error Mismatch between BOARD_HAS_JOYSTICK and implementation. | |||
#endif | |||
int main(void) | |||
{ | |||
uint_reg_t Dummy; | |||
/* ============================= | |||
* Buttons Compile Check | |||
* ============================= */ | |||
// cppcheck-suppress redundantAssignment | |||
Dummy = BUTTONS_BUTTON1; | |||
Buttons_Init(); | |||
// cppcheck-suppress redundantAssignment | |||
Dummy = Buttons_GetStatus(); | |||
Buttons_Disable(); | |||
/* ============================= | |||
* Dataflash Compile Check | |||
* ============================= */ | |||
// cppcheck-suppress redundantAssignment | |||
Dummy = DATAFLASH_TOTALCHIPS + DATAFLASH_NO_CHIP + DATAFLASH_CHIP1 + DATAFLASH_PAGE_SIZE + DATAFLASH_PAGES; | |||
Dataflash_Init(); | |||
Dataflash_TransferByte(0); | |||
Dataflash_SendByte(0); | |||
// cppcheck-suppress redundantAssignment | |||
Dummy = Dataflash_ReceiveByte(); | |||
// cppcheck-suppress redundantAssignment | |||
Dummy = Dataflash_GetSelectedChip(); | |||
Dataflash_SelectChip(DATAFLASH_CHIP1); | |||
Dataflash_DeselectChip(); | |||
Dataflash_SelectChipFromPage(0); | |||
Dataflash_ToggleSelectedChipCS(); | |||
Dataflash_WaitWhileBusy(); | |||
Dataflash_SendAddressBytes(0, 0); | |||
/* ============================= | |||
* LEDs Compile Check | |||
* ============================= */ | |||
// cppcheck-suppress redundantAssignment | |||
Dummy = LEDS_LED1 + LEDS_LED2 + LEDS_LED3 + LEDS_LED4; | |||
LEDs_Init(); | |||
LEDs_TurnOnLEDs(LEDS_ALL_LEDS); | |||
LEDs_TurnOffLEDs(LEDS_ALL_LEDS); | |||
LEDs_SetAllLEDs(LEDS_ALL_LEDS); | |||
LEDs_ChangeLEDs(LEDS_ALL_LEDS, LEDS_NO_LEDS); | |||
LEDs_ToggleLEDs(LEDS_ALL_LEDS); | |||
// cppcheck-suppress redundantAssignment | |||
Dummy = LEDs_GetLEDs(); | |||
LEDs_Disable(); | |||
/* ============================= | |||
* Joystick Compile Check | |||
* ============================= */ | |||
// cppcheck-suppress redundantAssignment | |||
Dummy = JOY_LEFT + JOY_RIGHT + JOY_UP + JOY_DOWN + JOY_PRESS; | |||
Joystick_Init(); | |||
// cppcheck-suppress redundantAssignment | |||
Dummy = Joystick_GetStatus(); | |||
Joystick_Disable(); | |||
(void)Dummy; | |||
} | |||
@@ -0,0 +1,68 @@ | |||
# | |||
# LUFA Library | |||
# Copyright (C) Dean Camera, 2014. | |||
# | |||
# dean [at] fourwalledcubicle [dot] com | |||
# www.lufa-lib.org | |||
# | |||
# Makefile for the board driver build test. This | |||
# test attempts to build a dummy project with all | |||
# possible board targets using their respective | |||
# compiler. | |||
# Path to the LUFA library core | |||
LUFA_PATH := ../../LUFA/ | |||
# Build test cannot be run with multiple parallel jobs | |||
.NOTPARALLEL: | |||
all: begin makeboardlist testboards clean end | |||
begin: | |||
@echo Executing build test "BoardDriverTest". | |||
@echo | |||
end: | |||
@echo Build test "BoardDriverTest" complete. | |||
@echo | |||
makeboardlist: | |||
@grep "BOARD_" $(patsubst %/,%,$(LUFA_PATH))/Common/BoardTypes.h | cut -d'#' -f2 | cut -d' ' -f2 | grep "BOARD_" > BoardList.txt | |||
testboards: | |||
@echo "buildtest:" > BuildMakefile | |||
@while read line; \ | |||
do \ | |||
build_cfg=`grep "$$line " BoardDeviceMap.cfg | grep -v "#" | cut -d'=' -f2- | sed 's/ //g'`; \ | |||
\ | |||
build_board=$$line; \ | |||
build_arch=`echo $$build_cfg | cut -d':' -f1`; \ | |||
build_mcu=`echo $$build_cfg | cut -d':' -f2`; \ | |||
\ | |||
if ( test -z "$$build_cfg" ); then \ | |||
echo "No matching information set for board $$build_board"; \ | |||
else \ | |||
echo "Found board configuration for $$build_board - $$build_arch, $$build_mcu"; \ | |||
\ | |||
printf "\t@echo Building dummy project for $$build_board...\n" >> BuildMakefile; \ | |||
printf "\t$(MAKE) -f makefile.test clean elf MCU=%s ARCH=%s BOARD=%s\n\n" $$build_mcu $$build_arch $$build_board >> BuildMakefile; \ | |||
fi; \ | |||
done < BoardList.txt | |||
$(MAKE) -f BuildMakefile buildtest | |||
clean: | |||
rm -f BuildMakefile | |||
rm -f BoardList.txt | |||
$(MAKE) -f makefile.test clean BOARD=NONE ARCH=AVR8 MCU=at90usb1287 | |||
$(MAKE) -f makefile.test clean BOARD=NONE ARCH=XMEGA MCU=atxmega128a1u | |||
$(MAKE) -f makefile.test clean BOARD=NONE ARCH=UC3 MCU=uc3a0256 | |||
%: | |||
.PHONY: all begin end makeboardlist testboards clean | |||
# Include LUFA build script makefiles | |||
include $(LUFA_PATH)/Build/lufa_core.mk |
@@ -0,0 +1,27 @@ | |||
# | |||
# LUFA Library | |||
# Copyright (C) Dean Camera, 2014. | |||
# | |||
# dean [at] fourwalledcubicle [dot] com | |||
# www.lufa-lib.org | |||
# | |||
# -------------------------------------- | |||
# LUFA Project Makefile. | |||
# -------------------------------------- | |||
# Run "make help" for target help. | |||
MCU = | |||
ARCH = | |||
BOARD = | |||
F_CPU = $(F_USB) | |||
F_USB = 8000000 | |||
OPTIMIZATION = 1 | |||
TARGET = Test | |||
SRC = $(TARGET).c | |||
LUFA_PATH = ../../LUFA | |||
CC_FLAGS = -Werror | |||
DEBUG_LEVEL = 0 | |||
# Include LUFA build script makefiles | |||
include $(LUFA_PATH)/Build/lufa_build.mk |
@@ -0,0 +1,167 @@ | |||
# | |||
# LUFA Library | |||
# Copyright (C) Dean Camera, 2014. | |||
# | |||
# dean [at] fourwalledcubicle [dot] com | |||
# www.lufa-lib.org | |||
# | |||
# | |||
# ============================================================================= | |||
# Bootloader configuration map script, processed with the "BootloaderTest" | |||
# makefile. This script file defines the targets for each LUFA bootloader, | |||
# which are then built as part of the build test to ensure that there are no | |||
# failures on all standard configurations. To add a new build target for a | |||
# bootloader to this script, use the format: | |||
# | |||
# BOOTLOADER = {ARCH} : {MCU} : {BOARD} : {FLASH SIZE KB} : {BOOT SIZE KB} : {F_USB MHZ} | |||
# | |||
# And re-run the makefile. | |||
# ============================================================================= | |||
# | |||
# | |||
# ------------ CDC Bootloader -------------------- | |||
CDC = AVR8 : at90usb1287 : XPLAIN : 128 : 8 : 8 : | |||
CDC = AVR8 : at90usb1287 : NONE : 128 : 8 : 8 : | |||
CDC = AVR8 : at90usb1287 : NONE : 128 : 4 : 8 : | |||
CDC = AVR8 : at90usb647 : NONE : 64 : 4 : 8 : | |||
CDC = AVR8 : at90usb1286 : NONE : 128 : 8 : 8 : | |||
CDC = AVR8 : at90usb1286 : NONE : 128 : 4 : 8 : | |||
CDC = AVR8 : at90usb646 : NONE : 64 : 4 : 8 : | |||
CDC = AVR8 : atmega32u4 : NONE : 32 : 4 : 8 : | |||
CDC = AVR8 : atmega16u4 : NONE : 16 : 4 : 8 : | |||
CDC = AVR8 : atmega32u2 : NONE : 32 : 4 : 8 : | |||
CDC = AVR8 : atmega16u2 : NONE : 16 : 4 : 8 : | |||
CDC = AVR8 : atmega8u2 : NONE : 8 : 4 : 8 : | |||
CDC = AVR8 : at90usb162 : NONE : 16 : 4 : 8 : | |||
CDC = AVR8 : at90usb82 : NONE : 8 : 4 : 8 : | |||
CDC = AVR8 : at90usb1287 : NONE : 128 : 8 : 16 : | |||
CDC = AVR8 : at90usb1287 : NONE : 128 : 4 : 16 : | |||
CDC = AVR8 : at90usb647 : NONE : 64 : 4 : 16 : | |||
CDC = AVR8 : at90usb1286 : NONE : 128 : 8 : 16 : | |||
CDC = AVR8 : at90usb1286 : NONE : 128 : 4 : 16 : | |||
CDC = AVR8 : at90usb646 : NONE : 64 : 4 : 16 : | |||
CDC = AVR8 : atmega32u4 : NONE : 32 : 4 : 16 : | |||
CDC = AVR8 : atmega16u4 : NONE : 16 : 4 : 16 : | |||
CDC = AVR8 : atmega32u2 : NONE : 32 : 4 : 16 : | |||
CDC = AVR8 : atmega16u2 : NONE : 16 : 4 : 16 : | |||
CDC = AVR8 : atmega8u2 : NONE : 8 : 4 : 16 : | |||
CDC = AVR8 : at90usb162 : NONE : 16 : 4 : 16 : | |||
CDC = AVR8 : at90usb82 : NONE : 8 : 4 : 16 : | |||
# | |||
# ------------ DFU Bootloader -------------------- | |||
DFU = AVR8 : at90usb1287 : XPLAIN : 128 : 8 : 8 : | |||
DFU = AVR8 : at90usb1287 : NONE : 128 : 8 : 8 : | |||
DFU = AVR8 : at90usb1287 : NONE : 128 : 4 : 8 : | |||
DFU = AVR8 : at90usb647 : NONE : 64 : 4 : 8 : | |||
DFU = AVR8 : at90usb1286 : NONE : 128 : 8 : 8 : | |||
DFU = AVR8 : at90usb1286 : NONE : 128 : 4 : 8 : | |||
DFU = AVR8 : at90usb646 : NONE : 64 : 4 : 8 : | |||
DFU = AVR8 : atmega32u4 : NONE : 32 : 4 : 8 : | |||
DFU = AVR8 : atmega16u4 : NONE : 16 : 4 : 8 : | |||
DFU = AVR8 : atmega32u2 : NONE : 32 : 4 : 8 : | |||
DFU = AVR8 : atmega16u2 : NONE : 16 : 4 : 8 : | |||
DFU = AVR8 : atmega8u2 : NONE : 8 : 4 : 8 : | |||
DFU = AVR8 : at90usb162 : NONE : 16 : 4 : 8 : | |||
DFU = AVR8 : at90usb82 : NONE : 8 : 4 : 8 : | |||
DFU = AVR8 : at90usb1287 : NONE : 128 : 8 : 16 : | |||
DFU = AVR8 : at90usb1287 : NONE : 128 : 4 : 16 : | |||
DFU = AVR8 : at90usb647 : NONE : 64 : 4 : 16 : | |||
DFU = AVR8 : at90usb1286 : NONE : 128 : 8 : 16 : | |||
DFU = AVR8 : at90usb1286 : NONE : 128 : 4 : 16 : | |||
DFU = AVR8 : at90usb646 : NONE : 64 : 4 : 16 : | |||
DFU = AVR8 : atmega32u4 : NONE : 32 : 4 : 16 : | |||
DFU = AVR8 : atmega16u4 : NONE : 16 : 4 : 16 : | |||
DFU = AVR8 : atmega32u2 : NONE : 32 : 4 : 16 : | |||
DFU = AVR8 : atmega16u2 : NONE : 16 : 4 : 16 : | |||
DFU = AVR8 : atmega8u2 : NONE : 8 : 4 : 16 : | |||
DFU = AVR8 : at90usb162 : NONE : 16 : 4 : 16 : | |||
DFU = AVR8 : at90usb82 : NONE : 8 : 4 : 16 : | |||
# | |||
# ------------ HID Bootloader -------------------- | |||
HID = AVR8 : at90usb1287 : NONE : 128 : 8 : 8 : | |||
HID = AVR8 : at90usb1287 : NONE : 128 : 4 : 8 : | |||
HID = AVR8 : at90usb647 : NONE : 64 : 4 : 8 : | |||
HID = AVR8 : at90usb1286 : NONE : 128 : 8 : 8 : | |||
HID = AVR8 : at90usb1286 : NONE : 128 : 4 : 8 : | |||
HID = AVR8 : at90usb646 : NONE : 64 : 4 : 8 : | |||
HID = AVR8 : atmega32u4 : NONE : 32 : 4 : 8 : | |||
HID = AVR8 : atmega16u4 : NONE : 16 : 4 : 8 : | |||
HID = AVR8 : atmega32u2 : NONE : 32 : 2 : 8 : | |||
HID = AVR8 : atmega32u2 : NONE : 32 : 4 : 8 : | |||
HID = AVR8 : atmega16u2 : NONE : 16 : 2 : 8 : | |||
HID = AVR8 : atmega16u2 : NONE : 16 : 4 : 8 : | |||
HID = AVR8 : atmega8u2 : NONE : 8 : 2 : 8 : | |||
HID = AVR8 : atmega8u2 : NONE : 8 : 4 : 8 : | |||
HID = AVR8 : at90usb162 : NONE : 16 : 2 : 8 : | |||
HID = AVR8 : at90usb162 : NONE : 16 : 4 : 8 : | |||
HID = AVR8 : at90usb162 : NONE : 16 : 2 : 8 : | |||
HID = AVR8 : at90usb162 : NONE : 16 : 4 : 8 : | |||
HID = AVR8 : at90usb1287 : NONE : 128 : 8 : 8 : | |||
HID = AVR8 : at90usb1287 : NONE : 128 : 4 : 8 : | |||
HID = AVR8 : at90usb647 : NONE : 64 : 4 : 8 : | |||
HID = AVR8 : at90usb1286 : NONE : 128 : 8 : 16 : | |||
HID = AVR8 : at90usb1286 : NONE : 128 : 4 : 16 : | |||
HID = AVR8 : at90usb646 : NONE : 64 : 4 : 16 : | |||
HID = AVR8 : atmega32u4 : NONE : 32 : 4 : 16 : | |||
HID = AVR8 : atmega16u4 : NONE : 16 : 4 : 16 : | |||
HID = AVR8 : atmega32u2 : NONE : 32 : 2 : 16 : | |||
HID = AVR8 : atmega32u2 : NONE : 32 : 4 : 16 : | |||
HID = AVR8 : atmega16u2 : NONE : 16 : 2 : 16 : | |||
HID = AVR8 : atmega16u2 : NONE : 16 : 4 : 16 : | |||
HID = AVR8 : atmega8u2 : NONE : 8 : 2 : 16 : | |||
HID = AVR8 : atmega8u2 : NONE : 8 : 4 : 16 : | |||
HID = AVR8 : at90usb162 : NONE : 16 : 2 : 16 : | |||
HID = AVR8 : at90usb162 : NONE : 16 : 4 : 16 : | |||
HID = AVR8 : at90usb162 : NONE : 16 : 2 : 16 : | |||
HID = AVR8 : at90usb162 : NONE : 16 : 4 : 16 : | |||
# | |||
# ---------- Printer Bootloader ------------------ | |||
Printer = AVR8 : at90usb1287 : NONE : 128 : 8 : 8 : | |||
Printer = AVR8 : at90usb1287 : NONE : 128 : 4 : 8 : | |||
Printer = AVR8 : at90usb647 : NONE : 64 : 4 : 8 : | |||
Printer = AVR8 : at90usb1286 : NONE : 128 : 8 : 8 : | |||
Printer = AVR8 : at90usb1286 : NONE : 128 : 4 : 8 : | |||
Printer = AVR8 : at90usb646 : NONE : 64 : 4 : 8 : | |||
Printer = AVR8 : atmega32u4 : NONE : 32 : 4 : 8 : | |||
Printer = AVR8 : atmega16u4 : NONE : 16 : 4 : 8 : | |||
Printer = AVR8 : atmega32u2 : NONE : 32 : 4 : 8 : | |||
Printer = AVR8 : atmega16u2 : NONE : 16 : 4 : 8 : | |||
Printer = AVR8 : atmega8u2 : NONE : 8 : 4 : 8 : | |||
Printer = AVR8 : at90usb162 : NONE : 16 : 4 : 8 : | |||
Printer = AVR8 : at90usb82 : NONE : 8 : 4 : 8 : | |||
Printer = AVR8 : at90usb1287 : NONE : 128 : 8 : 16 : | |||
Printer = AVR8 : at90usb1287 : NONE : 128 : 4 : 16 : | |||
Printer = AVR8 : at90usb647 : NONE : 64 : 4 : 16 : | |||
Printer = AVR8 : at90usb1286 : NONE : 128 : 8 : 16 : | |||
Printer = AVR8 : at90usb1286 : NONE : 128 : 4 : 16 : | |||
Printer = AVR8 : at90usb646 : NONE : 64 : 4 : 16 : | |||
Printer = AVR8 : atmega32u4 : NONE : 32 : 4 : 16 : | |||
Printer = AVR8 : atmega16u4 : NONE : 16 : 4 : 16 : | |||
Printer = AVR8 : atmega32u2 : NONE : 32 : 4 : 16 : | |||
Printer = AVR8 : atmega16u2 : NONE : 16 : 4 : 16 : | |||
Printer = AVR8 : atmega8u2 : NONE : 8 : 4 : 16 : | |||
Printer = AVR8 : at90usb162 : NONE : 16 : 4 : 16 : | |||
Printer = AVR8 : at90usb82 : NONE : 8 : 4 : 16 : | |||
# | |||
# ---------- Mass Storage Bootloader ----------------- | |||
MassStorage = AVR8 : at90usb1287 : XPLAIN : 128 : 8 : 8 : | |||
MassStorage = AVR8 : at90usb1287 : NONE : 128 : 8 : 8 : | |||
MassStorage = AVR8 : at90usb1287 : NONE : 128 : 4 : 8 : | |||
MassStorage = AVR8 : at90usb647 : NONE : 64 : 4 : 8 : | |||
MassStorage = AVR8 : at90usb1286 : NONE : 128 : 8 : 8 : | |||
MassStorage = AVR8 : at90usb1286 : NONE : 128 : 4 : 8 : | |||
MassStorage = AVR8 : at90usb646 : NONE : 64 : 4 : 8 : | |||
MassStorage = AVR8 : atmega32u4 : LEONARDO : 32 : 4 : 16 : | |||
MassStorage = AVR8 : atmega32u4 : NONE : 32 : 4 : 8 : | |||
MassStorage = AVR8 : atmega16u4 : NONE : 16 : 4 : 8 : | |||
MassStorage = AVR8 : atmega32u2 : NONE : 32 : 4 : 8 : | |||
MassStorage = AVR8 : at90usb1287 : NONE : 128 : 8 : 16 : | |||
MassStorage = AVR8 : at90usb1287 : NONE : 128 : 4 : 16 : | |||
MassStorage = AVR8 : at90usb647 : NONE : 64 : 4 : 16 : | |||
MassStorage = AVR8 : at90usb1286 : NONE : 128 : 8 : 16 : | |||
MassStorage = AVR8 : at90usb1286 : NONE : 128 : 4 : 16 : | |||
MassStorage = AVR8 : at90usb646 : NONE : 64 : 4 : 16 : | |||
MassStorage = AVR8 : atmega32u4 : NONE : 32 : 4 : 16 : | |||
MassStorage = AVR8 : atmega16u4 : NONE : 16 : 4 : 16 : | |||
MassStorage = AVR8 : atmega32u2 : NONE : 32 : 4 : 16 : | |||
# |
@@ -0,0 +1,64 @@ | |||
# | |||
# LUFA Library | |||
# Copyright (C) Dean Camera, 2014. | |||
# | |||
# dean [at] fourwalledcubicle [dot] com | |||
# www.lufa-lib.org | |||
# | |||
# Makefile for the bootloader build test. This | |||
# test attempts to build all the bootloaders | |||
# with all supported device configurations. | |||
# Path to the LUFA library core | |||
LUFA_PATH := ../../LUFA/ | |||
# Build test cannot be run with multiple parallel jobs | |||
.NOTPARALLEL: | |||
all: begin testbootloaders clean end | |||
begin: | |||
@echo Executing build test "BootloaderTest". | |||
@echo | |||
end: | |||
@echo Build test "BootloaderTest" complete. | |||
@echo | |||
testbootloaders: | |||
@echo "buildtest:" > BuildMakefile | |||
@while read line; \ | |||
do \ | |||
build_cfg=`echo $$line | grep -v "#" | sed 's/ //g'`; \ | |||
\ | |||
if ( test -n "$$build_cfg" ); then \ | |||
build_bootloader=`echo $$build_cfg | cut -d'=' -f1`; \ | |||
build_cfg=`echo $$build_cfg | cut -d'=' -f2-`; \ | |||
\ | |||
build_arch=`echo $$build_cfg | cut -d':' -f1`; \ | |||
build_mcu=`echo $$build_cfg | cut -d':' -f2`; \ | |||
build_board=`echo $$build_cfg | cut -d':' -f3`; \ | |||
build_flashsize=`echo $$build_cfg | cut -d':' -f4`; \ | |||
build_bootsize=`echo $$build_cfg | cut -d':' -f5`; \ | |||
build_fusb=`echo $$build_cfg | cut -d':' -f6`; \ | |||
\ | |||
printf "Found '%s' bootloader configuration (FLASH: %3s KB | BOOT: %3s KB | MCU: %12s / %4s | BOARD: %s | F_USB: %sMHz)\n" $$build_bootloader $$build_flashsize $$build_bootsize $$build_mcu $$build_arch $$build_board $$build_fusb; \ | |||
\ | |||
printf "\t@echo Building bootloader %s - %s - FLASH: %s KB, BOOT: %s KB, BOARD: %s, F_USB: %sMHz\n" $$build_bootloader $$build_mcu $$build_flashsize $$build_bootsize $$build_board $$build_fusb >> BuildMakefile; \ | |||
printf "\t$(MAKE) -C $(patsubst %/,%,$(LUFA_PATH))/../Bootloaders/%s/ clean elf ARCH=%s MCU=%s BOARD=%s FLASH_SIZE_KB=%s BOOT_SECTION_SIZE_KB=%s F_USB=%s000000 DEBUG_LEVEL=0\n\n" $$build_bootloader $$build_arch $$build_mcu $$build_board $$build_flashsize $$build_bootsize $$build_fusb >> BuildMakefile; \ | |||
fi; \ | |||
done < BootloaderDeviceMap.cfg | |||
$(MAKE) -f BuildMakefile buildtest | |||
clean: | |||
rm -f BuildMakefile | |||
%: | |||
.PHONY: all begin end testbootloaders clean | |||
# Include LUFA build script makefiles | |||
include $(LUFA_PATH)/Build/lufa_core.mk |
@@ -0,0 +1,41 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
.section .text | |||
# Mandatory entry point for successful compilation and link | |||
.global main | |||
main: | |||
# Mandatory callback needed for base compile of the USB driver | |||
.global CALLBACK_USB_GetDescriptor | |||
CALLBACK_USB_GetDescriptor: |
@@ -0,0 +1,56 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
#include <LUFA/Common/Common.h> | |||
#include <LUFA/Platform/Platform.h> | |||
#include <LUFA/Drivers/USB/USB.h> | |||
#include <LUFA/Drivers/Misc/RingBuffer.h> | |||
#include <LUFA/Drivers/Misc/TerminalCodes.h> | |||
#if (ARCH == ARCH_AVR8) | |||
#if defined(ADC) | |||
#include <LUFA/Drivers/Peripheral/ADC.h> | |||
#endif | |||
#include <LUFA/Drivers/Peripheral/Serial.h> | |||
#include <LUFA/Drivers/Peripheral/SerialSPI.h> | |||
#include <LUFA/Drivers/Peripheral/SPI.h> | |||
#if defined(TWCR) | |||
#include <LUFA/Drivers/Peripheral/TWI.h> | |||
#endif | |||
#elif (ARCH == ARCH_XMEGA) | |||
#include <LUFA/Drivers/Peripheral/Serial.h> | |||
#include <LUFA/Drivers/Peripheral/SerialSPI.h> | |||
#include <LUFA/Drivers/Peripheral/SPI.h> | |||
#include <LUFA/Drivers/Peripheral/TWI.h> | |||
#endif |
@@ -0,0 +1,31 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
#include "Modules.h" |
@@ -0,0 +1,31 @@ | |||
/* | |||
LUFA Library | |||
Copyright (C) Dean Camera, 2014. | |||
dean [at] fourwalledcubicle [dot] com | |||
www.lufa-lib.org | |||
*/ | |||
/* | |||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |||
Permission to use, copy, modify, distribute, and sell this | |||
software and its documentation for any purpose is hereby granted | |||
without fee, provided that the above copyright notice appear in | |||
all copies and that both that the copyright notice and this | |||
permission notice and warranty disclaimer appear in supporting | |||
documentation, and that the name of the author not be used in | |||
advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
The author disclaims all warranties with regard to this | |||
software, including all implied warranties of merchantability | |||
and fitness. In no event shall the author be liable for any | |||
special, indirect or consequential damages or any damages | |||
whatsoever resulting from loss of use, data or profits, whether | |||
in an action of contract, negligence or other tortious action, | |||
arising out of or in connection with the use or performance of | |||
this software. | |||
*/ | |||
#include "Modules.h" |
@@ -0,0 +1,66 @@ | |||
# | |||
# LUFA Library | |||
# Copyright (C) Dean Camera, 2014. | |||
# | |||
# dean [at] fourwalledcubicle [dot] com | |||
# www.lufa-lib.org | |||
# | |||
# Makefile for the module build test. This test | |||
# attempts to build as many modules as possible | |||
# under all supported architectures, and include | |||
# all module headers in a simple C and C++ | |||
# application. | |||
# Path to the LUFA library core | |||
LUFA_PATH := ../../LUFA/ | |||
# Build test cannot be run with multiple parallel jobs | |||
.NOTPARALLEL: | |||
# List of device families per architecture, one device per architecture sub-family | |||
AVR8_FAMILIES := at90usb1287 at90usb1286 atmega16u4 atmega16u2 at90usb162 | |||
XMEGA_FAMILIES := atxmega128a1u atxmega128a3u atxmega256a3bu atxmega128a4u atxmega128b1 atxmega128b3 atxmega128c3 atxmega32c4 | |||
UC3_FAMILIES := uc3a0256 uc3a1256 uc3a3256 uc3a4256 uc3b0256 uc3b1256 | |||
# List of all device families, with a family postfix | |||
DEVICE_FAMILIES := $(AVR8_FAMILIES:%=%.avr8) $(XMEGA_FAMILIES:%=%.xmega) $(UC3_FAMILIES:%=%.uc3) | |||
all: begin $(DEVICE_FAMILIES) clean end | |||
arch_avr8: begin $(AVR8_FAMILIES:%=%.avr8) end | |||
arch_xmega: begin $(XMEGA_FAMILIES:%=%.xmega) end | |||
arch_uc3: begin $(UC3_FAMILIES:%=%.uc3) end | |||
begin: | |||
@echo Executing build test "ModuleTest". | |||
@echo | |||
end: | |||
@echo Build test "ModuleTest" complete. | |||
@echo | |||
%.avr8: | |||
@echo Building ModuleTest for ARCH=AVR8 MCU=$(@:%.avr8=%)... | |||
$(MAKE) -f makefile.test clean elf ARCH=AVR8 MCU=$(@:%.avr8=%) | |||
%.xmega: | |||
@echo Building ModuleTest for ARCH=XMEGA MCU=$(@:%.xmega=%)... | |||
$(MAKE) -f makefile.test clean elf ARCH=XMEGA MCU=$(@:%.xmega=%) | |||
%.uc3: | |||
@echo Building ModuleTest for ARCH=UC3 MCU=$(@:%.uc3=%)... | |||
$(MAKE) -f makefile.test clean elf ARCH=UC3 MCU=$(@:%.uc3=%) | |||
clean: | |||
$(MAKE) -f makefile.test clean ARCH=AVR8 MCU=$(firstword $(AVR8_FAMILIES)) | |||
$(MAKE) -f makefile.test clean ARCH=XMEGA MCU=$(firstword $(XMEGA_FAMILIES)) | |||
$(MAKE) -f makefile.test clean ARCH=UC3 MCU=$(firstword $(UC3_FAMILIES)) | |||
%: | |||
.PHONY: all arch_avr8 arch_xmega arch_uc3 begin end | |||
# Include LUFA build script makefiles | |||
include $(LUFA_PATH)/Build/lufa_core.mk |