added hacked bootloader demo project that came with the MLA
This commit is contained in:
22
.gitignore
vendored
Normal file
22
.gitignore
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
**/*.X/*.d
|
||||||
|
**/*.X/*.pre
|
||||||
|
**/*.X/*.p1
|
||||||
|
**/*.X/*.lst
|
||||||
|
**/*.X/*.sym
|
||||||
|
**/*.X/*.obj
|
||||||
|
**/*.X/*.o
|
||||||
|
**/*.X/*.sdb
|
||||||
|
**/*.X/*.obj.dmp
|
||||||
|
**/*.X/html/
|
||||||
|
**/*.X/nbproject/private/
|
||||||
|
**/*.X/nbproject/Package-*.bash
|
||||||
|
**/*.X/build/
|
||||||
|
**/*.X/nbbuild/
|
||||||
|
**/*.X/dist/
|
||||||
|
**/*.X/nbdist/
|
||||||
|
**/*.X/nbactions.xml
|
||||||
|
**/*.X/nb-configuration.xml
|
||||||
|
**/*.X/funclist
|
||||||
|
**/*.X/nbproject/Makefile-*
|
||||||
|
**/*.X/disassembly/
|
||||||
|
**/*.X/*.map
|
||||||
108
bootloader_hacked_from_mla/clubdance_v2_bootloader.X/Makefile
Normal file
108
bootloader_hacked_from_mla/clubdance_v2_bootloader.X/Makefile
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
#
|
||||||
|
# There exist several targets which are by default empty and which can be
|
||||||
|
# used for execution of your targets. These targets are usually executed
|
||||||
|
# before and after some main targets. They are:
|
||||||
|
#
|
||||||
|
# .build-pre: called before 'build' target
|
||||||
|
# .build-post: called after 'build' target
|
||||||
|
# .clean-pre: called before 'clean' target
|
||||||
|
# .clean-post: called after 'clean' target
|
||||||
|
# .clobber-pre: called before 'clobber' target
|
||||||
|
# .clobber-post: called after 'clobber' target
|
||||||
|
# .all-pre: called before 'all' target
|
||||||
|
# .all-post: called after 'all' target
|
||||||
|
# .help-pre: called before 'help' target
|
||||||
|
# .help-post: called after 'help' target
|
||||||
|
#
|
||||||
|
# Targets beginning with '.' are not intended to be called on their own.
|
||||||
|
#
|
||||||
|
# Main targets can be executed directly, and they are:
|
||||||
|
#
|
||||||
|
# build build a specific configuration
|
||||||
|
# clean remove built files from a configuration
|
||||||
|
# clobber remove all built files
|
||||||
|
# all build all configurations
|
||||||
|
# help print help mesage
|
||||||
|
#
|
||||||
|
# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
|
||||||
|
# .help-impl are implemented in nbproject/makefile-impl.mk.
|
||||||
|
#
|
||||||
|
# Available make variables:
|
||||||
|
#
|
||||||
|
# CND_BASEDIR base directory for relative paths
|
||||||
|
# CND_DISTDIR default top distribution directory (build artifacts)
|
||||||
|
# CND_BUILDDIR default top build directory (object files, ...)
|
||||||
|
# CONF name of current configuration
|
||||||
|
# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration)
|
||||||
|
# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration)
|
||||||
|
# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration)
|
||||||
|
# CND_PACKAGE_DIR_${CONF} directory of package (current configuration)
|
||||||
|
# CND_PACKAGE_NAME_${CONF} name of package (current configuration)
|
||||||
|
# CND_PACKAGE_PATH_${CONF} path to package (current configuration)
|
||||||
|
#
|
||||||
|
# NOCDDL
|
||||||
|
|
||||||
|
|
||||||
|
# Environment
|
||||||
|
MKDIR=mkdir
|
||||||
|
CP=cp
|
||||||
|
CCADMIN=CCadmin
|
||||||
|
RANLIB=ranlib
|
||||||
|
|
||||||
|
|
||||||
|
# build
|
||||||
|
build: .build-post
|
||||||
|
|
||||||
|
.build-pre:
|
||||||
|
# Add your pre 'build' code here...
|
||||||
|
|
||||||
|
.build-post: .build-impl
|
||||||
|
# Add your post 'build' code here...
|
||||||
|
|
||||||
|
|
||||||
|
# clean
|
||||||
|
clean: .clean-post
|
||||||
|
|
||||||
|
.clean-pre:
|
||||||
|
# Add your pre 'clean' code here...
|
||||||
|
|
||||||
|
.clean-post: .clean-impl
|
||||||
|
# Add your post 'clean' code here...
|
||||||
|
|
||||||
|
|
||||||
|
# clobber
|
||||||
|
clobber: .clobber-post
|
||||||
|
|
||||||
|
.clobber-pre:
|
||||||
|
# Add your pre 'clobber' code here...
|
||||||
|
|
||||||
|
.clobber-post: .clobber-impl
|
||||||
|
# Add your post 'clobber' code here...
|
||||||
|
|
||||||
|
|
||||||
|
# all
|
||||||
|
all: .all-post
|
||||||
|
|
||||||
|
.all-pre:
|
||||||
|
# Add your pre 'all' code here...
|
||||||
|
|
||||||
|
.all-post: .all-impl
|
||||||
|
# Add your post 'all' code here...
|
||||||
|
|
||||||
|
|
||||||
|
# help
|
||||||
|
help: .help-post
|
||||||
|
|
||||||
|
.help-pre:
|
||||||
|
# Add your pre 'help' code here...
|
||||||
|
|
||||||
|
.help-post: .help-impl
|
||||||
|
# Add your post 'help' code here...
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# include project implementation makefile
|
||||||
|
include nbproject/Makefile-impl.mk
|
||||||
|
|
||||||
|
# include project make variables
|
||||||
|
include nbproject/Makefile-variables.mk
|
||||||
@@ -0,0 +1,264 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configurationDescriptor version="65">
|
||||||
|
<logicalFolder name="root" displayName="root" projectFiles="true">
|
||||||
|
<logicalFolder name="HeaderFiles"
|
||||||
|
displayName="Header Files"
|
||||||
|
projectFiles="true">
|
||||||
|
<itemPath>../src/BootPIC18NonJ.h</itemPath>
|
||||||
|
<itemPath>../src/HardwareProfile.h</itemPath>
|
||||||
|
<itemPath>../src/typedefs.h</itemPath>
|
||||||
|
<itemPath>../src/usb.h</itemPath>
|
||||||
|
<itemPath>../src/usb_config.h</itemPath>
|
||||||
|
<itemPath>../src/usb_device.h</itemPath>
|
||||||
|
<itemPath>../src/usb_device_hid.h</itemPath>
|
||||||
|
</logicalFolder>
|
||||||
|
<logicalFolder name="LibraryFiles"
|
||||||
|
displayName="Library Files"
|
||||||
|
projectFiles="true">
|
||||||
|
</logicalFolder>
|
||||||
|
<logicalFolder name="LinkerScript"
|
||||||
|
displayName="Linker Files"
|
||||||
|
projectFiles="true">
|
||||||
|
</logicalFolder>
|
||||||
|
<logicalFolder name="ObjectFiles"
|
||||||
|
displayName="Object Files"
|
||||||
|
projectFiles="true">
|
||||||
|
</logicalFolder>
|
||||||
|
<logicalFolder name="SourceFiles"
|
||||||
|
displayName="Source Files"
|
||||||
|
projectFiles="true">
|
||||||
|
<itemPath>../src/BootPIC18NonJ.c</itemPath>
|
||||||
|
<itemPath>../src/VectorRemap.asm</itemPath>
|
||||||
|
<itemPath>../src/main.c</itemPath>
|
||||||
|
<itemPath>../src/usb_descriptors.c</itemPath>
|
||||||
|
<itemPath>../src/usb_device.c</itemPath>
|
||||||
|
<itemPath>../src/usb_device_hid.c</itemPath>
|
||||||
|
<itemPath>../../src/system.c</itemPath>
|
||||||
|
</logicalFolder>
|
||||||
|
<logicalFolder name="ExternalFiles"
|
||||||
|
displayName="Important Files"
|
||||||
|
projectFiles="false">
|
||||||
|
<itemPath>Makefile</itemPath>
|
||||||
|
</logicalFolder>
|
||||||
|
</logicalFolder>
|
||||||
|
<sourceRootList>
|
||||||
|
<Elem>../</Elem>
|
||||||
|
<Elem>../../src</Elem>
|
||||||
|
</sourceRootList>
|
||||||
|
<projectmakefile>Makefile</projectmakefile>
|
||||||
|
<confs>
|
||||||
|
<conf name="PIC18F2550_XC8" type="2">
|
||||||
|
<toolsSet>
|
||||||
|
<developmentServer>localhost</developmentServer>
|
||||||
|
<targetDevice>PIC18F2550</targetDevice>
|
||||||
|
<targetHeader></targetHeader>
|
||||||
|
<targetPluginBoard></targetPluginBoard>
|
||||||
|
<platformTool>PICkit3PlatformTool</platformTool>
|
||||||
|
<languageToolchain>XC8</languageToolchain>
|
||||||
|
<languageToolchainVersion>2.05</languageToolchainVersion>
|
||||||
|
<platform>3</platform>
|
||||||
|
</toolsSet>
|
||||||
|
<packs>
|
||||||
|
<pack name="PIC18Fxxxx_DFP" vendor="Microchip" version="1.0.9"/>
|
||||||
|
</packs>
|
||||||
|
<compileType>
|
||||||
|
<linkerTool>
|
||||||
|
<linkerLibItems>
|
||||||
|
</linkerLibItems>
|
||||||
|
</linkerTool>
|
||||||
|
<archiverTool>
|
||||||
|
</archiverTool>
|
||||||
|
<loading>
|
||||||
|
<useAlternateLoadableFile>false</useAlternateLoadableFile>
|
||||||
|
<parseOnProdLoad>true</parseOnProdLoad>
|
||||||
|
<alternateLoadableFile></alternateLoadableFile>
|
||||||
|
</loading>
|
||||||
|
<subordinates>
|
||||||
|
</subordinates>
|
||||||
|
</compileType>
|
||||||
|
<makeCustomizationType>
|
||||||
|
<makeCustomizationPreStepEnabled>false</makeCustomizationPreStepEnabled>
|
||||||
|
<makeCustomizationPreStep></makeCustomizationPreStep>
|
||||||
|
<makeCustomizationPostStepEnabled>false</makeCustomizationPostStepEnabled>
|
||||||
|
<makeCustomizationPostStep></makeCustomizationPostStep>
|
||||||
|
<makeCustomizationPutChecksumInUserID>false</makeCustomizationPutChecksumInUserID>
|
||||||
|
<makeCustomizationEnableLongLines>false</makeCustomizationEnableLongLines>
|
||||||
|
<makeCustomizationNormalizeHexFile>false</makeCustomizationNormalizeHexFile>
|
||||||
|
</makeCustomizationType>
|
||||||
|
<HI-TECH-COMP>
|
||||||
|
<property key="additional-warnings" value="true"/>
|
||||||
|
<property key="asmlist" value="true"/>
|
||||||
|
<property key="default-bitfield-type" value="true"/>
|
||||||
|
<property key="default-char-type" value="true"/>
|
||||||
|
<property key="define-macros" value=""/>
|
||||||
|
<property key="disable-optimizations" value="true"/>
|
||||||
|
<property key="extra-include-directories" value=""/>
|
||||||
|
<property key="favor-optimization-for" value="-speed,+space"/>
|
||||||
|
<property key="garbage-collect-data" value="true"/>
|
||||||
|
<property key="garbage-collect-functions" value="true"/>
|
||||||
|
<property key="identifier-length" value="255"/>
|
||||||
|
<property key="local-generation" value="false"/>
|
||||||
|
<property key="operation-mode" value="pro"/>
|
||||||
|
<property key="opt-xc8-compiler-strict_ansi" value="false"/>
|
||||||
|
<property key="optimization-assembler" value="true"/>
|
||||||
|
<property key="optimization-assembler-files" value="false"/>
|
||||||
|
<property key="optimization-debug" value="false"/>
|
||||||
|
<property key="optimization-invariant-enable" value="false"/>
|
||||||
|
<property key="optimization-invariant-value" value="16"/>
|
||||||
|
<property key="optimization-level" value="-O0"/>
|
||||||
|
<property key="optimization-speed" value="false"/>
|
||||||
|
<property key="optimization-stable-enable" value="false"/>
|
||||||
|
<property key="pack-struct" value="true"/>
|
||||||
|
<property key="preprocess-assembler" value="true"/>
|
||||||
|
<property key="short-enums" value="true"/>
|
||||||
|
<property key="undefine-macros" value=""/>
|
||||||
|
<property key="use-cci" value="true"/>
|
||||||
|
<property key="use-iar" value="false"/>
|
||||||
|
<property key="verbose" value="false"/>
|
||||||
|
<property key="warning-level" value="0"/>
|
||||||
|
<property key="what-to-do" value="require"/>
|
||||||
|
</HI-TECH-COMP>
|
||||||
|
<HI-TECH-LINK>
|
||||||
|
<property key="additional-options-checksum" value=""/>
|
||||||
|
<property key="additional-options-code-offset" value=""/>
|
||||||
|
<property key="additional-options-command-line" value=""/>
|
||||||
|
<property key="additional-options-errata" value=""/>
|
||||||
|
<property key="additional-options-extend-address" value="false"/>
|
||||||
|
<property key="additional-options-trace-type" value=""/>
|
||||||
|
<property key="additional-options-use-response-files" value="false"/>
|
||||||
|
<property key="backup-reset-condition-flags" value="false"/>
|
||||||
|
<property key="calibrate-oscillator" value="true"/>
|
||||||
|
<property key="calibrate-oscillator-value" value=""/>
|
||||||
|
<property key="clear-bss" value="true"/>
|
||||||
|
<property key="code-model-external" value="wordwrite"/>
|
||||||
|
<property key="code-model-rom" value="default,-1400-7FFF"/>
|
||||||
|
<property key="create-html-files" value="false"/>
|
||||||
|
<property key="data-model-ram" value=""/>
|
||||||
|
<property key="data-model-size-of-double" value="32"/>
|
||||||
|
<property key="data-model-size-of-double-gcc" value="no-short-double"/>
|
||||||
|
<property key="data-model-size-of-float" value="32"/>
|
||||||
|
<property key="data-model-size-of-float-gcc" value="no-short-float"/>
|
||||||
|
<property key="display-class-usage" value="false"/>
|
||||||
|
<property key="display-hex-usage" value="false"/>
|
||||||
|
<property key="display-overall-usage" value="true"/>
|
||||||
|
<property key="display-psect-usage" value="false"/>
|
||||||
|
<property key="extra-lib-directories" value=""/>
|
||||||
|
<property key="fill-flash-options-addr" value=""/>
|
||||||
|
<property key="fill-flash-options-const" value=""/>
|
||||||
|
<property key="fill-flash-options-how" value="0"/>
|
||||||
|
<property key="fill-flash-options-inc-const" value="1"/>
|
||||||
|
<property key="fill-flash-options-increment" value=""/>
|
||||||
|
<property key="fill-flash-options-seq" value=""/>
|
||||||
|
<property key="fill-flash-options-what" value="0"/>
|
||||||
|
<property key="format-hex-file-for-download" value="false"/>
|
||||||
|
<property key="initialize-data" value="true"/>
|
||||||
|
<property key="input-libraries" value="libm"/>
|
||||||
|
<property key="keep-generated-startup.as" value="true"/>
|
||||||
|
<property key="link-in-c-library" value="true"/>
|
||||||
|
<property key="link-in-c-library-gcc" value=""/>
|
||||||
|
<property key="link-in-peripheral-library" value="false"/>
|
||||||
|
<property key="managed-stack" value="false"/>
|
||||||
|
<property key="opt-xc8-linker-file" value="false"/>
|
||||||
|
<property key="opt-xc8-linker-link_startup" value="false"/>
|
||||||
|
<property key="opt-xc8-linker-serial" value=""/>
|
||||||
|
<property key="program-the-device-with-default-config-words" value="true"/>
|
||||||
|
<property key="remove-unused-sections" value="true"/>
|
||||||
|
</HI-TECH-LINK>
|
||||||
|
<ICD3PlatformTool>
|
||||||
|
<property key="AutoSelectMemRanges" value="auto"/>
|
||||||
|
<property key="Freeze Peripherals" value="true"/>
|
||||||
|
<property key="SecureSegment.SegmentProgramming" value="FullChipProgramming"/>
|
||||||
|
<property key="ToolFirmwareFilePath"
|
||||||
|
value="Press to browse for a specific firmware version"/>
|
||||||
|
<property key="ToolFirmwareOption.UseLatestFirmware" value="true"/>
|
||||||
|
<property key="debugoptions.useswbreakpoints" value="false"/>
|
||||||
|
<property key="hwtoolclock.frcindebug" value="false"/>
|
||||||
|
<property key="memories.aux" value="false"/>
|
||||||
|
<property key="memories.bootflash" value="false"/>
|
||||||
|
<property key="memories.configurationmemory" value="false"/>
|
||||||
|
<property key="memories.configurationmemory2" value="true"/>
|
||||||
|
<property key="memories.dataflash" value="true"/>
|
||||||
|
<property key="memories.eeprom" value="true"/>
|
||||||
|
<property key="memories.flashdata" value="true"/>
|
||||||
|
<property key="memories.id" value="true"/>
|
||||||
|
<property key="memories.instruction.ram" value="true"/>
|
||||||
|
<property key="memories.instruction.ram.ranges"
|
||||||
|
value="${memories.instruction.ram.ranges}"/>
|
||||||
|
<property key="memories.programmemory" value="true"/>
|
||||||
|
<property key="memories.programmemory.ranges" value="0-7fff"/>
|
||||||
|
<property key="poweroptions.powerenable" value="false"/>
|
||||||
|
<property key="programoptions.donoteraseauxmem" value="false"/>
|
||||||
|
<property key="programoptions.eraseb4program" value="true"/>
|
||||||
|
<property key="programoptions.preservedataflash" value="false"/>
|
||||||
|
<property key="programoptions.preservedataflash.ranges" value=""/>
|
||||||
|
<property key="programoptions.preserveeeprom" value="false"/>
|
||||||
|
<property key="programoptions.preserveeeprom.ranges" value="0-ff"/>
|
||||||
|
<property key="programoptions.preserveprogram.ranges" value=""/>
|
||||||
|
<property key="programoptions.preserveprogramrange" value="false"/>
|
||||||
|
<property key="programoptions.preserveuserid" value="false"/>
|
||||||
|
<property key="programoptions.programcalmem" value="false"/>
|
||||||
|
<property key="programoptions.programuserotp" value="false"/>
|
||||||
|
<property key="programoptions.testmodeentrymethod" value="VPPFirst"/>
|
||||||
|
<property key="programoptions.usehighvoltageonmclr" value="false"/>
|
||||||
|
<property key="programoptions.uselvpprogramming" value="false"/>
|
||||||
|
<property key="voltagevalue" value="5.0"/>
|
||||||
|
</ICD3PlatformTool>
|
||||||
|
<PICkit3PlatformTool>
|
||||||
|
<property key="AutoSelectMemRanges" value="auto"/>
|
||||||
|
<property key="Freeze Peripherals" value="true"/>
|
||||||
|
<property key="SecureSegment.SegmentProgramming" value="FullChipProgramming"/>
|
||||||
|
<property key="ToolFirmwareFilePath"
|
||||||
|
value="Press to browse for a specific firmware version"/>
|
||||||
|
<property key="ToolFirmwareOption.UseLatestFirmware" value="true"/>
|
||||||
|
<property key="debugoptions.useswbreakpoints" value="false"/>
|
||||||
|
<property key="firmware.download.all" value="false"/>
|
||||||
|
<property key="hwtoolclock.frcindebug" value="false"/>
|
||||||
|
<property key="memories.aux" value="false"/>
|
||||||
|
<property key="memories.bootflash" value="true"/>
|
||||||
|
<property key="memories.configurationmemory" value="true"/>
|
||||||
|
<property key="memories.configurationmemory2" value="true"/>
|
||||||
|
<property key="memories.dataflash" value="true"/>
|
||||||
|
<property key="memories.eeprom" value="true"/>
|
||||||
|
<property key="memories.flashdata" value="true"/>
|
||||||
|
<property key="memories.id" value="true"/>
|
||||||
|
<property key="memories.instruction.ram" value="true"/>
|
||||||
|
<property key="memories.instruction.ram.ranges"
|
||||||
|
value="${memories.instruction.ram.ranges}"/>
|
||||||
|
<property key="memories.programmemory" value="true"/>
|
||||||
|
<property key="memories.programmemory.ranges" value="0-7fff"/>
|
||||||
|
<property key="poweroptions.powerenable" value="false"/>
|
||||||
|
<property key="programmertogo.imagename" value=""/>
|
||||||
|
<property key="programoptions.donoteraseauxmem" value="false"/>
|
||||||
|
<property key="programoptions.eraseb4program" value="true"/>
|
||||||
|
<property key="programoptions.pgmspeed" value="2"/>
|
||||||
|
<property key="programoptions.preservedataflash" value="false"/>
|
||||||
|
<property key="programoptions.preservedataflash.ranges"
|
||||||
|
value="${programoptions.preservedataflash.ranges}"/>
|
||||||
|
<property key="programoptions.preserveeeprom" value="false"/>
|
||||||
|
<property key="programoptions.preserveeeprom.ranges" value="0-ff"/>
|
||||||
|
<property key="programoptions.preserveprogram.ranges" value=""/>
|
||||||
|
<property key="programoptions.preserveprogramrange" value="false"/>
|
||||||
|
<property key="programoptions.preserveuserid" value="false"/>
|
||||||
|
<property key="programoptions.programcalmem" value="false"/>
|
||||||
|
<property key="programoptions.programuserotp" value="false"/>
|
||||||
|
<property key="programoptions.testmodeentrymethod" value="VDDFirst"/>
|
||||||
|
<property key="programoptions.usehighvoltageonmclr" value="false"/>
|
||||||
|
<property key="programoptions.uselvpprogramming" value="false"/>
|
||||||
|
<property key="voltagevalue" value="5.0"/>
|
||||||
|
</PICkit3PlatformTool>
|
||||||
|
<XC8-config-global>
|
||||||
|
<property key="advanced-elf" value="true"/>
|
||||||
|
<property key="gcc-opt-driver-new" value="true"/>
|
||||||
|
<property key="gcc-opt-std" value="-std=c90"/>
|
||||||
|
<property key="gcc-output-file-format" value="dwarf-3"/>
|
||||||
|
<property key="omit-pack-options" value="false"/>
|
||||||
|
<property key="output-file-format" value="-mcof,+elf"/>
|
||||||
|
<property key="stack-size-high" value="auto"/>
|
||||||
|
<property key="stack-size-low" value="auto"/>
|
||||||
|
<property key="stack-size-main" value="auto"/>
|
||||||
|
<property key="stack-type" value="compiled"/>
|
||||||
|
<property key="user-pack-device-support" value=""/>
|
||||||
|
</XC8-config-global>
|
||||||
|
</conf>
|
||||||
|
</confs>
|
||||||
|
</configurationDescriptor>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||||
|
<type>com.microchip.mplab.nbide.embedded.makeproject</type>
|
||||||
|
<configuration>
|
||||||
|
<data xmlns="http://www.netbeans.org/ns/make-project/1">
|
||||||
|
<name>bootloader_hacked_from_mla</name>
|
||||||
|
<creation-uuid>10ecf416-ca94-402f-a3ea-0a0beb0c5a13</creation-uuid>
|
||||||
|
<make-project-type>0</make-project-type>
|
||||||
|
<c-extensions>c</c-extensions>
|
||||||
|
<cpp-extensions/>
|
||||||
|
<header-extensions>h</header-extensions>
|
||||||
|
<sourceEncoding>ISO-8859-1</sourceEncoding>
|
||||||
|
<asminc-extensions/>
|
||||||
|
<make-dep-projects/>
|
||||||
|
<sourceRootList>
|
||||||
|
<sourceRootElem>../</sourceRootElem>
|
||||||
|
<sourceRootElem>../../src</sourceRootElem>
|
||||||
|
</sourceRootList>
|
||||||
|
<confList>
|
||||||
|
<confElem>
|
||||||
|
<name>PIC18F2550_XC8</name>
|
||||||
|
<type>2</type>
|
||||||
|
</confElem>
|
||||||
|
</confList>
|
||||||
|
<formatting>
|
||||||
|
<project-formatting-style>false</project-formatting-style>
|
||||||
|
</formatting>
|
||||||
|
</data>
|
||||||
|
</configuration>
|
||||||
|
</project>
|
||||||
926
bootloader_hacked_from_mla/src/BootPIC18NonJ.c
Normal file
926
bootloader_hacked_from_mla/src/BootPIC18NonJ.c
Normal file
@@ -0,0 +1,926 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
Copyright 2016 Microchip Technology Inc. (www.microchip.com)
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
To request to license the code under the MLA license (www.microchip.com/mla_license),
|
||||||
|
please contact mla_licensing@microchip.com
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
/** I N C L U D E S **********************************************************/
|
||||||
|
#include "usb.h"
|
||||||
|
#include "BootPIC18NonJ.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** C O N S T A N T S **********************************************************/
|
||||||
|
//The bootloader version, which the bootloader PC application can do extended query to get.
|
||||||
|
//Value provided is expected to be in the format of BOOTLOADER_VERSION_MAJOR.BOOTLOADER_VERSION_MINOR
|
||||||
|
//Ex: 1.01 would be BOOTLOADER_VERSION_MAJOR == 1, and BOOTLOADER_VERSION_MINOR == 1
|
||||||
|
#define BOOTLOADER_VERSION_MAJOR 1 //Legal value 0-255
|
||||||
|
#define BOOTLOADER_VERSION_MINOR 2 //Legal value 0-99. (1 = X.01)
|
||||||
|
|
||||||
|
|
||||||
|
//Section defining the address range to erase for the erase device command, along with the valid programming range to be reported by the QUERY_DEVICE command.
|
||||||
|
#define PROGRAM_MEM_START_ADDRESS REMAPPED_APPLICATION_RESET_VECTOR //Beginning of application program memory (not occupied by bootloader). **THIS VALUE MUST BE ALIGNED WITH 64 BYTE BLOCK BOUNDRY** Also, in order to work correctly, make sure the StartPageToErase is set to erase this section.
|
||||||
|
|
||||||
|
#if defined(__18F4550)||defined(__18F2550)||defined(__18F45K50)||defined(__18LF45K50)||defined(__18F25K50)||defined(__18LF25K50)
|
||||||
|
#define MAX_PAGE_TO_ERASE 511 //Last 64 byte page of flash on the PIC18F4550
|
||||||
|
#define PROGRAM_MEM_STOP_ADDRESS 0x008000 //**MUST BE WORD ALIGNED (EVEN) ADDRESS. This address does not get updated, but the one just below it does: IE: If PROGRAM_MEM_STOP_ADDRESS = 0x200, 0x1FF is the last programmed address (0x200 not programmed)**
|
||||||
|
#define CONFIG_WORDS_START_ADDRESS 0x300000 //0x300000 is start of CONFIG space for these devices
|
||||||
|
#define CONFIG_WORDS_SECTION_LENGTH 14 //14 bytes worth of Configuration words on these devices
|
||||||
|
#define USER_ID_ADDRESS 0x200000 //User ID is 8 bytes starting at 0x200000
|
||||||
|
#define USER_ID_SIZE 8
|
||||||
|
#define DEVICE_WITH_EEPROM //Comment this out, if you never want the bootloader to reprogram the EEPROM space
|
||||||
|
#define EEPROM_SIZE 0x100 //256 bytes of EEPROM on this device
|
||||||
|
#define EEPROM_EFFECTIVE_ADDRESS 0xF00000 //Location in the .hex file where the EEPROM contents are stored
|
||||||
|
#define WRITE_BLOCK_SIZE 0x20 //32 byte programming block size on the PIC18F4550/PIC18F4553 family devices
|
||||||
|
#define ERASE_PAGE_SIZE 64
|
||||||
|
|
||||||
|
#elif defined(__18F4553)||defined(__18F2553)
|
||||||
|
#define MAX_PAGE_TO_ERASE 511 //Last 64 byte page of flash on the PIC18F4550
|
||||||
|
#define PROGRAM_MEM_STOP_ADDRESS 0x008000 //**MUST BE WORD ALIGNED (EVEN) ADDRESS. This address does not get updated, but the one just below it does: IE: If PROGRAM_MEM_STOP_ADDRESS = 0x200, 0x1FF is the last programmed address (0x200 not programmed)**
|
||||||
|
#define CONFIG_WORDS_START_ADDRESS 0x300000 //0x300000 is start of CONFIG space for these devices
|
||||||
|
#define CONFIG_WORDS_SECTION_LENGTH 14 //14 bytes worth of Configuration words on these devices
|
||||||
|
#define USER_ID_ADDRESS 0x200000 //User ID is 8 bytes starting at 0x200000
|
||||||
|
#define USER_ID_SIZE 8
|
||||||
|
#define DEVICE_WITH_EEPROM //Comment this out, if you never want the bootloader to reprogram the EEPROM space
|
||||||
|
#define EEPROM_SIZE 0x100 //256 bytes of EEPROM on this device
|
||||||
|
#define EEPROM_EFFECTIVE_ADDRESS 0xF00000 //Location in the .hex file where the EEPROM contents are stored
|
||||||
|
#define WRITE_BLOCK_SIZE 0x20 //32 byte programming block size on the PIC18F4550/PIC18F4553 family devices
|
||||||
|
#define ERASE_PAGE_SIZE 64
|
||||||
|
|
||||||
|
#elif defined(__18F4455)||defined(__18F2455)
|
||||||
|
#define MAX_PAGE_TO_ERASE 383 //Last 64 byte page of flash on the PIC18F4455
|
||||||
|
#define PROGRAM_MEM_STOP_ADDRESS 0x006000 //**MUST BE WORD ALIGNED (EVEN) ADDRESS. This address does not get updated, but the one just below it does: IE: If PROGRAM_MEM_STOP_ADDRESS = 0x200, 0x1FF is the last programmed address (0x200 not programmed)**
|
||||||
|
#define CONFIG_WORDS_START_ADDRESS 0x300000 /0x300000 is start of CONFIG space for these devices
|
||||||
|
#define CONFIG_WORDS_SECTION_LENGTH 14 //14 bytes worth of Configuration words on these devices
|
||||||
|
#define USER_ID_ADDRESS 0x200000 //User ID is 8 bytes starting at 0x200000
|
||||||
|
#define USER_ID_SIZE 8
|
||||||
|
#define DEVICE_WITH_EEPROM //Comment this out, if you never want the bootloader to reprogram the EEPROM space
|
||||||
|
#define EEPROM_SIZE 0x100 //256 bytes of EEPROM on this device
|
||||||
|
#define EEPROM_EFFECTIVE_ADDRESS 0xF00000 //Location in the .hex file where the EEPROM contents are stored
|
||||||
|
#define WRITE_BLOCK_SIZE 0x20 //32 byte programming block size on the PIC18F4550/PIC18F4553 family devices
|
||||||
|
#define ERASE_PAGE_SIZE 64
|
||||||
|
|
||||||
|
#elif defined(__18F4458)||defined(__18F2458)
|
||||||
|
#define MAX_PAGE_TO_ERASE 383 //Last 64 byte page of flash on the PIC18F4455
|
||||||
|
#define PROGRAM_MEM_STOP_ADDRESS 0x006000 //**MUST BE WORD ALIGNED (EVEN) ADDRESS. This address does not get updated, but the one just below it does: IE: If PROGRAM_MEM_STOP_ADDRESS = 0x200, 0x1FF is the last programmed address (0x200 not programmed)**
|
||||||
|
#define CONFIG_WORDS_START_ADDRESS 0x300000 /0x300000 is start of CONFIG space for these devices
|
||||||
|
#define CONFIG_WORDS_SECTION_LENGTH 14 //14 bytes worth of Configuration words on these devices
|
||||||
|
#define USER_ID_ADDRESS 0x200000 //User ID is 8 bytes starting at 0x200000
|
||||||
|
#define UserIDSize 8
|
||||||
|
#define DEVICE_WITH_EEPROM //Comment this out, if you never want the bootloader to reprogram the EEPROM space
|
||||||
|
#define EEPROM_SIZE 0x100 //256 bytes of EEPROM on this device
|
||||||
|
#define EEPROM_EFFECTIVE_ADDRESS 0xF00000 //Location in the .hex file where the EEPROM contents are stored
|
||||||
|
#define WRITE_BLOCK_SIZE 0x20 //32 byte programming block size on the PIC18F4550/PIC18F4553 family devices
|
||||||
|
#define ERASE_PAGE_SIZE 64
|
||||||
|
|
||||||
|
#elif defined(__18F4450)||defined(__18F2450)
|
||||||
|
#define MAX_PAGE_TO_ERASE 255 //Last 64 byte page of flash on the PIC18F4450
|
||||||
|
#define PROGRAM_MEM_STOP_ADDRESS 0x004000 //**MUST BE WORD ALIGNED (EVEN) ADDRESS. This address does not get updated, but the one just below it does: IE: If PROGRAM_MEM_STOP_ADDRESS = 0x200, 0x1FF is the last programmed address (0x200 not programmed)**
|
||||||
|
#define CONFIG_WORDS_START_ADDRESS 0x300000 /0x300000 is start of CONFIG space for these devices
|
||||||
|
#define CONFIG_WORDS_SECTION_LENGTH 14 //14 bytes worth of Configuration words on these devices
|
||||||
|
#define USER_ID_ADDRESS 0x200000 //User ID is 8 bytes starting at 0x200000
|
||||||
|
#define USER_ID_SIZE 8
|
||||||
|
#define WRITE_BLOCK_SIZE 0x10 //16 byte programming block size on the PIC18F4450/2450 family devices
|
||||||
|
#define ERASE_PAGE_SIZE 64
|
||||||
|
|
||||||
|
#elif defined(__18F24K50)||defined(__18LF24K50)
|
||||||
|
#define MAX_PAGE_TO_ERASE 255 //Last 64 byte page of flash on the PIC18F4450
|
||||||
|
#define PROGRAM_MEM_STOP_ADDRESS 0x004000 //**MUST BE WORD ALIGNED (EVEN) ADDRESS. This address does not get updated, but the one just below it does: IE: If PROGRAM_MEM_STOP_ADDRESS = 0x200, 0x1FF is the last programmed address (0x200 not programmed)**
|
||||||
|
#define CONFIG_WORDS_START_ADDRESS 0x300000 /0x300000 is start of CONFIG space for these devices
|
||||||
|
#define CONFIG_WORDS_SECTION_LENGTH 14 //14 bytes worth of Configuration words on these devices
|
||||||
|
#define USER_ID_ADDRESS 0x200000 //User ID is 8 bytes starting at 0x200000
|
||||||
|
#define USER_ID_SIZE 8
|
||||||
|
#define DEVICE_WITH_EEPROM //Comment this out, if you never want the bootloader to reprogram the EEPROM space
|
||||||
|
#define EEPROM_SIZE 0x100 //256 bytes of EEPROM on this device
|
||||||
|
#define EEPROM_EFFECTIVE_ADDRESS 0xF00000 //Location in the .hex file where the EEPROM contents are stored
|
||||||
|
#define WRITE_BLOCK_SIZE 0x10 //16 byte programming block size on the PIC18F4450/2450 family devices
|
||||||
|
#define ERASE_PAGE_SIZE 64
|
||||||
|
|
||||||
|
#elif defined(__18F14K50) || defined(__18LF14K50)
|
||||||
|
#define MAX_PAGE_TO_ERASE 255 //Last 64 byte page of flash on the PIC18F4455
|
||||||
|
#define PROGRAM_MEM_STOP_ADDRESS 0x004000 //**MUST BE WORD ALIGNED (EVEN) ADDRESS. This address does not get updated, but the one just below it does: IE: If PROGRAM_MEM_STOP_ADDRESS = 0x200, 0x1FF is the last programmed address (0x200 not programmed)**
|
||||||
|
#define CONFIG_WORDS_START_ADDRESS 0x300000 //0x300000 is start of CONFIG space for these devices
|
||||||
|
#define CONFIG_WORDS_SECTION_LENGTH 14 //14 bytes worth of Configuration words on these devices
|
||||||
|
#define USER_ID_ADDRESS 0x200000 //User ID is 8 bytes starting at 0x200000
|
||||||
|
#define USER_ID_SIZE 8
|
||||||
|
#define DEVICE_WITH_EEPROM //Comment this out, if you never want the bootloader to reprogram the EEPROM space
|
||||||
|
#define EEPROM_SIZE 0x100 //256 bytes of EEPROM on this device
|
||||||
|
#define EEPROM_EFFECTIVE_ADDRESS 0xF00000 //Location in the .hex file where the EEPROM contents are stored
|
||||||
|
#define WRITE_BLOCK_SIZE 0x10 //16 byte programming block size on the PIC18F14K50 family devices
|
||||||
|
#define ERASE_PAGE_SIZE 64
|
||||||
|
|
||||||
|
#elif defined(__18F13K50) || defined(__18LF13K50)
|
||||||
|
#define MAX_PAGE_TO_ERASE 127 //Last 64 byte page of flash on the PIC18F4455
|
||||||
|
#define PROGRAM_MEM_STOP_ADDRESS 0x002000 //**MUST BE WORD ALIGNED (EVEN) ADDRESS. This address does not get updated, but the one just below it does: IE: If PROGRAM_MEM_STOP_ADDRESS = 0x200, 0x1FF is the last programmed address (0x200 not programmed)**
|
||||||
|
#define CONFIG_WORDS_START_ADDRESS 0x300000 //0x300000 is start of CONFIG space for these devices
|
||||||
|
#define CONFIG_WORDS_SECTION_LENGTH 14 //14 bytes worth of Configuration words on these devices
|
||||||
|
#define USER_ID_ADDRESS 0x200000 //User ID is 8 bytes starting at 0x200000
|
||||||
|
#define USER_ID_SIZE 8
|
||||||
|
#define DEVICE_WITH_EEPROM //Comment this out, if you never want the bootloader to reprogram the EEPROM space
|
||||||
|
#define EEPROM_SIZE 0x100 //256 bytes of EEPROM on this device
|
||||||
|
#define EEPROM_EFFECTIVE_ADDRESS 0xF00000 //Location in the .hex file where the EEPROM contents are stored
|
||||||
|
#define WRITE_BLOCK_SIZE 0x08 //8 byte programming block size on the PIC18F14K50 family devices
|
||||||
|
#define ERASE_PAGE_SIZE 64
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//Derived microcontroller address/page constants
|
||||||
|
#define START_PAGE_TO_ERASE (PROGRAM_MEM_START_ADDRESS/ERASE_PAGE_SIZE) //The first flash page number to erase, which is the start of the application program space
|
||||||
|
#define ERASE_PAGE_ADDRESS_MASK (uint24_t)(0x1000000 - ERASE_PAGE_SIZE) //AND mask to move an address pointer to the start of an erase page
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Bootloader Command From Host - Switch() State Variable Choices
|
||||||
|
#define QUERY_DEVICE 0x02 //Command that the host uses to learn about the device (what regions can be programmed, and what type of memory is the region)
|
||||||
|
#define UNLOCK_CONFIG 0x03 //Note, this command is used for both locking and unlocking the config bits (see the "//Unlock Configs Command Definitions" below)
|
||||||
|
#define ERASE_DEVICE 0x04 //Host sends this command to start an erase operation. Firmware controls which pages should be erased.
|
||||||
|
#define PROGRAM_DEVICE 0x05 //If host is going to send a full RequestDataBlockSize to be programmed, it uses this command.
|
||||||
|
#define PROGRAM_COMPLETE 0x06 //If host send less than a RequestDataBlockSize to be programmed, or if it wished to program whatever was left in the buffer, it uses this command.
|
||||||
|
#define GET_DATA 0x07 //The host sends this command in order to read out memory from the device. Used during verify (and read/export hex operations)
|
||||||
|
#define RESET_DEVICE 0x08 //Resets the microcontroller, so it can update the config bits (if they were programmed, and so as to leave the bootloader (and potentially go back into the main application)
|
||||||
|
#define SIGN_FLASH 0x09 //The host PC application should send this command after the verify operation has completed successfully. If checksums are used instead of a true verify (due to ALLOW_GET_DATA_COMMAND being commented), then the host PC application should send SIGN_FLASH command after is has verified the checksums are as exected. The firmware will then program the SIGNATURE_WORD into flash at the SIGNATURE_ADDRESS.
|
||||||
|
#define QUERY_EXTENDED_INFO 0x0C //Used by host PC app to get additional info about the device, beyond the basic NVM layout provided by the query device command
|
||||||
|
|
||||||
|
//Unlock Configs Command Definitions
|
||||||
|
#define UNLOCKCONFIG 0x00 //Sub-command for the ERASE_DEVICE command
|
||||||
|
#define LOCKCONFIG 0x01 //Sub-command for the ERASE_DEVICE command
|
||||||
|
|
||||||
|
//Query Device Response "Types"
|
||||||
|
#define MEMORY_REGION_PROGRAM_MEM 0x01 //When the host sends a QUERY_DEVICE command, need to respond by populating a list of valid memory regions that exist in the device (and should be programmed)
|
||||||
|
#define MEMORY_REGION_EEDATA 0x02
|
||||||
|
#define MEMORY_REGION_CONFIG 0x03
|
||||||
|
#define MEMORY_REGION_USERID 0x04
|
||||||
|
#define MEMORY_REGION_END 0xFF //Sort of serves as a "null terminator" like number, which denotes the end of the memory region list has been reached.
|
||||||
|
#define BOOTLOADER_V1_01_OR_NEWER_FLAG 0xA5 //Tacked on in the VersionFlag byte, to indicate when using newer version of bootloader with extended query info available
|
||||||
|
|
||||||
|
|
||||||
|
//BootState Variable States
|
||||||
|
#define IDLE 0x00
|
||||||
|
#define NOT_IDLE 0x01
|
||||||
|
|
||||||
|
//OtherConstants
|
||||||
|
#define INVALID_ADDRESS 0xFFFFFFFF
|
||||||
|
#define CORRECT_UNLOCK_KEY 0xB5
|
||||||
|
|
||||||
|
//Application and Microcontroller constants
|
||||||
|
#define BYTES_PER_ADDRESS_PIC18 0x01 //One byte per address. PIC24 uses 2 bytes for each address in the hex file.
|
||||||
|
#define USB_PACKET_SIZE 0x40
|
||||||
|
#define WORDSIZE 0x02 //PIC18 uses 2 byte words, PIC24 uses 3 byte words.
|
||||||
|
#define REQUEST_DATA_BLOCK_SIZE 0x3A //Number of data bytes in a standard request to the PC. Must be an even number from 2-58 (0x02-0x3A). Larger numbers make better use of USB bandwidth and
|
||||||
|
//yeild shorter program/verify times, but require more micrcontroller RAM for buffer space.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** USB Packet Request/Response Formatting Structure **********************************************************/
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
unsigned char Contents[USB_PACKET_SIZE];
|
||||||
|
|
||||||
|
//General command (with data in it) packet structure used by PROGRAM_DEVICE and GET_DATA commands
|
||||||
|
struct{
|
||||||
|
unsigned char Command;
|
||||||
|
unsigned long Address;
|
||||||
|
unsigned char Size;
|
||||||
|
//unsigned char PadBytes[58-REQUEST_DATA_BLOCK_SIZE]; //Uncomment this if using a smaller than 0x3A RequestDataBlockSize. Compiler doesn't like 0 byte array when using 58 byte data block size.
|
||||||
|
unsigned char Data[REQUEST_DATA_BLOCK_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
//This struct used for responding to QUERY_DEVICE command (on a device with four programmable sections)
|
||||||
|
struct{
|
||||||
|
unsigned char Command;
|
||||||
|
unsigned char PacketDataFieldSize;
|
||||||
|
unsigned char BytesPerAddress;
|
||||||
|
unsigned char Type1;
|
||||||
|
unsigned long Address1;
|
||||||
|
unsigned long Length1;
|
||||||
|
unsigned char Type2;
|
||||||
|
unsigned long Address2;
|
||||||
|
unsigned long Length2;
|
||||||
|
unsigned char Type3;
|
||||||
|
unsigned long Address3;
|
||||||
|
unsigned long Length3;
|
||||||
|
unsigned char Type4;
|
||||||
|
unsigned long Address4;
|
||||||
|
unsigned long Length4;
|
||||||
|
unsigned char Type5;
|
||||||
|
unsigned long Address5;
|
||||||
|
unsigned long Length5;
|
||||||
|
unsigned char Type6;
|
||||||
|
unsigned long Address6;
|
||||||
|
unsigned long Length6;
|
||||||
|
unsigned char VersionFlag; //Used by host software to identify if device is new enough to support QUERY_EXTENDED_INFO command
|
||||||
|
unsigned char ExtraPadBytes[7];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct{ //For UNLOCK_CONFIG command
|
||||||
|
unsigned char Command;
|
||||||
|
unsigned char LockValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
//Structure for the QUERY_EXTENDED_INFO command (and response)
|
||||||
|
struct{
|
||||||
|
unsigned char Command;
|
||||||
|
unsigned int BootloaderVersion;
|
||||||
|
unsigned int ApplicationVersion;
|
||||||
|
unsigned long SignatureAddress;
|
||||||
|
unsigned int SignatureValue;
|
||||||
|
unsigned long ErasePageSize;
|
||||||
|
unsigned char Config1LMask;
|
||||||
|
unsigned char Config1HMask;
|
||||||
|
unsigned char Config2LMask;
|
||||||
|
unsigned char Config2HMask;
|
||||||
|
unsigned char Config3LMask;
|
||||||
|
unsigned char Config3HMask;
|
||||||
|
unsigned char Config4LMask;
|
||||||
|
unsigned char Config4HMask;
|
||||||
|
unsigned char Config5LMask;
|
||||||
|
unsigned char Config5HMask;
|
||||||
|
unsigned char Config6LMask;
|
||||||
|
unsigned char Config6HMask;
|
||||||
|
unsigned char Config7LMask;
|
||||||
|
unsigned char Config7HMask;
|
||||||
|
};
|
||||||
|
} PacketToFromPC;
|
||||||
|
|
||||||
|
|
||||||
|
/** V A R I A B L E S ********************************************************/
|
||||||
|
#ifndef __XC8__
|
||||||
|
#pragma udata
|
||||||
|
#endif
|
||||||
|
PacketToFromPC PacketFromPC;
|
||||||
|
#ifndef __XC8__
|
||||||
|
#pragma udata SomeSectionName3
|
||||||
|
#endif
|
||||||
|
PacketToFromPC PacketToPC;
|
||||||
|
#ifndef __XC8__
|
||||||
|
#pragma udata WriteBufferSection
|
||||||
|
#endif
|
||||||
|
unsigned char ProgrammingBuffer[ERASE_PAGE_SIZE];
|
||||||
|
#ifndef __XC8__
|
||||||
|
#pragma udata OtherVariablesSection
|
||||||
|
#endif
|
||||||
|
unsigned char BootState;
|
||||||
|
unsigned int ErasePageTracker;
|
||||||
|
unsigned char BufferedDataIndex;
|
||||||
|
uint24_t ProgrammedPointer;
|
||||||
|
unsigned char ConfigsLockValue;
|
||||||
|
|
||||||
|
|
||||||
|
/** P R I V A T E P R O T O T Y P E S ***************************************/
|
||||||
|
void WriteFlashBlock(void);
|
||||||
|
void WriteConfigBits(void);
|
||||||
|
void WriteEEPROM(void);
|
||||||
|
void UnlockAndActivate(unsigned char UnlockKey);
|
||||||
|
void ResetDeviceCleanly(void);
|
||||||
|
void TableReadPostIncrement(void);
|
||||||
|
void SignFlash(void);
|
||||||
|
void LowVoltageCheck(void);
|
||||||
|
|
||||||
|
|
||||||
|
/** D E C L A R A T I O N S **************************************************/
|
||||||
|
#ifndef __XC8__
|
||||||
|
#pragma code
|
||||||
|
#endif
|
||||||
|
void UserInit(void)
|
||||||
|
{
|
||||||
|
//Initialize bootloader state variables
|
||||||
|
BootState = IDLE;
|
||||||
|
ProgrammedPointer = INVALID_ADDRESS;
|
||||||
|
BufferedDataIndex = 0;
|
||||||
|
ConfigsLockValue = TRUE;
|
||||||
|
}//end UserInit
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Function: void ProcessIO(void)
|
||||||
|
*
|
||||||
|
* PreCondition: None
|
||||||
|
*
|
||||||
|
* Input: None
|
||||||
|
*
|
||||||
|
* Output: None
|
||||||
|
*
|
||||||
|
* Side Effects: None
|
||||||
|
*
|
||||||
|
* Overview: This function receives/sends USB packets to/from the USB
|
||||||
|
* host. It also processes any received OUT packets and
|
||||||
|
* is reponsible for generating USB IN packet data.
|
||||||
|
*
|
||||||
|
* Note: None
|
||||||
|
*****************************************************************************/
|
||||||
|
void ProcessIO(void)
|
||||||
|
{
|
||||||
|
static unsigned char i;
|
||||||
|
static ROM uint8_t* pROM;
|
||||||
|
|
||||||
|
//Checks for and processes application related USB packets (assuming the
|
||||||
|
//USB bus is in the CONFIGURED_STATE, which is the only state where
|
||||||
|
//the host is allowed to send application related USB packets to the device.
|
||||||
|
if((USBGetDeviceState() != CONFIGURED_STATE) || (USBIsDeviceSuspended() == 1))
|
||||||
|
{
|
||||||
|
//No point to trying to run the application code until the device has
|
||||||
|
//been configured (finished with enumeration) and is not currently suspended.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check the current bootloader state (if we are currently waiting from a new
|
||||||
|
//command to process from the host, or if we are still processing a previous
|
||||||
|
//command.
|
||||||
|
if(BootState == IDLE)
|
||||||
|
{
|
||||||
|
//We are currently in the IDLE state waiting for a command from the
|
||||||
|
//PC software on the USB host.
|
||||||
|
if(!mHIDRxIsBusy()) //Did we receive a command?
|
||||||
|
{
|
||||||
|
//We received a new command from the host. Copy the OUT packet from
|
||||||
|
//the host into a local buffer for processing.
|
||||||
|
HIDRxReport((char *)&PacketFromPC, USB_PACKET_SIZE); //Also re-arms the OUT endpoint to be able to receive the next packet
|
||||||
|
BootState = NOT_IDLE; //Set flag letting state machine know it has a command that needs processing.
|
||||||
|
|
||||||
|
//Pre-initialize a response packet buffer (only used for some commands)
|
||||||
|
for(i = 0; i < USB_PACKET_SIZE; i++) //Prepare the next packet we will send to the host, by initializing the entire packet to 0x00.
|
||||||
|
PacketToPC.Contents[i] = 0; //This saves code space, since we don't have to do it independently in the QUERY_DEVICE and GET_DATA cases.
|
||||||
|
}
|
||||||
|
}//if(BootState == IDLE)
|
||||||
|
else //(BootState must be NOT_IDLE)
|
||||||
|
{
|
||||||
|
//Check the latest command we received from the PC app, to determine what
|
||||||
|
//we should be doing.
|
||||||
|
switch(PacketFromPC.Command)
|
||||||
|
{
|
||||||
|
case QUERY_DEVICE:
|
||||||
|
//Make sure the USB IN endpoint buffer is available, then load
|
||||||
|
//up a query response packet to send to the host.
|
||||||
|
if(!mHIDTxIsBusy())
|
||||||
|
{
|
||||||
|
//Prepare a response packet, which lets the PC software know about the memory ranges of this device.
|
||||||
|
PacketToPC.Command = QUERY_DEVICE;
|
||||||
|
PacketToPC.PacketDataFieldSize = REQUEST_DATA_BLOCK_SIZE;
|
||||||
|
PacketToPC.BytesPerAddress = BYTES_PER_ADDRESS_PIC18;
|
||||||
|
PacketToPC.Type1 = MEMORY_REGION_PROGRAM_MEM;
|
||||||
|
PacketToPC.Address1 = (unsigned long)PROGRAM_MEM_START_ADDRESS;
|
||||||
|
PacketToPC.Length1 = (unsigned long)(PROGRAM_MEM_STOP_ADDRESS - PROGRAM_MEM_START_ADDRESS); //Size of program memory area
|
||||||
|
PacketToPC.Type2 = MEMORY_REGION_CONFIG;
|
||||||
|
PacketToPC.Address2 = (unsigned long)CONFIG_WORDS_START_ADDRESS;
|
||||||
|
PacketToPC.Length2 = (unsigned long)CONFIG_WORDS_SECTION_LENGTH;
|
||||||
|
PacketToPC.Type3 = MEMORY_REGION_USERID; //Not really program memory (User ID), but may be treated as it it was as far as the host is concerned
|
||||||
|
PacketToPC.Address3 = (unsigned long)USER_ID_ADDRESS;
|
||||||
|
PacketToPC.Length3 = (unsigned long)(USER_ID_SIZE);
|
||||||
|
PacketToPC.Type4 = MEMORY_REGION_END;
|
||||||
|
#if defined(DEVICE_WITH_EEPROM)
|
||||||
|
PacketToPC.Type4 = MEMORY_REGION_EEDATA;
|
||||||
|
PacketToPC.Address4 = (unsigned long)EEPROM_EFFECTIVE_ADDRESS;
|
||||||
|
PacketToPC.Length4 = (unsigned long)EEPROM_SIZE;
|
||||||
|
PacketToPC.Type5 = MEMORY_REGION_END;
|
||||||
|
#endif
|
||||||
|
PacketToPC.VersionFlag = BOOTLOADER_V1_01_OR_NEWER_FLAG;
|
||||||
|
//Init pad bytes to 0x00... Already done after we received the QUERY_DEVICE command (just after calling HIDRxReport()).
|
||||||
|
|
||||||
|
//Now send the packet to the USB host software, assuming the USB endpoint is available/ready to accept new data.
|
||||||
|
HIDTxReport((char *)&PacketToPC, USB_PACKET_SIZE);
|
||||||
|
BootState = IDLE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case UNLOCK_CONFIG:
|
||||||
|
ConfigsLockValue = TRUE;
|
||||||
|
if(PacketFromPC.LockValue == UNLOCKCONFIG)
|
||||||
|
{
|
||||||
|
ConfigsLockValue = FALSE;
|
||||||
|
}
|
||||||
|
BootState = IDLE;
|
||||||
|
break;
|
||||||
|
case ERASE_DEVICE:
|
||||||
|
//First erase main program flash memory
|
||||||
|
for(ErasePageTracker = START_PAGE_TO_ERASE; ErasePageTracker < (unsigned int)(MAX_PAGE_TO_ERASE + 1); ErasePageTracker++)
|
||||||
|
{
|
||||||
|
ClearWatchdog();
|
||||||
|
#ifdef __XC8__
|
||||||
|
TBLPTRU = 0x00;
|
||||||
|
TBLPTRH = (uint8_t)((uint24_t)ErasePageTracker >> 2);
|
||||||
|
TBLPTRL = (uint8_t)((uint24_t)ErasePageTracker << 6);
|
||||||
|
#else
|
||||||
|
TBLPTR = ErasePageTracker << 6;
|
||||||
|
#endif
|
||||||
|
EECON1 = 0b10010100; //Prepare for erasing flash memory
|
||||||
|
UnlockAndActivate(CORRECT_UNLOCK_KEY);
|
||||||
|
USBDeviceTasks(); //Call USBDeviceTasks() periodically to prevent falling off the bus if any SETUP packets should happen to arrive.
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(DEVICE_WITH_EEPROM)
|
||||||
|
//Now erase EEPROM (if any is present on the device)
|
||||||
|
i = EEPROM_EFFECTIVE_ADDRESS & (EEPROM_SIZE-1);
|
||||||
|
do{
|
||||||
|
EEADR = i;
|
||||||
|
EEDATA = 0xFF;
|
||||||
|
EECON1 = 0b00000100; //EEPROM Write mode
|
||||||
|
USBDeviceTasks(); //Call USBDeviceTasks() periodically to prevent falling off the bus if any SETUP packets should happen to arrive.
|
||||||
|
UnlockAndActivate(CORRECT_UNLOCK_KEY);
|
||||||
|
}while(i++<((EEPROM_SIZE-1)+(EEPROM_EFFECTIVE_ADDRESS & (EEPROM_SIZE-1))));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Now erase the User ID space (0x200000 to 0x200007)
|
||||||
|
//TBLPTR = USER_ID_ADDRESS;
|
||||||
|
TBLPTRU = 0x20;
|
||||||
|
TBLPTRH = 0x00;
|
||||||
|
TBLPTRL = (uint8_t)USER_ID_ADDRESS;
|
||||||
|
EECON1 = 0b10010100; //Prepare for erasing flash memory
|
||||||
|
UnlockAndActivate(CORRECT_UNLOCK_KEY);
|
||||||
|
|
||||||
|
BootState = IDLE;
|
||||||
|
break;
|
||||||
|
case PROGRAM_DEVICE:
|
||||||
|
//Check if host is trying to program the config bits
|
||||||
|
if(PacketFromPC.Contents[3] == 0x30) // //PacketFromPC.Contents[3] is bits 23:16 of the address.
|
||||||
|
{ //0x30 implies config bits
|
||||||
|
if(ConfigsLockValue == FALSE)
|
||||||
|
{
|
||||||
|
WriteConfigBits(); //Doesn't get reprogrammed if the UNLOCK_CONFIG (LockValue = UNLOCKCONFIG) command hasn't previously been sent
|
||||||
|
}
|
||||||
|
BootState = IDLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(DEVICE_WITH_EEPROM)
|
||||||
|
//Check if host is trying to program the EEPROM
|
||||||
|
if(PacketFromPC.Contents[3] == 0xF0) //PacketFromPC.Contents[3] is bits 23:16 of the address.
|
||||||
|
{ //0xF0 implies EEPROM
|
||||||
|
WriteEEPROM();
|
||||||
|
BootState = IDLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(ProgrammedPointer == (uint24_t)INVALID_ADDRESS)
|
||||||
|
ProgrammedPointer = PacketFromPC.Address;
|
||||||
|
|
||||||
|
if(ProgrammedPointer == (uint24_t)PacketFromPC.Address)
|
||||||
|
{
|
||||||
|
for(i = 0; i < PacketFromPC.Size; i++)
|
||||||
|
{
|
||||||
|
ProgrammingBuffer[BufferedDataIndex] = PacketFromPC.Data[i+(REQUEST_DATA_BLOCK_SIZE-PacketFromPC.Size)]; //Data field is right justified. Need to put it in the buffer left justified.
|
||||||
|
BufferedDataIndex++;
|
||||||
|
ProgrammedPointer++;
|
||||||
|
if(BufferedDataIndex == WRITE_BLOCK_SIZE)
|
||||||
|
{
|
||||||
|
WriteFlashBlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//else host sent us a non-contiguous packet address... to make
|
||||||
|
//this firmware simpler, host should not do this without sending
|
||||||
|
//a PROGRAM_COMPLETE command in between program sections.
|
||||||
|
BootState = IDLE;
|
||||||
|
break;
|
||||||
|
case PROGRAM_COMPLETE:
|
||||||
|
WriteFlashBlock();
|
||||||
|
ProgrammedPointer = INVALID_ADDRESS; //Reinitialize pointer to an invalid range, so we know the next PROGRAM_DEVICE will be the start address of a contiguous section.
|
||||||
|
BootState = IDLE;
|
||||||
|
break;
|
||||||
|
case GET_DATA:
|
||||||
|
//Init pad bytes to 0x00... Already done after we received the QUERY_DEVICE command (just after calling HIDRxReport()).
|
||||||
|
PacketToPC.Command = GET_DATA;
|
||||||
|
PacketToPC.Address = PacketFromPC.Address;
|
||||||
|
PacketToPC.Size = PacketFromPC.Size;
|
||||||
|
|
||||||
|
pROM = (ROM uint8_t*)PacketFromPC.Address;
|
||||||
|
for(i = 0; i < PacketFromPC.Size; i++)
|
||||||
|
{
|
||||||
|
if(PacketFromPC.Contents[3] == 0xF0) //PacketFromPC.Contents[3] is bits 23:16 of the address.
|
||||||
|
{ //0xF0 implies EEPROM, which doesn't use the table pointer to read from
|
||||||
|
#if defined(DEVICE_WITH_EEPROM)
|
||||||
|
EEADR = (((unsigned char)PacketFromPC.Address) + i); //The bits 7:0 are 1:1 mapped to the EEPROM address space values
|
||||||
|
EECON1 = 0b00000000; //EEPROM read mode
|
||||||
|
EECON1bits.RD = 1;
|
||||||
|
PacketToPC.Data[i+((USB_PACKET_SIZE - 6) - PacketFromPC.Size)] = EEDATA;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else //else must have been a normal program memory region, or one that can be read from with the table pointer
|
||||||
|
{
|
||||||
|
PacketToPC.Data[i+((USB_PACKET_SIZE - 6) - PacketFromPC.Size)] = *pROM++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Assuming the USB IN (to host) buffer is available/ready, copy the
|
||||||
|
//data over so it can get sent to the USB host software.
|
||||||
|
if(!mHIDTxIsBusy())
|
||||||
|
{
|
||||||
|
HIDTxReport((char *)&PacketToPC, USB_PACKET_SIZE);
|
||||||
|
BootState = IDLE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SIGN_FLASH:
|
||||||
|
SignFlash();
|
||||||
|
BootState = IDLE;
|
||||||
|
break;
|
||||||
|
case QUERY_EXTENDED_INFO:
|
||||||
|
//Prepare a response packet with the QUERY_EXTENDED_INFO response info in it.
|
||||||
|
//This command is only supported in bootloader firmware verison 1.01 or later.
|
||||||
|
//Make sure the regular QUERY_DEVIER reponse packet value "PacketToPC.Type6" is = BOOTLOADER_V1_01_OR_NEWER_FLAG;
|
||||||
|
//to let the host PC software know that the QUERY_EXTENDED_INFO command is implemented
|
||||||
|
//in this firmware and is available for requesting by the host software.
|
||||||
|
PacketToPC.Command = QUERY_EXTENDED_INFO; //Echo the command byte
|
||||||
|
PacketToPC.BootloaderVersion = ((unsigned int)BOOTLOADER_VERSION_MAJOR << 8)| BOOTLOADER_VERSION_MINOR;
|
||||||
|
PacketToPC.ApplicationVersion = *(ROM unsigned int*)APP_VERSION_ADDRESS;
|
||||||
|
PacketToPC.SignatureAddress = APP_SIGNATURE_ADDRESS;
|
||||||
|
PacketToPC.SignatureValue = APP_SIGNATURE_VALUE;
|
||||||
|
PacketToPC.ErasePageSize = ERASE_PAGE_SIZE;
|
||||||
|
PacketToPC.Config1LMask = 0xFF;
|
||||||
|
PacketToPC.Config1HMask = 0xFF;
|
||||||
|
PacketToPC.Config2LMask = 0xFF;
|
||||||
|
PacketToPC.Config2HMask = 0xFF;
|
||||||
|
PacketToPC.Config3LMask = 0x00;
|
||||||
|
PacketToPC.Config3HMask = 0xFF;
|
||||||
|
PacketToPC.Config4LMask = 0xFF;
|
||||||
|
PacketToPC.Config4HMask = 0x00;
|
||||||
|
PacketToPC.Config5LMask = 0xFF;
|
||||||
|
PacketToPC.Config5HMask = 0xFF;
|
||||||
|
PacketToPC.Config6LMask = 0xFF;
|
||||||
|
PacketToPC.Config6HMask = 0xFF;
|
||||||
|
PacketToPC.Config7LMask = 0xFF;
|
||||||
|
PacketToPC.Config7HMask = 0xFF;
|
||||||
|
|
||||||
|
//Now actually command USB to send the packet to the host
|
||||||
|
if(!mHIDTxIsBusy())
|
||||||
|
{
|
||||||
|
HIDTxReport((char *)&PacketToPC, USB_PACKET_SIZE);
|
||||||
|
BootState = IDLE; //Packet will be sent, go back to idle state ready for next command from host
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RESET_DEVICE:
|
||||||
|
ResetDeviceCleanly();
|
||||||
|
//break; //no need, commented to save space
|
||||||
|
default:
|
||||||
|
//Should never hit the default
|
||||||
|
BootState = IDLE;
|
||||||
|
}//End switch
|
||||||
|
}//End of else of if(BootState == IDLE)
|
||||||
|
|
||||||
|
}//End ProcessIO()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Should be called once, only after the regular erase/program/verify sequence
|
||||||
|
//has completed successfully. This function will program the magic
|
||||||
|
//APP_SIGNATURE_VALUE into the magic APP_SIGNATURE_ADDRESS in the application
|
||||||
|
//flash memory space. This is used on the next bootup to know that the the
|
||||||
|
//flash memory image of the application is intact, and can be executed.
|
||||||
|
//This is useful for recovery purposes, in the event that an unexpected
|
||||||
|
//failure occurs during the erase/program sequence (ex: power loss or user
|
||||||
|
//unplugging the USB cable).
|
||||||
|
void SignFlash(void)
|
||||||
|
{
|
||||||
|
static unsigned char i;
|
||||||
|
static ROM uint8_t* pROM;
|
||||||
|
|
||||||
|
//First read in the erase page contents of the page with the signature WORD
|
||||||
|
//in it, and temporarily store it in a RAM buffer.
|
||||||
|
pROM = (ROM uint8_t*)(APP_SIGNATURE_ADDRESS & ERASE_PAGE_ADDRESS_MASK);
|
||||||
|
for(i = 0; i < ERASE_PAGE_SIZE; i++)
|
||||||
|
{
|
||||||
|
ProgrammingBuffer[i] = *pROM++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Now change the signature WORD value at the correct address in the RAM buffer
|
||||||
|
ProgrammingBuffer[(APP_SIGNATURE_ADDRESS & ~ERASE_PAGE_ADDRESS_MASK)] = (unsigned char)APP_SIGNATURE_VALUE;
|
||||||
|
ProgrammingBuffer[(APP_SIGNATURE_ADDRESS & ~ERASE_PAGE_ADDRESS_MASK) + 1] = (unsigned char)(APP_SIGNATURE_VALUE >> 8);
|
||||||
|
|
||||||
|
//Now erase the flash memory block with the signature WORD in it
|
||||||
|
//TBLPTR = APP_SIGNATURE_ADDRESS & ERASE_PAGE_ADDRESS_MASK;
|
||||||
|
TBLPTRU = (uint8_t)((APP_SIGNATURE_ADDRESS & ERASE_PAGE_ADDRESS_MASK) >> 16);
|
||||||
|
TBLPTRH = (uint8_t)((APP_SIGNATURE_ADDRESS & ERASE_PAGE_ADDRESS_MASK) >> 8);
|
||||||
|
TBLPTRL = (uint8_t)(APP_SIGNATURE_ADDRESS & ERASE_PAGE_ADDRESS_MASK);
|
||||||
|
|
||||||
|
EECON1 = 0x94; //Prepare for flash erase operation
|
||||||
|
UnlockAndActivate(CORRECT_UNLOCK_KEY);
|
||||||
|
|
||||||
|
//Now re-program the values from the RAM buffer into the flash memory. Use
|
||||||
|
//reverse order, so we program the larger addresses first. This way, the
|
||||||
|
//write page with the flash signature word is the last page that gets
|
||||||
|
//programmed (assuming the flash signature resides on the lowest address
|
||||||
|
//write page, which is recommended, so that it becomes the first page
|
||||||
|
//erased, and the last page programmed).
|
||||||
|
pROM = (ROM uint8_t*)((APP_SIGNATURE_ADDRESS & ERASE_PAGE_ADDRESS_MASK) + ERASE_PAGE_SIZE - 1); //Point to last byte on the erase page
|
||||||
|
//TBLPTR = (APP_SIGNATURE_ADDRESS & ERASE_PAGE_ADDRESS_MASK) + ERASE_PAGE_SIZE - 1; //Point to last byte on the erase page
|
||||||
|
i = ERASE_PAGE_SIZE - 1;
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
#ifdef __XC8__
|
||||||
|
TBLPTRU = (uint32_t)pROM >> 16;
|
||||||
|
TBLPTRH = (uint16_t)pROM >> 8;
|
||||||
|
TBLPTRL = (uint8_t)pROM;
|
||||||
|
#else
|
||||||
|
TBLPTR = (uint24_t)pROM;
|
||||||
|
#endif
|
||||||
|
TABLAT = ProgrammingBuffer[i];
|
||||||
|
|
||||||
|
#ifdef __XC8__
|
||||||
|
#asm
|
||||||
|
tblwt
|
||||||
|
#endasm
|
||||||
|
#else //must be C18 instead
|
||||||
|
_asm tblwt _endasm
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Check if we are at a program write block size boundary
|
||||||
|
if((i % WRITE_BLOCK_SIZE) == 0)
|
||||||
|
{
|
||||||
|
//The write latches are full, time to program the block.
|
||||||
|
ClearWatchdog();
|
||||||
|
EECON1 = 0xA4; //Write to flash on next WR = 1 operation
|
||||||
|
UnlockAndActivate(CORRECT_UNLOCK_KEY);
|
||||||
|
}
|
||||||
|
//Move ROM pointer back to next location
|
||||||
|
pROM--;
|
||||||
|
#ifdef __XC8__
|
||||||
|
#asm
|
||||||
|
tblrdpostdec
|
||||||
|
#endasm
|
||||||
|
#else //must be C18 instead
|
||||||
|
_asm tblrdpostdec _endasm
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Check if we are done writing all blocks
|
||||||
|
if(i == 0)
|
||||||
|
{
|
||||||
|
break; //Exit while loop
|
||||||
|
}
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Before resetting the microcontroller, we should shut down the USB module
|
||||||
|
//gracefully, to make sure the host correctly recognizes that we detached
|
||||||
|
//from the bus. Some USB hosts malfunction/fail to re-enumerate the device
|
||||||
|
//correctly if the USB device does not stay detached for a minimum amount of
|
||||||
|
//time before re-attaching to the USB bus. For reliable operation, the USB
|
||||||
|
//device should stay detached for as long as a human would require to unplug and
|
||||||
|
//reattach a USB device (ex: 100ms+), to ensure the USB host software has a
|
||||||
|
//chance to process the detach event and configure itself for a state ready for
|
||||||
|
//a new attachment event.
|
||||||
|
void ResetDeviceCleanly(void)
|
||||||
|
{
|
||||||
|
USBDisableWithLongDelay();
|
||||||
|
Reset();
|
||||||
|
Nop();
|
||||||
|
Nop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Routine used to write data to the flash memory from the ProgrammingBuffer[].
|
||||||
|
void WriteFlashBlock(void) //Use to write blocks of data to flash.
|
||||||
|
{
|
||||||
|
static unsigned char i;
|
||||||
|
static unsigned char BytesTakenFromBuffer;
|
||||||
|
static unsigned char CorrectionFactor;
|
||||||
|
|
||||||
|
#ifdef __XC8__
|
||||||
|
static ROM uint8_t* pROM;
|
||||||
|
|
||||||
|
pROM = (ROM uint8_t*)(ProgrammedPointer - BufferedDataIndex);
|
||||||
|
TBLPTRU = 0x00;
|
||||||
|
TBLPTRH = (uint8_t)((uint16_t)pROM >> 8);
|
||||||
|
TBLPTRL = (uint8_t)pROM;
|
||||||
|
#else
|
||||||
|
TBLPTR = (ProgrammedPointer - BufferedDataIndex);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BytesTakenFromBuffer = 0;
|
||||||
|
|
||||||
|
//Check the lower 5 bits of the TBLPTR to verify it is pointing to a 32 byte aligned block (5 LSb = 00000).
|
||||||
|
//If it isn't, need to somehow make it so before doing the actual loading of the programming latches.
|
||||||
|
//In order to maximize programming speed, the PC application meant to be used with this firmware will not send
|
||||||
|
//large blocks of 0xFF bytes. If the PC application
|
||||||
|
//detects a large block of unprogrammed space in the hex file (effectively = 0xFF), it will skip over that
|
||||||
|
//section and will not send it to the firmware. This works, because the firmware will have already done an
|
||||||
|
//erase on that section of memory when it received the ERASE_DEVICE command from the PC. Therefore, the section
|
||||||
|
//can be left unprogrammed (after an erase the flash ends up = 0xFF).
|
||||||
|
//This can result in a problem however, in that the next genuine non-0xFF section in the hex file may not start
|
||||||
|
//on a 32 byte aligned block boundary. This needs to be handled with care since the microcontroller can only
|
||||||
|
//program 32 byte blocks that are aligned with 32 byte boundaries.
|
||||||
|
//So, use the below code to avoid this potential issue.
|
||||||
|
|
||||||
|
#if(WRITE_BLOCK_SIZE == 0x20)
|
||||||
|
CorrectionFactor = (TBLPTRL & 0b00011111); //Correctionfactor = number of bytes tblptr must go back to find the immediate preceeding 32 byte boundary
|
||||||
|
TBLPTRL &= 0b11100000; //Move the table pointer back to the immediately preceeding 32 byte boundary
|
||||||
|
#elif(WRITE_BLOCK_SIZE == 0x10)
|
||||||
|
CorrectionFactor = (TBLPTRL & 0b00001111); //Correctionfactor = number of bytes tblptr must go back to find the immediate preceeding 16 byte boundary
|
||||||
|
TBLPTRL &= 0b11110000; //Move the table pointer back to the immediately preceeding 16 byte boundary
|
||||||
|
#elif(WRITE_BLOCK_SIZE == 0x8)
|
||||||
|
CorrectionFactor = (TBLPTRL & 0b00000111); //Correctionfactor = number of bytes tblptr must go back to find the immediate preceeding 16 byte boundary
|
||||||
|
TBLPTRL &= 0b11111000; //Move the table pointer back to the immediately preceeding 16 byte boundary
|
||||||
|
#else
|
||||||
|
#warning "Double click this error message and fix this section for your microcontroller type."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for(i = 0; i < WRITE_BLOCK_SIZE; i++) //Load the programming latches
|
||||||
|
{
|
||||||
|
if(CorrectionFactor == 0)
|
||||||
|
{
|
||||||
|
if(BufferedDataIndex != 0) //If the buffer isn't empty
|
||||||
|
{
|
||||||
|
TABLAT = ProgrammingBuffer[BytesTakenFromBuffer];
|
||||||
|
#ifdef __XC8__
|
||||||
|
#asm
|
||||||
|
tblwtpostinc
|
||||||
|
#endasm
|
||||||
|
#else //must be C18 instead
|
||||||
|
_asm tblwtpostinc _endasm
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BytesTakenFromBuffer++;
|
||||||
|
BufferedDataIndex--; //Used up a byte from the buffer.
|
||||||
|
}
|
||||||
|
else //No more data in buffer, need to write 0xFF to fill the rest of the programming latch locations
|
||||||
|
{
|
||||||
|
TABLAT = 0xFF;
|
||||||
|
#ifdef __XC8__
|
||||||
|
#asm
|
||||||
|
tblwtpostinc
|
||||||
|
#endasm
|
||||||
|
#else //must be C18 instead
|
||||||
|
_asm tblwtpostinc _endasm
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TABLAT = 0xFF;
|
||||||
|
#ifdef __XC8__
|
||||||
|
#asm
|
||||||
|
tblwtpostinc
|
||||||
|
#endasm
|
||||||
|
#else //must be C18 instead
|
||||||
|
_asm tblwtpostinc _endasm
|
||||||
|
#endif
|
||||||
|
CorrectionFactor--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TBLPTR--; //Need to make table pointer point to the region which will be programmed before initiating the programming operation
|
||||||
|
#ifdef __XC8__
|
||||||
|
#asm
|
||||||
|
tblrdpostdec
|
||||||
|
#endasm
|
||||||
|
#else //must be C18 instead
|
||||||
|
_asm tblrdpostdec _endasm //Do this instead of TBLPTR--; since it takes less code space.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EECON1 = 0b10100100; //flash programming mode
|
||||||
|
UnlockAndActivate(CORRECT_UNLOCK_KEY);
|
||||||
|
|
||||||
|
//Now need to fix the ProgrammingBuffer[]. We may not have taken a full 32 bytes out of the buffer. In this case,
|
||||||
|
//the data is no longer justified correctly.
|
||||||
|
for(i = 0; i < BufferedDataIndex; i++) //Need to rejustify the remaining data to the "left" of the buffer (if there is any left)
|
||||||
|
{
|
||||||
|
ProgrammingBuffer[i] = ProgrammingBuffer[BytesTakenFromBuffer+i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WriteConfigBits(void) //Also used to write the Device ID
|
||||||
|
{
|
||||||
|
static unsigned char i;
|
||||||
|
|
||||||
|
#ifdef __XC8__
|
||||||
|
TBLPTRU = 0x30;
|
||||||
|
TBLPTRH = (uint8_t)((uint16_t)PacketFromPC.Address >> 8);
|
||||||
|
TBLPTRH = (uint8_t)(PacketFromPC.Address);
|
||||||
|
#else
|
||||||
|
TBLPTR = (uint24_t)PacketFromPC.Address;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for(i = 0; i < PacketFromPC.Size; i++)
|
||||||
|
{
|
||||||
|
TABLAT = PacketFromPC.Data[i+(REQUEST_DATA_BLOCK_SIZE-PacketFromPC.Size)];
|
||||||
|
#ifdef __XC8__
|
||||||
|
#asm
|
||||||
|
tblwt
|
||||||
|
#endasm
|
||||||
|
#else //must be C18 instead
|
||||||
|
_asm tblwt _endasm
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EECON1 = 0b11000100; //Config bits programming mode
|
||||||
|
UnlockAndActivate(CORRECT_UNLOCK_KEY);
|
||||||
|
|
||||||
|
#ifdef __XC8__
|
||||||
|
#asm
|
||||||
|
tblrdpostinc
|
||||||
|
#endasm
|
||||||
|
#else //must be C18 instead
|
||||||
|
_asm tblrdpostinc _endasm
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(DEVICE_WITH_EEPROM)
|
||||||
|
void WriteEEPROM(void)
|
||||||
|
{
|
||||||
|
static unsigned char i;
|
||||||
|
|
||||||
|
for(i = 0; i < PacketFromPC.Size; i++)
|
||||||
|
{
|
||||||
|
EEADR = (((unsigned char)PacketFromPC.Address) + i);
|
||||||
|
EEDATA = PacketFromPC.Data[i+(REQUEST_DATA_BLOCK_SIZE-PacketFromPC.Size)];
|
||||||
|
|
||||||
|
EECON1 = 0b00000100; //EEPROM Write mode
|
||||||
|
UnlockAndActivate(CORRECT_UNLOCK_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//It is preferrable to only place this sequence in only one place in the flash memory.
|
||||||
|
//This reduces the probabilty of the code getting executed inadvertently by
|
||||||
|
//errant code. It is also recommended to enable BOR (in hardware) and/or add
|
||||||
|
//software checks to avoid microcontroller "overclocking". Always make sure
|
||||||
|
//to obey the voltage versus frequency graph in the datasheet, even during
|
||||||
|
//momentary events (such as the power up and power down ramp of the microcontroller).
|
||||||
|
void UnlockAndActivate(unsigned char UnlockKey)
|
||||||
|
{
|
||||||
|
INTCONbits.GIE = 0; //Make certain interrupts disabled for unlock process.
|
||||||
|
|
||||||
|
//Check to make sure the caller really was trying to call this function.
|
||||||
|
//If they were, they should always pass us the CORRECT_UNLOCK_KEY.
|
||||||
|
if(UnlockKey != CORRECT_UNLOCK_KEY)
|
||||||
|
{
|
||||||
|
//Warning! Errant code execution detected. Somehow this
|
||||||
|
//UnlockAndActivate() function got called by someone that wasn't trying
|
||||||
|
//to actually perform an NVM erase or write. This could happen due to
|
||||||
|
//microcontroller overclocking (or undervolting for an otherwise allowed
|
||||||
|
//CPU frequency), or due to buggy code (ex: incorrect use of function
|
||||||
|
//pointers, etc.). In either case, we should execute some fail safe
|
||||||
|
//code here to prevent corruption of the NVM contents.
|
||||||
|
OSCCON = 0x03; //Switch to INTOSC at low frequency
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
Sleep();
|
||||||
|
}
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __XC8__
|
||||||
|
EECON2 = 0x55;
|
||||||
|
EECON2 = 0xAA;
|
||||||
|
EECON1bits.WR = 1;
|
||||||
|
#else
|
||||||
|
_asm
|
||||||
|
//Now unlock sequence to set WR (make sure interrupts are disabled before executing this)
|
||||||
|
MOVLW 0x55
|
||||||
|
MOVWF EECON2, 0
|
||||||
|
MOVLW 0xAA
|
||||||
|
MOVWF EECON2, 0
|
||||||
|
BSF EECON1, 1, 0 //Performs write by setting WR bit
|
||||||
|
_endasm
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while(EECON1bits.WR); //Wait until complete (relevant when programming EEPROM, not important when programming flash since processor stalls during flash program)
|
||||||
|
EECON1bits.WREN = 0; //Good practice now to clear the WREN bit, as further protection against any accidental activation of self write/erase operations.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Note: The ClrWdt() and "_asm tblrdpostinc _endasm" are inline assembly language
|
||||||
|
//instructions. The ClearWatchdog() and TableReadPostIncrement() functions are
|
||||||
|
//theoretically extraneous, since the operations being accomplished could be
|
||||||
|
//done without calling them as separate functions. However, when using inline
|
||||||
|
//assembly language, the C18 compiler normally doesn't know what the code will
|
||||||
|
//actually do (ex: will it modify STATUS reg, WREG, BSR contents??). As a
|
||||||
|
//result, it is potentially dangerous for the C compiler to make assumptions,
|
||||||
|
//that might turn out not to be correct. Therefore, the C18 compiler disables
|
||||||
|
//the compiler optimizations for a function, when one or more inline asm
|
||||||
|
//instructions are located within the C function. Therefore, to promote best
|
||||||
|
//code size optimizations from the C18 compiler, it is best to locate inline
|
||||||
|
//assembly sequences in their own separate C functions, that do not contain much
|
||||||
|
//other code (which could otherwise be optimized by the C compiler). This often
|
||||||
|
//results in the smallest code size, and is the reason it is being done here.
|
||||||
|
void TableReadPostIncrement(void)
|
||||||
|
{
|
||||||
|
#ifdef __XC8__
|
||||||
|
#asm
|
||||||
|
tblrdpostinc
|
||||||
|
#endasm
|
||||||
|
#else //must be C18 instead
|
||||||
|
_asm tblrdpostinc _endasm
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** EOF BootPIC18NonJ.c *********************************************************/
|
||||||
41
bootloader_hacked_from_mla/src/BootPIC18NonJ.h
Normal file
41
bootloader_hacked_from_mla/src/BootPIC18NonJ.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
Copyright 2016 Microchip Technology Inc. (www.microchip.com)
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
To request to license the code under the MLA license (www.microchip.com/mla_license),
|
||||||
|
please contact mla_licensing@microchip.com
|
||||||
|
*******************************************************************************/
|
||||||
|
#ifndef BOOTPIC18NONJ_H
|
||||||
|
#define BOOTPIC18NONJ_H
|
||||||
|
|
||||||
|
/** P U B L I C P R O T O T Y P E S *****************************************/
|
||||||
|
void UserInit(void);
|
||||||
|
void ProcessIO(void);
|
||||||
|
void ClearWatchdog(void);
|
||||||
|
void DisableUSBandExecuteLongDelay(void);
|
||||||
|
|
||||||
|
|
||||||
|
//Vector remapping/absolute address constants
|
||||||
|
#define REMAPPED_APPLICATION_RESET_VECTOR 0x1400
|
||||||
|
//#define REMAPPED_APPLICATION_HIGH_ISR_VECTOR 0x1408 //See VectorRemap.asm
|
||||||
|
//#define REMAPPED_APPLICATION_LOW_ISR_VECTOR 0x1418 //See VectorRemap.asm
|
||||||
|
#define BOOTLOADER_ABSOLUTE_ENTRY_ADDRESS 0x001C //Execute a "goto 0x001C" inline assembly instruction, if you want to enter the bootloader mode from the application via software
|
||||||
|
|
||||||
|
#define APP_SIGNATURE_ADDRESS 0x1406 //0x1006 and 0x1007 contains the "signature" WORD, indicating successful erase/program/verify operation
|
||||||
|
#define APP_SIGNATURE_VALUE 0x600D //leet "GOOD", implying that the erase/program was a success and the bootloader intentionally programmed the APP_SIGNATURE_ADDRESS with this value
|
||||||
|
#define APP_VERSION_ADDRESS 0x1416 //0x1016 and 0x1017 should contain the application image firmware version number
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif //BOOTPIC18NONJ_H
|
||||||
30
bootloader_hacked_from_mla/src/HardwareProfile.h
Normal file
30
bootloader_hacked_from_mla/src/HardwareProfile.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
Copyright 2016 Microchip Technology Inc. (www.microchip.com)
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
To request to license the code under the MLA license (www.microchip.com/mla_license),
|
||||||
|
please contact mla_licensing@microchip.com
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __HARDWARE_PROFILE_H_
|
||||||
|
#define __HARDWARE_PROFILE_H_
|
||||||
|
|
||||||
|
|
||||||
|
/** I N C L U D E S *************************************************/
|
||||||
|
#include "usb_config.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif //__HARDWARE_PROFILE_H_
|
||||||
39
bootloader_hacked_from_mla/src/VectorRemap.asm
Normal file
39
bootloader_hacked_from_mla/src/VectorRemap.asm
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
;/*******************************************************************************
|
||||||
|
;Copyright 2016 Microchip Technology Inc. (www.microchip.com)
|
||||||
|
;
|
||||||
|
;Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
;you may not use this file except in compliance with the License.
|
||||||
|
;You may obtain a copy of the License at
|
||||||
|
;
|
||||||
|
; http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
;
|
||||||
|
;Unless required by applicable law or agreed to in writing, software
|
||||||
|
;distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
;See the License for the specific language governing permissions and
|
||||||
|
;limitations under the License.
|
||||||
|
;
|
||||||
|
;To request to license the code under the MLA license (www.microchip.com/mla_license),
|
||||||
|
;please contact mla_licensing@microchip.com
|
||||||
|
;*******************************************************************************/
|
||||||
|
|
||||||
|
;//High priority interrupt vector remapping
|
||||||
|
#ifdef __XC8__
|
||||||
|
PSECT HiVector,class=CODE,delta=1,abs
|
||||||
|
#endif
|
||||||
|
org 0x08
|
||||||
|
goto 0x1408 ;Resides at 0x0008 (hardware high priority interrupt vector), and causes PC to jump to 0x1408 upon a high priority interrupt event
|
||||||
|
|
||||||
|
|
||||||
|
;//Low priority interrupt vector remapping, as well as bootloader mode absolute
|
||||||
|
;//entry point (located at 0x001C).
|
||||||
|
#ifdef __XC8__
|
||||||
|
PSECT LoVector,class=CODE,delta=1,abs
|
||||||
|
#endif
|
||||||
|
org 0x18
|
||||||
|
goto 0x1418 ;Resides at 0x0018 (hardware low priority interrupt vector), and causes PC to jump to 0x1418 upon a low priority interrupt event
|
||||||
|
goto 0x30 ;Resides at 0x001C //Serves as absolute entry point from application program into the bootloader mode
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
626
bootloader_hacked_from_mla/src/main.c
Normal file
626
bootloader_hacked_from_mla/src/main.c
Normal file
@@ -0,0 +1,626 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
Copyright 2016 Microchip Technology Inc. (www.microchip.com)
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
To request to license the code under the MLA license (www.microchip.com/mla_license),
|
||||||
|
please contact mla_licensing@microchip.com
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
IMPORTANT NOTES: This code can be readily adapted for use with the
|
||||||
|
both the F and LF versions of the following devices:
|
||||||
|
|
||||||
|
PIC18F4553/4458/2553/2458
|
||||||
|
PIC18F4550/4455/2550/2455
|
||||||
|
PIC18F4450/2450
|
||||||
|
PIC18F14K50/13K50
|
||||||
|
PIC18F45K50/25K50/24K50
|
||||||
|
|
||||||
|
However, the default device that is currently selected in the project
|
||||||
|
may not be the device you are interested. To change the device:
|
||||||
|
|
||||||
|
Replace the linker script with an appropriate version, and
|
||||||
|
click "Configure --> Select Device" and select the proper
|
||||||
|
microcontroller. Also double check to verify that the HardwareProfile.h and
|
||||||
|
usb_config.h are properly configured to match your desired application
|
||||||
|
platform.
|
||||||
|
|
||||||
|
Verify that the configuration bits are set correctly for the intended
|
||||||
|
target application, and fix any build errors that result from either
|
||||||
|
the #error directives, or due to I/O pin count mismatch issues (such
|
||||||
|
as when using a 28-pin device, but without making sufficient changes
|
||||||
|
to the HardwareProfile.h file)
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
NOTE FOR BUILDING WITH C18 COMPILER:
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
This project needs to be built with the full compiler optimizations
|
||||||
|
enabled, and using the Default storage class "Static" or the total
|
||||||
|
code size will be too large to fit within the program memory
|
||||||
|
range 0x000-0xFFF. The default linker script included
|
||||||
|
in the project has this range reserved for the use by the bootloader,
|
||||||
|
but marks the rest of program memory as "PROTECTED". If you try to
|
||||||
|
build this project with the compiler optimizations turned off, or
|
||||||
|
you try to modify some of this code, but add too much code to fit
|
||||||
|
within the 0x000-0xFFF region, a linker error like that below may occur:
|
||||||
|
|
||||||
|
Error - section '.code' can not fit the section. Section '.code' length=0x00000020
|
||||||
|
To fix this error, either optimize the program to fit within 0x000-0xFFF
|
||||||
|
(such as by turning on all compiler optimizations, and making sure the
|
||||||
|
"default storage class" is set to "Static"), or modify the linker
|
||||||
|
and vector remapping (as well as the application projects) to allow this
|
||||||
|
bootloader to use more program memory.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
NOTE FOR BUILDING THIS BOOTLOADER FIRMWARE WITH THE XC8 COMPILER:
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
To build this code with the XC8 compiler, make sure to use the linker
|
||||||
|
option:
|
||||||
|
ROM ranges: default,-1000-XXXXXX //Where "XXXXXX" is the last implemented flash memory
|
||||||
|
address, excluding the config bit region (ex: "default,-1000-7FFF" for the 32kB PIC18F45K50)
|
||||||
|
This setting is found in the XC8 compiler linker settings, Option category: Memory Model.
|
||||||
|
|
||||||
|
If any errors are encountered relating to "cannot find space", this
|
||||||
|
presumably means that either the compiler was configured to build the
|
||||||
|
code in Free or Standard mode, or that modifications have been made to
|
||||||
|
the code that have increased the code size to exceed the 0x000-0xFFF program
|
||||||
|
memory region. If this error is encountered, make sure to build the project
|
||||||
|
with all PRO mode optimizations enabled, and/or optimize any user added code
|
||||||
|
that is causing the project size to exceed the 0x000-0xFFF region.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
NOTE FOR BUILDING APPLICATION FIRMWARE PROJECTS WITH THE XC8 COMPILER:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
When building the application project that is meant to be programmed by this
|
||||||
|
bootloader, you must use different XC8 linker settings as this project.
|
||||||
|
For application projects, two linker settings are required:
|
||||||
|
|
||||||
|
ROM ranges: default,-0-FFF,-1006-1007,-1016-1017
|
||||||
|
Codeoffset: 0x1000
|
||||||
|
|
||||||
|
When the above settings are implemented, the application firmware will no longer work
|
||||||
|
without the bootloader present. Therefore, it is recommended to add the bootloader
|
||||||
|
firmware output (from this bootloader project) .hex file as a "Loadable" into
|
||||||
|
the application firmware project. This will allow the "HEXMATE" tool to run
|
||||||
|
after building the application firmware project, which will merge the application
|
||||||
|
output .hex file contents with the bootloader output .hex file contents (which was
|
||||||
|
added as a loadable file).
|
||||||
|
|
||||||
|
However, in some cases you may encounter build errors during the hex merge operation.
|
||||||
|
This will occur if there are any overlapping regions in the bootloader firmware
|
||||||
|
.hex file, with the application firmware .hex file, when the contents of these
|
||||||
|
overlapping regions are not 100% exact matches to each other. Normally, only the
|
||||||
|
configuration bit settings will be overlapping between the two projects.
|
||||||
|
|
||||||
|
Therefore, to prevent build errors, the configuration bit settings between the
|
||||||
|
bootloader firmware project and the application firmware project must be set to
|
||||||
|
100% exactly identical values (or they must only be set in one of the projects,
|
||||||
|
to eliminate the overlapping region altogether).
|
||||||
|
|
||||||
|
|
||||||
|
----------------------Bootloader Entry------------------------------------------
|
||||||
|
Entry into this bootloader firmware can be done by either of two possible
|
||||||
|
ways:
|
||||||
|
|
||||||
|
1. I/O pin check at power up/after any reset. and/or:
|
||||||
|
2. Software entry via absolute jump to address 0x001C.
|
||||||
|
|
||||||
|
The I/O pin check method is the most rugged, since it does not require the
|
||||||
|
application firmware image to be intact (at all) to get into the bootloader
|
||||||
|
mode. However, software entry is also possible and may be more convenient
|
||||||
|
in applications that do not have user exposed pushbuttons available.
|
||||||
|
|
||||||
|
When the "application" image is executing, it may optionally jump into
|
||||||
|
bootloader mode, by executing a _asm goto 0x001C _endasm instruction.
|
||||||
|
Before doing so however, the firwmare should configure the current
|
||||||
|
clock settings to be compatible with USB module operation, in they
|
||||||
|
are not already. Once the goto 0x001C has been executed the USB device
|
||||||
|
will detach from the USB bus (if it was previously attached), and will
|
||||||
|
re-enumerate as a HID class device with a new VID/PID (adjustable via
|
||||||
|
usb_dsc.c settings), which can communicate with the associated
|
||||||
|
USB host software that loads and programs the new .hex file.
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
Anytime that an application implements flash self erase/write capability,
|
||||||
|
special care should be taken to make sure that the microcontroller is operated
|
||||||
|
within all datasheet ratings, especially those associated with voltage versus
|
||||||
|
frequency.
|
||||||
|
|
||||||
|
Operating the device at too high of a frequency (for a given voltage, ex: by
|
||||||
|
operating at 48MHz at 2.1V, while the device datasheet indicates some higher
|
||||||
|
value such as 2.35V+ is required) can cause unexpected code operation. This
|
||||||
|
could potentially allow inadvertent execution of bootloader or other self
|
||||||
|
erase/write routines, causing corruption of the flash memory of the application.
|
||||||
|
|
||||||
|
To avoid this, all applications that implement self erase/write capability
|
||||||
|
should make sure to prevent execution during overclocked/undervolted conditions.
|
||||||
|
|
||||||
|
For this reason, enabling and using the microcontroller hardware Brown-out-Reset
|
||||||
|
feature is particularly recommended for applications using a bootloader. If
|
||||||
|
BOR is not used, or the trip threshold is too low for the intended application
|
||||||
|
frequency, it is suggested to add extra code in the application to detect low
|
||||||
|
voltage conditions, and to intentionally clock switch to a lower frequency
|
||||||
|
(or put the device to sleep) during the low voltage condition. Hardware
|
||||||
|
modules such as the ADC, comparators, or the HLVD (high/low voltage detect)
|
||||||
|
can often be used for this purpose.
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
This bootloader supports reprogramming of the microcontroller configuration bits,
|
||||||
|
however, it is strongly recommended never to do so, unless absolutely necessary.
|
||||||
|
Reprogramming the config bits is potentially risky, since it requires that the
|
||||||
|
new configuration bits be 100% compatible with USB operation (ex: oscillator
|
||||||
|
settings, etc.). If a .hex file with incorrect config bits is programmed
|
||||||
|
into this device, it can render the bootloader inoperable. Additionally,
|
||||||
|
unexpected power failure or device detachment during the reprogramming of the
|
||||||
|
config bits could result in unknown values getting stored in the config bits,
|
||||||
|
which could "brick" the application.
|
||||||
|
|
||||||
|
Normally, the application firmware project and this bootloader project should
|
||||||
|
be configured to use/set the exact same configuration bit values. Only one set
|
||||||
|
of configuration bits actually exists in the microcontroller, and these values
|
||||||
|
must be shared between the bootloader and application firmware.
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** I N C L U D E S **********************************************************/
|
||||||
|
#include "usb.h"
|
||||||
|
#include "HardwareProfile.h"
|
||||||
|
#include "BootPIC18NonJ.h"
|
||||||
|
|
||||||
|
/** V A R I A B L E S ********************************************************/
|
||||||
|
//NOTE: You must not use initalized variables in this bootloader project. This
|
||||||
|
//firmware project does not rely on the standard C initializer, which is
|
||||||
|
//responsible for setting up initialized variables in RAM. Therefore, all
|
||||||
|
//variables will be non-initialized/random at start up.
|
||||||
|
#ifndef __XC8__
|
||||||
|
#pragma udata
|
||||||
|
#endif
|
||||||
|
unsigned int uint_delay_counter;
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
//Private prototypes
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void main(void);
|
||||||
|
void BootMain(void);
|
||||||
|
void LowVoltageCheck(void);
|
||||||
|
void InitializeSystem(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Special "flash signature" located in the application program memory space (not
|
||||||
|
//part of the bootloader firmware program space). This flash signature is used
|
||||||
|
//to improve application recoverability/robustness, in the event the user unplugs
|
||||||
|
//the USB cable or AC power is lost during an erase/program/verify sequence.
|
||||||
|
#ifdef __XC8__
|
||||||
|
const unsigned int __at(APP_SIGNATURE_ADDRESS) FlashSignatureWord = APP_SIGNATURE_VALUE;
|
||||||
|
#else
|
||||||
|
#pragma romdata FLASH_SIG_SECTION = APP_SIGNATURE_ADDRESS
|
||||||
|
ROM unsigned int FlashSignatureWord = APP_SIGNATURE_VALUE;
|
||||||
|
#pragma code
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//Special handling for modified linker script.
|
||||||
|
#ifndef __XC8__
|
||||||
|
//Note: This project uses a modified linker script, which does not include the
|
||||||
|
//c018i.o standard C initializer for C18 projects. Therefore, we must manually
|
||||||
|
//place a goto main() at the hardware reset vector.
|
||||||
|
#pragma code _entry_scn=0x000000 //Reset vector is at 0x00. Device begins executing code from 0x00 after a reset or POR event
|
||||||
|
void _entry (void)
|
||||||
|
{
|
||||||
|
_asm goto main _endasm
|
||||||
|
}
|
||||||
|
#pragma code
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Function: void main(void)
|
||||||
|
*
|
||||||
|
* PreCondition: None
|
||||||
|
*
|
||||||
|
* Input: None
|
||||||
|
*
|
||||||
|
* Output: None
|
||||||
|
*
|
||||||
|
* Side Effects: None
|
||||||
|
*
|
||||||
|
* Overview: This is the first code that executes during boot up of
|
||||||
|
* the microcontroller. This code checks to see if execution
|
||||||
|
* should stay in the "bootloader" mode, or if it should jump
|
||||||
|
* into the "application" (non-bootloder) execution mode.
|
||||||
|
* No other unrelated code should be added to this function.
|
||||||
|
*
|
||||||
|
* Note: THIS FUNCTION EXECUTES PRIOR TO INITIALIZATION OF THE C
|
||||||
|
* STACK. NO C INITIALIZATION OF STATIC VARIABLES OR RESOURCES
|
||||||
|
* WILL OCCUR, PRIOR TO EXECUTING THIS FUNCTION. THEREFORE,
|
||||||
|
* THE CODE IN THIS FUNCTION MUST NOT CALL OTHER FUNCTIONS OR
|
||||||
|
* PERFORM ANY OPERATIONS THAT WILL REQUIRE C INITIALIZED
|
||||||
|
* BEHAVIOR.
|
||||||
|
*****************************************************************************/
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
//Assuming the I/O pin check entry method is enabled, check the I/O pin value
|
||||||
|
//to see if we should stay in bootloader mode, or jump to normal applicaiton
|
||||||
|
//execution mode.
|
||||||
|
/*#ifdef ENABLE_IO_PIN_CHECK_BOOTLOADER_ENTRY
|
||||||
|
//Check Bootload Mode Entry Condition from the I/O pin (ex: place a
|
||||||
|
//pushbutton and pull up resistor on the pin)
|
||||||
|
if(0)
|
||||||
|
{
|
||||||
|
//Before going to application image however, make sure the image
|
||||||
|
//is properly signed and is intact.
|
||||||
|
goto DoFlashSignatureCheck;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//User is pressing the pushbutton. We should stay in bootloader mode
|
||||||
|
BootMain();
|
||||||
|
}
|
||||||
|
#endif //#ifdef ENABLE_IO_PIN_CHECK_BOOTLOADER_ENTRY
|
||||||
|
*/
|
||||||
|
DoFlashSignatureCheck:
|
||||||
|
//Check if the application region flash signature is valid
|
||||||
|
if(*(ROM unsigned int*)APP_SIGNATURE_ADDRESS == APP_SIGNATURE_VALUE)
|
||||||
|
{
|
||||||
|
//The flash signature was valid, implying the previous
|
||||||
|
//erase/program/verify operation was a success.
|
||||||
|
|
||||||
|
//Also make sure the first WORD of program memory in the app space
|
||||||
|
//is not blank, meaning there is an application image programmed into the device.
|
||||||
|
if(*(ROM unsigned int*)REMAPPED_APPLICATION_RESET_VECTOR != 0xFFFF)
|
||||||
|
{
|
||||||
|
//Go ahead and jump out of bootloader mode into the application run mode
|
||||||
|
#ifdef __XC8__
|
||||||
|
#asm
|
||||||
|
goto REMAPPED_APPLICATION_RESET_VECTOR
|
||||||
|
#endasm
|
||||||
|
#else //Must be C18 instead
|
||||||
|
_asm goto REMAPPED_APPLICATION_RESET_VECTOR _endasm
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//else the application image is missing or corrupt. In this case, we
|
||||||
|
//need to stay in the bootloader mode, so the user has the ability to
|
||||||
|
//try (again) to re-program a valid application image into the device.
|
||||||
|
|
||||||
|
//We should stay in bootloader mode
|
||||||
|
BootMain();
|
||||||
|
|
||||||
|
}//end UninitializedMain
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Function: void BootMain(void)
|
||||||
|
*
|
||||||
|
* PreCondition: None
|
||||||
|
*
|
||||||
|
* Input: None
|
||||||
|
*
|
||||||
|
* Output: None
|
||||||
|
*
|
||||||
|
* Side Effects: None
|
||||||
|
*
|
||||||
|
* Overview: This is the main function for this bootloader mode firmware.
|
||||||
|
* if execution gets to this function, it is assumed that we
|
||||||
|
* want to stay in bootloader mode for now.
|
||||||
|
*
|
||||||
|
* Note: If adding code to this function, make sure to add it only
|
||||||
|
* after the C initializer like code at the top of this function.
|
||||||
|
* Additionally, code written in this project should not assume
|
||||||
|
* any variables or registers have been initialized by the C
|
||||||
|
* compiler (since they may not have been, if the user jumped
|
||||||
|
* from the application run mode into bootloader mode directly).
|
||||||
|
*****************************************************************************/
|
||||||
|
#ifdef __XC8__
|
||||||
|
void __at(0x30) BootMain(void)
|
||||||
|
#else
|
||||||
|
#pragma code BOOT_MAIN_SECTION=0x30
|
||||||
|
void BootMain(void)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
//NOTE: The c018.o file is not included in the linker script for this project.
|
||||||
|
//The C initialization code in the c018.c (comes with C18 compiler in the src directory)
|
||||||
|
//file is instead modified and included here manually. This is done so as to provide
|
||||||
|
//a more convenient entry method into the bootloader firmware. Ordinarily the _entry_scn
|
||||||
|
//program code section starts at 0x00 and is created by the code of c018.o. However,
|
||||||
|
//the linker will not work if there is more than one section of code trying to occupy 0x00.
|
||||||
|
//Therefore, must not use the c018.o code, must instead manually include the useful code
|
||||||
|
//here instead.
|
||||||
|
|
||||||
|
//Make sure interrupts are disabled for this code (could still be on,
|
||||||
|
//if the application firmware jumped into the bootloader via software methods)
|
||||||
|
INTCON = 0x00;
|
||||||
|
|
||||||
|
//Initialize the C stack pointer, and other compiler managed items as
|
||||||
|
//normally done in the c018.c file (applicable when using C18 compiler)
|
||||||
|
#ifndef __XC8__
|
||||||
|
_asm
|
||||||
|
lfsr 1, _stack
|
||||||
|
lfsr 2, _stack
|
||||||
|
clrf TBLPTRU, 0
|
||||||
|
_endasm
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Clear the stack pointer, in case the user application jumped into
|
||||||
|
//bootloader mode with excessive junk on the call stack
|
||||||
|
STKPTR = 0x00;
|
||||||
|
|
||||||
|
// End of the important parts of the C initializer. This bootloader firmware does not use
|
||||||
|
// any C initialized user variables (idata memory sections). Therefore, the above is all
|
||||||
|
// the initialization that is required.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Call other initialization code and (re)enable the USB module
|
||||||
|
InitializeSystem(); //Some USB, I/O pins, and other initialization
|
||||||
|
|
||||||
|
//Execute main loop
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
ClrWdt();
|
||||||
|
|
||||||
|
//Need to call USBDeviceTasks() periodically. This function takes care of
|
||||||
|
//processing non-USB application related USB packets (ex: "Chapter 9"
|
||||||
|
//packets associated with USB enumeration)
|
||||||
|
USBDeviceTasks();
|
||||||
|
|
||||||
|
ProcessIO(); //This is where all the actual bootloader related data transfer/self programming takes
|
||||||
|
//place see ProcessIO() function in the BootPIC[xxxx].c file.
|
||||||
|
}//end while
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __XC8__
|
||||||
|
#pragma code
|
||||||
|
#endif
|
||||||
|
/******************************************************************************
|
||||||
|
* Function: static void InitializeSystem(void)
|
||||||
|
*
|
||||||
|
* PreCondition: None
|
||||||
|
*
|
||||||
|
* Input: None
|
||||||
|
*
|
||||||
|
* Output: None
|
||||||
|
*
|
||||||
|
* Side Effects: None
|
||||||
|
*
|
||||||
|
* Overview: InitializeSystem is a centralize initialization routine.
|
||||||
|
* All required USB initialization routines are called from
|
||||||
|
* here.
|
||||||
|
*
|
||||||
|
* User application initialization routine should also be
|
||||||
|
* called from here.
|
||||||
|
*
|
||||||
|
* Note: None
|
||||||
|
*****************************************************************************/
|
||||||
|
void InitializeSystem(void)
|
||||||
|
{
|
||||||
|
UserInit(); //Initialize bootloader application variables (see Bootxxxx.c file)
|
||||||
|
|
||||||
|
//Initialize USB module only after oscillator and other settings are compatible with USB operation
|
||||||
|
USBDeviceInit(); //Initializes USB module SFRs and firmware
|
||||||
|
//variables to known states.
|
||||||
|
}//end InitializeSystem
|
||||||
|
|
||||||
|
// ******************************************************************************************************
|
||||||
|
// ************** USB Callback Functions ****************************************************************
|
||||||
|
// ******************************************************************************************************
|
||||||
|
// The USB firmware stack will call the callback functions USBCBxxx() in response to certain USB related
|
||||||
|
// events. For example, if the host PC is powering down, it will stop sending out Start of Frame (SOF)
|
||||||
|
// packets to your device. In response to this, all USB devices are supposed to decrease their power
|
||||||
|
// consumption from the USB Vbus to <2.5mA* each. The USB module detects this condition (which according
|
||||||
|
// to the USB specifications is 3+ms of no bus activity/SOF packets) and then calls the USBCBSuspend()
|
||||||
|
// function. You should modify these callback functions to take appropriate actions for each of these
|
||||||
|
// conditions. For example, in the USBCBSuspend(), you may wish to add code that will decrease power
|
||||||
|
// consumption from Vbus to <2.5mA (such as by clock switching, turning off LEDs, putting the
|
||||||
|
// microcontroller to sleep, etc.). Then, in the USBCBWakeFromSuspend() function, you may then wish to
|
||||||
|
// add code that undoes the power saving things done in the USBCBSuspend() function.
|
||||||
|
//
|
||||||
|
// Note *: The "usb_20.pdf" specs indicate 500uA or 2.5mA, depending upon device classification. However,
|
||||||
|
// the USB-IF has officially issued an ECN (engineering change notice) changing this to 2.5mA for all
|
||||||
|
// devices. Make sure to re-download the latest specifications to get all of the newest ECNs.
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Function: void USBCBWakeFromSuspend(void)
|
||||||
|
*
|
||||||
|
* PreCondition: None
|
||||||
|
*
|
||||||
|
* Input: None
|
||||||
|
*
|
||||||
|
* Output: None
|
||||||
|
*
|
||||||
|
* Side Effects: None
|
||||||
|
*
|
||||||
|
* Overview: The host may put USB peripheral devices in low power
|
||||||
|
* suspend mode (by "sending" 3+ms of idle). Once in suspend
|
||||||
|
* mode, the host may wake the device back up by sending non-
|
||||||
|
* idle state signalling.
|
||||||
|
*
|
||||||
|
* This call back is invoked when a wakeup from USB suspend
|
||||||
|
* is detected.
|
||||||
|
*
|
||||||
|
* Note: Before returning from this function, make sure that the
|
||||||
|
* oscillator settings are fully compatible with USB module
|
||||||
|
* operation.
|
||||||
|
* If using the two-speed startup feature, wakeup and execution
|
||||||
|
* will occur before the main oscillator + PLL has had a chance
|
||||||
|
* to start. Device will run from INTOSC (no PLL). However, the
|
||||||
|
* USB module cannot be clocked and receive correct USB data when
|
||||||
|
* it is not clocked with the correct frequency clock source.
|
||||||
|
* Therefore, when using two-speed startup, should execute software
|
||||||
|
* delay to prevent any other code from executing until the main
|
||||||
|
* oscillator is ready.
|
||||||
|
* The host will allow at least 10ms for USB "resume recovery", during
|
||||||
|
* which it will not try to communicate with the device.
|
||||||
|
*****************************************************************************/
|
||||||
|
void USBCBWakeFromSuspend(void)
|
||||||
|
{
|
||||||
|
//This code delays ~5ms @ 8MHz to execute (using C18 3.21 with full
|
||||||
|
//optimizations enabled), but takes much less time at 48MHz. This delay
|
||||||
|
//is to make sure the PLL is enabled and locked, in case two speed startup
|
||||||
|
//was enabled
|
||||||
|
DelayRoutine(0x300); //Device will switch clocks (if using two-speed startup) while executing this delay function
|
||||||
|
|
||||||
|
//Primary oscillator and PLL should be running by now.
|
||||||
|
|
||||||
|
//Do not return from this function until the oscillator is correctly configured and
|
||||||
|
//running in a USB compatible mode/frequency.
|
||||||
|
|
||||||
|
|
||||||
|
//Additional code for re-enabling I/O pins and increasing power draw from VBUS
|
||||||
|
//may be placed here (up to the maximum of 100mA [when unconfigured] or the
|
||||||
|
//amount specified in the configuration descriptor (when configured).
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Function: void USBCBSuspend(void)
|
||||||
|
*
|
||||||
|
* PreCondition: None
|
||||||
|
*
|
||||||
|
* Input: None
|
||||||
|
*
|
||||||
|
* Output: None
|
||||||
|
*
|
||||||
|
* Side Effects: None
|
||||||
|
*
|
||||||
|
* Overview: Call back that is invoked when a USB suspend is detected
|
||||||
|
*
|
||||||
|
* Note: None
|
||||||
|
*****************************************************************************/
|
||||||
|
void USBCBSuspend(void)
|
||||||
|
{
|
||||||
|
Sleep(); // Go to sleep, wake up when a USB activity event occurs
|
||||||
|
//If using the WDT, should go back to sleep if awoke by WDT instead of USBIF
|
||||||
|
while((USBIF_FLAG == 0) && (RCONbits.TO == 0)) //If using the WDT, should go back to sleep if awoke by WDT instead of USBIF
|
||||||
|
{
|
||||||
|
Sleep(); //Entry into sleep clears WDT count, much like executing ClrWdt() instruction
|
||||||
|
}
|
||||||
|
|
||||||
|
//After the USB suspend event ends, you should re-configure your I/O pins
|
||||||
|
//for normal operation mode (which is allowed to consume more current).
|
||||||
|
//However, it is recommended to put this code in the USBCBWakeFromSuspend()
|
||||||
|
//function instead of here (so that this function will work with either
|
||||||
|
//sleeping or clock switching to a lower frequency).
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
* Function: void USBCBInitEP(uint8_t ConfigurationIndex)
|
||||||
|
*
|
||||||
|
* PreCondition: None
|
||||||
|
*
|
||||||
|
* Input: None
|
||||||
|
*
|
||||||
|
* Output: None
|
||||||
|
*
|
||||||
|
* Side Effects: None
|
||||||
|
*
|
||||||
|
* Overview: This function is called when the device becomes
|
||||||
|
* initialized, which occurs after the host sends a
|
||||||
|
* SET_CONFIGURATION request. This
|
||||||
|
* callback function should initialize the endpoints
|
||||||
|
* for the device's usage according to the current
|
||||||
|
* configuration.
|
||||||
|
*
|
||||||
|
* Note: If the host ever "unconfigures" the device, it will
|
||||||
|
* set the configuration to '0'. In this case, this
|
||||||
|
* callback gets called with ConfigurationIndex == 0, where
|
||||||
|
* the firmware should disable all non-EP0 endpoints (until
|
||||||
|
* the next non-zero SET_CONFIGURATION request is received,
|
||||||
|
* which will cause this callback to execute again).
|
||||||
|
*******************************************************************/
|
||||||
|
void USBCBInitEP(uint8_t ConfigurationIndex)
|
||||||
|
{
|
||||||
|
//Check what configuration "index" the host has requested us to select.
|
||||||
|
//Configuration index 0 is special and represents that the device should be
|
||||||
|
//un-configured. However, when the host sets the configuration (with index
|
||||||
|
//matching the valid/implemented configuration from the configuration descriptor),
|
||||||
|
//the firmware should enable the application endpoints associated with that
|
||||||
|
//configuration, and (re)initialize all application state variables associated
|
||||||
|
//with the USB application endpoints operation.
|
||||||
|
if(ConfigurationIndex == 1) //This application only implements one configuration, with index == 1.
|
||||||
|
{
|
||||||
|
//The host sent us a non-zero set configuration index. In this
|
||||||
|
//case we should prepare the application endpoints to be ready
|
||||||
|
//to use, and to (re-)initialize any application variables associated
|
||||||
|
//with the endpoints.
|
||||||
|
HIDInitEP();
|
||||||
|
|
||||||
|
//(Re-)Initialize the application variables associated with the USB interface
|
||||||
|
UserInit(); // See BootPIC[xxxx].c. Initializes the bootloader firmware state machine variables.
|
||||||
|
}
|
||||||
|
//else the host set the configuration back to 0 (indicating unconfigured), or
|
||||||
|
//to some higher (non-implemented value). In either case, we don't need to
|
||||||
|
//do anything specifically, unless the application requires some kind of
|
||||||
|
//"safe shutdown" code to execute after the host has deconfigured the device.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
* Function: void USBCBCheckOtherReq(void)
|
||||||
|
*
|
||||||
|
* PreCondition: None
|
||||||
|
*
|
||||||
|
* Input: None
|
||||||
|
*
|
||||||
|
* Output: None
|
||||||
|
*
|
||||||
|
* Side Effects: None
|
||||||
|
*
|
||||||
|
* Overview: This function is called when the USB stack receives a
|
||||||
|
* new control transfer SETUP packet from the host. The
|
||||||
|
* USB stack handles normal USB "Chapter 9" requests internally,
|
||||||
|
* but some control transfer requests are class specific. In
|
||||||
|
* order to handle these class specific requests, you must call
|
||||||
|
* the class handler's firmware control transfer handler function.
|
||||||
|
* If implementing a composite device with multiple classes
|
||||||
|
* implemented, call each of the handlers in the below callback.
|
||||||
|
*
|
||||||
|
* Note: None
|
||||||
|
*******************************************************************/
|
||||||
|
void USBCBCheckOtherReq(void)
|
||||||
|
{
|
||||||
|
USBCheckHIDRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Compiler mode and version check. This code needs to fit within the [0x000-0xFFF] program
|
||||||
|
//memory region that is reserved for use by the bootloader. However, if this
|
||||||
|
//code is built in XC8 Standard or Free mode (instead of PRO),
|
||||||
|
//the code may be too large to fit within the region, and a variety of linker
|
||||||
|
//error messages (ex: "can't find space") will result. Unfortunately these
|
||||||
|
//linker error messages can be cryptic to a user, so instead we add a deliberate
|
||||||
|
//#error to make a more human friendly error appear, in the event the wrong
|
||||||
|
//compiler mode is attempted to use to build this code. If you get this error
|
||||||
|
//message, please upgrade to the PRO compiler, and then use the mode
|
||||||
|
//(ex: build configuration --> XC8 compiler --> Option Categories: Optimizations --> Operation Mode: PRO)
|
||||||
|
//#ifdef __XC8__
|
||||||
|
// #if _HTC_EDITION_ < 2 //Check if PRO, Standard, or Free mode
|
||||||
|
// #error "This bootloader project must be built in PRO mode to fit within the reserved region. Double click this message for more details."
|
||||||
|
// #endif
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
/** EOF main.c ***************************************************************/
|
||||||
425
bootloader_hacked_from_mla/src/typedefs.h
Normal file
425
bootloader_hacked_from_mla/src/typedefs.h
Normal file
@@ -0,0 +1,425 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
Copyright 2016 Microchip Technology Inc. (www.microchip.com)
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
To request to license the code under the MLA license (www.microchip.com/mla_license),
|
||||||
|
please contact mla_licensing@microchip.com
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CUSTOMIZED_TYPE_DEFS_H_
|
||||||
|
#define __CUSTOMIZED_TYPE_DEFS_H_
|
||||||
|
|
||||||
|
#include <xc.h>
|
||||||
|
#define ROM const
|
||||||
|
#define rom
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#ifndef Nop()
|
||||||
|
#define Nop() {asm("NOP");}
|
||||||
|
#endif
|
||||||
|
#ifndef ClrWdt()
|
||||||
|
#define ClrWdt() {asm("CLRWDT");}
|
||||||
|
#endif
|
||||||
|
#ifndef Reset()
|
||||||
|
#define Reset() {asm("RESET");}
|
||||||
|
#endif
|
||||||
|
#ifndef Sleep()
|
||||||
|
#define Sleep() {asm("SLEEP");}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define __EXTENSION
|
||||||
|
|
||||||
|
#if !defined(__PACKED)
|
||||||
|
#define __PACKED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* get compiler defined type definitions (NULL, size_t, etc) */
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE 1
|
||||||
|
#endif
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PUBLIC /* Function attributes */
|
||||||
|
#define PROTECTED
|
||||||
|
#define PRIVATE static
|
||||||
|
|
||||||
|
/* INT is processor specific in length may vary in size */
|
||||||
|
typedef signed int INT;
|
||||||
|
typedef signed char INT8;
|
||||||
|
typedef signed short int INT16;
|
||||||
|
typedef signed long int INT32;
|
||||||
|
|
||||||
|
/* UINT is processor specific in length may vary in size */
|
||||||
|
typedef unsigned int UINT;
|
||||||
|
typedef unsigned char UINT8;
|
||||||
|
typedef unsigned short int UINT16;
|
||||||
|
typedef unsigned long int UINT32; /* other name for 32-bit integer */
|
||||||
|
|
||||||
|
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
UINT8 Val;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
__EXTENSION UINT8 b0:1;
|
||||||
|
__EXTENSION UINT8 b1:1;
|
||||||
|
__EXTENSION UINT8 b2:1;
|
||||||
|
__EXTENSION UINT8 b3:1;
|
||||||
|
__EXTENSION UINT8 b4:1;
|
||||||
|
__EXTENSION UINT8 b5:1;
|
||||||
|
__EXTENSION UINT8 b6:1;
|
||||||
|
__EXTENSION UINT8 b7:1;
|
||||||
|
} bits;
|
||||||
|
} UINT8_VAL, UINT8_BITS;
|
||||||
|
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
UINT16 Val;
|
||||||
|
UINT8 v[2] __PACKED;
|
||||||
|
struct __PACKED
|
||||||
|
{
|
||||||
|
UINT8 LB;
|
||||||
|
UINT8 HB;
|
||||||
|
} byte;
|
||||||
|
struct __PACKED
|
||||||
|
{
|
||||||
|
__EXTENSION UINT8 b0:1;
|
||||||
|
__EXTENSION UINT8 b1:1;
|
||||||
|
__EXTENSION UINT8 b2:1;
|
||||||
|
__EXTENSION UINT8 b3:1;
|
||||||
|
__EXTENSION UINT8 b4:1;
|
||||||
|
__EXTENSION UINT8 b5:1;
|
||||||
|
__EXTENSION UINT8 b6:1;
|
||||||
|
__EXTENSION UINT8 b7:1;
|
||||||
|
__EXTENSION UINT8 b8:1;
|
||||||
|
__EXTENSION UINT8 b9:1;
|
||||||
|
__EXTENSION UINT8 b10:1;
|
||||||
|
__EXTENSION UINT8 b11:1;
|
||||||
|
__EXTENSION UINT8 b12:1;
|
||||||
|
__EXTENSION UINT8 b13:1;
|
||||||
|
__EXTENSION UINT8 b14:1;
|
||||||
|
__EXTENSION UINT8 b15:1;
|
||||||
|
} bits;
|
||||||
|
} UINT16_VAL, UINT16_BITS;
|
||||||
|
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
UINT32 Val;
|
||||||
|
UINT16 w[2] __PACKED;
|
||||||
|
UINT8 v[4] __PACKED;
|
||||||
|
struct __PACKED
|
||||||
|
{
|
||||||
|
UINT16 LW;
|
||||||
|
UINT16 HW;
|
||||||
|
} word;
|
||||||
|
struct __PACKED
|
||||||
|
{
|
||||||
|
UINT8 LB;
|
||||||
|
UINT8 HB;
|
||||||
|
UINT8 UB;
|
||||||
|
UINT8 MB;
|
||||||
|
} byte;
|
||||||
|
struct __PACKED
|
||||||
|
{
|
||||||
|
UINT16_VAL low;
|
||||||
|
UINT16_VAL high;
|
||||||
|
}wordUnion;
|
||||||
|
struct __PACKED
|
||||||
|
{
|
||||||
|
__EXTENSION UINT8 b0:1;
|
||||||
|
__EXTENSION UINT8 b1:1;
|
||||||
|
__EXTENSION UINT8 b2:1;
|
||||||
|
__EXTENSION UINT8 b3:1;
|
||||||
|
__EXTENSION UINT8 b4:1;
|
||||||
|
__EXTENSION UINT8 b5:1;
|
||||||
|
__EXTENSION UINT8 b6:1;
|
||||||
|
__EXTENSION UINT8 b7:1;
|
||||||
|
__EXTENSION UINT8 b8:1;
|
||||||
|
__EXTENSION UINT8 b9:1;
|
||||||
|
__EXTENSION UINT8 b10:1;
|
||||||
|
__EXTENSION UINT8 b11:1;
|
||||||
|
__EXTENSION UINT8 b12:1;
|
||||||
|
__EXTENSION UINT8 b13:1;
|
||||||
|
__EXTENSION UINT8 b14:1;
|
||||||
|
__EXTENSION UINT8 b15:1;
|
||||||
|
__EXTENSION UINT8 b16:1;
|
||||||
|
__EXTENSION UINT8 b17:1;
|
||||||
|
__EXTENSION UINT8 b18:1;
|
||||||
|
__EXTENSION UINT8 b19:1;
|
||||||
|
__EXTENSION UINT8 b20:1;
|
||||||
|
__EXTENSION UINT8 b21:1;
|
||||||
|
__EXTENSION UINT8 b22:1;
|
||||||
|
__EXTENSION UINT8 b23:1;
|
||||||
|
__EXTENSION UINT8 b24:1;
|
||||||
|
__EXTENSION UINT8 b25:1;
|
||||||
|
__EXTENSION UINT8 b26:1;
|
||||||
|
__EXTENSION UINT8 b27:1;
|
||||||
|
__EXTENSION UINT8 b28:1;
|
||||||
|
__EXTENSION UINT8 b29:1;
|
||||||
|
__EXTENSION UINT8 b30:1;
|
||||||
|
__EXTENSION UINT8 b31:1;
|
||||||
|
} bits;
|
||||||
|
} UINT32_VAL;
|
||||||
|
|
||||||
|
/***********************************************************************************/
|
||||||
|
|
||||||
|
/* Alternate definitions */
|
||||||
|
typedef void VOID;
|
||||||
|
|
||||||
|
typedef char CHAR8;
|
||||||
|
typedef unsigned char UCHAR8;
|
||||||
|
|
||||||
|
typedef unsigned char BYTE; /* 8-bit unsigned */
|
||||||
|
typedef unsigned short int WORD; /* 16-bit unsigned */
|
||||||
|
typedef unsigned long DWORD; /* 32-bit unsigned */
|
||||||
|
//typedef unsigned long long QWORD; /* 64-bit unsigned */
|
||||||
|
typedef signed char CHAR; /* 8-bit signed */
|
||||||
|
typedef signed short int SHORT; /* 16-bit signed */
|
||||||
|
typedef signed long LONG; /* 32-bit signed */
|
||||||
|
//typedef signed long long LONGLONG; /* 64-bit signed */
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
BYTE Val;
|
||||||
|
struct __PACKED
|
||||||
|
{
|
||||||
|
__EXTENSION BYTE b0:1;
|
||||||
|
__EXTENSION BYTE b1:1;
|
||||||
|
__EXTENSION BYTE b2:1;
|
||||||
|
__EXTENSION BYTE b3:1;
|
||||||
|
__EXTENSION BYTE b4:1;
|
||||||
|
__EXTENSION BYTE b5:1;
|
||||||
|
__EXTENSION BYTE b6:1;
|
||||||
|
__EXTENSION BYTE b7:1;
|
||||||
|
} bits;
|
||||||
|
} BYTE_VAL, BYTE_BITS;
|
||||||
|
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
WORD Val;
|
||||||
|
BYTE v[2] __PACKED;
|
||||||
|
struct __PACKED
|
||||||
|
{
|
||||||
|
BYTE LB;
|
||||||
|
BYTE HB;
|
||||||
|
} byte;
|
||||||
|
struct __PACKED
|
||||||
|
{
|
||||||
|
__EXTENSION BYTE b0:1;
|
||||||
|
__EXTENSION BYTE b1:1;
|
||||||
|
__EXTENSION BYTE b2:1;
|
||||||
|
__EXTENSION BYTE b3:1;
|
||||||
|
__EXTENSION BYTE b4:1;
|
||||||
|
__EXTENSION BYTE b5:1;
|
||||||
|
__EXTENSION BYTE b6:1;
|
||||||
|
__EXTENSION BYTE b7:1;
|
||||||
|
__EXTENSION BYTE b8:1;
|
||||||
|
__EXTENSION BYTE b9:1;
|
||||||
|
__EXTENSION BYTE b10:1;
|
||||||
|
__EXTENSION BYTE b11:1;
|
||||||
|
__EXTENSION BYTE b12:1;
|
||||||
|
__EXTENSION BYTE b13:1;
|
||||||
|
__EXTENSION BYTE b14:1;
|
||||||
|
__EXTENSION BYTE b15:1;
|
||||||
|
} bits;
|
||||||
|
} WORD_VAL, WORD_BITS;
|
||||||
|
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
DWORD Val;
|
||||||
|
WORD w[2] __PACKED;
|
||||||
|
BYTE v[4] __PACKED;
|
||||||
|
struct __PACKED
|
||||||
|
{
|
||||||
|
WORD LW;
|
||||||
|
WORD HW;
|
||||||
|
} word;
|
||||||
|
struct __PACKED
|
||||||
|
{
|
||||||
|
BYTE LB;
|
||||||
|
BYTE HB;
|
||||||
|
BYTE UB;
|
||||||
|
BYTE MB;
|
||||||
|
} byte;
|
||||||
|
struct __PACKED
|
||||||
|
{
|
||||||
|
WORD_VAL low;
|
||||||
|
WORD_VAL high;
|
||||||
|
}wordUnion;
|
||||||
|
struct __PACKED
|
||||||
|
{
|
||||||
|
__EXTENSION BYTE b0:1;
|
||||||
|
__EXTENSION BYTE b1:1;
|
||||||
|
__EXTENSION BYTE b2:1;
|
||||||
|
__EXTENSION BYTE b3:1;
|
||||||
|
__EXTENSION BYTE b4:1;
|
||||||
|
__EXTENSION BYTE b5:1;
|
||||||
|
__EXTENSION BYTE b6:1;
|
||||||
|
__EXTENSION BYTE b7:1;
|
||||||
|
__EXTENSION BYTE b8:1;
|
||||||
|
__EXTENSION BYTE b9:1;
|
||||||
|
__EXTENSION BYTE b10:1;
|
||||||
|
__EXTENSION BYTE b11:1;
|
||||||
|
__EXTENSION BYTE b12:1;
|
||||||
|
__EXTENSION BYTE b13:1;
|
||||||
|
__EXTENSION BYTE b14:1;
|
||||||
|
__EXTENSION BYTE b15:1;
|
||||||
|
__EXTENSION BYTE b16:1;
|
||||||
|
__EXTENSION BYTE b17:1;
|
||||||
|
__EXTENSION BYTE b18:1;
|
||||||
|
__EXTENSION BYTE b19:1;
|
||||||
|
__EXTENSION BYTE b20:1;
|
||||||
|
__EXTENSION BYTE b21:1;
|
||||||
|
__EXTENSION BYTE b22:1;
|
||||||
|
__EXTENSION BYTE b23:1;
|
||||||
|
__EXTENSION BYTE b24:1;
|
||||||
|
__EXTENSION BYTE b25:1;
|
||||||
|
__EXTENSION BYTE b26:1;
|
||||||
|
__EXTENSION BYTE b27:1;
|
||||||
|
__EXTENSION BYTE b28:1;
|
||||||
|
__EXTENSION BYTE b29:1;
|
||||||
|
__EXTENSION BYTE b30:1;
|
||||||
|
__EXTENSION BYTE b31:1;
|
||||||
|
} bits;
|
||||||
|
} DWORD_VAL;
|
||||||
|
|
||||||
|
/* MPLAB C Compiler for PIC18 does not support 64-bit integers */
|
||||||
|
/*typedef union
|
||||||
|
{
|
||||||
|
QWORD Val;
|
||||||
|
DWORD d[2] __PACKED;
|
||||||
|
WORD w[4] __PACKED;
|
||||||
|
BYTE v[8] __PACKED;
|
||||||
|
struct __PACKED
|
||||||
|
{
|
||||||
|
DWORD LD;
|
||||||
|
DWORD HD;
|
||||||
|
} dword;
|
||||||
|
struct __PACKED
|
||||||
|
{
|
||||||
|
WORD LW;
|
||||||
|
WORD HW;
|
||||||
|
WORD UW;
|
||||||
|
WORD MW;
|
||||||
|
} word;
|
||||||
|
struct __PACKED
|
||||||
|
{
|
||||||
|
__EXTENSION BYTE b0:1;
|
||||||
|
__EXTENSION BYTE b1:1;
|
||||||
|
__EXTENSION BYTE b2:1;
|
||||||
|
__EXTENSION BYTE b3:1;
|
||||||
|
__EXTENSION BYTE b4:1;
|
||||||
|
__EXTENSION BYTE b5:1;
|
||||||
|
__EXTENSION BYTE b6:1;
|
||||||
|
__EXTENSION BYTE b7:1;
|
||||||
|
__EXTENSION BYTE b8:1;
|
||||||
|
__EXTENSION BYTE b9:1;
|
||||||
|
__EXTENSION BYTE b10:1;
|
||||||
|
__EXTENSION BYTE b11:1;
|
||||||
|
__EXTENSION BYTE b12:1;
|
||||||
|
__EXTENSION BYTE b13:1;
|
||||||
|
__EXTENSION BYTE b14:1;
|
||||||
|
__EXTENSION BYTE b15:1;
|
||||||
|
__EXTENSION BYTE b16:1;
|
||||||
|
__EXTENSION BYTE b17:1;
|
||||||
|
__EXTENSION BYTE b18:1;
|
||||||
|
__EXTENSION BYTE b19:1;
|
||||||
|
__EXTENSION BYTE b20:1;
|
||||||
|
__EXTENSION BYTE b21:1;
|
||||||
|
__EXTENSION BYTE b22:1;
|
||||||
|
__EXTENSION BYTE b23:1;
|
||||||
|
__EXTENSION BYTE b24:1;
|
||||||
|
__EXTENSION BYTE b25:1;
|
||||||
|
__EXTENSION BYTE b26:1;
|
||||||
|
__EXTENSION BYTE b27:1;
|
||||||
|
__EXTENSION BYTE b28:1;
|
||||||
|
__EXTENSION BYTE b29:1;
|
||||||
|
__EXTENSION BYTE b30:1;
|
||||||
|
__EXTENSION BYTE b31:1;
|
||||||
|
__EXTENSION BYTE b32:1;
|
||||||
|
__EXTENSION BYTE b33:1;
|
||||||
|
__EXTENSION BYTE b34:1;
|
||||||
|
__EXTENSION BYTE b35:1;
|
||||||
|
__EXTENSION BYTE b36:1;
|
||||||
|
__EXTENSION BYTE b37:1;
|
||||||
|
__EXTENSION BYTE b38:1;
|
||||||
|
__EXTENSION BYTE b39:1;
|
||||||
|
__EXTENSION BYTE b40:1;
|
||||||
|
__EXTENSION BYTE b41:1;
|
||||||
|
__EXTENSION BYTE b42:1;
|
||||||
|
__EXTENSION BYTE b43:1;
|
||||||
|
__EXTENSION BYTE b44:1;
|
||||||
|
__EXTENSION BYTE b45:1;
|
||||||
|
__EXTENSION BYTE b46:1;
|
||||||
|
__EXTENSION BYTE b47:1;
|
||||||
|
__EXTENSION BYTE b48:1;
|
||||||
|
__EXTENSION BYTE b49:1;
|
||||||
|
__EXTENSION BYTE b50:1;
|
||||||
|
__EXTENSION BYTE b51:1;
|
||||||
|
__EXTENSION BYTE b52:1;
|
||||||
|
__EXTENSION BYTE b53:1;
|
||||||
|
__EXTENSION BYTE b54:1;
|
||||||
|
__EXTENSION BYTE b55:1;
|
||||||
|
__EXTENSION BYTE b56:1;
|
||||||
|
__EXTENSION BYTE b57:1;
|
||||||
|
__EXTENSION BYTE b58:1;
|
||||||
|
__EXTENSION BYTE b59:1;
|
||||||
|
__EXTENSION BYTE b60:1;
|
||||||
|
__EXTENSION BYTE b61:1;
|
||||||
|
__EXTENSION BYTE b62:1;
|
||||||
|
__EXTENSION BYTE b63:1;
|
||||||
|
} bits;
|
||||||
|
} QWORD_VAL;
|
||||||
|
*/
|
||||||
|
#undef __EXTENSION
|
||||||
|
|
||||||
|
#ifndef uint24_t
|
||||||
|
#define uint24_t uint32_t
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef void(*pFunc)(void);
|
||||||
|
|
||||||
|
typedef union _POINTER
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
BYTE bLow;
|
||||||
|
BYTE bHigh;
|
||||||
|
//BYTE bUpper;
|
||||||
|
};
|
||||||
|
uint16_t _word; // bLow & bHigh
|
||||||
|
|
||||||
|
//pFunc _pFunc; // Usage: ptr.pFunc(); Init: ptr.pFunc = &<Function>;
|
||||||
|
|
||||||
|
BYTE* bRam; // Ram byte pointer: 2 bytes pointer pointing
|
||||||
|
// to 1 byte of data
|
||||||
|
uint16_t* wRam; // Ram word poitner: 2 bytes poitner pointing
|
||||||
|
// to 2 bytes of data
|
||||||
|
|
||||||
|
ROM BYTE* bRom; // Size depends on compiler setting
|
||||||
|
ROM WORD* wRom;
|
||||||
|
//ROM near BYTE* nbRom; // Near = 2 bytes pointer
|
||||||
|
//ROM near uint16_t* nwRom;
|
||||||
|
//ROM far BYTE* fbRom; // Far = 3 bytes pointer
|
||||||
|
//ROM far uint16_t* fwRom;
|
||||||
|
} POINTER;
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __CUSTOMIZED_TYPE_DEFS_H_ */
|
||||||
56
bootloader_hacked_from_mla/src/usb.h
Normal file
56
bootloader_hacked_from_mla/src/usb.h
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
Copyright 2016 Microchip Technology Inc. (www.microchip.com)
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
To request to license the code under the MLA license (www.microchip.com/mla_license),
|
||||||
|
please contact mla_licensing@microchip.com
|
||||||
|
*******************************************************************************/
|
||||||
|
#ifndef USB_H
|
||||||
|
#define USB_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* usb.h provides a centralize way to include all files
|
||||||
|
* required by Microchip USB Firmware.
|
||||||
|
*
|
||||||
|
* The order of inclusion is important.
|
||||||
|
* Dependency conflicts are resolved by the correct ordering.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "typedefs.h"
|
||||||
|
#include "usb_config.h"
|
||||||
|
#include "usb_device.h"
|
||||||
|
#include "HardwareProfile.h"
|
||||||
|
|
||||||
|
#if defined(USB_USE_HID) // See usb_config.h
|
||||||
|
#include "usb_device_hid.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//These callback functions belong in your main.c (or equivalent) file. The USB
|
||||||
|
//stack will call these callback functions in response to specific USB bus events,
|
||||||
|
//such as entry into USB suspend mode, exit from USB suspend mode, and upon
|
||||||
|
//receiving the "set configuration" control tranfer request, which marks the end
|
||||||
|
//of the USB enumeration sequence and the start of normal application run mode (and
|
||||||
|
//where application related variables and endpoints may need to get (re)-initialized.
|
||||||
|
void USBCBSuspend(void);
|
||||||
|
void USBCBWakeFromSuspend(void);
|
||||||
|
void USBCBInitEP(uint8_t ConfigurationIndex);
|
||||||
|
void USBCBCheckOtherReq(void);
|
||||||
|
|
||||||
|
|
||||||
|
//API renaming wrapper functions
|
||||||
|
#define HIDTxHandleBusy(a) {mHIDTxIsBusy()}
|
||||||
|
#define HIDRxHandleBusy(a) {mHIDRxIsBusy()}
|
||||||
|
|
||||||
|
#endif //USB_H
|
||||||
74
bootloader_hacked_from_mla/src/usb_config.h
Normal file
74
bootloader_hacked_from_mla/src/usb_config.h
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
Copyright 2016 Microchip Technology Inc. (www.microchip.com)
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
To request to license the code under the MLA license (www.microchip.com/mla_license),
|
||||||
|
please contact mla_licensing@microchip.com
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef USBCFG_H
|
||||||
|
#define USBCFG_H
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------
|
||||||
|
//User configurable options
|
||||||
|
//----------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//When defined/enabled, this option allows the boot up code to check an I/O pin
|
||||||
|
//(as defined by the sw2() macro in HardwareProfile.h), and if logic low, execution
|
||||||
|
//stays within the bootloader, allowing the user to update the firmware. If this
|
||||||
|
//option is not enabled, then the only method of entering the bootloader will
|
||||||
|
//be from the application firmware project, by executing a goto 0x001C operation.
|
||||||
|
//Enabling the I/O pin to enter the bootloader is recommended, since it is more
|
||||||
|
//robust/recoverable (compared to software only entry into the bootloader), in
|
||||||
|
//the event of a failed erase/program/verify operation, or an otherwise corrupted
|
||||||
|
//application firmware image is loaded.
|
||||||
|
#define ENABLE_IO_PIN_CHECK_BOOTLOADER_ENTRY //Uncomment if you wish to enable I/O pin entry method into bootloader mode
|
||||||
|
//Make sure proper sw2() macro definition is provided in HardwareProfile.h
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------
|
||||||
|
//Other semi-configurable settings that tell the USB stack how to operate (but usually don't need changing)
|
||||||
|
//----------------------------------------------------------------------------------------------------------
|
||||||
|
#define MAX_EP_NUMBER 1 // EP0 and EP1 are the only EPs used in this application
|
||||||
|
#define MAX_NUM_INT 1 // For tracking Alternate Setting - make sure this matches the number of interfaces implemented in the device
|
||||||
|
#define EP0_BUFF_SIZE 8 // Valid Options: 8, 16, 32, or 64 bytes.
|
||||||
|
// There is little advantage in using
|
||||||
|
// more than 8 bytes on EP0 IN/OUT in most cases.
|
||||||
|
#define USB_MAX_NUM_CONFIG_DSC 1 // Number of configurations that this firmware implements
|
||||||
|
//#define ENABLE_CONTROL_TRANSFERS_WITH_OUT_DATA_STAGE //Commented out to save code size, since this bootloader firmware doesn't use OUT control transfers with data stage
|
||||||
|
|
||||||
|
|
||||||
|
#define CONFIG_DESC_TOTAL_LEN 41 //Make sure this matches the size of your configuration descriptor + all subordinate
|
||||||
|
//descriptors returned by the get descriptor(configuration) request
|
||||||
|
|
||||||
|
/* Parameter definitions are defined in usb_device.h */
|
||||||
|
#define MODE_PP _PPBM1 //This code is only written to support _PPBM1 mode only (ping pong on EP0 OUT buffer only). Do not change.
|
||||||
|
#define UCFG_VAL _PUEN|_TRINT|_FS|MODE_PP
|
||||||
|
|
||||||
|
//Device class and endpoint definitions
|
||||||
|
#define USB_USE_HID
|
||||||
|
|
||||||
|
/* HID */
|
||||||
|
#define HID_INTF_ID 0x00
|
||||||
|
#define HID_UEP UEP1
|
||||||
|
#define HID_BD_OUT ep1Bo
|
||||||
|
#define HID_INT_OUT_EP_SIZE 64
|
||||||
|
#define HID_BD_IN ep1Bi
|
||||||
|
#define HID_INT_IN_EP_SIZE 64
|
||||||
|
#define HID_NUM_OF_DSC 1 //Just the Report descriptor (no physical descriptor present)
|
||||||
|
#define HID_RPT01_SIZE 29 //Make sure this matches the size of your HID report descriptor
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif //USBCFG_H
|
||||||
282
bootloader_hacked_from_mla/src/usb_descriptors.c
Normal file
282
bootloader_hacked_from_mla/src/usb_descriptors.c
Normal file
@@ -0,0 +1,282 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
Copyright 2016 Microchip Technology Inc. (www.microchip.com)
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
To request to license the code under the MLA license (www.microchip.com/mla_license),
|
||||||
|
please contact mla_licensing@microchip.com
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* -usb_descriptors.c-
|
||||||
|
* This file contains the USB descriptor information. It is used
|
||||||
|
* in conjunction with the usb_descriptors.h file. When a descriptor is added
|
||||||
|
* or removed from the main configuration descriptor, i.e. CFG01,
|
||||||
|
* the user must also change the descriptor structure defined in
|
||||||
|
* the usb_descriptors.h file. The structure is used to calculate the
|
||||||
|
* descriptor size, i.e. sizeof(CFG01).
|
||||||
|
*
|
||||||
|
* A typical configuration descriptor consists of:
|
||||||
|
* At least one configuration descriptor (USB_CFG_DSC)
|
||||||
|
* One or more interface descriptors (USB_INTF_DSC)
|
||||||
|
* One or more endpoint descriptors (USB_EP_DSC)
|
||||||
|
*
|
||||||
|
* Naming Convention:
|
||||||
|
* To resolve ambiguity, the naming convention are as followed:
|
||||||
|
* - USB_CFG_DSC type should be named cdxx, where xx is the
|
||||||
|
* configuration number. This number should match the actual
|
||||||
|
* index value of this configuration.
|
||||||
|
* - USB_INTF_DSC type should be named i<yy>a<zz>, where yy is the
|
||||||
|
* interface number and zz is the alternate interface number.
|
||||||
|
* - USB_EP_DSC type should be named ep<##><d>_i<yy>a<zz>, where
|
||||||
|
* ## is the endpoint number and d is the direction of transfer.
|
||||||
|
* The interface name should also be listed as a suffix to identify
|
||||||
|
* which interface does the endpoint belong to.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* If a device has one configuration, two interfaces; interface 0
|
||||||
|
* has two endpoints (in and out), and interface 1 has one endpoint(in).
|
||||||
|
* Then the CFG01 structure in the usb_descriptors.h should be:
|
||||||
|
*
|
||||||
|
* #define CFG01 ROM struct \
|
||||||
|
* { USB_CFG_DSC cd01; \
|
||||||
|
* USB_INTF_DSC i00a00; \
|
||||||
|
* USB_EP_DSC ep01o_i00a00; \
|
||||||
|
* USB_EP_DSC ep01i_i00a00; \
|
||||||
|
* USB_INTF_DSC i01a00; \
|
||||||
|
* USB_EP_DSC ep02i_i01a00; \
|
||||||
|
* } cfg01
|
||||||
|
*
|
||||||
|
* Note the hierarchy of the descriptors above, it follows the USB
|
||||||
|
* specification requirement. All endpoints belonging to an interface
|
||||||
|
* should be listed immediately after that interface.
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
* Filling in the descriptor values in the usb_descriptors.c file:
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
* Most items should be self-explanatory, however, a few will be
|
||||||
|
* explained for clarification.
|
||||||
|
*
|
||||||
|
* [Configuration Descriptor(USB_CFG_DSC)]
|
||||||
|
* The configuration attribute must always have the _DEFAULT
|
||||||
|
* definition at the minimum. Additional options can be ORed
|
||||||
|
* to the _DEFAULT attribute. Available options are _SELF and _RWU.
|
||||||
|
* These definitions are defined in the usb_device.h file. The
|
||||||
|
* _SELF tells the USB host that this device is self-powered. The
|
||||||
|
* _RWU tells the USB host that this device supports Remote Wakeup.
|
||||||
|
*
|
||||||
|
* [Endpoint Descriptor(USB_EP_DSC)]
|
||||||
|
* Assume the following example:
|
||||||
|
* sizeof(USB_EP_DSC),DSC_EP,_EP01_OUT,_BULK,64,0x00
|
||||||
|
*
|
||||||
|
* The first two parameters are self-explanatory. They specify the
|
||||||
|
* length of this endpoint descriptor (7) and the descriptor type.
|
||||||
|
* The next parameter identifies the endpoint, the definitions are
|
||||||
|
* defined in usb_device.h and has the following naming
|
||||||
|
* convention:
|
||||||
|
* _EP<##>_<dir>
|
||||||
|
* where ## is the endpoint number and dir is the direction of
|
||||||
|
* transfer. The dir has the value of either 'OUT' or 'IN'.
|
||||||
|
* The next parameter identifies the type of the endpoint. Available
|
||||||
|
* options are _BULK, _INT, _ISO, and _CTRL. The _CTRL is not
|
||||||
|
* typically used because the default control transfer endpoint is
|
||||||
|
* not defined in the USB descriptors. When _ISO option is used,
|
||||||
|
* addition options can be ORed to _ISO. Example:
|
||||||
|
* _ISO|_AD|_FE
|
||||||
|
* This describes the endpoint as an isochronous pipe with adaptive
|
||||||
|
* and feedback attributes. See usb_device.h and the USB
|
||||||
|
* specification for details. The next parameter defines the size of
|
||||||
|
* the endpoint. The last parameter in the polling interval.
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
* Adding a USB String
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
* A string descriptor array should have the following format:
|
||||||
|
*
|
||||||
|
* ROM struct{uint8_t bLength;uint8_t bDscType;uint16_t string[size];}sdxxx={
|
||||||
|
* sizeof(sdxxx),DSC_STR,<text>};
|
||||||
|
*
|
||||||
|
* The above structure provides a means for the C compiler to
|
||||||
|
* calculate the length of string descriptor sdxxx, where xxx is the
|
||||||
|
* index number. The first two bytes of the descriptor are descriptor
|
||||||
|
* length and type. The rest <text> are string texts which must be
|
||||||
|
* in the unicode format. The unicode format is achieved by declaring
|
||||||
|
* each character as a word type. The whole text string is declared
|
||||||
|
* as a word array with the number of characters equals to <size>.
|
||||||
|
* <size> has to be manually counted and entered into the array
|
||||||
|
* declaration. Let's study this through an example:
|
||||||
|
* if the string is "USB" , then the string descriptor should be:
|
||||||
|
* (Using index 02)
|
||||||
|
* ROM struct{byte bLength;uint8_t bDscType;uint16_t string[3];}sd002={
|
||||||
|
* sizeof(sd002),DSC_STR,'U','S','B'};
|
||||||
|
*
|
||||||
|
* A USB project may have multiple strings and the firmware supports
|
||||||
|
* the management of multiple strings through a look-up table.
|
||||||
|
* The look-up table is defined as:
|
||||||
|
* ROM const unsigned char *ROM USB_SD_Ptr[]={&sd000,&sd001,&sd002};
|
||||||
|
*
|
||||||
|
* The above declaration has 3 strings, sd000, sd001, and sd002.
|
||||||
|
* Strings can be removed or added. sd000 is a specialized string
|
||||||
|
* descriptor. It defines the language code, usually this is
|
||||||
|
* US English (0x0409). The index of the string must match the index
|
||||||
|
* position of the USB_SD_Ptr array, &sd000 must be in position
|
||||||
|
* USB_SD_Ptr[0], &sd001 must be in position USB_SD_Ptr[1] and so on.
|
||||||
|
* The look-up table USB_SD_Ptr is used by the get string handler
|
||||||
|
* function in usb9.c.
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* The look-up table scheme also applies to the configuration
|
||||||
|
* descriptor. A USB device may have multiple configuration
|
||||||
|
* descriptors, i.e. CFG01, CFG02, etc. To add a configuration
|
||||||
|
* descriptor, user must implement a structure similar to CFG01.
|
||||||
|
* The next step is to add the configuration descriptor name, i.e.
|
||||||
|
* cfg01, cfg02,.., to the look-up table USB_CD_Ptr. USB_CD_Ptr[0]
|
||||||
|
* is a dummy place holder since configuration 0 is the un-configured
|
||||||
|
* state according to the definition in the USB specification.
|
||||||
|
*
|
||||||
|
********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** I N C L U D E S *************************************************/
|
||||||
|
#include "usb.h"
|
||||||
|
|
||||||
|
|
||||||
|
/** C O N S T A N T S ************************************************/
|
||||||
|
#ifndef __XC8__
|
||||||
|
#pragma romdata
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Device Descriptor */
|
||||||
|
ROM USB_DEV_DSC device_dsc=
|
||||||
|
{
|
||||||
|
sizeof(USB_DEV_DSC), // Size of this descriptor in bytes
|
||||||
|
DSC_DEV, // DEVICE descriptor type
|
||||||
|
0x0200, // USB Spec Release Number in BCD format
|
||||||
|
0x00, // Class Code
|
||||||
|
0x00, // Subclass code
|
||||||
|
0x00, // Protocol code
|
||||||
|
EP0_BUFF_SIZE, // Max packet size for EP0, see usb_config.h
|
||||||
|
0x04D8, // Vendor ID: Microchip
|
||||||
|
0x003C, // Product ID: HID Bootloader
|
||||||
|
0x0101, // Device release number in BCD format
|
||||||
|
0x01, // Manufacturer string index
|
||||||
|
0x02, // Product string index
|
||||||
|
0x00, // Device serial number string index
|
||||||
|
0x01 // Number of possible configurations
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Configuration 1 Descriptors */
|
||||||
|
ROM uint8_t CFG01[CONFIG_DESC_TOTAL_LEN]={
|
||||||
|
/* Configuration Descriptor */
|
||||||
|
sizeof(USB_CFG_DSC), // Size of this descriptor in bytes
|
||||||
|
DSC_CFG, // CONFIGURATION descriptor type
|
||||||
|
(uint8_t)CONFIG_DESC_TOTAL_LEN, // Total length of data for this cfg - LSB
|
||||||
|
(uint8_t)(CONFIG_DESC_TOTAL_LEN>>8), // Total length of data for this cfg - MSB
|
||||||
|
1, // Number of interfaces in this cfg
|
||||||
|
1, // Index value of this configuration
|
||||||
|
0, // Configuration string index
|
||||||
|
_DEFAULT, // Attributes, see usb_device.h
|
||||||
|
50, // Max power consumption (2X mA)
|
||||||
|
|
||||||
|
/* Interface Descriptor */
|
||||||
|
sizeof(USB_INTF_DSC), // Size of this descriptor in bytes
|
||||||
|
DSC_INTF, // INTERFACE descriptor type
|
||||||
|
0, // Interface Number
|
||||||
|
0, // Alternate Setting Number
|
||||||
|
2, // Number of endpoints in this intf
|
||||||
|
HID_INTF, // Class code
|
||||||
|
0, // Subclass code, no subclass
|
||||||
|
0, // Protocol code, no protocol
|
||||||
|
0, // Interface string index
|
||||||
|
|
||||||
|
/* HID Class-Specific Descriptor */
|
||||||
|
sizeof(USB_HID_DSC), // Size of this descriptor in bytes
|
||||||
|
DSC_HID, // HID descriptor type
|
||||||
|
0x11, // HID Spec Release Number in BCD format (0x0111 = v1.11) - LSB
|
||||||
|
0x01, // HID Spec Release Number in BCD format (0x0111 = v1.11) - MSB
|
||||||
|
0x00, // Country Code (0x00 for Not supported)
|
||||||
|
HID_NUM_OF_DSC, // Number of class descriptors, see usb_config.h
|
||||||
|
DSC_RPT, // Report descriptor type
|
||||||
|
(uint8_t)HID_RPT01_SIZE, // Size of the report descriptor - LSB
|
||||||
|
(uint8_t)((uint16_t)HID_RPT01_SIZE >> 8), // Size of the report descriptor - MSB
|
||||||
|
|
||||||
|
/* Endpoint Descriptor */
|
||||||
|
sizeof(USB_EP_DSC), //Endpoint descriptor size
|
||||||
|
DSC_EP, //Type of descriptor (endpoint)
|
||||||
|
_EP01_IN, //Endpoint number + direction
|
||||||
|
_INT, //Endpoint transfer type implemented
|
||||||
|
HID_INT_IN_EP_SIZE, //LSB - endpoint size
|
||||||
|
0x00, //MSB - endpoint size
|
||||||
|
0x01, //bInterval
|
||||||
|
|
||||||
|
/* Endpoint Descriptor */
|
||||||
|
sizeof(USB_EP_DSC), //Endpoint descriptor size
|
||||||
|
DSC_EP, //Type of descriptor (endpoint)
|
||||||
|
_EP01_OUT, //Endpoint number + direction
|
||||||
|
_INT, //Endpoint transfer type implemented
|
||||||
|
HID_INT_OUT_EP_SIZE, //LSB - endpoint size
|
||||||
|
0x00, //MSB - endpoint size
|
||||||
|
0x01 //bInterval
|
||||||
|
};
|
||||||
|
|
||||||
|
ROM struct{uint8_t bLength;uint8_t bDscType;uint16_t string[1];}sd000={
|
||||||
|
sizeof(sd000),DSC_STR,0x0409};
|
||||||
|
|
||||||
|
ROM struct{uint8_t bLength;uint8_t bDscType;uint16_t string[25];}sd001={
|
||||||
|
sizeof(sd001),DSC_STR,
|
||||||
|
'M','i','c','r','o','c','h','i','p',' ',
|
||||||
|
'T','e','c','h','n','o','l','o','g','y',' ','I','n','c','.'};
|
||||||
|
|
||||||
|
ROM struct{uint8_t bLength;uint8_t bDscType;uint16_t string[18];}sd002={
|
||||||
|
sizeof(sd002),DSC_STR,
|
||||||
|
'H','I','D',' ','U','S','B',' ','B','o','o',
|
||||||
|
't','l','o','a','d','e','r'};
|
||||||
|
|
||||||
|
ROM uint8_t hid_rpt01[HID_RPT01_SIZE]=
|
||||||
|
// First byte in each row is the "item". First byte's two least significant
|
||||||
|
// bits are the number of data bytes that follow, but encoded (0=0, 1=1, 2=2, 3=4 bytes).
|
||||||
|
// bSize should match number of bytes that follow, or REPORT descriptor parser won't work. The bytes
|
||||||
|
// that follow in each item line are data bytes
|
||||||
|
{
|
||||||
|
0x06, 0x00, 0xFF, // Usage Page = 0xFF00 (Vendor Defined Page 1)
|
||||||
|
0x09, 0x01, // Usage (Vendor Usage 1)
|
||||||
|
0xA1, 0x01, // Collection (Application)
|
||||||
|
0x19, 0x01, // Usage Minimum
|
||||||
|
0x29, 0x40, // Usage Maximum //64 input usages total (0x01 to 0x40)
|
||||||
|
0x15, 0x00, // Logical Minimum (data bytes in the report may have minimum value = 0x00)
|
||||||
|
0x26, 0xFF, 0x00, // Logical Maximum (data bytes in the report may have maximum value = 0x00FF = unsigned 255)
|
||||||
|
0x75, 0x08, // Report Size: 8-bit field size
|
||||||
|
0x95, 0x40, // Report Count: Make sixty-four 8-bit fields (the next time the parser hits an "Input", "Output", or "Feature" item)
|
||||||
|
0x81, 0x00, // Input (Data, Array, Abs): Instantiates input packet fields based on the above report size, count, logical min/max, and usage.
|
||||||
|
0x19, 0x01, // Usage Minimum
|
||||||
|
0x29, 0x40, // Usage Maximum //64 output usages total (0x01 to 0x40)
|
||||||
|
0x91, 0x00, // Output (Data, Array, Abs): Instantiates output packet fields. Uses same report size and count as "Input" fields, since nothing new/different was specified to the parser since the "Input" item.
|
||||||
|
0xC0 // End Collection
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
ROM unsigned char* ROM USB_SD_Ptr[]=
|
||||||
|
{
|
||||||
|
(ROM const unsigned char *ROM)&sd000,
|
||||||
|
(ROM const unsigned char *ROM)&sd001,
|
||||||
|
(ROM const unsigned char *ROM)&sd002
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __XC8__
|
||||||
|
#pragma code
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** EOF usb_descriptors.c ****************************************************/
|
||||||
1626
bootloader_hacked_from_mla/src/usb_device.c
Normal file
1626
bootloader_hacked_from_mla/src/usb_device.c
Normal file
File diff suppressed because it is too large
Load Diff
699
bootloader_hacked_from_mla/src/usb_device.h
Normal file
699
bootloader_hacked_from_mla/src/usb_device.h
Normal file
@@ -0,0 +1,699 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
Copyright 2016 Microchip Technology Inc. (www.microchip.com)
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
To request to license the code under the MLA license (www.microchip.com/mla_license),
|
||||||
|
please contact mla_licensing@microchip.com
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _USB_DEVICE_H
|
||||||
|
#define _USB_DEVICE_H
|
||||||
|
|
||||||
|
/** I N C L U D E S **********************************************************/
|
||||||
|
#include "usb.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Hardware abstraction. The USBIF and USBIE bits reside in different registers
|
||||||
|
//on different USB microcontrollers.
|
||||||
|
#if defined(__18F45K50) || defined(__18F25K50) || defined(__18F24K50) || defined(__18LF45K50) || defined(__18LF25K50) || defined(__18LF24K50)
|
||||||
|
#define USBIF_FLAG PIR3bits.USBIF
|
||||||
|
#define USBIE_BIT PIE3bits.USBIE
|
||||||
|
#else
|
||||||
|
#define USBIF_FLAG PIR2bits.USBIF
|
||||||
|
#define USBIE_BIT PIE2bits.USBIE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/** D E F I N I T I O N S ****************************************************/
|
||||||
|
/******************************************************************************
|
||||||
|
* Standard Request Codes
|
||||||
|
* USB 2.0 Spec Ref Table 9-4
|
||||||
|
*****************************************************************************/
|
||||||
|
#define GET_STATUS 0
|
||||||
|
#define CLR_FEATURE 1
|
||||||
|
#define SET_FEATURE 3
|
||||||
|
#define SET_ADR 5
|
||||||
|
#define GET_DSC 6
|
||||||
|
#define SET_DSC 7
|
||||||
|
#define GET_CFG 8
|
||||||
|
#define SET_CFG 9
|
||||||
|
#define GET_INTF 10
|
||||||
|
#define SET_INTF 11
|
||||||
|
#define SYNCH_FRAME 12
|
||||||
|
|
||||||
|
/* Standard Feature Selectors */
|
||||||
|
#define DEVICE_REMOTE_WAKEUP 0x01
|
||||||
|
#define ENDPOINT_HALT 0x00
|
||||||
|
|
||||||
|
|
||||||
|
/* UCFG Initialization Parameters */
|
||||||
|
#define _PPBM0 0x00 // Pingpong Buffer Mode 0 - ping pong bufferring disabled
|
||||||
|
#define _PPBM1 0x01 // Pingpong Buffer Mode 1 - ping pong on EP0 OUT only
|
||||||
|
#define _PPBM2 0x02 // Pingpong Buffer Mode 2 - ping pong on all endpoints
|
||||||
|
#define _LS 0x00 // Use Low-Speed USB Mode
|
||||||
|
#define _FS 0x04 // Use Full-Speed USB Mode
|
||||||
|
#define _TRINT 0x00 // Use internal transceiver
|
||||||
|
#define _TREXT 0x08 // Use external transceiver
|
||||||
|
#define _PUEN 0x10 // Use internal pull-up resistor
|
||||||
|
#define _OEMON 0x40 // Use SIE output indicator
|
||||||
|
#define _UTEYE 0x80 // Use Eye-Pattern test
|
||||||
|
|
||||||
|
/* UEPn Initialization Parameters */
|
||||||
|
#define EP_CTRL 0x06 // Cfg Control pipe for this ep
|
||||||
|
#define EP_OUT 0x0C // Cfg OUT only pipe for this ep
|
||||||
|
#define EP_IN 0x0A // Cfg IN only pipe for this ep
|
||||||
|
#define EP_OUT_IN 0x0E // Cfg both OUT & IN pipes for this ep
|
||||||
|
#define HSHK_EN 0x10 // Enable handshake packet
|
||||||
|
// Handshake should be disable for isoch
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* USB - PICmicro Endpoint Definitions
|
||||||
|
* PICmicro EP Address Format: X:EP3:EP2:EP1:EP0:DIR:PPBI:X
|
||||||
|
* This is used when checking the value read from USTAT
|
||||||
|
*
|
||||||
|
* NOTE: These definitions are not used in the descriptors.
|
||||||
|
* EP addresses used in the descriptors have different format and
|
||||||
|
* are defined in: usb_device.h
|
||||||
|
*****************************************************************************/
|
||||||
|
#define OUT 0
|
||||||
|
#define IN 1
|
||||||
|
|
||||||
|
#define PIC_EP_NUM_MASK 0b01111000
|
||||||
|
#define PIC_EP_DIR_MASK 0b00000100
|
||||||
|
|
||||||
|
#define EP00_OUT ((0x00<<3)|(OUT<<2))
|
||||||
|
#define EP00_IN ((0x00<<3)|(IN<<2))
|
||||||
|
#define EP01_OUT ((0x01<<3)|(OUT<<2))
|
||||||
|
#define EP01_IN ((0x01<<3)|(IN<<2))
|
||||||
|
#define EP02_OUT ((0x02<<3)|(OUT<<2))
|
||||||
|
#define EP02_IN ((0x02<<3)|(IN<<2))
|
||||||
|
#define EP03_OUT ((0x03<<3)|(OUT<<2))
|
||||||
|
#define EP03_IN ((0x03<<3)|(IN<<2))
|
||||||
|
#define EP04_OUT ((0x04<<3)|(OUT<<2))
|
||||||
|
#define EP04_IN ((0x04<<3)|(IN<<2))
|
||||||
|
#define EP05_OUT ((0x05<<3)|(OUT<<2))
|
||||||
|
#define EP05_IN ((0x05<<3)|(IN<<2))
|
||||||
|
#define EP06_OUT ((0x06<<3)|(OUT<<2))
|
||||||
|
#define EP06_IN ((0x06<<3)|(IN<<2))
|
||||||
|
#define EP07_OUT ((0x07<<3)|(OUT<<2))
|
||||||
|
#define EP07_IN ((0x07<<3)|(IN<<2))
|
||||||
|
#define EP08_OUT ((0x08<<3)|(OUT<<2))
|
||||||
|
#define EP08_IN ((0x08<<3)|(IN<<2))
|
||||||
|
#define EP09_OUT ((0x09<<3)|(OUT<<2))
|
||||||
|
#define EP09_IN ((0x09<<3)|(IN<<2))
|
||||||
|
#define EP10_OUT ((0x0A<<3)|(OUT<<2))
|
||||||
|
#define EP10_IN ((0x0A<<3)|(IN<<2))
|
||||||
|
#define EP11_OUT ((0x0B<<3)|(OUT<<2))
|
||||||
|
#define EP11_IN ((0x0B<<3)|(IN<<2))
|
||||||
|
#define EP12_OUT ((0x0C<<3)|(OUT<<2))
|
||||||
|
#define EP12_IN ((0x0C<<3)|(IN<<2))
|
||||||
|
#define EP13_OUT ((0x0D<<3)|(OUT<<2))
|
||||||
|
#define EP13_IN ((0x0D<<3)|(IN<<2))
|
||||||
|
#define EP14_OUT ((0x0E<<3)|(OUT<<2))
|
||||||
|
#define EP14_IN ((0x0E<<3)|(IN<<2))
|
||||||
|
#define EP15_OUT ((0x0F<<3)|(OUT<<2))
|
||||||
|
#define EP15_IN ((0x0F<<3)|(IN<<2))
|
||||||
|
|
||||||
|
#define EP0_OUT_EVEN_BDT_INDEX 0
|
||||||
|
#define EP0_OUT_ODD_BDT_INDEX 1
|
||||||
|
|
||||||
|
|
||||||
|
/* Buffer Descriptor Status Register Initialization Parameters */
|
||||||
|
#define _BSTALL 0x04 //Buffer Stall enable
|
||||||
|
#define _DTSEN 0x08 //Data Toggle Synch enable
|
||||||
|
#define _INCDIS 0x10 //Address increment disable
|
||||||
|
#define _KEN 0x20 //SIE keeps buff descriptors enable
|
||||||
|
#define _DAT0 0x00 //DATA0 packet expected next
|
||||||
|
#define _DAT1 0x40 //DATA1 packet expected next
|
||||||
|
#define _DTSMASK 0x40 //DTS Mask
|
||||||
|
#define _USIE 0x80 //SIE owns buffer
|
||||||
|
#define _UCPU 0x00 //CPU owns buffer
|
||||||
|
|
||||||
|
/* USB Device States - To be used with [byte usb_device_state] */
|
||||||
|
#define DETACHED_STATE 0
|
||||||
|
#define ATTACHED_STATE 1
|
||||||
|
#define POWERED_STATE 2
|
||||||
|
#define DEFAULT_STATE 3
|
||||||
|
#define ADR_PENDING_STATE 4
|
||||||
|
#define ADDRESS_STATE 5
|
||||||
|
#define CONFIGURED_STATE 6
|
||||||
|
|
||||||
|
/* Memory Types for Control Transfer - used in USB_DEVICE_STATUS */
|
||||||
|
#define _RAM 0
|
||||||
|
#define _ROM 1
|
||||||
|
|
||||||
|
/* Descriptor Types */
|
||||||
|
#define DSC_DEV 0x01
|
||||||
|
#define DSC_CFG 0x02
|
||||||
|
#define DSC_STR 0x03
|
||||||
|
#define DSC_INTF 0x04
|
||||||
|
#define DSC_EP 0x05
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* USB Endpoint Definitions
|
||||||
|
* USB Standard EP Address Format: DIR:X:X:X:EP3:EP2:EP1:EP0
|
||||||
|
* This is used in the descriptors. See usb_descriptors.c
|
||||||
|
*
|
||||||
|
* NOTE: Do not use these values for checking against USTAT.
|
||||||
|
* To check against USTAT, use values defined in "usb_device.h"
|
||||||
|
*****************************************************************************/
|
||||||
|
#define _EP01_OUT 0x01
|
||||||
|
#define _EP01_IN 0x81
|
||||||
|
#define _EP02_OUT 0x02
|
||||||
|
#define _EP02_IN 0x82
|
||||||
|
#define _EP03_OUT 0x03
|
||||||
|
#define _EP03_IN 0x83
|
||||||
|
#define _EP04_OUT 0x04
|
||||||
|
#define _EP04_IN 0x84
|
||||||
|
#define _EP05_OUT 0x05
|
||||||
|
#define _EP05_IN 0x85
|
||||||
|
#define _EP06_OUT 0x06
|
||||||
|
#define _EP06_IN 0x86
|
||||||
|
#define _EP07_OUT 0x07
|
||||||
|
#define _EP07_IN 0x87
|
||||||
|
#define _EP08_OUT 0x08
|
||||||
|
#define _EP08_IN 0x88
|
||||||
|
#define _EP09_OUT 0x09
|
||||||
|
#define _EP09_IN 0x89
|
||||||
|
#define _EP10_OUT 0x0A
|
||||||
|
#define _EP10_IN 0x8A
|
||||||
|
#define _EP11_OUT 0x0B
|
||||||
|
#define _EP11_IN 0x8B
|
||||||
|
#define _EP12_OUT 0x0C
|
||||||
|
#define _EP12_IN 0x8C
|
||||||
|
#define _EP13_OUT 0x0D
|
||||||
|
#define _EP13_IN 0x8D
|
||||||
|
#define _EP14_OUT 0x0E
|
||||||
|
#define _EP14_IN 0x8E
|
||||||
|
#define _EP15_OUT 0x0F
|
||||||
|
#define _EP15_IN 0x8F
|
||||||
|
|
||||||
|
/* Configuration Attributes */
|
||||||
|
#define _DEFAULT 0x01<<7 //Default Value (Bit 7 is set)
|
||||||
|
#define _SELF 0x01<<6 //Self-powered (Supports if set)
|
||||||
|
#define _RWU 0x01<<5 //Remote Wakeup (Supports if set)
|
||||||
|
|
||||||
|
/* Endpoint Transfer Type */
|
||||||
|
#define _CTRL 0x00 //Control Transfer
|
||||||
|
#define _ISO 0x01 //Isochronous Transfer
|
||||||
|
#define _BULK 0x02 //Bulk Transfer
|
||||||
|
#define _INT 0x03 //Interrupt Transfer
|
||||||
|
|
||||||
|
/* Isochronous Endpoint Synchronization Type */
|
||||||
|
#define _NS 0x00<<2 //No Synchronization
|
||||||
|
#define _AS 0x01<<2 //Asynchronous
|
||||||
|
#define _AD 0x02<<2 //Adaptive
|
||||||
|
#define _SY 0x03<<2 //Synchronous
|
||||||
|
|
||||||
|
/* Isochronous Endpoint Usage Type */
|
||||||
|
#define _DE 0x00<<4 //Data endpoint
|
||||||
|
#define _FE 0x01<<4 //Feedback endpoint
|
||||||
|
#define _IE 0x02<<4 //Implicit feedback Data endpoint
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** T Y P E S ****************************************************************/
|
||||||
|
typedef union _USB_DEVICE_STATUS
|
||||||
|
{
|
||||||
|
uint8_t _byte;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned RemoteWakeup:1;// [0]Disabled [1]Enabled: See usb_device.c,usb9.c
|
||||||
|
unsigned ctrl_trf_mem:1;// [0]RAM [1]ROM
|
||||||
|
};
|
||||||
|
} USB_DEVICE_STATUS;
|
||||||
|
|
||||||
|
typedef union _BD_STAT
|
||||||
|
{
|
||||||
|
uint8_t _byte;
|
||||||
|
struct{
|
||||||
|
unsigned BC8:1;
|
||||||
|
unsigned BC9:1;
|
||||||
|
unsigned BSTALL:1; //Buffer Stall Enable
|
||||||
|
unsigned DTSEN:1; //Data Toggle Synch Enable
|
||||||
|
unsigned INCDIS:1; //Address Increment Disable
|
||||||
|
unsigned KEN:1; //BD Keep Enable
|
||||||
|
unsigned DTS:1; //Data Toggle Synch Value
|
||||||
|
unsigned UOWN:1; //USB Ownership
|
||||||
|
};
|
||||||
|
struct{
|
||||||
|
unsigned :2;
|
||||||
|
unsigned PID0:1;
|
||||||
|
unsigned PID1:1;
|
||||||
|
unsigned PID2:1;
|
||||||
|
unsigned PID3:1;
|
||||||
|
unsigned :2;
|
||||||
|
};
|
||||||
|
struct{
|
||||||
|
unsigned :2;
|
||||||
|
unsigned PID:4; //Packet Identifier
|
||||||
|
unsigned :2;
|
||||||
|
};
|
||||||
|
} BD_STAT; //Buffer Descriptor Status Register
|
||||||
|
|
||||||
|
typedef union _BDT
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
BD_STAT Stat;
|
||||||
|
uint8_t Cnt;
|
||||||
|
uint8_t ADRL; //Buffer Address Low
|
||||||
|
uint8_t ADRH; //Buffer Address High
|
||||||
|
};
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
uint8_t* ADR; //Buffer Address
|
||||||
|
};
|
||||||
|
} BDT; //Buffer Descriptor Table
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* CTRL_TRF_SETUP:
|
||||||
|
*
|
||||||
|
* Every setup packet has 8 bytes.
|
||||||
|
* However, the buffer size has to equal the EP0_BUFF_SIZE value specified
|
||||||
|
* in usb_config.h
|
||||||
|
* The value of EP0_BUFF_SIZE can be 8, 16, 32, or 64.
|
||||||
|
*
|
||||||
|
* First 8 bytes are defined to be directly addressable to improve speed
|
||||||
|
* and reduce code size.
|
||||||
|
* Bytes beyond the 8th byte have to be accessed using indirect addressing.
|
||||||
|
*****************************************************************************/
|
||||||
|
typedef union _CTRL_TRF_SETUP
|
||||||
|
{
|
||||||
|
/** Array for indirect addressing ****************************************/
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint8_t _byte[EP0_BUFF_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Standard Device Requests *********************************************/
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint8_t bmRequestType;
|
||||||
|
uint8_t bRequest;
|
||||||
|
uint16_t wValue;
|
||||||
|
uint16_t wIndex;
|
||||||
|
uint16_t wLength;
|
||||||
|
};
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
WORD_VAL W_Value;
|
||||||
|
WORD_VAL W_Index;
|
||||||
|
WORD_VAL W_Length;
|
||||||
|
};
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned Recipient:5; //Device,Interface,Endpoint,Other
|
||||||
|
unsigned RequestType:2; //Standard,Class,Vendor,Reserved
|
||||||
|
unsigned DataDir:1; //Host-to-device,Device-to-host
|
||||||
|
unsigned :8;
|
||||||
|
uint8_t bFeature; //DEVICE_REMOTE_WAKEUP,ENDPOINT_HALT
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
};
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
uint8_t bDscIndex; //For Configuration and String DSC Only
|
||||||
|
uint8_t bDscType; //Device,Configuration,String
|
||||||
|
uint16_t wLangID; //Language ID
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
};
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
uint8_t bDevADR; //Device Address 0-127
|
||||||
|
uint8_t bDevADRH; //Must equal zero
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
};
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
uint8_t bCfgValue; //Configuration Value 0-255
|
||||||
|
uint8_t bCfgRSD; //Must equal zero (Reserved)
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
};
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
uint8_t bAltID; //Alternate Setting Value 0-255
|
||||||
|
uint8_t bAltID_H; //Must equal zero
|
||||||
|
uint8_t bIntfID; //Interface Number Value 0-255
|
||||||
|
uint8_t bIntfID_H; //Must equal zero
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
};
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
uint8_t bEPID; //Endpoint ID (Number & Direction)
|
||||||
|
uint8_t bEPID_H; //Must equal zero
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
};
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
unsigned EPNum:4; //Endpoint Number 0-15
|
||||||
|
unsigned :3;
|
||||||
|
unsigned EPDir:1; //Endpoint Direction: 0-OUT, 1-IN
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
unsigned :8;
|
||||||
|
};
|
||||||
|
/** End: Standard Device Requests ****************************************/
|
||||||
|
|
||||||
|
} CTRL_TRF_SETUP;
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* CTRL_TRF_DATA:
|
||||||
|
*
|
||||||
|
* Buffer size has to equal the EP0_BUFF_SIZE value specified
|
||||||
|
* in usb_config.h
|
||||||
|
* The value of EP0_BUFF_SIZE can be 8, 16, 32, or 64.
|
||||||
|
*
|
||||||
|
* First 8 bytes are defined to be directly addressable to improve speed
|
||||||
|
* and reduce code size.
|
||||||
|
* Bytes beyond the 8th byte have to be accessed using indirect addressing.
|
||||||
|
*****************************************************************************/
|
||||||
|
typedef union _CTRL_TRF_DATA
|
||||||
|
{
|
||||||
|
/** Array for indirect addressing ****************************************/
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint8_t _byte[EP0_BUFF_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
/** First 8-byte direct addressing ***************************************/
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint8_t _byte0;
|
||||||
|
uint8_t _byte1;
|
||||||
|
uint8_t _byte2;
|
||||||
|
uint8_t _byte3;
|
||||||
|
uint8_t _byte4;
|
||||||
|
uint8_t _byte5;
|
||||||
|
uint8_t _byte6;
|
||||||
|
uint8_t _byte7;
|
||||||
|
};
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint16_t _word0;
|
||||||
|
uint16_t _word1;
|
||||||
|
uint16_t _word2;
|
||||||
|
uint16_t _word3;
|
||||||
|
};
|
||||||
|
|
||||||
|
} CTRL_TRF_DATA;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* USB Device Descriptor Structure
|
||||||
|
*****************************************************************************/
|
||||||
|
typedef struct _USB_DEV_DSC
|
||||||
|
{
|
||||||
|
uint8_t bLength; uint8_t bDscType; uint16_t bcdUSB;
|
||||||
|
uint8_t bDevCls; uint8_t bDevSubCls; uint8_t bDevProtocol;
|
||||||
|
uint8_t bMaxPktSize0; uint16_t idVendor; uint16_t idProduct;
|
||||||
|
uint16_t bcdDevice; uint8_t iMFR; uint8_t iProduct;
|
||||||
|
uint8_t iSerialNum; uint8_t bNumCfg;
|
||||||
|
} USB_DEV_DSC;
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* USB Configuration Descriptor Structure
|
||||||
|
*****************************************************************************/
|
||||||
|
typedef struct _USB_CFG_DSC
|
||||||
|
{
|
||||||
|
uint8_t bLength; uint8_t bDscType; uint16_t wTotalLength;
|
||||||
|
uint8_t bNumIntf; uint8_t bCfgValue; uint8_t iCfg;
|
||||||
|
uint8_t bmAttributes; uint8_t bMaxPower;
|
||||||
|
} USB_CFG_DSC;
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* USB Interface Descriptor Structure
|
||||||
|
*****************************************************************************/
|
||||||
|
typedef struct _USB_INTF_DSC
|
||||||
|
{
|
||||||
|
uint8_t bLength; uint8_t bDscType; uint8_t bIntfNum;
|
||||||
|
uint8_t bAltSetting; uint8_t bNumEPs; uint8_t bIntfCls;
|
||||||
|
uint8_t bIntfSubCls; uint8_t bIntfProtocol; uint8_t iIntf;
|
||||||
|
} USB_INTF_DSC;
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* USB Endpoint Descriptor Structure
|
||||||
|
*****************************************************************************/
|
||||||
|
typedef struct _USB_EP_DSC
|
||||||
|
{
|
||||||
|
uint8_t bLength; uint8_t bDscType; uint8_t bEPAdr;
|
||||||
|
uint8_t bmAttributes; uint16_t wMaxPktSize; uint8_t bInterval;
|
||||||
|
} USB_EP_DSC;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Macro: void mInitializeUSBDriver(void)
|
||||||
|
*
|
||||||
|
* PreCondition: None
|
||||||
|
*
|
||||||
|
* Input: None
|
||||||
|
*
|
||||||
|
* Output: None
|
||||||
|
*
|
||||||
|
* Side Effects: None
|
||||||
|
*
|
||||||
|
* Overview: Configures the USB module, definition of UCFG_VAL can be
|
||||||
|
* found in usb_config.h
|
||||||
|
*
|
||||||
|
* This register determines: USB Speed, On-chip pull-up
|
||||||
|
* resistor selection, On-chip tranceiver selection, bus
|
||||||
|
* eye pattern generation mode, Ping-pong buffering mode
|
||||||
|
* selection.
|
||||||
|
*
|
||||||
|
* Note: None
|
||||||
|
*****************************************************************************/
|
||||||
|
#define mInitializeUSBDriver() {UCFG = UCFG_VAL; \
|
||||||
|
usb_device_state = DETACHED_STATE; \
|
||||||
|
USBProtocolResetHandler();}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Macro: void mDisableEP1to15(void)
|
||||||
|
*
|
||||||
|
* PreCondition: None
|
||||||
|
*
|
||||||
|
* Input: None
|
||||||
|
*
|
||||||
|
* Output: None
|
||||||
|
*
|
||||||
|
* Side Effects: None
|
||||||
|
*
|
||||||
|
* Overview: This macro disables all endpoints except EP0.
|
||||||
|
* This macro should be called when the host sends a RESET
|
||||||
|
* signal or a SET_CONFIGURATION request.
|
||||||
|
*
|
||||||
|
* Note: None
|
||||||
|
*****************************************************************************/
|
||||||
|
//#if defined(__18F14K50) || defined(__18F13K50) || defined(__18LF14K50) || defined(__18LF13K50)
|
||||||
|
// #define mDisableEP1to15() ClearArray((uint8_t*)&UEP1,7);
|
||||||
|
//#else
|
||||||
|
// #define mDisableEP1to15() ClearArray((uint8_t*)&UEP1,15);
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
//Using below instead to save code space. Dedicated bootloader project,
|
||||||
|
//will never use UEP3+, therefore no need to really mess with those registers
|
||||||
|
#define mDisableEP1to7() UEP1=0x00;UEP2=0x00;UEP3=0x00;\
|
||||||
|
UEP4=0x00;UEP5=0x00;UEP6=0x00;UEP7=0x00;
|
||||||
|
// UEP8=0x00;UEP9=0x00;UEP10=0x00;UEP11=0x00;\
|
||||||
|
// UEP12=0x00;UEP13=0x00;UEP14=0x00;UEP15=0x00;
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Macro: void mUSBBufferReady(buffer_dsc)
|
||||||
|
*
|
||||||
|
* PreCondition: IN Endpoint: Buffer is loaded and ready to be sent.
|
||||||
|
* OUT Endpoint: Buffer is free to be written to by SIE.
|
||||||
|
*
|
||||||
|
* Input: byte buffer_dsc: Root name of the buffer descriptor group.
|
||||||
|
* i.e. ep0Bo, ep1Bi, ... Declared in usbmmap.c
|
||||||
|
* Names can be remapped for readability, see examples in
|
||||||
|
* usb_config.h (#define HID_BD_OUT ep1Bo)
|
||||||
|
*
|
||||||
|
* Output: None
|
||||||
|
*
|
||||||
|
* Side Effects: None
|
||||||
|
*
|
||||||
|
* Overview: This macro should be called each time after:
|
||||||
|
* 1. A non-EP0 IN endpoint buffer is populated with data.
|
||||||
|
* 2. A non-EP0 OUT endpoint buffer is read.
|
||||||
|
* This macro turns the buffer ownership to SIE for servicing.
|
||||||
|
* It also toggles the DTS bit for synchronization.
|
||||||
|
*
|
||||||
|
* Note: None
|
||||||
|
*****************************************************************************/
|
||||||
|
#define mUSBBufferReady(buffer_dsc) \
|
||||||
|
{ \
|
||||||
|
buffer_dsc.Stat._byte &= _DTSMASK; /* Save only DTS bit */ \
|
||||||
|
buffer_dsc.Stat.DTS = !buffer_dsc.Stat.DTS; /* Toggle DTS bit */ \
|
||||||
|
buffer_dsc.Stat._byte |= _DTSEN; /* Configure other settings */ \
|
||||||
|
buffer_dsc.Stat._byte |= _USIE; /* Turn ownership to SIE */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** D E F I N I T I O N S ****************************************************/
|
||||||
|
/*
|
||||||
|
* MUID = Microchip USB Class ID
|
||||||
|
* Used to identify which of the USB classes owns the current
|
||||||
|
* session of control transfer over EP0
|
||||||
|
*/
|
||||||
|
#define MUID_NULL 0
|
||||||
|
#define MUID_USB9 1
|
||||||
|
#define MUID_HID 2
|
||||||
|
#define MUID_CDC 3
|
||||||
|
|
||||||
|
|
||||||
|
/* Control Transfer States */
|
||||||
|
#define WAIT_SETUP 0
|
||||||
|
#define CTRL_TRF_TX 1
|
||||||
|
#define CTRL_TRF_RX 2
|
||||||
|
|
||||||
|
/* Short Packet States - Used by Control Transfer Read - CTRL_TRF_TX */
|
||||||
|
#define SHORT_PKT_NOT_SENT 0
|
||||||
|
#define SHORT_PKT_PENDING 1
|
||||||
|
#define SHORT_PKT_SENT 2
|
||||||
|
|
||||||
|
/* USB PID: Token Types - See chapter 8 in the USB specification */
|
||||||
|
#define SETUP_TOKEN 0b00001101
|
||||||
|
#define OUT_TOKEN 0b00000001
|
||||||
|
#define IN_TOKEN 0b00001001
|
||||||
|
|
||||||
|
/* bmRequestType Definitions */
|
||||||
|
#define HOST_TO_DEV 0
|
||||||
|
#define DEV_TO_HOST 1
|
||||||
|
|
||||||
|
#define STANDARD 0x00
|
||||||
|
#define CLASS 0x01
|
||||||
|
#define VENDOR 0x02
|
||||||
|
|
||||||
|
#define RCPT_DEV 0
|
||||||
|
#define RCPT_INTF 1
|
||||||
|
#define RCPT_EP 2
|
||||||
|
#define RCPT_OTH 3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** E X T E R N S ************************************************************/
|
||||||
|
extern uint8_t ctrl_trf_session_owner;
|
||||||
|
extern POINTER pSrc;
|
||||||
|
extern POINTER pDst;
|
||||||
|
extern WORD_VAL wCount;
|
||||||
|
extern uint8_t usb_device_state;
|
||||||
|
extern USB_DEVICE_STATUS usb_stat;
|
||||||
|
extern uint8_t usb_active_cfg;
|
||||||
|
extern uint8_t usb_alt_intf[MAX_NUM_INT];
|
||||||
|
|
||||||
|
extern volatile BDT ep0Bo; //Endpoint #0 BD Out
|
||||||
|
extern volatile BDT ep0Bi; //Endpoint #0 BD In
|
||||||
|
extern volatile BDT ep1Bo; //Endpoint #1 BD Out
|
||||||
|
extern volatile BDT ep1Bi; //Endpoint #1 BD In
|
||||||
|
extern volatile BDT ep2Bo; //Endpoint #2 BD Out
|
||||||
|
extern volatile BDT ep2Bi; //Endpoint #2 BD In
|
||||||
|
extern volatile BDT ep3Bo; //Endpoint #3 BD Out
|
||||||
|
extern volatile BDT ep3Bi; //Endpoint #3 BD In
|
||||||
|
extern volatile BDT ep4Bo; //Endpoint #4 BD Out
|
||||||
|
extern volatile BDT ep4Bi; //Endpoint #4 BD In
|
||||||
|
extern volatile BDT ep5Bo; //Endpoint #5 BD Out
|
||||||
|
extern volatile BDT ep5Bi; //Endpoint #5 BD In
|
||||||
|
extern volatile BDT ep6Bo; //Endpoint #6 BD Out
|
||||||
|
extern volatile BDT ep6Bi; //Endpoint #6 BD In
|
||||||
|
extern volatile BDT ep7Bo; //Endpoint #7 BD Out
|
||||||
|
extern volatile BDT ep7Bi; //Endpoint #7 BD In
|
||||||
|
extern volatile BDT ep8Bo; //Endpoint #8 BD Out
|
||||||
|
extern volatile BDT ep8Bi; //Endpoint #8 BD In
|
||||||
|
extern volatile BDT ep9Bo; //Endpoint #9 BD Out
|
||||||
|
extern volatile BDT ep9Bi; //Endpoint #9 BD In
|
||||||
|
extern volatile BDT ep10Bo; //Endpoint #10 BD Out
|
||||||
|
extern volatile BDT ep10Bi; //Endpoint #10 BD In
|
||||||
|
extern volatile BDT ep11Bo; //Endpoint #11 BD Out
|
||||||
|
extern volatile BDT ep11Bi; //Endpoint #11 BD In
|
||||||
|
extern volatile BDT ep12Bo; //Endpoint #12 BD Out
|
||||||
|
extern volatile BDT ep12Bi; //Endpoint #12 BD In
|
||||||
|
extern volatile BDT ep13Bo; //Endpoint #13 BD Out
|
||||||
|
extern volatile BDT ep13Bi; //Endpoint #13 BD In
|
||||||
|
extern volatile BDT ep14Bo; //Endpoint #14 BD Out
|
||||||
|
extern volatile BDT ep14Bi; //Endpoint #14 BD In
|
||||||
|
extern volatile BDT ep15Bo; //Endpoint #15 BD Out
|
||||||
|
extern volatile BDT ep15Bi; //Endpoint #15 BD In
|
||||||
|
|
||||||
|
extern CTRL_TRF_SETUP SetupPkt;
|
||||||
|
volatile extern CTRL_TRF_DATA CtrlTrfData;
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(USB_USE_HID)
|
||||||
|
extern volatile unsigned char hid_report_out[HID_INT_OUT_EP_SIZE];
|
||||||
|
extern volatile unsigned char hid_report_in[HID_INT_IN_EP_SIZE];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
extern ROM USB_DEV_DSC device_dsc;
|
||||||
|
extern ROM uint8_t CFG01[CONFIG_DESC_TOTAL_LEN];
|
||||||
|
extern ROM const unsigned char *ROM USB_CD_Ptr[];
|
||||||
|
extern ROM unsigned char* ROM USB_SD_Ptr[];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** P U B L I C P R O T O T Y P E S *****************************************/
|
||||||
|
void USBDeviceInit(void);
|
||||||
|
void USBCheckBusStatus(void);
|
||||||
|
void USBSoftAttach(void);
|
||||||
|
void USBSoftDetach(void);
|
||||||
|
void USBDeviceTasks(void);
|
||||||
|
void USBDisableWithLongDelay(void);
|
||||||
|
void DelayRoutine(unsigned int DelayAmount);
|
||||||
|
void ClearWatchdog(void);
|
||||||
|
#define USBGetDeviceState() usb_device_state
|
||||||
|
#define USBIsDeviceSuspended() UCONbits.SUSPND
|
||||||
|
|
||||||
|
|
||||||
|
#endif //_USB_DEVICE_H
|
||||||
302
bootloader_hacked_from_mla/src/usb_device_hid.c
Normal file
302
bootloader_hacked_from_mla/src/usb_device_hid.c
Normal file
@@ -0,0 +1,302 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
Copyright 2016 Microchip Technology Inc. (www.microchip.com)
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
To request to license the code under the MLA license (www.microchip.com/mla_license),
|
||||||
|
please contact mla_licensing@microchip.com
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
/** I N C L U D E S **********************************************************/
|
||||||
|
#include "usb.h"
|
||||||
|
|
||||||
|
#ifdef USB_USE_HID
|
||||||
|
|
||||||
|
/** V A R I A B L E S ********************************************************/
|
||||||
|
#ifndef __XC8__
|
||||||
|
#pragma udata
|
||||||
|
#endif
|
||||||
|
uint8_t idle_rate;
|
||||||
|
uint8_t active_protocol; // [0] Boot Protocol [1] Report Protocol
|
||||||
|
uint8_t hid_rpt_rx_len;
|
||||||
|
|
||||||
|
/** P R I V A T E P R O T O T Y P E S ***************************************/
|
||||||
|
void HIDGetReportHandler(void);
|
||||||
|
void HIDSetReportHandler(void);
|
||||||
|
|
||||||
|
/** D E C L A R A T I O N S **************************************************/
|
||||||
|
#ifndef __XC8__
|
||||||
|
#pragma code
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** C L A S S S P E C I F I C R E Q ****************************************/
|
||||||
|
/******************************************************************************
|
||||||
|
* Function: void USBCheckHIDRequest(void)
|
||||||
|
*
|
||||||
|
* PreCondition: None
|
||||||
|
*
|
||||||
|
* Input: None
|
||||||
|
*
|
||||||
|
* Output: None
|
||||||
|
*
|
||||||
|
* Side Effects: None
|
||||||
|
*
|
||||||
|
* Overview: This routine checks the setup data packet to see if it
|
||||||
|
* knows how to handle it
|
||||||
|
*
|
||||||
|
* Note: None
|
||||||
|
*****************************************************************************/
|
||||||
|
void USBCheckHIDRequest(void)
|
||||||
|
{
|
||||||
|
if(SetupPkt.Recipient != RCPT_INTF) return;
|
||||||
|
if(SetupPkt.bIntfID != HID_INTF_ID) return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There are two standard requests that hid.c may support.
|
||||||
|
* 1. GET_DSC(DSC_HID,DSC_RPT,DSC_PHY);
|
||||||
|
* 2. SET_DSC(DSC_HID,DSC_RPT,DSC_PHY);
|
||||||
|
*/
|
||||||
|
if(SetupPkt.bRequest == GET_DSC)
|
||||||
|
{
|
||||||
|
switch(SetupPkt.bDscType)
|
||||||
|
{
|
||||||
|
case DSC_HID:
|
||||||
|
ctrl_trf_session_owner = MUID_HID;
|
||||||
|
pSrc.bRom = &CFG01[18]; //18 is a magic number (offset from start of configuration descriptor, to the start of the HID descriptor)
|
||||||
|
wCount.Val = sizeof(USB_HID_DSC);
|
||||||
|
break;
|
||||||
|
case DSC_RPT:
|
||||||
|
ctrl_trf_session_owner = MUID_HID;
|
||||||
|
mUSBGetHIDRptDscAdr(pSrc.bRom); // See usb_config.h
|
||||||
|
mUSBGetHIDRptDscSize(wCount.Val); // See usb_config.h
|
||||||
|
break;
|
||||||
|
case DSC_PHY:
|
||||||
|
// ctrl_trf_session_owner = MUID_HID;
|
||||||
|
break;
|
||||||
|
}//end switch(SetupPkt.bDscType)
|
||||||
|
usb_stat.ctrl_trf_mem = _ROM;
|
||||||
|
}//end if(SetupPkt.bRequest == GET_DSC)
|
||||||
|
|
||||||
|
if(SetupPkt.RequestType != CLASS) return;
|
||||||
|
switch(SetupPkt.bRequest)
|
||||||
|
{
|
||||||
|
case GET_REPORT:
|
||||||
|
HIDGetReportHandler();
|
||||||
|
break;
|
||||||
|
case SET_REPORT:
|
||||||
|
HIDSetReportHandler();
|
||||||
|
break;
|
||||||
|
case GET_IDLE:
|
||||||
|
ctrl_trf_session_owner = MUID_HID;
|
||||||
|
pSrc.bRam = (uint8_t*)&idle_rate; // Set source
|
||||||
|
usb_stat.ctrl_trf_mem = _RAM; // Set memory type
|
||||||
|
wCount.v[0] = 1; // Set data count
|
||||||
|
break;
|
||||||
|
case SET_IDLE:
|
||||||
|
ctrl_trf_session_owner = MUID_HID;
|
||||||
|
//idle_rate = MSB(SetupPkt.W_Value);
|
||||||
|
idle_rate = SetupPkt.W_Value.v[1];
|
||||||
|
break;
|
||||||
|
case GET_PROTOCOL:
|
||||||
|
ctrl_trf_session_owner = MUID_HID;
|
||||||
|
pSrc.bRam = (uint8_t*)&active_protocol;// Set source
|
||||||
|
usb_stat.ctrl_trf_mem = _RAM; // Set memory type
|
||||||
|
wCount.v[0] = 1; // Set data count
|
||||||
|
break;
|
||||||
|
case SET_PROTOCOL:
|
||||||
|
ctrl_trf_session_owner = MUID_HID;
|
||||||
|
//active_protocol = LSB(SetupPkt.W_Value);
|
||||||
|
active_protocol = SetupPkt.W_Value.v[0];
|
||||||
|
break;
|
||||||
|
}//end switch(SetupPkt.bRequest)
|
||||||
|
|
||||||
|
}//end USBCheckHIDRequest
|
||||||
|
|
||||||
|
void HIDGetReportHandler(void)
|
||||||
|
{
|
||||||
|
// ctrl_trf_session_owner = MUID_HID;
|
||||||
|
}//end HIDGetReportHandler
|
||||||
|
|
||||||
|
void HIDSetReportHandler(void)
|
||||||
|
{
|
||||||
|
// ctrl_trf_session_owner = MUID_HID;
|
||||||
|
// pDst.bRam = (byte*)&hid_report_out;
|
||||||
|
}//end HIDSetReportHandler
|
||||||
|
|
||||||
|
/** U S E R A P I ***********************************************************/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Function: void HIDInitEP(void)
|
||||||
|
*
|
||||||
|
* PreCondition: None
|
||||||
|
*
|
||||||
|
* Input: None
|
||||||
|
*
|
||||||
|
* Output: None
|
||||||
|
*
|
||||||
|
* Side Effects: None
|
||||||
|
*
|
||||||
|
* Overview: HIDInitEP initializes HID endpoints, buffer descriptors,
|
||||||
|
* internal state-machine, and variables.
|
||||||
|
* It should be called after the USB host has sent out a
|
||||||
|
* SET_CONFIGURATION request.
|
||||||
|
* See USBStdSetCfgHandler() in usb9.c for examples.
|
||||||
|
*
|
||||||
|
* Note: None
|
||||||
|
*****************************************************************************/
|
||||||
|
void HIDInitEP(void)
|
||||||
|
{
|
||||||
|
hid_rpt_rx_len =0;
|
||||||
|
|
||||||
|
HID_UEP = EP_OUT_IN|HSHK_EN; // Enable 2 data pipes
|
||||||
|
|
||||||
|
//Arm the OUT interrupt endpoint so the host can send the first packet of data.
|
||||||
|
HID_BD_OUT.Cnt = sizeof(hid_report_out); // Set buffer size
|
||||||
|
HID_BD_OUT.ADR = (uint8_t*)&hid_report_out; // Set buffer address
|
||||||
|
HID_BD_OUT.Stat._byte = _DAT0|_DTSEN; // Set status
|
||||||
|
HID_BD_OUT.Stat._byte |= _USIE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do not have to init Cnt of IN pipes here.
|
||||||
|
* Reason: Number of bytes to send to the host
|
||||||
|
* varies from one transaction to
|
||||||
|
* another. Cnt should equal the exact
|
||||||
|
* number of bytes to transmit for
|
||||||
|
* a given IN transaction.
|
||||||
|
* This number of bytes will only
|
||||||
|
* be known right before the data is
|
||||||
|
* sent.
|
||||||
|
*/
|
||||||
|
HID_BD_IN.ADR = (uint8_t*)&hid_report_in; // Set buffer address
|
||||||
|
HID_BD_IN.Stat._byte = _UCPU|_DAT1; // Set status
|
||||||
|
|
||||||
|
}//end HIDInitEP
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Function: void HIDTxReport(char *buffer, byte len)
|
||||||
|
*
|
||||||
|
* PreCondition: mHIDTxIsBusy() must return false.
|
||||||
|
*
|
||||||
|
* Value of 'len' must be equal to or smaller than
|
||||||
|
* HID_INT_IN_EP_SIZE
|
||||||
|
* For an interrupt endpoint, the largest buffer size is
|
||||||
|
* 64 bytes.
|
||||||
|
*
|
||||||
|
* Input: buffer : Pointer to the starting location of data bytes
|
||||||
|
* len : Number of bytes to be transferred
|
||||||
|
*
|
||||||
|
* Output: None
|
||||||
|
*
|
||||||
|
* Side Effects: None
|
||||||
|
*
|
||||||
|
* Overview: Use this macro to transfer data located in data memory.
|
||||||
|
*
|
||||||
|
* Remember: mHIDTxIsBusy() must return false before user
|
||||||
|
* can call this function.
|
||||||
|
* Unexpected behavior will occur if this function is called
|
||||||
|
* when mHIDTxIsBusy() == 0
|
||||||
|
*
|
||||||
|
* Typical Usage:
|
||||||
|
* if(!mHIDTxIsBusy())
|
||||||
|
* HIDTxReport(buffer, 3);
|
||||||
|
*
|
||||||
|
* Note: None
|
||||||
|
*****************************************************************************/
|
||||||
|
void HIDTxReport(char *buffer, uint8_t len)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Value of len should be equal to or smaller than HID_INT_IN_EP_SIZE.
|
||||||
|
* This check forces the value of len to meet the precondition.
|
||||||
|
*/
|
||||||
|
if(len > HID_INT_IN_EP_SIZE)
|
||||||
|
len = HID_INT_IN_EP_SIZE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy data from user's buffer to a USB module accessible RAM packet buffer
|
||||||
|
*/
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
hid_report_in[i] = buffer[i];
|
||||||
|
|
||||||
|
HID_BD_IN.Cnt = len;
|
||||||
|
mUSBBufferReady(HID_BD_IN);
|
||||||
|
|
||||||
|
}//end HIDTxReport
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Function: byte HIDRxReport(char *buffer, byte len)
|
||||||
|
*
|
||||||
|
* PreCondition: Value of input argument 'len' should be smaller than the
|
||||||
|
* maximum endpoint size responsible for receiving report
|
||||||
|
* data from USB host for HID class.
|
||||||
|
* Input argument 'buffer' should point to a buffer area that
|
||||||
|
* is bigger or equal to the size specified by 'len'.
|
||||||
|
*
|
||||||
|
* Input: buffer : Pointer to where received bytes are to be stored
|
||||||
|
* len : The number of bytes expected.
|
||||||
|
*
|
||||||
|
* Output: The number of bytes copied to buffer.
|
||||||
|
*
|
||||||
|
* Side Effects: Publicly accessible variable hid_rpt_rx_len is updated
|
||||||
|
* with the number of bytes copied to buffer.
|
||||||
|
* Once HIDRxReport is called, subsequent retrieval of
|
||||||
|
* hid_rpt_rx_len can be done by calling macro
|
||||||
|
* mHIDGetRptRxLength().
|
||||||
|
*
|
||||||
|
* Overview: HIDRxReport copies a string of bytes received through
|
||||||
|
* USB HID OUT endpoint to a user's specified location.
|
||||||
|
* It is a non-blocking function. It does not wait
|
||||||
|
* for data if there is no data available. Instead it returns
|
||||||
|
* '0' to notify the caller that there is no data available.
|
||||||
|
*
|
||||||
|
* Note: If the actual number of bytes received is larger than the
|
||||||
|
* number of bytes expected (len), only the expected number
|
||||||
|
* of bytes specified will be copied to buffer.
|
||||||
|
* If the actual number of bytes received is smaller than the
|
||||||
|
* number of bytes expected (len), only the actual number
|
||||||
|
* of bytes received will be copied to buffer.
|
||||||
|
*****************************************************************************/
|
||||||
|
uint8_t HIDRxReport(char *buffer, uint8_t len)
|
||||||
|
{
|
||||||
|
hid_rpt_rx_len = 0;
|
||||||
|
|
||||||
|
if(!mHIDRxIsBusy())
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Adjust the expected number of bytes to equal
|
||||||
|
* the actual number of bytes received.
|
||||||
|
*/
|
||||||
|
if(len > HID_BD_OUT.Cnt)
|
||||||
|
len = HID_BD_OUT.Cnt;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy data from dual-ram buffer to user's buffer
|
||||||
|
*/
|
||||||
|
for(hid_rpt_rx_len = 0; hid_rpt_rx_len < len; hid_rpt_rx_len++)
|
||||||
|
buffer[hid_rpt_rx_len] = hid_report_out[hid_rpt_rx_len];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prepare dual-ram buffer for next OUT transaction
|
||||||
|
*/
|
||||||
|
HID_BD_OUT.Cnt = sizeof(hid_report_out);
|
||||||
|
mUSBBufferReady(HID_BD_OUT);
|
||||||
|
}//end if
|
||||||
|
|
||||||
|
return hid_rpt_rx_len;
|
||||||
|
|
||||||
|
}//end HIDRxReport
|
||||||
|
|
||||||
|
#endif //def USB_USE_HID
|
||||||
|
|
||||||
|
/** EOF hid.c ***************************************************************/
|
||||||
163
bootloader_hacked_from_mla/src/usb_device_hid.h
Normal file
163
bootloader_hacked_from_mla/src/usb_device_hid.h
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
Copyright 2016 Microchip Technology Inc. (www.microchip.com)
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
To request to license the code under the MLA license (www.microchip.com/mla_license),
|
||||||
|
please contact mla_licensing@microchip.com
|
||||||
|
*******************************************************************************/
|
||||||
|
#ifndef HID_H
|
||||||
|
#define HID_H
|
||||||
|
|
||||||
|
/** I N C L U D E S **********************************************************/
|
||||||
|
#include "typedefs.h"
|
||||||
|
|
||||||
|
/** D E F I N I T I O N S ****************************************************/
|
||||||
|
|
||||||
|
/* Class-Specific Requests */
|
||||||
|
#define GET_REPORT 0x01
|
||||||
|
#define GET_IDLE 0x02
|
||||||
|
#define GET_PROTOCOL 0x03
|
||||||
|
#define SET_REPORT 0x09
|
||||||
|
#define SET_IDLE 0x0A
|
||||||
|
#define SET_PROTOCOL 0x0B
|
||||||
|
|
||||||
|
/* Class Descriptor Types */
|
||||||
|
#define DSC_HID 0x21
|
||||||
|
#define DSC_RPT 0x22
|
||||||
|
#define DSC_PHY 0x23
|
||||||
|
|
||||||
|
/* Protocol Selection */
|
||||||
|
#define BOOT_PROTOCOL 0x00
|
||||||
|
#define RPT_PROTOCOL 0x01
|
||||||
|
|
||||||
|
|
||||||
|
/* HID Interface Class Code */
|
||||||
|
#define HID_INTF 0x03
|
||||||
|
|
||||||
|
/* HID Interface Class SubClass Codes */
|
||||||
|
#define BOOT_INTF_SUBCLASS 0x01
|
||||||
|
|
||||||
|
/* HID Interface Class Protocol Codes */
|
||||||
|
#define HID_PROTOCOL_NONE 0x00
|
||||||
|
#define HID_PROTOCOL_KEYBOAD 0x01
|
||||||
|
#define HID_PROTOCOL_MOUSE 0x02
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Macro: (bit) mHIDRxIsBusy(void)
|
||||||
|
*
|
||||||
|
* PreCondition: None
|
||||||
|
*
|
||||||
|
* Input: None
|
||||||
|
*
|
||||||
|
* Output: None
|
||||||
|
*
|
||||||
|
* Side Effects: None
|
||||||
|
*
|
||||||
|
* Overview: This macro is used to check if HID OUT endpoint is
|
||||||
|
* busy (owned by SIE) or not.
|
||||||
|
* Typical Usage: if(mHIDRxIsBusy())
|
||||||
|
*
|
||||||
|
* Note: None
|
||||||
|
*****************************************************************************/
|
||||||
|
#define mHIDRxIsBusy() HID_BD_OUT.Stat.UOWN
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Macro: (bit) mHIDTxIsBusy(void)
|
||||||
|
*
|
||||||
|
* PreCondition: None
|
||||||
|
*
|
||||||
|
* Input: None
|
||||||
|
*
|
||||||
|
* Output: None
|
||||||
|
*
|
||||||
|
* Side Effects: None
|
||||||
|
*
|
||||||
|
* Overview: This macro is used to check if HID IN endpoint is
|
||||||
|
* busy (owned by SIE) or not.
|
||||||
|
* Typical Usage: if(mHIDTxIsBusy())
|
||||||
|
*
|
||||||
|
* Note: None
|
||||||
|
*****************************************************************************/
|
||||||
|
#define mHIDTxIsBusy() HID_BD_IN.Stat.UOWN
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Macro: uint8_t mHIDGetRptRxLength(void)
|
||||||
|
*
|
||||||
|
* PreCondition: None
|
||||||
|
*
|
||||||
|
* Input: None
|
||||||
|
*
|
||||||
|
* Output: mHIDGetRptRxLength returns hid_rpt_rx_len
|
||||||
|
*
|
||||||
|
* Side Effects: None
|
||||||
|
*
|
||||||
|
* Overview: mHIDGetRptRxLength is used to retrieve the number of bytes
|
||||||
|
* copied to user's buffer by the most recent call to
|
||||||
|
* HIDRxReport function.
|
||||||
|
*
|
||||||
|
* Note: None
|
||||||
|
*****************************************************************************/
|
||||||
|
#define mHIDGetRptRxLength() hid_rpt_rx_len
|
||||||
|
|
||||||
|
|
||||||
|
/* HID macros */
|
||||||
|
#define mUSBGetHIDDscAdr(ptr) \
|
||||||
|
{ \
|
||||||
|
if(usb_active_cfg == 1) \
|
||||||
|
ptr = (ROM uint8_t*)&cfg01.hid_i00a00; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define mUSBGetHIDRptDscAdr(ptr) \
|
||||||
|
{ \
|
||||||
|
if(usb_active_cfg == 1) \
|
||||||
|
ptr = (ROM uint8_t*)&hid_rpt01; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define mUSBGetHIDRptDscSize(count) \
|
||||||
|
{ \
|
||||||
|
if(usb_active_cfg == 1) \
|
||||||
|
count = sizeof(hid_rpt01); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** S T R U C T U R E S ******************************************************/
|
||||||
|
typedef struct _USB_HID_DSC_HEADER
|
||||||
|
{
|
||||||
|
uint8_t bDscType;
|
||||||
|
uint16_t wDscLength;
|
||||||
|
} USB_HID_DSC_HEADER;
|
||||||
|
|
||||||
|
typedef struct _USB_HID_DSC
|
||||||
|
{
|
||||||
|
uint8_t bLength; uint8_t bDscType; uint16_t bcdHID;
|
||||||
|
uint8_t bCountryCode; uint8_t bNumDsc;
|
||||||
|
USB_HID_DSC_HEADER hid_dsc_header[HID_NUM_OF_DSC];
|
||||||
|
/*
|
||||||
|
* HID_NUM_OF_DSC is defined in autofiles\usb_config.h
|
||||||
|
*/
|
||||||
|
} USB_HID_DSC;
|
||||||
|
|
||||||
|
/** E X T E R N S ************************************************************/
|
||||||
|
extern uint8_t hid_rpt_rx_len;
|
||||||
|
extern ROM uint8_t hid_rpt01[HID_RPT01_SIZE];
|
||||||
|
|
||||||
|
|
||||||
|
/** P U B L I C P R O T O T Y P E S *****************************************/
|
||||||
|
void HIDInitEP(void);
|
||||||
|
void USBCheckHIDRequest(void);
|
||||||
|
void HIDTxReport(char *buffer, uint8_t len);
|
||||||
|
uint8_t HIDRxReport(char *buffer, uint8_t len);
|
||||||
|
|
||||||
|
#endif //HID_H
|
||||||
Reference in New Issue
Block a user