diff --git a/Fred_bootloader/Fred_bootloader.atsln b/Fred_bootloader/Fred_bootloader.atsln new file mode 100644 index 0000000000000000000000000000000000000000..527ff63c390e6b9e1120da6b70cad3cd4b6420f6 --- /dev/null +++ b/Fred_bootloader/Fred_bootloader.atsln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Atmel Studio Solution File, Format Version 11.00 +Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "Fred_bootloader", "Fred_bootloader.cproj", "{EBC5876E-D5B6-47AB-845E-0A6704688731}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|AVR = Debug|AVR + Release|AVR = Release|AVR + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EBC5876E-D5B6-47AB-845E-0A6704688731}.Debug|AVR.ActiveCfg = Debug|AVR + {EBC5876E-D5B6-47AB-845E-0A6704688731}.Debug|AVR.Build.0 = Debug|AVR + {EBC5876E-D5B6-47AB-845E-0A6704688731}.Release|AVR.ActiveCfg = Release|AVR + {EBC5876E-D5B6-47AB-845E-0A6704688731}.Release|AVR.Build.0 = Release|AVR + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Fred_bootloader/Fred_bootloader.atsuo b/Fred_bootloader/Fred_bootloader.atsuo new file mode 100644 index 0000000000000000000000000000000000000000..471d4105d291e8faa22abb93728603eb9a53638a Binary files /dev/null and b/Fred_bootloader/Fred_bootloader.atsuo differ diff --git a/Fred_bootloader/Fred_bootloader.cproj b/Fred_bootloader/Fred_bootloader.cproj new file mode 100644 index 0000000000000000000000000000000000000000..8950fd68d4e5a37fee83686844a5560c87afaefa --- /dev/null +++ b/Fred_bootloader/Fred_bootloader.cproj @@ -0,0 +1,507 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <SchemaVersion>2.0</SchemaVersion> + <ProjectVersion>6.2</ProjectVersion> + <ToolchainName>com.Atmel.AVRGCC8.C</ToolchainName> + <ProjectGuid>{ebc5876e-d5b6-47ab-845e-0a6704688731}</ProjectGuid> + <avrdevice>atxmega128a3u</avrdevice> + <avrdeviceseries>xmegaau</avrdeviceseries> + <OutputType>Executable</OutputType> + <Language>C</Language> + <OutputFileName>$(MSBuildProjectName)</OutputFileName> + <OutputFileExtension>.elf</OutputFileExtension> + <OutputDirectory>$(MSBuildProjectDirectory)\$(Configuration)</OutputDirectory> + <AssemblyName>Fred_bootloader</AssemblyName> + <Name>Fred_bootloader</Name> + <RootNamespace>Fred_bootloader</RootNamespace> + <ToolchainFlavour>Native</ToolchainFlavour> + <KeepTimersRunning>true</KeepTimersRunning> + <OverrideVtor>false</OverrideVtor> + <CacheFlash>true</CacheFlash> + <ProgFlashFromRam>true</ProgFlashFromRam> + <RamSnippetAddress>0x20000000</RamSnippetAddress> + <UncachedRange /> + <preserveEEPROM>true</preserveEEPROM> + <OverrideVtorValue>exception_table</OverrideVtorValue> + <BootSegment>2</BootSegment> + <eraseonlaunchrule>0</eraseonlaunchrule> + <AsfFrameworkConfig> + <framework-data> + <options> + <option id="common.boards" value="Add" config="" content-id="Atmel.ASF" /> + <option id="common.services.basic.clock" value="Add" config="" content-id="Atmel.ASF" /> + <option id="common.services.ioport" value="Add" config="" content-id="Atmel.ASF" /> + <option id="common.services.basic.serial" value="Add" config="" content-id="Atmel.ASF" /> + <option id="common.utils.interrupt" value="Add" config="" content-id="Atmel.ASF" /> + <option id="xmega.drivers.nvm" value="Add" config="" content-id="Atmel.ASF" /> + <option id="xmega.drivers.tc" value="Add" config="" content-id="Atmel.ASF" /> + <option id="xmega.drivers.usart" value="Add" config="" content-id="Atmel.ASF" /> + <option id="xmega.drivers.wdt" value="Add" config="" content-id="Atmel.ASF" /> + <option id="xmega.drivers.pmic" value="Add" config="" content-id="Atmel.ASF" /> + </options> + <configurations /> + <files> + <file path="src/main.c" framework="" version="" source="common/applications/user_application/main.c" changed="False" content-id="Atmel.ASF" /> + <file path="src/config/conf_board.h" framework="" version="" source="common/applications/user_application/user_board/config/conf_board.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/boards/board.h" framework="" version="" source="common/boards/board.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/boards/user_board/init.c" framework="" version="" source="common/boards/user_board/init.c" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/boards/user_board/user_board.h" framework="" version="" source="common/boards/user_board/user_board.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/utils/interrupt.h" framework="" version="" source="common/utils/interrupt.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/utils/interrupt/interrupt_avr8.h" framework="" version="" source="common/utils/interrupt/interrupt_avr8.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/utils/make/Makefile.avr.in" framework="" version="" source="common/utils/make/Makefile.avr.in" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/utils/parts.h" framework="" version="" source="common/utils/parts.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/utils/assembler.h" framework="" version="" source="xmega/utils/assembler.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/utils/assembler/gas.h" framework="" version="" source="xmega/utils/assembler/gas.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/utils/bit_handling/clz_ctz.h" framework="" version="" source="xmega/utils/bit_handling/clz_ctz.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/utils/compiler.h" framework="" version="" source="xmega/utils/compiler.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/utils/preprocessor/mrepeat.h" framework="" version="" source="xmega/utils/preprocessor/mrepeat.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/utils/preprocessor/preprocessor.h" framework="" version="" source="xmega/utils/preprocessor/preprocessor.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/utils/preprocessor/stringz.h" framework="" version="" source="xmega/utils/preprocessor/stringz.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/utils/preprocessor/tpaste.h" framework="" version="" source="xmega/utils/preprocessor/tpaste.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/utils/progmem.h" framework="" version="" source="xmega/utils/progmem.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/utils/status_codes.h" framework="" version="" source="xmega/utils/status_codes.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/drivers/cpu/ccp.s" framework="" version="3.19.0" source="xmega\drivers\cpu\ccp.s" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/drivers/cpu/xmega_reset_cause.h" framework="" version="3.19.0" source="xmega\drivers\cpu\xmega_reset_cause.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/drivers/cpu/ccp.h" framework="" version="3.19.0" source="xmega\drivers\cpu\ccp.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/drivers/nvm/nvm.c" framework="" version="3.19.0" source="xmega\drivers\nvm\nvm.c" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/drivers/nvm/nvm_asm.s" framework="" version="3.19.0" source="xmega\drivers\nvm\nvm_asm.s" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/drivers/nvm/nvm.h" framework="" version="3.19.0" source="xmega\drivers\nvm\nvm.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/drivers/pmic/pmic.h" framework="" version="3.19.0" source="xmega\drivers\pmic\pmic.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/drivers/wdt/wdt.c" framework="" version="3.19.0" source="xmega\drivers\wdt\wdt.c" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/drivers/wdt/wdt.h" framework="" version="3.19.0" source="xmega\drivers\wdt\wdt.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/services/clock/xmega/sysclk.c" framework="" version="3.19.0" source="common\services\clock\xmega\sysclk.c" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/services/clock/pll.h" framework="" version="3.19.0" source="common\services\clock\pll.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/services/clock/genclk.h" framework="" version="3.19.0" source="common\services\clock\genclk.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/services/clock/osc.h" framework="" version="3.19.0" source="common\services\clock\osc.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/services/clock/xmega/pll.h" framework="" version="3.19.0" source="common\services\clock\xmega\pll.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/services/clock/xmega/sysclk.h" framework="" version="3.19.0" source="common\services\clock\xmega\sysclk.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/services/clock/xmega/osc.h" framework="" version="3.19.0" source="common\services\clock\xmega\osc.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/services/clock/sysclk.h" framework="" version="3.19.0" source="common\services\clock\sysclk.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/Config/conf_clock.h" framework="" version="3.19.0" source="common\services\clock\xmega\module_config_usb\conf_clock.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/services/ioport/xmega/ioport_compat.c" framework="" version="3.19.0" source="common\services\ioport\xmega\ioport_compat.c" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/services/ioport/xmega/ioport_compat.h" framework="" version="3.19.0" source="common\services\ioport\xmega\ioport_compat.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/services/ioport/xmega/ioport.h" framework="" version="3.19.0" source="common\services\ioport\xmega\ioport.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/services/ioport/ioport.h" framework="" version="3.19.0" source="common\services\ioport\ioport.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/services/serial/usart_serial.c" framework="" version="3.19.0" source="common\services\serial\usart_serial.c" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/services/serial/xmega_usart/usart_serial.h" framework="" version="3.19.0" source="common\services\serial\xmega_usart\usart_serial.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/services/serial/serial.h" framework="" version="3.19.0" source="common\services\serial\serial.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/Config/conf_usart_serial.h" framework="" version="3.19.0" source="common\services\serial\xmega_usart\module_config\conf_usart_serial.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/drivers/usart/usart.c" framework="" version="3.19.0" source="xmega\drivers\usart\usart.c" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/drivers/usart/usart.h" framework="" version="3.19.0" source="xmega\drivers\usart\usart.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/drivers/sleep/sleep.h" framework="" version="3.19.0" source="xmega\drivers\sleep\sleep.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/drivers/tc/tc.c" framework="" version="3.19.0" source="xmega\drivers\tc\tc.c" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/xmega/drivers/tc/tc.h" framework="" version="3.19.0" source="xmega\drivers\tc\tc.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/services/sleepmgr/xmega/sleepmgr.c" framework="" version="3.19.0" source="common\services\sleepmgr\xmega\sleepmgr.c" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/services/sleepmgr/sleepmgr.h" framework="" version="3.19.0" source="common\services\sleepmgr\sleepmgr.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/ASF/common/services/sleepmgr/xmega/sleepmgr.h" framework="" version="3.19.0" source="common\services\sleepmgr\xmega\sleepmgr.h" changed="False" content-id="Atmel.ASF" /> + <file path="src/Config/conf_sleepmgr.h" framework="" version="3.19.0" source="common\services\sleepmgr\xmega\module_config\conf_sleepmgr.h" changed="False" content-id="Atmel.ASF" /> + </files> + <documentation help="http://asf.atmel.com/docs/3.19.0/common.applications.user_application.user_board.xmegaau/html/index.html" /> + <offline-documentation help="" /> + <dependencies> + <content-extension eid="atmel.asf" uuidref="Atmel.ASF" version="3.19.0" /> + </dependencies> + <project id="common.applications.user_application.user_board.xmegaau" value="Add" config="" content-id="Atmel.ASF" /> + <board id="board.user_board.xmegaau" value="Add" config="" content-id="Atmel.ASF" /> + </framework-data> + </AsfFrameworkConfig> + <avrtool>com.atmel.avrdbg.tool.jtagice3plus</avrtool> + <com_atmel_avrdbg_tool_jtagice3plus> + <ToolOptions> + <InterfaceProperties> + <JtagDbgClock>3470000</JtagDbgClock> + </InterfaceProperties> + <InterfaceName>JTAG</InterfaceName> + </ToolOptions> + <ToolType>com.atmel.avrdbg.tool.jtagice3plus</ToolType> + <ToolNumber>J30200026848</ToolNumber> + <ToolName>JTAGICE3</ToolName> + </com_atmel_avrdbg_tool_jtagice3plus> + <avrtoolinterface>JTAG</avrtoolinterface> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)' == 'Release' "> + <ToolchainSettings> + <AvrGcc> + <avrgcc.common.optimization.RelaxBranches>True</avrgcc.common.optimization.RelaxBranches> + <avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex> + <avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss> + <avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep> + <avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec> + <avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures> + <avrgcc.compiler.symbols.DefSymbols> + <ListValues> + <Value>NDEBUG</Value> + <Value>BOARD=USER_BOARD</Value> + <Value>IOPORT_XMEGA_COMPAT=1</Value> + <Value>F_CPU=32000000UL</Value> + </ListValues> + </avrgcc.compiler.symbols.DefSymbols> + <avrgcc.compiler.directories.IncludePaths> + <ListValues> + <Value>../common/applications/user_application/user_board/config</Value> + <Value>../src/ASF/xmega/utils</Value> + <Value>../src/config</Value> + <Value>../src/ASF/common/boards</Value> + <Value>../src/ASF/xmega/utils/preprocessor</Value> + <Value>../src/ASF/common/utils</Value> + <Value>../src</Value> + <Value>../src/ASF/common/boards/user_board</Value> + <Value>../src/ASF/xmega/drivers/cpu</Value> + <Value>../src/ASF/xmega/drivers/nvm</Value> + <Value>../src/ASF/xmega/drivers/pmic</Value> + <Value>../src/ASF/xmega/drivers/wdt</Value> + <Value>../src/ASF/common/services/clock</Value> + <Value>../src/ASF/common/services/ioport</Value> + <Value>../src/ASF/common/services/serial/xmega_usart</Value> + <Value>../src/ASF/common/services/serial</Value> + <Value>../src/ASF/xmega/drivers/usart</Value> + <Value>../src/ASF/xmega/drivers/sleep</Value> + <Value>../src/ASF/xmega/drivers/tc</Value> + <Value>../src/ASF/common/services/sleepmgr</Value> + </ListValues> + </avrgcc.compiler.directories.IncludePaths> + <avrgcc.compiler.optimization.level>Optimize for size (-Os)</avrgcc.compiler.optimization.level> + <avrgcc.compiler.optimization.OtherFlags>-fdata-sections</avrgcc.compiler.optimization.OtherFlags> + <avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers> + <avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum> + <avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings> + <avrgcc.compiler.miscellaneous.OtherFlags>-std=gnu99 -fno-strict-aliasing -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax</avrgcc.compiler.miscellaneous.OtherFlags> + <avrgcc.linker.libraries.Libraries> + <ListValues> + <Value>libm</Value> + </ListValues> + </avrgcc.linker.libraries.Libraries> + <avrgcc.linker.miscellaneous.LinkerFlags>-Wl,--relax,-section-start=.text=0x20000</avrgcc.linker.miscellaneous.LinkerFlags> + <avrgcc.assembler.general.AssemblerFlags>-mrelax -DBOARD=USER_BOARD</avrgcc.assembler.general.AssemblerFlags> + <avrgcc.assembler.general.IncludePaths> + <ListValues> + <Value>../common/applications/user_application/user_board/config</Value> + <Value>../src/ASF/xmega/utils</Value> + <Value>../src/config</Value> + <Value>../src/ASF/common/boards</Value> + <Value>../src/ASF/xmega/utils/preprocessor</Value> + <Value>../src/ASF/common/utils</Value> + <Value>../src</Value> + <Value>../src/ASF/common/boards/user_board</Value> + <Value>../src/ASF/xmega/drivers/cpu</Value> + <Value>../src/ASF/xmega/drivers/nvm</Value> + <Value>../src/ASF/xmega/drivers/pmic</Value> + <Value>../src/ASF/xmega/drivers/wdt</Value> + <Value>../src/ASF/common/services/clock</Value> + <Value>../src/ASF/common/services/ioport</Value> + <Value>../src/ASF/common/services/serial/xmega_usart</Value> + <Value>../src/ASF/common/services/serial</Value> + <Value>../src/ASF/xmega/drivers/usart</Value> + <Value>../src/ASF/xmega/drivers/sleep</Value> + <Value>../src/ASF/xmega/drivers/tc</Value> + <Value>../src/ASF/common/services/sleepmgr</Value> + </ListValues> + </avrgcc.assembler.general.IncludePaths> +</AvrGcc> + </ToolchainSettings> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> + <ToolchainSettings> + <AvrGcc> + <avrgcc.common.optimization.RelaxBranches>True</avrgcc.common.optimization.RelaxBranches> + <avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex> + <avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss> + <avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep> + <avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec> + <avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures> + <avrgcc.compiler.symbols.DefSymbols> + <ListValues> + <Value>DEBUG</Value> + <Value>BOARD=USER_BOARD</Value> + <Value>F_CPU=32000000UL</Value> + <Value>IOPORT_XMEGA_COMPAT</Value> + </ListValues> + </avrgcc.compiler.symbols.DefSymbols> + <avrgcc.compiler.directories.IncludePaths> + <ListValues> + <Value>../common/applications/user_application/user_board/config</Value> + <Value>../src/ASF/xmega/utils</Value> + <Value>../src/config</Value> + <Value>../src/ASF/common/boards</Value> + <Value>../src/ASF/xmega/utils/preprocessor</Value> + <Value>../src/ASF/common/utils</Value> + <Value>../src</Value> + <Value>../src/ASF/common/boards/user_board</Value> + <Value>../src/ASF/xmega/drivers/cpu</Value> + <Value>../src/ASF/xmega/drivers/nvm</Value> + <Value>../src/ASF/xmega/drivers/pmic</Value> + <Value>../src/ASF/xmega/drivers/wdt</Value> + <Value>../src/ASF/common/services/clock</Value> + <Value>../src/ASF/common/services/ioport</Value> + <Value>../src/ASF/common/services/serial/xmega_usart</Value> + <Value>../src/ASF/common/services/serial</Value> + <Value>../src/ASF/xmega/drivers/usart</Value> + <Value>../src/ASF/xmega/drivers/sleep</Value> + <Value>../src/ASF/xmega/drivers/tc</Value> + <Value>../src/ASF/common/services/sleepmgr</Value> + </ListValues> + </avrgcc.compiler.directories.IncludePaths> + <avrgcc.compiler.optimization.level>Optimize (-O1)</avrgcc.compiler.optimization.level> + <avrgcc.compiler.optimization.OtherFlags>-fdata-sections</avrgcc.compiler.optimization.OtherFlags> + <avrgcc.compiler.optimization.DebugLevel>Maximum (-g3)</avrgcc.compiler.optimization.DebugLevel> + <avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings> + <avrgcc.compiler.miscellaneous.OtherFlags>-std=gnu99 -fno-strict-aliasing -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax</avrgcc.compiler.miscellaneous.OtherFlags> + <avrgcc.linker.libraries.Libraries> + <ListValues> + <Value>libm</Value> + </ListValues> + </avrgcc.linker.libraries.Libraries> + <avrgcc.linker.miscellaneous.LinkerFlags>-Wl,--relax</avrgcc.linker.miscellaneous.LinkerFlags> + <avrgcc.assembler.general.AssemblerFlags>-mrelax -DBOARD=USER_BOARD</avrgcc.assembler.general.AssemblerFlags> + <avrgcc.assembler.general.IncludePaths> + <ListValues> + <Value>../common/applications/user_application/user_board/config</Value> + <Value>../src/ASF/xmega/utils</Value> + <Value>../src/config</Value> + <Value>../src/ASF/common/boards</Value> + <Value>../src/ASF/xmega/utils/preprocessor</Value> + <Value>../src/ASF/common/utils</Value> + <Value>../src</Value> + <Value>../src/ASF/common/boards/user_board</Value> + <Value>../src/ASF/xmega/drivers/cpu</Value> + <Value>../src/ASF/xmega/drivers/nvm</Value> + <Value>../src/ASF/xmega/drivers/pmic</Value> + <Value>../src/ASF/xmega/drivers/wdt</Value> + <Value>../src/ASF/common/services/clock</Value> + <Value>../src/ASF/common/services/ioport</Value> + <Value>../src/ASF/common/services/serial/xmega_usart</Value> + <Value>../src/ASF/common/services/serial</Value> + <Value>../src/ASF/xmega/drivers/usart</Value> + <Value>../src/ASF/xmega/drivers/sleep</Value> + <Value>../src/ASF/xmega/drivers/tc</Value> + <Value>../src/ASF/common/services/sleepmgr</Value> + </ListValues> + </avrgcc.assembler.general.IncludePaths> + <avrgcc.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcc.assembler.debugging.DebugLevel> + </AvrGcc> + </ToolchainSettings> + </PropertyGroup> + <ItemGroup> + <Folder Include="src\" /> + <Folder Include="src\ASF\" /> + <Folder Include="src\ASF\common\" /> + <Folder Include="src\ASF\common\boards\" /> + <Folder Include="src\ASF\common\boards\user_board\" /> + <Folder Include="src\ASF\common\services\" /> + <Folder Include="src\ASF\common\services\clock\" /> + <Folder Include="src\ASF\common\services\clock\xmega\" /> + <Folder Include="src\ASF\common\services\ioport\" /> + <Folder Include="src\ASF\common\services\ioport\xmega\" /> + <Folder Include="src\ASF\common\services\serial\" /> + <Folder Include="src\ASF\common\services\serial\xmega_usart\" /> + <Folder Include="src\ASF\common\services\sleepmgr\" /> + <Folder Include="src\ASF\common\services\sleepmgr\xmega\" /> + <Folder Include="src\ASF\common\utils\" /> + <Folder Include="src\ASF\common\utils\interrupt\" /> + <Folder Include="src\ASF\common\utils\make\" /> + <Folder Include="src\ASF\xmega\" /> + <Folder Include="src\ASF\xmega\drivers\" /> + <Folder Include="src\ASF\xmega\drivers\cpu\" /> + <Folder Include="src\ASF\xmega\drivers\nvm\" /> + <Folder Include="src\ASF\xmega\drivers\pmic\" /> + <Folder Include="src\ASF\xmega\drivers\sleep\" /> + <Folder Include="src\ASF\xmega\drivers\tc\" /> + <Folder Include="src\ASF\xmega\drivers\usart\" /> + <Folder Include="src\ASF\xmega\drivers\wdt\" /> + <Folder Include="src\ASF\xmega\utils\" /> + <Folder Include="src\ASF\xmega\utils\assembler\" /> + <Folder Include="src\ASF\xmega\utils\bit_handling\" /> + <Folder Include="src\ASF\xmega\utils\preprocessor\" /> + <Folder Include="src\config\" /> + </ItemGroup> + <ItemGroup> + <Compile Include="src\ASF\common\boards\user_board\fuse_relay_board_pinout.h"> + <SubType>compile</SubType> + </Compile> + <Compile Include="src\bootloader.c"> + <SubType>compile</SubType> + </Compile> + <Compile Include="src\bootloader.h"> + <SubType>compile</SubType> + </Compile> + <Compile Include="src\config\conf_sleepmgr.h"> + <SubType>compile</SubType> + </Compile> + <None Include="src\ASF\common\services\sleepmgr\xmega\sleepmgr.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\common\services\sleepmgr\sleepmgr.h"> + <SubType>compile</SubType> + </None> + <Compile Include="src\ASF\common\services\sleepmgr\xmega\sleepmgr.c"> + <SubType>compile</SubType> + </Compile> + <Compile Include="src\ASF\xmega\drivers\tc\tc.c"> + <SubType>compile</SubType> + </Compile> + <None Include="src\ASF\xmega\drivers\tc\tc.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\xmega\drivers\sleep\sleep.h"> + <SubType>compile</SubType> + </None> + <Compile Include="src\ASF\xmega\drivers\usart\usart.c"> + <SubType>compile</SubType> + </Compile> + <Compile Include="src\timer_lib.c"> + <SubType>compile</SubType> + </Compile> + <Compile Include="src\timer_lib.h"> + <SubType>compile</SubType> + </Compile> + <Compile Include="src\usart_lib.c"> + <SubType>compile</SubType> + </Compile> + <Compile Include="src\usart_lib.h"> + <SubType>compile</SubType> + </Compile> + <None Include="src\ASF\xmega\drivers\usart\usart.h"> + <SubType>compile</SubType> + </None> + <None Include="src\config\conf_usart_serial.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\common\services\serial\serial.h"> + <SubType>compile</SubType> + </None> + <Compile Include="src\ASF\common\services\serial\usart_serial.c"> + <SubType>compile</SubType> + </Compile> + <None Include="src\ASF\common\services\serial\xmega_usart\usart_serial.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\common\services\ioport\ioport.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\common\services\ioport\xmega\ioport.h"> + <SubType>compile</SubType> + </None> + <Compile Include="src\ASF\common\services\ioport\xmega\ioport_compat.c"> + <SubType>compile</SubType> + </Compile> + <None Include="src\ASF\common\services\ioport\xmega\ioport_compat.h"> + <SubType>compile</SubType> + </None> + <None Include="src\config\conf_clock.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\common\services\clock\sysclk.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\common\services\clock\xmega\osc.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\common\services\clock\xmega\sysclk.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\common\services\clock\xmega\pll.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\common\services\clock\osc.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\common\services\clock\genclk.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\common\services\clock\pll.h"> + <SubType>compile</SubType> + </None> + <Compile Include="src\ASF\common\services\clock\xmega\sysclk.c"> + <SubType>compile</SubType> + </Compile> + <Compile Include="src\ASF\xmega\drivers\nvm\nvm.c"> + <SubType>compile</SubType> + </Compile> + <Compile Include="src\ASF\xmega\drivers\wdt\wdt.c"> + <SubType>compile</SubType> + </Compile> + <None Include="src\ASF\xmega\drivers\wdt\wdt.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\xmega\drivers\pmic\pmic.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\xmega\drivers\nvm\nvm.h"> + <SubType>compile</SubType> + </None> + <Compile Include="src\ASF\xmega\drivers\nvm\nvm_asm.s"> + <SubType>compile</SubType> + </Compile> + <None Include="src\ASF\xmega\drivers\cpu\ccp.h"> + <SubType>compile</SubType> + </None> + <Compile Include="src\ASF\xmega\drivers\cpu\ccp.s"> + <SubType>compile</SubType> + </Compile> + <None Include="src\ASF\xmega\drivers\cpu\xmega_reset_cause.h"> + <SubType>compile</SubType> + </None> + <None Include="src\asf.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\common\boards\user_board\user_board.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\common\utils\make\Makefile.avr.in"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\xmega\utils\assembler\gas.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\xmega\utils\progmem.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\xmega\utils\preprocessor\stringz.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\common\boards\board.h"> + <SubType>compile</SubType> + </None> + <Compile Include="src\ASF\common\boards\user_board\init.c"> + <SubType>compile</SubType> + </Compile> + <None Include="src\ASF\common\utils\interrupt\interrupt_avr8.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\common\utils\parts.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\xmega\utils\status_codes.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\xmega\utils\preprocessor\preprocessor.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\xmega\utils\assembler.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\xmega\utils\preprocessor\tpaste.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\xmega\utils\bit_handling\clz_ctz.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\common\utils\interrupt.h"> + <SubType>compile</SubType> + </None> + <None Include="src\config\conf_board.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\xmega\utils\preprocessor\mrepeat.h"> + <SubType>compile</SubType> + </None> + <None Include="src\ASF\xmega\utils\compiler.h"> + <SubType>compile</SubType> + </None> + <Compile Include="src\main.c"> + <SubType>compile</SubType> + </Compile> + </ItemGroup> + <Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" /> +</Project> \ No newline at end of file diff --git a/Fred_bootloader/doxySettings.xml b/Fred_bootloader/doxySettings.xml new file mode 100644 index 0000000000000000000000000000000000000000..46ac3a94e1c1de5a469537904dfbb9fd873a288c --- /dev/null +++ b/Fred_bootloader/doxySettings.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<DoxySettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <SettingsFile>C:\desy\Fred_bootloader\Fred_bootloader\doxySettings.xml</SettingsFile> + <ProjectName>Fred_bootloader</ProjectName> + <DoxyExePath>C:\Users\Pawel\AppData\Local\Atmel\AtmelStudio\6.2\Extensions\Atmel\Doxygen Integrator\1.2.0.14\Doxygen/doxygen.exe</DoxyExePath> + <UseDefaultSettings>true</UseDefaultSettings> + <GenerateAsPartOfBuild>false</GenerateAsPartOfBuild> + <ConfigFilePath>C:\desy\Fred_bootloader\Fred_bootloader\doxyfile</ConfigFilePath> + <OutputDirPath>C:\desy\Fred_bootloader\Fred_bootloader\doxygen</OutputDirPath> + <ShowErrorsAndWarnings>false</ShowErrorsAndWarnings> +</DoxySettings> \ No newline at end of file diff --git a/Fred_bootloader/doxyfile b/Fred_bootloader/doxyfile new file mode 100644 index 0000000000000000000000000000000000000000..9094ef9f9db13b5a7724faa81d084dd093e21e22 --- /dev/null +++ b/Fred_bootloader/doxyfile @@ -0,0 +1,1792 @@ +# Doxyfile 1.8.1.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME ="Fred_bootloader" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY ="C:\desy\Fred_bootloader\Fred_bootloader\doxygen" + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields will be shown inline in the documentation +# of the scope in which they are defined (i.e. file, namespace, or group +# documentation), provided this scope is documented. If set to NO (the default), +# structs, classes, and unions are shown on a separate page (for HTML and Man +# pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +SYMBOL_CACHE_SIZE = 0 + +# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be +# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given +# their name and scope. Since this can be an expensive process and often the +# same symbol appear multiple times in the code, doxygen keeps a cache of +# pre-resolved symbols. If the cache is too small doxygen will become slower. +# If the cache is too large, memory is wasted. The cache size is given by this +# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command <command> <input-file>, where <command> is the value of +# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT ="C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\boards\user_board\fuse_relay_board_pinout.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\boards\user_board\init.c" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\boards\user_board\user_board.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\boards\board.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\services\clock\xmega\osc.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\services\clock\xmega\pll.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\services\clock\xmega\sysclk.c" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\services\clock\xmega\sysclk.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\services\clock\genclk.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\services\clock\osc.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\services\clock\pll.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\services\clock\sysclk.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\services\ioport\xmega\ioport.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\services\ioport\xmega\ioport_compat.c" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\services\ioport\xmega\ioport_compat.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\services\ioport\ioport.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\services\serial\xmega_usart\usart_serial.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\services\serial\serial.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\services\serial\usart_serial.c" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\services\sleepmgr\xmega\sleepmgr.c" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\services\sleepmgr\xmega\sleepmgr.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\services\sleepmgr\sleepmgr.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\utils\interrupt\interrupt_avr8.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\utils\make\Makefile.avr.in" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\utils\interrupt.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\common\utils\parts.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\drivers\cpu\ccp.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\drivers\cpu\ccp.s" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\drivers\cpu\xmega_reset_cause.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\drivers\nvm\nvm.c" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\drivers\nvm\nvm.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\drivers\nvm\nvm_asm.s" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\drivers\pmic\pmic.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\drivers\sleep\sleep.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\drivers\tc\tc.c" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\drivers\tc\tc.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\drivers\usart\usart.c" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\drivers\usart\usart.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\drivers\wdt\wdt.c" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\drivers\wdt\wdt.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\utils\assembler\gas.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\utils\bit_handling\clz_ctz.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\utils\preprocessor\mrepeat.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\utils\preprocessor\preprocessor.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\utils\preprocessor\stringz.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\utils\preprocessor\tpaste.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\utils\assembler.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\utils\compiler.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\utils\progmem.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\ASF\xmega\utils\status_codes.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\config\conf_board.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\config\conf_clock.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\config\conf_sleepmgr.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\config\conf_usart_serial.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\asf.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\bootloader.c" "C:\desy\Fred_bootloader\Fred_bootloader\src\bootloader.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\main.c" "C:\desy\Fred_bootloader\Fred_bootloader\src\timer_lib.c" "C:\desy\Fred_bootloader\Fred_bootloader\src\timer_lib.h" "C:\desy\Fred_bootloader\Fred_bootloader\src\usart_lib.c" "C:\desy\Fred_bootloader\Fred_bootloader\src\usart_lib.h" + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command <filter> <input-file>, where <filter> +# is the value of the INPUT_FILTER tag, and <input-file> is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C, C++ and Fortran comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# style sheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> +# Qt Help Project / Custom Filters</a>. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> +# Qt Help Project / Filter Attributes</a>. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. +# However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which +# doxygen is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# managable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/Fred_bootloader/src/ASF/common/boards/board.h b/Fred_bootloader/src/ASF/common/boards/board.h new file mode 100644 index 0000000000000000000000000000000000000000..b98c9ab6770e76ff136ea75281192ebcba0f66c7 --- /dev/null +++ b/Fred_bootloader/src/ASF/common/boards/board.h @@ -0,0 +1,333 @@ +/** + * \file + * + * \brief Standard board header file. + * + * This file includes the appropriate board header file according to the + * defined board (parameter BOARD). + * + * Copyright (c) 2009-2013 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +/** + * \defgroup group_common_boards Generic board support + * + * The generic board support module includes board-specific definitions + * and function prototypes, such as the board initialization function. + * + * \{ + */ + +#include "compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! \name Base Boards + */ +//! @{ +#define EVK1100 1 //!< AT32UC3A EVK1100 board. +#define EVK1101 2 //!< AT32UC3B EVK1101 board. +#define UC3C_EK 3 //!< AT32UC3C UC3C_EK board. +#define EVK1104 4 //!< AT32UC3A3 EVK1104 board. +#define EVK1105 5 //!< AT32UC3A EVK1105 board. +#define STK600_RCUC3L0 6 //!< STK600 RCUC3L0 board. +#define UC3L_EK 7 //!< AT32UC3L-EK board. +#define XPLAIN 8 //!< ATxmega128A1 Xplain board. +#define STK600_RC064X 10 //!< ATxmega256A3 STK600 board. +#define STK600_RC100X 11 //!< ATxmega128A1 STK600 board. +#define UC3_A3_XPLAINED 13 //!< ATUC3A3 UC3-A3 Xplained board. +#define UC3_L0_XPLAINED 15 //!< ATUC3L0 UC3-L0 Xplained board. +#define STK600_RCUC3D 16 //!< STK600 RCUC3D board. +#define STK600_RCUC3C0 17 //!< STK600 RCUC3C board. +#define XMEGA_B1_XPLAINED 18 //!< ATxmega128B1 Xplained board. +#define XMEGA_A1_XPLAINED 19 //!< ATxmega128A1 Xplain-A1 board. +#define STK600_RCUC3L4 21 //!< ATUCL4 STK600 board +#define UC3_L0_XPLAINED_BC 22 //!< ATUC3L0 UC3-L0 Xplained board controller board +#define MEGA1284P_XPLAINED_BC 23 //!< ATmega1284P-Xplained board controller board +#define STK600_RC044X 24 //!< STK600 with RC044X routing card board. +#define STK600_RCUC3B0 25 //!< STK600 RCUC3B0 board. +#define UC3_L0_QT600 26 //!< QT600 UC3L0 MCU board. +#define XMEGA_A3BU_XPLAINED 27 //!< ATxmega256A3BU Xplained board. +#define STK600_RC064X_LCDX 28 //!< XMEGAB3 STK600 RC064X LCDX board. +#define STK600_RC100X_LCDX 29 //!< XMEGAB1 STK600 RC100X LCDX board. +#define UC3B_BOARD_CONTROLLER 30 //!< AT32UC3B1 board controller for Atmel boards +#define RZ600 31 //!< AT32UC3A RZ600 MCU board +#define SAM3S_EK 32 //!< SAM3S-EK board. +#define SAM3U_EK 33 //!< SAM3U-EK board. +#define SAM3X_EK 34 //!< SAM3X-EK board. +#define SAM3N_EK 35 //!< SAM3N-EK board. +#define SAM3S_EK2 36 //!< SAM3S-EK2 board. +#define SAM4S_EK 37 //!< SAM4S-EK board. +#define STK600_RCUC3A0 38 //!< STK600 RCUC3A0 board. +#define STK600_MEGA 39 //!< STK600 MEGA board. +#define MEGA_1284P_XPLAINED 40 //!< ATmega1284P Xplained board. +#define SAM4S_XPLAINED 41 //!< SAM4S Xplained board. +#define ATXMEGA128A1_QT600 42 //!< QT600 ATXMEGA128A1 MCU board. +#define ARDUINO_DUE_X 43 //!< Arduino Due/X board. +#define STK600_RCUC3L3 44 //!< ATUCL3 STK600 board +#define SAM4L_EK 45 //!< SAM4L-EK board. +#define STK600_MEGA_RF 46 //!< STK600 MEGA RF EVK board. +#define XMEGA_C3_XPLAINED 47 //!< ATxmega384C3 Xplained board. +#define STK600_RC032X 48 //!< STK600 with RC032X routing card board. +#define SAM4S_EK2 49 //!< SAM4S-EK2 board. +#define XMEGA_E5_XPLAINED 50 //!< ATxmega32E5 Xplained board. +#define SAM4E_EK 51 //!< SAM4E-EK board. +#define ATMEGA256RFR2_XPLAINED_PRO 52 //!< ATmega256RFR2 Xplained Pro board. +#define SAM4S_XPLAINED_PRO 53 //!< SAM4S Xplained Pro board. +#define SAM4L_XPLAINED_PRO 54 //!< SAM4L Xplained Pro board. +#define ATMEGA256RFR2_ZIGBIT 55 //!< ATmega256RFR2 zigbit +#define XMEGA_RF233_ZIGBIT 56 //!< ATxmega256A3U with AT86RF233 zigbit +#define XMEGA_RF212B_ZIGBIT 57 //!< ATxmega256A3U with AT86RF212B zigbit +#define SAM4S_WPIR_RD 58 //!< SAM4S-WPIR-RD board. +#define SIMULATOR_XMEGA_A1 97 //!< Simulator for XMEGA A1 devices +#define AVR_SIMULATOR_UC3 98 //!< AVR SIMULATOR for AVR UC3 device family. +#define USER_BOARD 99 //!< User-reserved board (if any). +#define DUMMY_BOARD 100 //!< Dummy board to support board-independent applications (e.g. bootloader) +//! @} + +/*! \name Extension Boards + */ +//! @{ +#define EXT1102 1 //!< AT32UC3B EXT1102 board +#define MC300 2 //!< AT32UC3 MC300 board +#define SENSORS_XPLAINED_INERTIAL_1 3 //!< Xplained inertial sensor board 1 +#define SENSORS_XPLAINED_INERTIAL_2 4 //!< Xplained inertial sensor board 2 +#define SENSORS_XPLAINED_PRESSURE_1 5 //!< Xplained pressure sensor board +#define SENSORS_XPLAINED_LIGHTPROX_1 6 //!< Xplained light & proximity sensor board +#define SENSORS_XPLAINED_INERTIAL_A1 7 //!< Xplained inertial sensor board "A" +#define RZ600_AT86RF231 8 //!< AT86RF231 RF board in RZ600 +#define RZ600_AT86RF230B 9 //!< AT86RF230B RF board in RZ600 +#define RZ600_AT86RF212 10 //!< AT86RF212 RF board in RZ600 +#define SENSORS_XPLAINED_BREADBOARD 11 //!< Xplained sensor development breadboard +#define SECURITY_XPLAINED 12 //!< Xplained ATSHA204 board +#define USER_EXT_BOARD 99 //!< User-reserved extension board (if any). +//! @} + +#if BOARD == EVK1100 +# include "evk1100/evk1100.h" +#elif BOARD == EVK1101 +# include "evk1101/evk1101.h" +#elif BOARD == UC3C_EK +# include "uc3c_ek/uc3c_ek.h" +#elif BOARD == EVK1104 +# include "evk1104/evk1104.h" +#elif BOARD == EVK1105 +# include "evk1105/evk1105.h" +#elif BOARD == STK600_RCUC3L0 +# include "stk600/rcuc3l0/stk600_rcuc3l0.h" +#elif BOARD == UC3L_EK +# include "uc3l_ek/uc3l_ek.h" +#elif BOARD == STK600_RCUC3L4 +# include "stk600/rcuc3l4/stk600_rcuc3l4.h" +#elif BOARD == XPLAIN +# include "xplain/xplain.h" +#elif BOARD == STK600_MEGA + /*No header-file to include*/ +#elif BOARD == STK600_MEGA_RF +# include "stk600.h" +#elif BOARD == ATMEGA256RFR2_XPLAINED_PRO +# include "atmega256rfr2_xplained_pro/atmega256rfr2_xplained_pro.h" +#elif BOARD == ATMEGA256RFR2_ZIGBIT +# include "atmega256rfr2_zigbit/atmega256rfr2_zigbit.h" +#elif BOARD == STK600_RC032X +# include "stk600/rc032x/stk600_rc032x.h" +#elif BOARD == STK600_RC044X +# include "stk600/rc044x/stk600_rc044x.h" +#elif BOARD == STK600_RC064X +# include "stk600/rc064x/stk600_rc064x.h" +#elif BOARD == STK600_RC100X +# include "stk600/rc100x/stk600_rc100x.h" +#elif BOARD == UC3_A3_XPLAINED +# include "uc3_a3_xplained/uc3_a3_xplained.h" +#elif BOARD == UC3_L0_XPLAINED +# include "uc3_l0_xplained/uc3_l0_xplained.h" +#elif BOARD == STK600_RCUC3B0 +# include "stk600/rcuc3b0/stk600_rcuc3b0.h" +#elif BOARD == STK600_RCUC3D +# include "stk600/rcuc3d/stk600_rcuc3d.h" +#elif BOARD == STK600_RCUC3C0 +# include "stk600/rcuc3c0/stk600_rcuc3c0.h" +#elif BOARD == XMEGA_B1_XPLAINED +# include "xmega_b1_xplained/xmega_b1_xplained.h" +#elif BOARD == STK600_RC064X_LCDX +# include "stk600/rc064x_lcdx/stk600_rc064x_lcdx.h" +#elif BOARD == STK600_RC100X_LCDX +# include "stk600/rc100x_lcdx/stk600_rc100x_lcdx.h" +#elif BOARD == XMEGA_A1_XPLAINED +# include "xmega_a1_xplained/xmega_a1_xplained.h" +#elif BOARD == UC3_L0_XPLAINED_BC +# include "uc3_l0_xplained_bc/uc3_l0_xplained_bc.h" +#elif BOARD == SAM3S_EK +# include "sam3s_ek/sam3s_ek.h" +# include "system_sam3s.h" +#elif BOARD == SAM3S_EK2 +# include "sam3s_ek2/sam3s_ek2.h" +# include "system_sam3sd8.h" +#elif BOARD == SAM3U_EK +# include "sam3u_ek/sam3u_ek.h" +# include "system_sam3u.h" +#elif BOARD == SAM3X_EK +# include "sam3x_ek/sam3x_ek.h" +# include "system_sam3x.h" +#elif BOARD == SAM3N_EK +# include "sam3n_ek/sam3n_ek.h" +# include "system_sam3n.h" +#elif BOARD == SAM4S_EK +# include "sam4s_ek/sam4s_ek.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_WPIR_RD +# include "sam4s_wpir_rd/sam4s_wpir_rd.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_XPLAINED +# include "sam4s_xplained/sam4s_xplained.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_EK2 +# include "sam4s_ek2/sam4s_ek2.h" +# include "system_sam4s.h" +#elif BOARD == MEGA_1284P_XPLAINED + /*No header-file to include*/ +#elif BOARD == ARDUINO_DUE_X +# include "arduino_due_x/arduino_due_x.h" +# include "system_sam3x.h" +#elif BOARD == SAM4L_EK +# include "sam4l_ek/sam4l_ek.h" +#elif BOARD == SAM4E_EK +# include "sam4e_ek/sam4e_ek.h" +#elif BOARD == MEGA1284P_XPLAINED_BC +# include "mega1284p_xplained_bc/mega1284p_xplained_bc.h" +#elif BOARD == UC3_L0_QT600 +# include "uc3_l0_qt600/uc3_l0_qt600.h" +#elif BOARD == XMEGA_A3BU_XPLAINED +# include "xmega_a3bu_xplained/xmega_a3bu_xplained.h" +#elif BOARD == XMEGA_E5_XPLAINED +# include "xmega_e5_xplained/xmega_e5_xplained.h" +#elif BOARD == UC3B_BOARD_CONTROLLER +# include "uc3b_board_controller/uc3b_board_controller.h" +#elif BOARD == RZ600 +# include "rz600/rz600.h" +#elif BOARD == STK600_RCUC3A0 +# include "stk600/rcuc3a0/stk600_rcuc3a0.h" +#elif BOARD == ATXMEGA128A1_QT600 +# include "atxmega128a1_qt600/atxmega128a1_qt600.h" +#elif BOARD == STK600_RCUC3L3 +# include "stk600/rcuc3l3/stk600_rcuc3l3.h" +#elif BOARD == SAM4S_XPLAINED_PRO +# include "sam4s_xplained_pro/sam4s_xplained_pro.h" +#elif BOARD == SAM4L_XPLAINED_PRO +# include "sam4l_xplained_pro/sam4l_xplained_pro.h" +#elif BOARD == SIMULATOR_XMEGA_A1 +# include "simulator/xmega_a1/simulator_xmega_a1.h" +#elif BOARD == XMEGA_C3_XPLAINED +# include "xmega_c3_xplained/xmega_c3_xplained.h" +#elif BOARD == XMEGA_RF233_ZIGBIT +# include "xmega_rf233_zigbit/xmega_rf233_zigbit.h" +#elif BOARD == XMEGA_RF212B_ZIGBIT +# include "xmega_rf212b_zigbit/xmega_rf212b_zigbit.h" +#elif BOARD == AVR_SIMULATOR_UC3 +# include "avr_simulator_uc3/avr_simulator_uc3.h" +#elif BOARD == USER_BOARD + // User-reserved area: #include the header file of your board here (if any). +# include "fuse_relay_board_pinout.h" +# include "user_board.h" +#elif BOARD == DUMMY_BOARD +# include "dummy/dummy_board.h" +#else +# error No known Atmel board defined +#endif + +#if (defined EXT_BOARD) +# if EXT_BOARD == MC300 +# include "mc300/mc300.h" +# elif (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_2) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_A1) || \ + (EXT_BOARD == SENSORS_XPLAINED_PRESSURE_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_LIGHTPROX_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_BREADBOARD) +# include "sensors_xplained/sensors_xplained.h" +# elif EXT_BOARD == RZ600_AT86RF231 +# include "at86rf231/at86rf231.h" +# elif EXT_BOARD == RZ600_AT86RF230B +# include "at86rf230b/at86rf230b.h" +# elif EXT_BOARD == RZ600_AT86RF212 +# include "at86rf212/at86rf212.h" +# elif EXT_BOARD == SECURITY_XPLAINED +# include "security_xplained.h" +# elif EXT_BOARD == USER_EXT_BOARD + // User-reserved area: #include the header file of your extension board here + // (if any). +# endif +#endif + + +#if (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling. + +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); + +#endif // #ifdef __AVR32_ABI_COMPILER__ +#else +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); +#endif + + +#ifdef __cplusplus +} +#endif + +/** + * \} + */ + +#endif // _BOARD_H_ diff --git a/Fred_bootloader/src/ASF/common/boards/user_board/fuse_relay_board_pinout.h b/Fred_bootloader/src/ASF/common/boards/user_board/fuse_relay_board_pinout.h new file mode 100644 index 0000000000000000000000000000000000000000..482b0a987116c3340d42143ff86b780fb264688d --- /dev/null +++ b/Fred_bootloader/src/ASF/common/boards/user_board/fuse_relay_board_pinout.h @@ -0,0 +1,59 @@ +/* + * fuse_relay_board.h + * + * Created: 2014-01-28 18:08:44 + * Author: pperek + */ + + +#ifndef FUSE_RELAY_BOARD_H_ +#define FUSE_RELAY_BOARD_H_ + +#define MMC_LED IOPORT_CREATE_PIN(PORTA, 0) + +#define I2C_SDA IOPORT_CREATE_PIN(PORTC, 0) +#define I2C_SCL IOPORT_CREATE_PIN(PORTC, 1) +#define LOCAL_I2C_SDA_ERR IOPORT_CREATE_PIN(PORTD, 0) +#define LOCAL_I2C_SCL_ERR IOPORT_CREATE_PIN(PORTD, 1) +#define LOCAL_I2C_SDA IOPORT_CREATE_PIN(PORTE, 0) +#define LOCAL_I2C_SCL IOPORT_CREATE_PIN(PORTE, 1) + +#define GPIO_1 IOPORT_CREATE_PIN(PORTC, 2) +#define GPIO_2 IOPORT_CREATE_PIN(PORTC, 3) +#define GPIO_3 IOPORT_CREATE_PIN(PORTC, 4) +#define GPIO_4 IOPORT_CREATE_PIN(PORTC, 5) +#define GPIO_5 IOPORT_CREATE_PIN(PORTC, 6) +#define GPIO_6 IOPORT_CREATE_PIN(PORTC, 7) +#define GPIO_7 IOPORT_CREATE_PIN(PORTD, 2) +#define GPIO_8 IOPORT_CREATE_PIN(PORTD, 3) +#define GPIO_9 IOPORT_CREATE_PIN(PORTD, 4) +#define GPIO_10 IOPORT_CREATE_PIN(PORTD, 5) +#define GPIO_11 IOPORT_CREATE_PIN(PORTD, 6) + +#define CPLD_RESET IOPORT_CREATE_PIN(PORTD, 7) + +#define SPI_SS IOPORT_CREATE_PIN(PORTE, 4) +#define SPI_MOSI IOPORT_CREATE_PIN(PORTE, 5) +#define SPI_MISO IOPORT_CREATE_PIN(PORTE, 6) +#define SPI_SCK IOPORT_CREATE_PIN(PORTE, 7) + +#define SUART_XCK IOPORT_CREATE_PIN(PORTF, 1) +#define SUART_RX IOPORT_CREATE_PIN(PORTF, 2) +#define SUART_TX IOPORT_CREATE_PIN(PORTF, 3) +#define ON_OFF_FLIP_FLOP IOPORT_CREATE_PIN(PORTF, 4) + +#define CPLD_ADDR0 IOPORT_CREATE_PIN(PORTC, 2) +#define CPLD_ADDR1 IOPORT_CREATE_PIN(PORTC, 3) +#define CPLD_ADDR2 IOPORT_CREATE_PIN(PORTC, 4) +#define CPLD_ADDR3 IOPORT_CREATE_PIN(PORTC, 5) +#define CPLD_ADDR4 IOPORT_CREATE_PIN(PORTD, 6) + +#define CPLD_DATA0 IOPORT_CREATE_PIN(PORTD, 3) +#define CPLD_DATA1 IOPORT_CREATE_PIN(PORTD, 4) +#define CPLD_DATA2 IOPORT_CREATE_PIN(PORTD, 5) +#define CPLD_DATA3 IOPORT_CREATE_PIN(PORTD, 6) + +#define CPLD_READ IOPORT_CREATE_PIN(PORTC, 7) +#define CPLD_CLOCK IOPORT_CREATE_PIN(PORTD, 2) + +#endif /* FUSE_RELAY_BOARD_H_ */ \ No newline at end of file diff --git a/Fred_bootloader/src/ASF/common/boards/user_board/init.c b/Fred_bootloader/src/ASF/common/boards/user_board/init.c new file mode 100644 index 0000000000000000000000000000000000000000..ecdb648f5fbed89770b8277dd92c2ded5f26982a --- /dev/null +++ b/Fred_bootloader/src/ASF/common/boards/user_board/init.c @@ -0,0 +1,46 @@ +/** + * \file + * + * \brief User board initialization template + * + */ + +#include <asf.h> +#include <board.h> +#include <conf_board.h> +#include <ioport.h> + + +void board_init(void) +{ + ioport_configure_pin(MMC_LED, IOPORT_DIR_OUTPUT); + + ioport_configure_pin(LOCAL_I2C_SCL_ERR, IOPORT_DIR_INPUT); + ioport_configure_pin(LOCAL_I2C_SDA_ERR, IOPORT_DIR_INPUT); + + ioport_configure_pin(LOCAL_I2C_SCL, IOPORT_MODE_WIREDANDPULL); + ioport_configure_pin(LOCAL_I2C_SDA, IOPORT_MODE_WIREDANDPULL); + + //USART + ioport_configure_pin(SUART_TX, IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH); + ioport_configure_pin(SUART_RX, IOPORT_DIR_INPUT); + + //CPLD parallel bus + ioport_configure_pin(CPLD_ADDR0, IOPORT_DIR_OUTPUT); + ioport_configure_pin(CPLD_ADDR1, IOPORT_DIR_OUTPUT); + ioport_configure_pin(CPLD_ADDR2, IOPORT_DIR_OUTPUT); + ioport_configure_pin(CPLD_ADDR3, IOPORT_DIR_OUTPUT); + ioport_configure_pin(CPLD_ADDR4, IOPORT_DIR_OUTPUT); + + ioport_configure_pin(CPLD_READ, IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH); + ioport_configure_pin(CPLD_CLOCK, IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW); + //ioport_configure_pin(CPLD_WRITE, IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH); + + ioport_configure_pin(CPLD_DATA0, IOPORT_DIR_INPUT); + ioport_configure_pin(CPLD_DATA1, IOPORT_DIR_INPUT); + ioport_configure_pin(CPLD_DATA2, IOPORT_DIR_INPUT); + ioport_configure_pin(CPLD_DATA3, IOPORT_DIR_INPUT); + + + ioport_configure_pin(ON_OFF_FLIP_FLOP, IOPORT_DIR_INPUT); +} diff --git a/Fred_bootloader/src/ASF/common/boards/user_board/user_board.h b/Fred_bootloader/src/ASF/common/boards/user_board/user_board.h new file mode 100644 index 0000000000000000000000000000000000000000..7d9aeea6a49c39b7bcc54cfdcaad002ac2336677 --- /dev/null +++ b/Fred_bootloader/src/ASF/common/boards/user_board/user_board.h @@ -0,0 +1,44 @@ +/** + * \file + * + * \brief User board definition template + * + */ + + /* This file is intended to contain definitions and configuration details for + * features and devices that are available on the board, e.g., frequency and + * startup time for an external crystal, external memory devices, LED and USART + * pins. + */ + +#ifndef USER_BOARD_H +#define USER_BOARD_H + +#include <conf_board.h> + +#define FW_MAJOR_VERSION 2 +#define FW_MINOR_VERSION 0 +#define FW_REVISION 0 + +#define MAX_CURRENT_LIMIT 10000 +#define CHANNEL_NUMBER 8 + +// External oscillator settings. +// Uncomment and set correct values if external oscillator is used. + +// External oscillator frequency +//#define BOARD_XOSC_HZ 8000000 + +// External oscillator type. +//!< External clock signal +//#define BOARD_XOSC_TYPE XOSC_TYPE_EXTERNAL +//!< 32.768 kHz resonator on TOSC +//#define BOARD_XOSC_TYPE XOSC_TYPE_32KHZ +//!< 0.4 to 16 MHz resonator on XTALS +//#define BOARD_XOSC_TYPE XOSC_TYPE_XTAL + +// External oscillator startup time +//#define BOARD_XOSC_STARTUP_US 500000 + + +#endif // USER_BOARD_H diff --git a/Fred_bootloader/src/ASF/common/services/clock/genclk.h b/Fred_bootloader/src/ASF/common/services/clock/genclk.h new file mode 100644 index 0000000000000000000000000000000000000000..8e63acd5373f065db49830b87b2ce34dfd9e5cc9 --- /dev/null +++ b/Fred_bootloader/src/ASF/common/services/clock/genclk.h @@ -0,0 +1,188 @@ +/** + * \file + * + * \brief Generic clock management + * + * Copyright (c) 2010-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef CLK_GENCLK_H_INCLUDED +#define CLK_GENCLK_H_INCLUDED + +#include "parts.h" + +#if SAM3S +# include "sam3s/genclk.h" +#elif SAM3U +# include "sam3u/genclk.h" +#elif SAM3N +# include "sam3n/genclk.h" +#elif SAM3XA +# include "sam3x/genclk.h" +#elif SAM4S +# include "sam4s/genclk.h" +#elif SAM4L +# include "sam4l/genclk.h" +#elif SAM4E +# include "sam4e/genclk.h" +#elif SAM4N +# include "sam4n/genclk.h" +#elif SAM4C +# include "sam4c/genclk.h" +#elif SAM4CM +# include "sam4cm/genclk.h" +#elif SAM4CP +# include "sam4cp/genclk.h" +#elif SAMG +# include "samg/genclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/genclk.h" +#elif UC3A3 +# include "uc3a3_a4/genclk.h" +#elif UC3B +# include "uc3b0_b1/genclk.h" +#elif UC3C +# include "uc3c/genclk.h" +#elif UC3D +# include "uc3d/genclk.h" +#elif UC3L +# include "uc3l/genclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup genclk_group Generic Clock Management + * + * Generic clocks are configurable clocks which run outside the system + * clock domain. They are often connected to peripherals which have an + * asynchronous component running independently of the bus clock, e.g. + * USB controllers, low-power timers and RTCs, etc. + * + * Note that not all platforms have support for generic clocks; on such + * platforms, this API will not be available. + * + * @{ + */ + +/** + * \def GENCLK_DIV_MAX + * \brief Maximum divider supported by the generic clock implementation + */ +/** + * \enum genclk_source + * \brief Generic clock source ID + * + * Each generic clock may be generated from a different clock source. + * These are the available alternatives provided by the chip. + */ + +//! \name Generic clock configuration +//@{ +/** + * \struct genclk_config + * \brief Hardware representation of a set of generic clock parameters + */ +/** + * \fn void genclk_config_defaults(struct genclk_config *cfg, + * unsigned int id) + * \brief Initialize \a cfg to the default configuration for the clock + * identified by \a id. + */ +/** + * \fn void genclk_config_read(struct genclk_config *cfg, unsigned int id) + * \brief Read the currently active configuration of the clock + * identified by \a id into \a cfg. + */ +/** + * \fn void genclk_config_write(const struct genclk_config *cfg, + * unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id. + */ +/** + * \fn void genclk_config_set_source(struct genclk_config *cfg, + * enum genclk_source src) + * \brief Select a new source clock \a src in configuration \a cfg. + */ +/** + * \fn void genclk_config_set_divider(struct genclk_config *cfg, + * unsigned int divider) + * \brief Set a new \a divider in configuration \a cfg. + */ +/** + * \fn void genclk_enable_source(enum genclk_source src) + * \brief Enable the source clock \a src used by a generic clock. + */ + //@} + +//! \name Enabling and disabling Generic Clocks +//@{ +/** + * \fn void genclk_enable(const struct genclk_config *cfg, unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id and enable it. + */ +/** + * \fn void genclk_disable(unsigned int id) + * \brief Disable the generic clock identified by \a id. + */ +//@} + +/** + * \brief Enable the configuration defined by \a src and \a divider + * for the generic clock identified by \a id. + * + * \param id The ID of the generic clock. + * \param src The source clock of the generic clock. + * \param divider The divider used to generate the generic clock. + */ +static inline void genclk_enable_config(unsigned int id, enum genclk_source src, unsigned int divider) +{ + struct genclk_config gcfg; + + genclk_config_defaults(&gcfg, id); + genclk_enable_source(src); + genclk_config_set_source(&gcfg, src); + genclk_config_set_divider(&gcfg, divider); + genclk_enable(&gcfg, id); +} + +//! @} + +#endif /* CLK_GENCLK_H_INCLUDED */ diff --git a/Fred_bootloader/src/ASF/common/services/clock/osc.h b/Fred_bootloader/src/ASF/common/services/clock/osc.h new file mode 100644 index 0000000000000000000000000000000000000000..597c9aa17fa443a3dedd4a12b62d267586ebe66a --- /dev/null +++ b/Fred_bootloader/src/ASF/common/services/clock/osc.h @@ -0,0 +1,174 @@ +/** + * \file + * + * \brief Oscillator management + * + * Copyright (c) 2010-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef OSC_H_INCLUDED +#define OSC_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/osc.h" +#elif SAM3XA +# include "sam3x/osc.h" +#elif SAM3U +# include "sam3u/osc.h" +#elif SAM3N +# include "sam3n/osc.h" +#elif SAM4S +# include "sam4s/osc.h" +#elif SAM4E +# include "sam4e/osc.h" +#elif SAM4C +# include "sam4c/osc.h" +#elif SAM4CM +# include "sam4cm/osc.h" +#elif SAM4CP +# include "sam4cp/osc.h" +#elif SAM4L +# include "sam4l/osc.h" +#elif SAM4N +# include "sam4n/osc.h" +#elif SAMG +# include "samg/osc.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/osc.h" +#elif UC3A3 +# include "uc3a3_a4/osc.h" +#elif UC3B +# include "uc3b0_b1/osc.h" +#elif UC3C +# include "uc3c/osc.h" +#elif UC3D +# include "uc3d/osc.h" +#elif UC3L +# include "uc3l/osc.h" +#elif XMEGA +# include "xmega/osc.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup osc_group Oscillator Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip oscillators. Internal RC-oscillators, + * external crystal oscillators and external clock generators are + * supported by this module. What all of these have in common is that + * they swing at a fixed, nominal frequency which is normally not + * adjustable. + * + * \par Example: Enabling an oscillator + * + * The following example demonstrates how to enable the external + * oscillator on XMEGA A and wait for it to be ready to use. The + * oscillator identifiers are platform-specific, so while the same + * procedure is used on all platforms, the parameter to osc_enable() + * will be different from device to device. + * \code + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); \endcode + * + * \section osc_group_board Board-specific Definitions + * If external oscillators are used, the board code must provide the + * following definitions for each of those: + * - \b BOARD_<osc name>_HZ: The nominal frequency of the oscillator. + * - \b BOARD_<osc name>_STARTUP_US: The startup time of the + * oscillator in microseconds. + * - \b BOARD_<osc name>_TYPE: The type of oscillator connected, i.e. + * whether it's a crystal or external clock, and sometimes what kind + * of crystal it is. The meaning of this value is platform-specific. + * + * @{ + */ + +//! \name Oscillator Management +//@{ +/** + * \fn void osc_enable(uint8_t id) + * \brief Enable oscillator \a id + * + * The startup time and mode value is automatically determined based on + * definitions in the board code. + */ +/** + * \fn void osc_disable(uint8_t id) + * \brief Disable oscillator \a id + */ +/** + * \fn osc_is_ready(uint8_t id) + * \brief Determine whether oscillator \a id is ready. + * \retval true Oscillator \a id is running and ready to use as a clock + * source. + * \retval false Oscillator \a id is not running. + */ +/** + * \fn uint32_t osc_get_rate(uint8_t id) + * \brief Return the frequency of oscillator \a id in Hz + */ + +#ifndef __ASSEMBLY__ + +/** + * \brief Wait until the oscillator identified by \a id is ready + * + * This function will busy-wait for the oscillator identified by \a id + * to become stable and ready to use as a clock source. + * + * \param id A number identifying the oscillator to wait for. + */ +static inline void osc_wait_ready(uint8_t id) +{ + while (!osc_is_ready(id)) { + /* Do nothing */ + } +} + +#endif /* __ASSEMBLY__ */ + +//@} + +//! @} + +#endif /* OSC_H_INCLUDED */ diff --git a/Fred_bootloader/src/ASF/common/services/clock/pll.h b/Fred_bootloader/src/ASF/common/services/clock/pll.h new file mode 100644 index 0000000000000000000000000000000000000000..18b5a6e4d1ecd4ec7e16ac25bc75ab724f6e7221 --- /dev/null +++ b/Fred_bootloader/src/ASF/common/services/clock/pll.h @@ -0,0 +1,330 @@ +/** + * \file + * + * \brief PLL management + * + * Copyright (c) 2010-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef CLK_PLL_H_INCLUDED +#define CLK_PLL_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/pll.h" +#elif SAM3XA +# include "sam3x/pll.h" +#elif SAM3U +# include "sam3u/pll.h" +#elif SAM3N +# include "sam3n/pll.h" +#elif SAM4S +# include "sam4s/pll.h" +#elif SAM4E +# include "sam4e/pll.h" +#elif SAM4C +# include "sam4c/pll.h" +#elif SAM4CM +# include "sam4cm/pll.h" +#elif SAM4CP +# include "sam4cp/pll.h" +#elif SAM4L +# include "sam4l/pll.h" +#elif SAM4N +# include "sam4n/pll.h" +#elif SAMG +# include "samg/pll.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/pll.h" +#elif UC3A3 +# include "uc3a3_a4/pll.h" +#elif UC3B +# include "uc3b0_b1/pll.h" +#elif UC3C +# include "uc3c/pll.h" +#elif UC3D +# include "uc3d/pll.h" +#elif (UC3L0128 || UC3L0256 || UC3L3_L4) +# include "uc3l/pll.h" +#elif XMEGA +# include "xmega/pll.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup pll_group PLL Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip PLLs. A PLL will take an input signal + * (the \em source), optionally divide the frequency by a configurable + * \em divider, and then multiply the frequency by a configurable \em + * multiplier. + * + * Some devices don't support input dividers; specifying any other + * divisor than 1 on these devices will result in an assertion failure. + * Other devices may have various restrictions to the frequency range of + * the input and output signals. + * + * \par Example: Setting up PLL0 with default parameters + * + * The following example shows how to configure and enable PLL0 using + * the default parameters specified using the configuration symbols + * listed above. + * \code + pll_enable_config_defaults(0); \endcode + * + * To configure, enable PLL0 using the default parameters and to disable + * a specific feature like Wide Bandwidth Mode (a UC3A3-specific + * PLL option.), you can use this initialization process. + * \code + struct pll_config pllcfg; + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_defaults(&pllcfg, 0); + pll_config_set_option(&pllcfg, PLL_OPT_WBM_DISABLE); + pll_enable(&pllcfg, 0); + pll_wait_for_lock(0); \endcode + * + * When the last function call returns, PLL0 is ready to be used as the + * main system clock source. + * + * \section pll_group_config Configuration Symbols + * + * Each PLL has a set of default parameters determined by the following + * configuration symbols in the application's configuration file: + * - \b CONFIG_PLLn_SOURCE: The default clock source connected to the + * input of PLL \a n. Must be one of the values defined by the + * #pll_source enum. + * - \b CONFIG_PLLn_MUL: The default multiplier (loop divider) of PLL + * \a n. + * - \b CONFIG_PLLn_DIV: The default input divider of PLL \a n. + * + * These configuration symbols determine the result of calling + * pll_config_defaults() and pll_get_default_rate(). + * + * @{ + */ + +//! \name Chip-specific PLL characteristics +//@{ +/** + * \def PLL_MAX_STARTUP_CYCLES + * \brief Maximum PLL startup time in number of slow clock cycles + */ +/** + * \def NR_PLLS + * \brief Number of on-chip PLLs + */ + +/** + * \def PLL_MIN_HZ + * \brief Minimum frequency that the PLL can generate + */ +/** + * \def PLL_MAX_HZ + * \brief Maximum frequency that the PLL can generate + */ +/** + * \def PLL_NR_OPTIONS + * \brief Number of PLL option bits + */ +//@} + +/** + * \enum pll_source + * \brief PLL clock source + */ + +//! \name PLL configuration +//@{ + +/** + * \struct pll_config + * \brief Hardware-specific representation of PLL configuration. + * + * This structure contains one or more device-specific values + * representing the current PLL configuration. The contents of this + * structure is typically different from platform to platform, and the + * user should not access any fields except through the PLL + * configuration API. + */ + +/** + * \fn void pll_config_init(struct pll_config *cfg, + * enum pll_source src, unsigned int div, unsigned int mul) + * \brief Initialize PLL configuration from standard parameters. + * + * \note This function may be defined inline because it is assumed to be + * called very few times, and usually with constant parameters. Inlining + * it will in such cases reduce the code size significantly. + * + * \param cfg The PLL configuration to be initialized. + * \param src The oscillator to be used as input to the PLL. + * \param div PLL input divider. + * \param mul PLL loop divider (i.e. multiplier). + * + * \return A configuration which will make the PLL run at + * (\a mul / \a div) times the frequency of \a src + */ +/** + * \def pll_config_defaults(cfg, pll_id) + * \brief Initialize PLL configuration using default parameters. + * + * After this function returns, \a cfg will contain a configuration + * which will make the PLL run at (CONFIG_PLLx_MUL / CONFIG_PLLx_DIV) + * times the frequency of CONFIG_PLLx_SOURCE. + * + * \param cfg The PLL configuration to be initialized. + * \param pll_id Use defaults for this PLL. + */ +/** + * \def pll_get_default_rate(pll_id) + * \brief Get the default rate in Hz of \a pll_id + */ +/** + * \fn void pll_config_set_option(struct pll_config *cfg, + * unsigned int option) + * \brief Set the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be set. + */ +/** + * \fn void pll_config_clear_option(struct pll_config *cfg, + * unsigned int option) + * \brief Clear the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be cleared. + */ +/** + * \fn void pll_config_read(struct pll_config *cfg, unsigned int pll_id) + * \brief Read the currently active configuration of \a pll_id. + * + * \param cfg The configuration object into which to store the currently + * active configuration. + * \param pll_id The ID of the PLL to be accessed. + */ +/** + * \fn void pll_config_write(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg on \a pll_id + * + * \param cfg The configuration object representing the PLL + * configuration to be activated. + * \param pll_id The ID of the PLL to be updated. + */ + +//@} + +//! \name Interaction with the PLL hardware +//@{ +/** + * \fn void pll_enable(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg and enable PLL \a pll_id. + * + * \param cfg The PLL configuration to be activated. + * \param pll_id The ID of the PLL to be enabled. + */ +/** + * \fn void pll_disable(unsigned int pll_id) + * \brief Disable the PLL identified by \a pll_id. + * + * After this function is called, the PLL identified by \a pll_id will + * be disabled. The PLL configuration stored in hardware may be affected + * by this, so if the caller needs to restore the same configuration + * later, it should either do a pll_config_read() before disabling the + * PLL, or remember the last configuration written to the PLL. + * + * \param pll_id The ID of the PLL to be disabled. + */ +/** + * \fn bool pll_is_locked(unsigned int pll_id) + * \brief Determine whether the PLL is locked or not. + * + * \param pll_id The ID of the PLL to check. + * + * \retval true The PLL is locked and ready to use as a clock source + * \retval false The PLL is not yet locked, or has not been enabled. + */ +/** + * \fn void pll_enable_source(enum pll_source src) + * \brief Enable the source of the pll. + * The source is enabled, if the source is not already running. + * + * \param src The ID of the PLL source to enable. + */ +/** + * \fn void pll_enable_config_defaults(unsigned int pll_id) + * \brief Enable the pll with the default configuration. + * PLL is enabled, if the PLL is not already locked. + * + * \param pll_id The ID of the PLL to enable. + */ + +/** + * \brief Wait for PLL \a pll_id to become locked + * + * \todo Use a timeout to avoid waiting forever and hanging the system + * + * \param pll_id The ID of the PLL to wait for. + * + * \retval STATUS_OK The PLL is now locked. + * \retval ERR_TIMEOUT Timed out waiting for PLL to become locked. + */ +static inline int pll_wait_for_lock(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + while (!pll_is_locked(pll_id)) { + /* Do nothing */ + } + + return 0; +} + +//@} +//! @} + +#endif /* CLK_PLL_H_INCLUDED */ diff --git a/Fred_bootloader/src/ASF/common/services/clock/sysclk.h b/Fred_bootloader/src/ASF/common/services/clock/sysclk.h new file mode 100644 index 0000000000000000000000000000000000000000..50a1c3f4535316cc095714f4c3283a0c032e6664 --- /dev/null +++ b/Fred_bootloader/src/ASF/common/services/clock/sysclk.h @@ -0,0 +1,183 @@ +/** + * \file + * + * \brief System clock management + * + * Copyright (c) 2010-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef SYSCLK_H_INCLUDED +#define SYSCLK_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/sysclk.h" +#elif SAM3U +# include "sam3u/sysclk.h" +#elif SAM3N +# include "sam3n/sysclk.h" +#elif SAM3XA +# include "sam3x/sysclk.h" +#elif SAM4S +# include "sam4s/sysclk.h" +#elif SAM4E +# include "sam4e/sysclk.h" +#elif SAM4C +# include "sam4c/sysclk.h" +#elif SAM4CM +# include "sam4cm/sysclk.h" +#elif SAM4CP +# include "sam4cp/sysclk.h" +#elif SAM4L +# include "sam4l/sysclk.h" +#elif SAM4N +# include "sam4n/sysclk.h" +#elif SAMG +# include "samg/sysclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/sysclk.h" +#elif UC3A3 +# include "uc3a3_a4/sysclk.h" +#elif UC3B +# include "uc3b0_b1/sysclk.h" +#elif UC3C +# include "uc3c/sysclk.h" +#elif UC3D +# include "uc3d/sysclk.h" +#elif UC3L +# include "uc3l/sysclk.h" +#elif XMEGA +# include "xmega/sysclk.h" +#elif MEGA +# include "mega/sysclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \defgroup clk_group Clock Management + */ + +/** + * \ingroup clk_group + * \defgroup sysclk_group System Clock Management + * + * See \ref sysclk_quickstart. + * + * The <em>sysclk</em> API covers the <em>system clock</em> and all + * clocks derived from it. The system clock is a chip-internal clock on + * which all <em>synchronous clocks</em>, i.e. CPU and bus/peripheral + * clocks, are based. The system clock is typically generated from one + * of a variety of sources, which may include crystal and RC oscillators + * as well as PLLs. The clocks derived from the system clock are + * sometimes also known as <em>synchronous clocks</em>, since they + * always run synchronously with respect to each other, as opposed to + * <em>generic clocks</em> which may run from different oscillators or + * PLLs. + * + * Most applications should simply call sysclk_init() to initialize + * everything related to the system clock and its source (oscillator, + * PLL or DFLL), and leave it at that. More advanced applications, and + * platform-specific drivers, may require additional services from the + * clock system, some of which may be platform-specific. + * + * \section sysclk_group_platform Platform Dependencies + * + * The sysclk API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms with the same + * parameters and functionality. These functions may be called freely by + * portable applications, drivers and services: + * - sysclk_init() + * - sysclk_set_source() + * - sysclk_get_main_hz() + * - sysclk_get_cpu_hz() + * - sysclk_get_peripheral_bus_hz() + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behavior. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - sysclk_enable_peripheral_clock() + * - sysclk_disable_peripheral_clock() + * - sysclk_enable_module() + * - sysclk_disable_module() + * - sysclk_module_is_enabled() + * - sysclk_set_prescalers() + * + * All other functions should be considered platform-specific. + * Enabling/disabling clocks to specific peripherals as well as + * determining the speed of these clocks should be done by calling + * functions provided by the driver for that peripheral. + * + * @{ + */ + +//! \name System Clock Initialization +//@{ +/** + * \fn void sysclk_init(void) + * \brief Initialize the synchronous clock system. + * + * This function will initialize the system clock and its source. This + * includes: + * - Mask all synchronous clocks except for any clocks which are + * essential for normal operation (for example internal memory + * clocks). + * - Set up the system clock prescalers as specified by the + * application's configuration file. + * - Enable the clock source specified by the application's + * configuration file (oscillator or PLL) and wait for it to become + * stable. + * - Set the main system clock source to the clock specified by the + * application's configuration file. + * + * Since all non-essential peripheral clocks are initially disabled, it + * is the responsibility of the peripheral driver to re-enable any + * clocks that are needed for normal operation. + */ +//@} + +//! @} + +#endif /* SYSCLK_H_INCLUDED */ diff --git a/Fred_bootloader/src/ASF/common/services/clock/xmega/osc.h b/Fred_bootloader/src/ASF/common/services/clock/xmega/osc.h new file mode 100644 index 0000000000000000000000000000000000000000..9cc0333b15bded216fa2006e3f91f04b9ca16521 --- /dev/null +++ b/Fred_bootloader/src/ASF/common/services/clock/xmega/osc.h @@ -0,0 +1,504 @@ +/** + * \file + * + * \brief Chip-specific oscillator management functions + * + * Copyright (c) 2010-2013 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_OSC_H_INCLUDED +#define XMEGA_OSC_H_INCLUDED + +#include <compiler.h> +#include <board.h> + +/** + * \weakgroup osc_group + * + * \section osc_group_errata Errata + * - Auto-calibration does not work on XMEGA A1 revision H and + * earlier. + * @{ + */ + +//! \name Oscillator identifiers +//@{ +//! 2 MHz Internal RC Oscillator +#define OSC_ID_RC2MHZ OSC_RC2MEN_bm +//! 32 MHz Internal RC Oscillator +#define OSC_ID_RC32MHZ OSC_RC32MEN_bm +//! 32 KHz Internal RC Oscillator +#define OSC_ID_RC32KHZ OSC_RC32KEN_bm +//! External Oscillator +#define OSC_ID_XOSC OSC_XOSCEN_bm +#if XMEGA_E +//! 8 MHz Internal RC Oscillator +# define OSC_ID_RC8MHZ OSC_RC8MEN_bm +#endif + +/** + * \brief Reference from USB Start Of Frame + * \note This cannot be enabled or disabled, but can be used as a reference for + * the autocalibration (DFLL). + */ +#define OSC_ID_USBSOF 0xff +//@} + +//! \name External oscillator types +//@{ +#define XOSC_TYPE_EXTERNAL 0 //!< External clock signal +#define XOSC_TYPE_32KHZ 2 //!< 32.768 kHz resonator on TOSC +#define XOSC_TYPE_XTAL 3 //!< 0.4 to 16 MHz resonator on XTAL +//@} + +/** + * \def CONFIG_XOSC_32KHZ_LPM + * \brief Define for enabling Low Power Mode for 32 kHz external oscillator. + */ +#ifdef __DOXYGEN__ +# define CONFIG_XOSC_32KHZ_LPM +#endif /* __DOXYGEN__ */ + +/** + * \def CONFIG_XOSC_STARTUP + * \brief Board-dependent value that determines the number of start-up cycles + * for external resonators, based on BOARD_XOSC_STARTUP_US. This is written to + * the two MSB of the XOSCSEL field of OSC.XOSCCTRL. + * + * \note This is automatically computed from BOARD_XOSC_HZ and + * BOARD_XOSC_STARTUP_US if it is not manually set. + */ + +//! \name XTAL resonator start-up cycles +//@{ +#define XOSC_STARTUP_256 0 //!< 256 cycle start-up time +#define XOSC_STARTUP_1024 1 //!< 1 k cycle start-up time +#define XOSC_STARTUP_16384 2 //!< 16 k cycle start-up time +//@} + +/** + * \def CONFIG_XOSC_RANGE + * \brief Board-dependent value that sets the frequency range of the external + * oscillator. This is written to the FRQRANGE field of OSC.XOSCCTRL. + * + * \note This is automatically computed from BOARD_XOSC_HZ if it is not manually + * set. + */ + +//! \name XTAL resonator frequency range +//@{ +//! 0.4 to 2 MHz frequency range +#define XOSC_RANGE_04TO2 OSC_FRQRANGE_04TO2_gc +//! 2 to 9 MHz frequency range +#define XOSC_RANGE_2TO9 OSC_FRQRANGE_2TO9_gc +//! 9 to 12 MHz frequency range +#define XOSC_RANGE_9TO12 OSC_FRQRANGE_9TO12_gc +//! 12 to 16 MHz frequency range +#define XOSC_RANGE_12TO16 OSC_FRQRANGE_12TO16_gc +//@} + +/** + * \def XOSC_STARTUP_TIMEOUT + * \brief Number of us to wait for XOSC to start + * + * This is the number of slow clock cycles corresponding to + * OSC0_STARTUP_VALUE with an additional 25% safety margin. If the + * oscillator isn't running when this timeout has expired, it is assumed + * to have failed to start. + */ + +// If application intends to use XOSC. +#ifdef BOARD_XOSC_HZ +// Get start-up config for XOSC, if not manually set. +# ifndef CONFIG_XOSC_STARTUP +# ifndef BOARD_XOSC_STARTUP_US +# error BOARD_XOSC_STARTUP_US must be configured. +# else +//! \internal Number of start-up cycles for the board's XOSC. +# define BOARD_XOSC_STARTUP_CYCLES \ + (BOARD_XOSC_HZ / 1000000 * BOARD_XOSC_STARTUP_US) + +# if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL) +# if (BOARD_XOSC_STARTUP_CYCLES > 16384) +# error BOARD_XOSC_STARTUP_US is too high for current BOARD_XOSC_HZ. + +# elif (BOARD_XOSC_STARTUP_CYCLES > 1024) +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_16384 +# define XOSC_STARTUP_TIMEOUT (16384*(1000000/BOARD_XOSC_HZ)) + +# elif (BOARD_XOSC_STARTUP_CYCLES > 256) +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_1024 +# define XOSC_STARTUP_TIMEOUT (1024*(1000000/BOARD_XOSC_HZ)) + +# else +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_256 +# define XOSC_STARTUP_TIMEOUT (256*(1000000/BOARD_XOSC_HZ)) +# endif +# else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */ +# define CONFIG_XOSC_STARTUP 0 +# endif +# endif /* BOARD_XOSC_STARTUP_US */ +# endif /* CONFIG_XOSC_STARTUP */ + +// Get frequency range setting for XOSC, if not manually set. +# ifndef CONFIG_XOSC_RANGE +# if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL) +# if (BOARD_XOSC_HZ < 400000) +# error BOARD_XOSC_HZ is below minimum frequency of 400 kHz. + +# elif (BOARD_XOSC_HZ < 2000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_04TO2 + +# elif (BOARD_XOSC_HZ < 9000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_2TO9 + +# elif (BOARD_XOSC_HZ < 12000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_9TO12 + +# elif (BOARD_XOSC_HZ <= 16000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_12TO16 + +# else +# error BOARD_XOSC_HZ is above maximum frequency of 16 MHz. +# endif +# else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */ +# define CONFIG_XOSC_RANGE 0 +# endif +# endif /* CONFIG_XOSC_RANGE */ +#endif /* BOARD_XOSC_HZ */ + +#ifndef __ASSEMBLY__ + +/** + * \internal + * \brief Enable internal oscillator \a id + * + * Do not call this function directly. Use osc_enable() instead. + */ +static inline void osc_enable_internal(uint8_t id) +{ + irqflags_t flags; + + Assert(id != OSC_ID_USBSOF); + + flags = cpu_irq_save(); + OSC.CTRL |= id; +#if (XMEGA_E && CONFIG_SYSCLK_RC8MHZ_LPM) + if(id == OSC_ID_RC8MHZ) { + OSC.CTRL |= OSC_RC8MLPM_bm; + } +#endif + cpu_irq_restore(flags); +} + +#if defined(BOARD_XOSC_HZ) || defined(__DOXYGEN__) + +/** + * \internal + * \brief Enable external oscillator \a id + * + * Do not call this function directly. Use osc_enable() instead. Also + * note that this function is only available if the board actually has + * an external oscillator crystal. + */ +static inline void osc_enable_external(uint8_t id) +{ + irqflags_t flags; + + Assert(id == OSC_ID_XOSC); + +#ifndef CONFIG_XOSC_32KHZ_LPM +# if (XMEGA_E && (BOARD_XOSC_TYPE == XOSC_TYPE_EXTERNAL) && defined(CONFIG_XOSC_EXTERNAL_PC4)) + OSC.XOSCCTRL = OSC_XOSCSEL4_bm; +# else + OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) | + CONFIG_XOSC_RANGE; +# endif +#else + OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) | + CONFIG_XOSC_RANGE | OSC_X32KLPM_bm; +#endif /* CONFIG_XOSC_32KHZ_LPM */ + + flags = cpu_irq_save(); + OSC.CTRL |= id; + cpu_irq_restore(flags); +} +#else + +static inline void osc_enable_external(uint8_t id) +{ + Assert(false); // No external oscillator on the selected board +} +#endif + +static inline void osc_disable(uint8_t id) +{ + irqflags_t flags; + + Assert(id != OSC_ID_USBSOF); + + flags = cpu_irq_save(); + OSC.CTRL &= ~id; + cpu_irq_restore(flags); +} + +static inline void osc_enable(uint8_t id) +{ + if (id != OSC_ID_XOSC) { + osc_enable_internal(id); + } else { + osc_enable_external(id); + } +} + +static inline bool osc_is_ready(uint8_t id) +{ + Assert(id != OSC_ID_USBSOF); + + return OSC.STATUS & id; +} + +//! \name XMEGA-Specific Oscillator Features +//@{ + +/** + * \brief Enable DFLL-based automatic calibration of an internal + * oscillator. + * + * The XMEGA features two Digital Frequency Locked Loops (DFLLs) which + * can be used to improve the accuracy of the 2 MHz and 32 MHz internal + * RC oscillators. The DFLL compares the oscillator frequency with a + * more accurate reference clock to do automatic run-time calibration of + * the oscillator. + * + * This function enables auto-calibration for either the 2 MHz or 32 MHz + * internal oscillator using either the 32.768 kHz calibrated internal + * oscillator or an external crystal oscillator as a reference. If the + * latter option is used, the crystal must be connected to the TOSC pins + * and run at 32.768 kHz. + * + * \param id The ID of the oscillator for which to enable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + * \param ref_id The ID of the oscillator to use as a reference: + * \arg \c OSC_ID_RC32KHZ or \c OSC_ID_XOSC for internal or external 32 kHz + * reference, respectively. + * \arg \c OSC_ID_USBSOF for 32 MHz only when USB is available and running. + */ +static inline void osc_enable_autocalibration(uint8_t id, uint8_t ref_id) +{ + irqflags_t flags; + + flags = cpu_irq_save(); + switch (id) { + case OSC_ID_RC2MHZ: +#if !XMEGA_E + Assert((ref_id == OSC_ID_RC32KHZ) || (ref_id == OSC_ID_XOSC)); + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC2MCREF_bm; + } else { + OSC.DFLLCTRL &= ~(OSC_RC2MCREF_bm); + } + DFLLRC2M.CTRL |= DFLL_ENABLE_bm; +#endif + break; + + case OSC_ID_RC32MHZ: +#if XMEGA_AU || XMEGA_B || XMEGA_C || XMEGA_E + Assert((ref_id == OSC_ID_RC32KHZ) + || (ref_id == OSC_ID_XOSC) +# if !XMEGA_E + || (ref_id == OSC_ID_USBSOF) +#endif + ); + + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_gm); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC32MCREF_XOSC32K_gc; + } + else if (ref_id == OSC_ID_RC32KHZ) { + OSC.DFLLCTRL |= OSC_RC32MCREF_RC32K_gc; + } +# if !XMEGA_E + else if (ref_id == OSC_ID_USBSOF) { + /* + * Calibrate 32MRC at 48MHz using USB SOF + * 48MHz / 1kHz = 0xBB80 + */ + DFLLRC32M.COMP1 = 0x80; + DFLLRC32M.COMP2 = 0xBB; + OSC.DFLLCTRL |= OSC_RC32MCREF_USBSOF_gc; + } +# endif +#else + Assert((ref_id == OSC_ID_RC32KHZ) || + (ref_id == OSC_ID_XOSC)); + +# if defined(OSC_RC32MCREF_gm) + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_gm); +# endif + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); +# if defined(OSC_RC32MCREF_gm) + OSC.DFLLCTRL |= OSC_RC32MCREF_XOSC32K_gc; +# else + OSC.DFLLCTRL |= OSC_RC32MCREF_bm; +# endif + } + else if (ref_id == OSC_ID_RC32KHZ) { +# if defined(OSC_RC32MCREF_gm) + OSC.DFLLCTRL |= OSC_RC32MCREF_RC32K_gc; +# else + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_bm); +# endif + } +#endif + + DFLLRC32M.CTRL |= DFLL_ENABLE_bm; + break; + + default: + Assert(false); + break; + } + cpu_irq_restore(flags); +} + +/** + * \brief Disable DFLL-based automatic calibration of an internal + * oscillator. + * + * \see osc_enable_autocalibration + * + * \param id The ID of the oscillator for which to disable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + */ +static inline void osc_disable_autocalibration(uint8_t id) +{ + switch (id) { + case OSC_ID_RC2MHZ: +#if !XMEGA_E + DFLLRC2M.CTRL = 0; +#endif + break; + + case OSC_ID_RC32MHZ: + DFLLRC32M.CTRL = 0; + break; + + default: + Assert(false); + break; + } +} + +/** + * \brief Load a specific calibration value for the specified oscillator. + * + * \param id The ID of the oscillator for which to disable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + * \param calib The specific calibration value required: + * + */ +static inline void osc_user_calibration(uint8_t id, uint16_t calib) +{ + switch (id) { + case OSC_ID_RC2MHZ: +#if !XMEGA_E + DFLLRC2M.CALA=LSB(calib); + DFLLRC2M.CALB=MSB(calib); +#endif + break; + + case OSC_ID_RC32MHZ: + DFLLRC32M.CALA=LSB(calib); + DFLLRC32M.CALB=MSB(calib); + break; + +#if XMEGA_E + case OSC_ID_RC8MHZ: + OSC.RC8MCAL=LSB(calib); + break; +#endif + + default: + Assert(false); + break; + } +} +//@} + +static inline uint32_t osc_get_rate(uint8_t id) +{ + Assert(id != OSC_ID_USBSOF); + + switch (id) { + case OSC_ID_RC2MHZ: + return 2000000UL; + + case OSC_ID_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL + return CONFIG_OSC_RC32_CAL; +#else + return 32000000UL; +#endif + + case OSC_ID_RC32KHZ: + return 32768UL; + +#ifdef BOARD_XOSC_HZ + case OSC_ID_XOSC: + return BOARD_XOSC_HZ; +#endif + + default: + Assert(false); + return 0; + } +} + +#endif /* __ASSEMBLY__ */ + +//! @} + +#endif /* XMEGA_OSC_H_INCLUDED */ diff --git a/Fred_bootloader/src/ASF/common/services/clock/xmega/pll.h b/Fred_bootloader/src/ASF/common/services/clock/xmega/pll.h new file mode 100644 index 0000000000000000000000000000000000000000..dba4c0707063be43277751d4feed8ab76043620c --- /dev/null +++ b/Fred_bootloader/src/ASF/common/services/clock/xmega/pll.h @@ -0,0 +1,271 @@ +/** + * \file + * + * \brief Chip-specific PLL management functions + * + * Copyright (c) 2010-2013 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_PLL_H_INCLUDED +#define XMEGA_PLL_H_INCLUDED + +#include <compiler.h> + +/** + * \weakgroup pll_group + * @{ + */ + +#define NR_PLLS 1 +#define PLL_MIN_HZ 10000000UL +#define PLL_MAX_HZ 200000000UL +#define PLL_NR_OPTIONS 0 + +enum pll_source { + //! 2 MHz Internal RC Oscillator + PLL_SRC_RC2MHZ = OSC_PLLSRC_RC2M_gc, + //! 32 MHz Internal RC Oscillator + PLL_SRC_RC32MHZ = OSC_PLLSRC_RC32M_gc, + //! External Clock Source + PLL_SRC_XOSC = OSC_PLLSRC_XOSC_gc, +}; + +#define pll_get_default_rate(pll_id) \ + pll_get_default_rate_priv(CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_MUL, \ + CONFIG_PLL##pll_id##_DIV) + +/** + * \internal + * \brief Return clock rate for specified PLL settings. + * + * \note Due to the hardware implementation of the PLL, \a div must be 4 if the + * 32 MHz RC oscillator is used as reference and 1 otherwise. The reference must + * be above 440 kHz, and the output between 10 and 200 MHz. + * + * \param src ID of the PLL's reference source oscillator. + * \param mul Multiplier for the PLL. + * \param div Divisor for the PLL. + * + * \retval Output clock rate from PLL. + */ +static inline uint32_t pll_get_default_rate_priv(enum pll_source src, + unsigned int mul, unsigned int div) +{ + uint32_t rate; + + switch (src) { + case PLL_SRC_RC2MHZ: + rate = 2000000UL; + Assert(div == 1); + break; + + case PLL_SRC_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL //32MHz oscillator is calibrated to another frequency + rate = CONFIG_OSC_RC32_CAL / 4; +#else + rate = 8000000UL; + #endif + Assert(div == 4); + break; + + case PLL_SRC_XOSC: + rate = osc_get_rate(OSC_ID_XOSC); + Assert(div == 1); + break; + + default: + break; + } + + Assert(rate >= 440000UL); + + rate *= mul; + + Assert(rate >= PLL_MIN_HZ); + Assert(rate <= PLL_MAX_HZ); + + return rate; +} + +struct pll_config { + uint8_t ctrl; +}; + +/** + * \note The XMEGA PLL hardware uses hard-wired input dividers, so the + * user must ensure that \a div is set as follows: + * - If \a src is PLL_SRC_32MHZ, \a div must be set to 4. + * - Otherwise, \a div must be set to 1. + */ +static inline void pll_config_init(struct pll_config *cfg, enum pll_source src, + unsigned int div, unsigned int mul) +{ + Assert(mul >= 1 && mul <= 31); + + if (src == PLL_SRC_RC32MHZ) { + Assert(div == 4); + } else { + Assert(div == 1); + } + + /* Initialize the configuration */ + cfg->ctrl = src | (mul << OSC_PLLFAC_gp); +} + +#define pll_config_defaults(cfg, pll_id) \ + pll_config_init(cfg, \ + CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_DIV, \ + CONFIG_PLL##pll_id##_MUL) + +static inline void pll_config_read(struct pll_config *cfg, unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + cfg->ctrl = OSC.PLLCTRL; +} + +static inline void pll_config_write(const struct pll_config *cfg, + unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + OSC.PLLCTRL = cfg->ctrl; +} + +/** + * \note If a different PLL reference oscillator than those enabled by + * \ref sysclk_init() is used, the user must ensure that the desired reference + * is enabled prior to calling this function. + */ +static inline void pll_enable(const struct pll_config *cfg, + unsigned int pll_id) +{ + irqflags_t flags; + + Assert(pll_id < NR_PLLS); + + flags = cpu_irq_save(); + pll_config_write(cfg, pll_id); + OSC.CTRL |= OSC_PLLEN_bm; + cpu_irq_restore(flags); +} + +/*! \note This will not automatically disable the reference oscillator that is + * configured for the PLL. + */ +static inline void pll_disable(unsigned int pll_id) +{ + irqflags_t flags; + + Assert(pll_id < NR_PLLS); + + flags = cpu_irq_save(); + OSC.CTRL &= ~OSC_PLLEN_bm; + cpu_irq_restore(flags); +} + +static inline bool pll_is_locked(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + return OSC.STATUS & OSC_PLLRDY_bm; +} + +static inline void pll_enable_source(enum pll_source src) +{ + switch (src) { + case PLL_SRC_RC2MHZ: + break; + + case PLL_SRC_RC32MHZ: + if (!osc_is_ready(OSC_ID_RC32MHZ)) { + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + != OSC_ID_USBSOF) { + osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + } + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + } + break; + + case PLL_SRC_XOSC: + if (!osc_is_ready(OSC_ID_XOSC)) { + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + } + break; + default: + Assert(false); + break; + } +} + +static inline void pll_enable_config_defaults(unsigned int pll_id) +{ + struct pll_config pllcfg; + + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + switch (pll_id) { +#ifdef CONFIG_PLL0_SOURCE + case 0: + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_init(&pllcfg, + CONFIG_PLL0_SOURCE, + CONFIG_PLL0_DIV, + CONFIG_PLL0_MUL); + break; +#endif + default: + Assert(false); + break; + } + pll_enable(&pllcfg, pll_id); + while (!pll_is_locked(pll_id)); +} + +//! @} + +#endif /* XMEGA_PLL_H_INCLUDED */ diff --git a/Fred_bootloader/src/ASF/common/services/clock/xmega/sysclk.c b/Fred_bootloader/src/ASF/common/services/clock/xmega/sysclk.c new file mode 100644 index 0000000000000000000000000000000000000000..db5aab419bbd88aed8d5e613a61958f0598d1604 --- /dev/null +++ b/Fred_bootloader/src/ASF/common/services/clock/xmega/sysclk.c @@ -0,0 +1,257 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (c) 2010-2013 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#include <compiler.h> + +#include <sysclk.h> +#include <osc.h> +#include <pll.h> + +#if XMEGA_AU || XMEGA_B || XMEGA_C +# include <nvm.h> +#endif + + +void sysclk_init(void) +{ + uint8_t *reg = (uint8_t *)&PR.PRGEN; + uint8_t i; +#ifdef CONFIG_OSC_RC32_CAL + uint16_t cal; + /* avoid Cppcheck Warning */ + UNUSED(cal); +#endif + bool need_rc2mhz = false; + + /* Turn off all peripheral clocks that can be turned off. */ + for (i = 0; i <= SYSCLK_PORT_F; i++) { + *(reg++) = 0xff; + } + + /* Set up system clock prescalers if different from defaults */ + if ((CONFIG_SYSCLK_PSADIV != SYSCLK_PSADIV_1) + || (CONFIG_SYSCLK_PSBCDIV != SYSCLK_PSBCDIV_1_1)) { + sysclk_set_prescalers(CONFIG_SYSCLK_PSADIV, + CONFIG_SYSCLK_PSBCDIV); + } +#if (CONFIG_OSC_RC32_CAL==48000000UL) + MSB(cal) = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSC)); + LSB(cal) = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSCA)); + /* + * If a device has an uncalibrated value in the + * production signature row (early sample part), load a + * sane default calibration value. + */ + if (cal == 0xFFFF) { + cal = 0x2340; + } + osc_user_calibration(OSC_ID_RC32MHZ,cal); +#endif + /* + * Switch to the selected initial system clock source, unless + * the default internal 2 MHz oscillator is selected. + */ + if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RC2MHZ) { + need_rc2mhz = true; + } else { + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RC32MHZ: + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + != OSC_ID_USBSOF) { + osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + } + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + break; + + case SYSCLK_SRC_RC32KHZ: + osc_enable(OSC_ID_RC32KHZ); + osc_wait_ready(OSC_ID_RC32KHZ); + break; + + case SYSCLK_SRC_XOSC: + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + break; + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL: + if (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) { + need_rc2mhz = true; + } + pll_enable_config_defaults(0); + break; +#endif +#if XMEGA_E + case SYSCLK_SRC_RC8MHZ: + osc_enable(OSC_ID_RC8MHZ); + osc_wait_ready(OSC_ID_RC8MHZ); + break; +#endif + default: + //unhandled_case(CONFIG_SYSCLK_SOURCE); + return; + } + + ccp_write_io((uint8_t *)&CLK.CTRL, CONFIG_SYSCLK_SOURCE); + Assert(CLK.CTRL == CONFIG_SYSCLK_SOURCE); + } + + if (need_rc2mhz) { +#ifdef CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC + osc_enable(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); + osc_enable_autocalibration(OSC_ID_RC2MHZ, + CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); +#endif + } else { + osc_disable(OSC_ID_RC2MHZ); + } + +#ifdef CONFIG_RTC_SOURCE + sysclk_rtcsrc_enable(CONFIG_RTC_SOURCE); +#endif +} + +void sysclk_enable_module(enum sysclk_port_id port, uint8_t id) +{ + irqflags_t flags = cpu_irq_save(); + + *((uint8_t *)&PR.PRGEN + port) &= ~id; + + cpu_irq_restore(flags); +} + +void sysclk_disable_module(enum sysclk_port_id port, uint8_t id) +{ + irqflags_t flags = cpu_irq_save(); + + *((uint8_t *)&PR.PRGEN + port) |= id; + + cpu_irq_restore(flags); +} + +#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__) + +/** + * \brief Enable clock for the USB module + * + * \pre CONFIG_USBCLK_SOURCE must be defined. + * + * \param frequency The required USB clock frequency in MHz: + * \arg \c 6 for 6 MHz + * \arg \c 48 for 48 MHz + */ +void sysclk_enable_usb(uint8_t frequency) +{ + uint8_t prescaler; + + Assert((frequency == 6) || (frequency == 48)); + + /* + * Enable or disable prescaler depending on if the USB frequency is 6 + * MHz or 48 MHz. Only 6 MHz USB frequency requires prescaling. + */ + if (frequency == 6) { + prescaler = CLK_USBPSDIV_8_gc; + } + else { + prescaler = 0; + } + + /* + * Switch to the system clock selected by the user. + */ + switch (CONFIG_USBCLK_SOURCE) { + case USBCLK_SRC_RCOSC: + if (!osc_is_ready(OSC_ID_RC32MHZ)) { + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + != OSC_ID_USBSOF) { + osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + } + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + } + ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) + | CLK_USBSRC_RC32M_gc + | CLK_USBSEN_bm); + break; + +#ifdef CONFIG_PLL0_SOURCE + case USBCLK_SRC_PLL: + pll_enable_config_defaults(0); + ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) + | CLK_USBSRC_PLL_gc + | CLK_USBSEN_bm); + break; +#endif + + default: + Assert(false); + break; + } + + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_USB); +} + +/** + * \brief Disable clock for the USB module + */ +void sysclk_disable_usb(void) +{ + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_USB); + ccp_write_io((uint8_t *)&CLK.USBCTRL, 0); +} +#endif // XMEGA_AU || XMEGA_B || XMEGA_C diff --git a/Fred_bootloader/src/ASF/common/services/clock/xmega/sysclk.h b/Fred_bootloader/src/ASF/common/services/clock/xmega/sysclk.h new file mode 100644 index 0000000000000000000000000000000000000000..ab7cebda35651a5d550ca9d5efa322d0771faf80 --- /dev/null +++ b/Fred_bootloader/src/ASF/common/services/clock/xmega/sysclk.h @@ -0,0 +1,1531 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (c) 2010-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_SYSCLK_H_INCLUDED +#define XMEGA_SYSCLK_H_INCLUDED + +#include <board.h> +#include <compiler.h> +#include <parts.h> +#include <ccp.h> +#include <osc.h> +#include <pll.h> + +// Include clock configuration for the project. +#include <conf_clock.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \page sysclk_quickstart Quick Start Guide for the System Clock Management service (XMEGA) + * + * This is the quick start guide for the \ref sysclk_group "System Clock Management" + * service, with step-by-step instructions on how to configure and use the service for + * specific use cases. + * + * \section sysclk_quickstart_usecases System Clock Management use cases + * - \ref sysclk_quickstart_basic + * - \ref sysclk_quickstart_use_case_2 + * - \ref sysclk_quickstart_use_case_3 + * + * \section sysclk_quickstart_basic Basic usage of the System Clock Management service + * This section will present a basic use case for the System Clock Management service. + * This use case will configure the main system clock to 32MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. The + * secondary peripheral bus clock and CPU clock are scaled down from the speed of the + * main system clock. + * + * \subsection sysclk_quickstart_use_case_1_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_1_setup_steps Initialization code + * Add to the application initialization code: + * \code + sysclk_init(); +\endcode + * + * \subsection sysclk_quickstart_use_case_1_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL + + // Fpll0 = (Fclk * PLL_mul) / PLL_div + #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC + #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + #define CONFIG_PLL0_DIV 1 + + // Fbus = Fsys / (2 ^ BUS_div) + #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 +\endcode + * + * \subsection sysclk_quickstart_use_case_1_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode + * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode + * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: + * \code + #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + #define CONFIG_PLL0_DIV 1 +\endcode + * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration + * file as the frequency of the crystal attached to XOSC. + * -# Configure the main CPU clock and slow peripheral bus to run at 16MHz, run the fast peripheral bus + * at the full 32MHz speed: + * \code + #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 +\endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + */ + +/** + * \page sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management (XMEGA) + * + * \section sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management + * This section will present a more advanced use case for the System Clock Management service. + * This use case will configure the main system clock to 32MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. The peripheral bus + * clocks will run at the same speed as the CPU clock, and the USB clock will be configured to use + * the internal 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB Start-of-Frame as the + * calibration reference. + * + * \subsection sysclk_quickstart_use_case_2_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_2_setup_steps Initialization code + * Add to the application initialization code: + * \code + sysclk_init(); +\endcode + * + * \subsection sysclk_quickstart_use_case_2_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_2_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL + + // Fpll0 = (Fclk * PLL_mul) / PLL_div + #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC + #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + #define CONFIG_PLL0_DIV 1 + + // Fbus = Fsys / (2 ^ BUS_div) + #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 + + #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + #define CONFIG_OSC_RC32_CAL 48000000UL + #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ + #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF +\endcode + * + * \subsection sysclk_quickstart_use_case_2_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode + * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode + * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: + * \code + #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + #define CONFIG_PLL0_DIV 1 +\endcode + * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration + * file as the frequency of the crystal attached to XOSC. + * -# Configure the main CPU and peripheral bus clocks to run at 32MHz: + * \code + #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 +\endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: + * \code + #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC +\endcode + * \note When the internal RC oscillator is used for the USB module, it must be recalibrated to 48MHz for + * the USB peripheral to function. If this oscillator is then used as the main system clock source, + * the clock must be divided down via the peripheral and CPU bus clock division constants to ensure + * that the maximum allowable CPU frequency is not exceeded. + * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz using the USB Start of Frame (SOF) + * as the calibration reference: + * \code + #define CONFIG_OSC_RC32_CAL 48000000UL + #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ + #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF +\endcode + */ + +/** + * \page sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration (XMEGA) + * + * \section sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration + * This section will present a more advanced use case for the System Clock + * Management service. This use case will configure the main system clock to + * 2MHz, using the internal 2MHz RC oscillator calibrated against the internal + * 32KHz oscillator. The peripheral bus clocks will run at the same speed as + * the CPU clock, and the USB clock will be configured to use the internal + * 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB + * Start-of-Frame as the calibration reference. + * + * \subsection sysclk_quickstart_use_case_3_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_3_setup_steps Initialization code + * Add to the application initialization code: + * \code + sysclk_init(); +\endcode + * + * \subsection sysclk_quickstart_use_case_3_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_3_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, + * commenting out all other definitions of the same symbol(s): + * \code + #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ + + #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ + + #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + #define CONFIG_OSC_RC32_CAL 48000000UL + #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF +\endcode + * + * \subsection sysclk_quickstart_use_case_3_example_workflow Workflow + * -# Configure the main system clock to use the internal 2MHz RC oscillator + * as its source: + * \code + #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ +\endcode + * -# Configure the 2MHz DFLL auto-calibration to use the internal 32KHz RC + * oscillator: + * \code + #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ +\endcode + * \note For auto-calibration it's typically more relevant to use an external + * 32KHz crystal. So if that's the case use OSC_ID_XOSC instead. + * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: + * \code + #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC +\endcode + * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz + * using the USB Start of Frame (SOF) as the calibration reference: + * \code + #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + #define CONFIG_OSC_RC32_CAL 48000000UL + #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF +\endcode + */ + +/* Wrap old config into new one */ +#ifdef CONFIG_OSC_AUTOCAL +# if CONFIG_OSC_AUTOCAL == OSC_ID_RC2MHZ +# define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC +# elif CONFIG_OSC_AUTOCAL == OSC_ID_RC32MHZ +# define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC +# else +# error Bad configuration of CONFIG_OSC_AUTOCAL and/or CONFIG_OSC_AUTOCAL_REF_OSC +# endif +#endif + +// Use 2 MHz with no prescaling if config was empty. +#ifndef CONFIG_SYSCLK_SOURCE +# define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ +#endif /* CONFIG_SYSCLK_SOURCE */ + +#ifndef CONFIG_SYSCLK_PSADIV +# define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 +#endif /* CONFIG_SYSCLK_PSADIV */ + +#ifndef CONFIG_SYSCLK_PSBCDIV +# define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 +#endif /* CONFIG_SYSCLK_PSBCDIV */ + +/** + * \weakgroup sysclk_group + * + * \section sysclk_group_config Configuration Symbols + * + * The following configuration symbols may be used to specify the + * initial system clock configuration. If any of the symbols are not + * set, reasonable defaults will be provided. + * - \b CONFIG_SYSCLK_SOURCE: The initial system clock source. + * - \b CONFIG_SYSCLK_PSADIV: The initial Prescaler A setting. + * - \b CONFIG_SYSCLK_PSBCDIV: The initial Prescaler B setting. + * - \b CONFIG_USBCLK_SOURCE: The initial USB clock source. + * + * @{ + */ + +//! \name System Clock Sources +//@{ +//! Internal 2 MHz RC oscillator +#define SYSCLK_SRC_RC2MHZ CLK_SCLKSEL_RC2M_gc +//! Internal 32 MHz RC oscillator +#define SYSCLK_SRC_RC32MHZ CLK_SCLKSEL_RC32M_gc +//! Internal 32 KHz RC oscillator +#define SYSCLK_SRC_RC32KHZ CLK_SCLKSEL_RC32K_gc +//! External oscillator +#define SYSCLK_SRC_XOSC CLK_SCLKSEL_XOSC_gc +//! Phase-Locked Loop +#define SYSCLK_SRC_PLL CLK_SCLKSEL_PLL_gc +#if XMEGA_E +//! Internal 8 MHz RC oscillator +# define SYSCLK_SRC_RC8MHZ CLK_SCLKSEL_RC8M_gc +#endif +//@} + +//! \name Prescaler A Setting (relative to CLKsys) +//@{ +#define SYSCLK_PSADIV_1 CLK_PSADIV_1_gc //!< Do not prescale +#define SYSCLK_PSADIV_2 CLK_PSADIV_2_gc //!< Prescale CLKper4 by 2 +#define SYSCLK_PSADIV_4 CLK_PSADIV_4_gc //!< Prescale CLKper4 by 4 +#define SYSCLK_PSADIV_8 CLK_PSADIV_8_gc //!< Prescale CLKper4 by 8 +#define SYSCLK_PSADIV_16 CLK_PSADIV_16_gc //!< Prescale CLKper4 by 16 +#define SYSCLK_PSADIV_32 CLK_PSADIV_32_gc //!< Prescale CLKper4 by 32 +#define SYSCLK_PSADIV_64 CLK_PSADIV_64_gc //!< Prescale CLKper4 by 64 +#define SYSCLK_PSADIV_128 CLK_PSADIV_128_gc //!< Prescale CLKper4 by 128 +#define SYSCLK_PSADIV_256 CLK_PSADIV_256_gc //!< Prescale CLKper4 by 256 +#define SYSCLK_PSADIV_512 CLK_PSADIV_512_gc //!< Prescale CLKper4 by 512 + +#if XMEGA_E +# define SYSCLK_PSADIV_6 CLK_PSADIV_6_gc //!< Prescale CLKper4 by 6 +# define SYSCLK_PSADIV_10 CLK_PSADIV_10_gc //!< Prescale CLKper4 by 10 +# define SYSCLK_PSADIV_12 CLK_PSADIV_12_gc //!< Prescale CLKper4 by 12 +# define SYSCLK_PSADIV_24 CLK_PSADIV_24_gc //!< Prescale CLKper4 by 24 +# define SYSCLK_PSADIV_48 CLK_PSADIV_48_gc //!< Prescale CLKper4 by 48 +#endif +//@} + +//! \name Prescaler B and C Setting (relative to CLKper4) +//@{ +//! Do not prescale +#define SYSCLK_PSBCDIV_1_1 CLK_PSBCDIV_1_1_gc +//! Prescale CLKper and CLKcpu by 2 +#define SYSCLK_PSBCDIV_1_2 CLK_PSBCDIV_1_2_gc +//! Prescale CLKper2, CLKper and CLKcpu by 4 +#define SYSCLK_PSBCDIV_4_1 CLK_PSBCDIV_4_1_gc +//! Prescale CLKper2 by 2, CLKper and CLKcpu by 4 +#define SYSCLK_PSBCDIV_2_2 CLK_PSBCDIV_2_2_gc +//@} + +//! \name System Clock Port Numbers +enum sysclk_port_id { + SYSCLK_PORT_GEN, //!< Devices not associated with a specific port. + SYSCLK_PORT_A, //!< Devices on PORTA + SYSCLK_PORT_B, //!< Devices on PORTB + SYSCLK_PORT_C, //!< Devices on PORTC + SYSCLK_PORT_D, //!< Devices on PORTD + SYSCLK_PORT_E, //!< Devices on PORTE + SYSCLK_PORT_F, //!< Devices on PORTF +}; + +/*! \name Clocks not associated with any port + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_DMA PR_DMA_bm //!< DMA Controller +#define SYSCLK_EDMA PR_EDMA_bm //!< EDMA Controller +#define SYSCLK_EVSYS PR_EVSYS_bm //!< Event System +#define SYSCLK_RTC PR_RTC_bm //!< Real-Time Counter +#define SYSCLK_EBI PR_EBI_bm //!< Ext Bus Interface +#define SYSCLK_AES PR_AES_bm //!< AES Module +#define SYSCLK_USB PR_USB_bm //!< USB Module +#define SYSCLK_XCL PR_XCL_bm //!< USB Module +//@} + +/*! \name Clocks on PORTA and PORTB + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_AC PR_AC_bm //!< Analog Comparator +#define SYSCLK_ADC PR_ADC_bm //!< A/D Converter +#define SYSCLK_DAC PR_DAC_bm //!< D/A Converter +//@} + +/*! \name Clocks on PORTC, PORTD, PORTE and PORTF + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_TC0 PR_TC0_bm //!< Timer/Counter 0 +#define SYSCLK_TC1 PR_TC1_bm //!< Timer/Counter 1 +#define SYSCLK_TC4 PR_TC4_bm //!< Timer/Counter 0 +#define SYSCLK_TC5 PR_TC5_bm //!< Timer/Counter 1 +#define SYSCLK_HIRES PR_HIRES_bm //!< Hi-Res Extension +#define SYSCLK_SPI PR_SPI_bm //!< SPI controller +#define SYSCLK_USART0 PR_USART0_bm //!< USART 0 +#define SYSCLK_USART1 PR_USART1_bm //!< USART 1 +#define SYSCLK_TWI PR_TWI_bm //!< TWI controller +//@} + +/** + * \name RTC clock source identifiers + * + * @{ + */ + +/** 1kHz from internal ULP oscillator. Low precision */ +#define SYSCLK_RTCSRC_ULP CLK_RTCSRC_ULP_gc +/** 1.024kHz from 32.768kHz crystal oscillator TOSC */ +#define SYSCLK_RTCSRC_TOSC CLK_RTCSRC_TOSC_gc +/** 1.024kHz from 32.768kHz internal RC oscillator */ +#define SYSCLK_RTCSRC_RCOSC CLK_RTCSRC_RCOSC_gc +/** 32.768kHz from crystal oscillator TOSC */ +#define SYSCLK_RTCSRC_TOSC32 CLK_RTCSRC_TOSC32_gc +/** 32.768kHz from internal RC oscillator */ +#define SYSCLK_RTCSRC_RCOSC32 CLK_RTCSRC_RCOSC32_gc +/** External clock on TOSC1 */ +#define SYSCLK_RTCSRC_EXTCLK CLK_RTCSRC_EXTCLK_gc + +/** @} */ + +#if XMEGA_AU || XMEGA_B || XMEGA_C +//! \name USB Clock Sources +//@{ +//! Internal 32 MHz RC oscillator +#define USBCLK_SRC_RCOSC 0 +//! Phase-Locked Loop +#define USBCLK_SRC_PLL 1 +//@} + +/** + * \def CONFIG_USBCLK_SOURCE + * \brief Configuration symbol for the USB clock source + * + * If the device features an USB module, and this is intended to be used, this + * symbol must be defined with the clock source configuration. + * + * Define this as one of the \c USBCLK_SRC_xxx definitions. If the PLL is + * selected, it must be configured to run at 48 MHz. If the 32 MHz RC oscillator + * is selected, it must be tuned to 48 MHz by means of the DFLL. + */ +#ifdef __DOXYGEN__ +# define CONFIG_USBCLK_SOURCE +#endif + +#endif // XMEGA_AU || XMEGA_B || XMEGA_C + +#ifndef __ASSEMBLY__ + +/** + * \name Querying the system clock and its derived clocks + */ +//@{ + +/** + * \brief Return the current rate in Hz of the main system clock + * + * \todo This function assumes that the main clock source never changes + * once it's been set up, and that PLL0 always runs at the compile-time + * configured default rate. While this is probably the most common + * configuration, which we want to support as a special case for + * performance reasons, we will at some point need to support more + * dynamic setups as well. + * + * \return Frequency of the main system clock, in Hz. + */ +static inline uint32_t sysclk_get_main_hz(void) +{ + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RC2MHZ: + return 2000000UL; +#if XMEGA_E + case SYSCLK_SRC_RC8MHZ: + return 8000000UL; +#endif + case SYSCLK_SRC_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL + return CONFIG_OSC_RC32_CAL; +#else + return 32000000UL; +#endif + + case SYSCLK_SRC_RC32KHZ: + return 32768UL; + +#ifdef BOARD_XOSC_HZ + case SYSCLK_SRC_XOSC: + return BOARD_XOSC_HZ; +#endif + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL: + return pll_get_default_rate(0); +#endif + + default: + //unhandled_case(CONFIG_SYSCLK_SOURCE); + return 0; + } +} + +/** + * \brief Return the current rate in Hz of clk_PER4. + * + * This clock can run up to four times faster than the CPU clock. + * + * \return Frequency of the clk_PER4 clock, in Hz. + */ +static inline uint32_t sysclk_get_per4_hz(void) +{ + uint8_t shift = 0; + +#if XMEGA_E + if (CONFIG_SYSCLK_PSADIV > SYSCLK_PSADIV_512) { + switch (CONFIG_SYSCLK_PSADIV) { + case SYSCLK_PSADIV_6: + return sysclk_get_main_hz() / 6; + case SYSCLK_PSADIV_10: + return sysclk_get_main_hz() / 10; + case SYSCLK_PSADIV_12: + return sysclk_get_main_hz() / 12; + case SYSCLK_PSADIV_24: + return sysclk_get_main_hz() / 24; + case SYSCLK_PSADIV_48: + return sysclk_get_main_hz() / 48; + default: + //unhandled_case; + return 0; + } + } +#endif + if (CONFIG_SYSCLK_PSADIV & (1U << CLK_PSADIV_gp)) { + shift = (CONFIG_SYSCLK_PSADIV >> (1 + CLK_PSADIV_gp)) + 1; + } + + return sysclk_get_main_hz() >> shift; +} + +/** + * \brief Return the current rate in Hz of clk_PER2. + * + * This clock can run up to two times faster than the CPU clock. + * + * \return Frequency of the clk_PER2 clock, in Hz. + */ +static inline uint32_t sysclk_get_per2_hz(void) +{ + switch (CONFIG_SYSCLK_PSBCDIV) { + case SYSCLK_PSBCDIV_1_1: /* Fall through */ + case SYSCLK_PSBCDIV_1_2: + return sysclk_get_per4_hz(); + + case SYSCLK_PSBCDIV_4_1: + return sysclk_get_per4_hz() / 4; + + case SYSCLK_PSBCDIV_2_2: + return sysclk_get_per4_hz() / 2; + + default: + //unhandled_case(CONFIG_SYSCLK_PSBCDIV); + return 0; + } +} + +/** + * \brief Return the current rate in Hz of clk_PER. + * + * This clock always runs at the same rate as the CPU clock unless the divider + * is set. + * + * \return Frequency of the clk_PER clock, in Hz. + */ +static inline uint32_t sysclk_get_per_hz(void) +{ + if (CONFIG_SYSCLK_PSBCDIV & (1U << CLK_PSBCDIV_gp)) + return sysclk_get_per2_hz() / 2; + else + return sysclk_get_per2_hz(); +} + +/** + * \brief Return the current rate in Hz of the CPU clock. + * + * \return Frequency of the CPU clock, in Hz. + */ +static inline uint32_t sysclk_get_cpu_hz(void) +{ + return sysclk_get_per_hz(); +} + +/** + * \brief Retrieves the current rate in Hz of the Peripheral Bus clock attached + * to the specified peripheral. + * + * \param module Pointer to the module's base address. + * + * \return Frequency of the bus attached to the specified peripheral, in Hz. + */ +static inline uint32_t sysclk_get_peripheral_bus_hz(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + return 0; + } +#ifdef AES + else if (module == &AES) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EBI + else if (module == &EBI) { + return sysclk_get_per2_hz(); + } +#endif +#ifdef RTC + else if (module == &RTC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + return sysclk_get_per_hz(); + } +#endif +#ifdef DMA + else if (module == &DMA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EDMA + else if (module == &EDMA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ACA + else if (module == &ACA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ACB + else if (module == &ACB) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + return sysclk_get_per_hz(); + } +#endif +#ifdef DACA + else if (module == &DACA) { + return sysclk_get_per_hz(); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + return sysclk_get_per_hz(); + } +#endif +#endif // Workaround end +#ifdef FAULTC0 + else if (module == &FAULTC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef FAULTC1 + else if (module == &FAULTC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCC0 + else if (module == &TCC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCC4 + else if (module == &TCC4) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCC5 + else if (module == &TCC5) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD4 + else if (module == &TCD4) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD5 + else if (module == &TCD5) { + return sysclk_get_per_hz(); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPID + else if (module == &SPID) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWID + else if (module == &TWID) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + return sysclk_get_per_hz(); + } +#endif +#ifdef XCL + else if (module == &XCL) { + return sysclk_get_per_hz(); + } +#endif + else { + Assert(false); + return 0; + } +} + +//@} + +//! \name Enabling and disabling synchronous clocks +//@{ + +/** + * \brief Enable the clock to peripheral \a id on port \a port + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to be enabled. + */ +extern void sysclk_enable_module(enum sysclk_port_id port, uint8_t id); + +/** + * \brief Disable the clock to peripheral \a id on port \a port + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to be disabled. + */ +extern void sysclk_disable_module(enum sysclk_port_id port, uint8_t id); + +/** + * \brief Enable a peripheral's clock from its base address. + * + * Enables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be enabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_enable_peripheral_clock(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + } +#ifdef AES + else if (module == &AES) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_AES); + } +#endif +#ifdef EBI + else if (module == &EBI) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); + } +#endif +#ifdef RTC + else if (module == &RTC) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); + } +#endif +#ifdef DMA + else if (module == &DMA) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); + } +#endif +#ifdef EDMA + else if (module == &EDMA) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EDMA); + } +#endif +#ifdef ACA + else if (module == &ACA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_AC); + } +#endif +#ifdef ACB + else if (module == &ACB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_AC); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_ADC); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_ADC); + } +#endif +#ifdef DACA + else if (module == &DACA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_DAC); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_DAC); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC0); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC0); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC0); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC0); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC1); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC1); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC1); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC1); + } +#endif +#ifdef TCC4 + else if (module == &TCC4) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC4); + } +#endif +#ifdef TCC5 + else if (module == &TCC5) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC5); + } +#endif +#ifdef TCD4 + else if (module == &TCD4) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC4); + } +#endif +#ifdef TCD5 + else if (module == &TCD5) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC5); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_SPI); + } +#endif +#ifdef SPID + else if (module == &SPID) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_SPI); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_SPI); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_SPI); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART0); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART0); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART0); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART0); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART1); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART1); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART1); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART1); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TWI); + } +#endif +#ifdef TWID + else if (module == &TWID) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TWI); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TWI); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TWI); + } +#endif +#ifdef XCL + else if (module == &XCL) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_XCL); + } +#endif + else { + Assert(false); + } +} + +/** + * \brief Disable a peripheral's clock from its base address. + * + * Disables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be disabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_disable_peripheral_clock(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + } +#ifdef AES + else if (module == &AES) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_AES); + } +#endif +#ifdef EBI + else if (module == &EBI) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); + } +#endif +#ifdef RTC + else if (module == &RTC) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); + } +#endif +#ifdef DMA + else if (module == &DMA) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); + } +#endif +#ifdef EDMA + else if (module == &EDMA) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EDMA); + } +#endif +#ifdef ACA + else if (module == &ACA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_AC); + } +#endif +#ifdef ACB + else if (module == &ACB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_AC); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_ADC); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_ADC); + } +#endif +#ifdef DACA + else if (module == &DACA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_DAC); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_DAC); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC0); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC0); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC0); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC0); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC1); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC1); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC1); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC1); + } +#endif +#ifdef TCC4 + else if (module == &TCC4) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC4); + } +#endif +#ifdef TCC5 + else if (module == &TCC5) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC5); + } +#endif +#ifdef TCD4 + else if (module == &TCD4) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC4); + } +#endif +#ifdef TCD5 + else if (module == &TCD5) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC5); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_SPI); + } +#endif +#ifdef SPID + else if (module == &SPID) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_SPI); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_SPI); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_SPI); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART0); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART0); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART0); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART0); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART1); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART1); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART1); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART1); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TWI); + } +#endif +#ifdef TWID + else if (module == &TWID) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TWI); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TWI); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TWI); + } +#endif +#ifdef XCL + else if (module == &XCL) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_XCL); + } +#endif + else { + Assert(false); + } +} + +/** + * \brief Check if the synchronous clock is enabled for a module + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to check (one of + * the \c SYSCLK_* module definitions). + * + * \retval true If the clock for module \a id on \a port is enabled. + * \retval false If the clock for module \a id on \a port is disabled. + */ +static inline bool sysclk_module_is_enabled(enum sysclk_port_id port, + uint8_t id) +{ + uint8_t mask = *((uint8_t *)&PR.PRGEN + port); + return (mask & id) == 0; +} + +#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__) +# if defined(CONFIG_USBCLK_SOURCE) || defined(__DOXYGEN__) +# if (CONFIG_USBCLK_SOURCE == USBCLK_SRC_RCOSC) +# define USBCLK_STARTUP_TIMEOUT 1 +# elif (CONFIG_USBCLK_SOURCE == USBCLK_SRC_PLL) +# if (CONFIG_PLL0_SOURCE == PLL_SRC_XOSC) +# define USBCLK_STARTUP_TIMEOUT XOSC_STARTUP_TIMEOUT +# elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC32MHZ) +# define USBCLK_STARTUP_TIMEOUT 1 +# elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) +# define USBCLK_STARTUP_TIMEOUT 1 +# else +# error Unknow value for CONFIG_PLL0_SOURCE, see conf_clock.h. +# endif +# endif +# else /* CONFIG_USBCLK_SOURCE not defined */ +# define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC +# define USBCLK_STARTUP_TIMEOUT 1 +# endif /* CONFIG_USBCLK_SOURCE */ +void sysclk_enable_usb(uint8_t frequency); +void sysclk_disable_usb(void); +#endif /* XMEGA_AU || XMEGA_B || XMEGA_C */ +//@} + +//! \name System Clock Source and Prescaler configuration +//@{ + +/** + * \brief Set system clock prescaler configuration + * + * This function will change the system clock prescaler configuration to + * match the parameters. + * + * \note The parameters to this function are device-specific. + * + * \param psadiv The prescaler A setting (one of the \c SYSCLK_PSADIV_* + * definitions). This determines the clkPER4 frequency. + * \param psbcdiv The prescaler B and C settings (one of the \c SYSCLK_PSBCDIV_* + * definitions). These determine the clkPER2, clkPER and clkCPU frequencies. + */ +static inline void sysclk_set_prescalers(uint8_t psadiv, uint8_t psbcdiv) +{ + ccp_write_io((uint8_t *)&CLK.PSCTRL, psadiv | psbcdiv); +} + +/** + * \brief Change the source of the main system clock. + * + * \param src The new system clock source. Must be one of the constants + * from the <em>System Clock Sources</em> section. + */ +static inline void sysclk_set_source(uint8_t src) +{ + ccp_write_io((uint8_t *)&CLK.CTRL, src); +} + +/** + * \brief Lock the system clock configuration + * + * This function will lock the current system clock source and prescaler + * configuration, preventing any further changes. + */ +static inline void sysclk_lock(void) +{ + ccp_write_io((uint8_t *)&CLK.LOCK, CLK_LOCK_bm); +} + +//@} + +/** + * \name RTC clock source control + * @{ + */ + +/** + * \brief Enable RTC clock with specified clock source + * + * \param id RTC clock source ID. Select from SYSCLK_RTCSRC_ULP, + * SYSCLK_RTCSRC_RCOSC, SYSCLK_RTCSRC_TOSC, SYSCLK_RTCSRC_RCOSC32, + * SYSCLK_RTCSRC_TOSC32 or SYSCLK_RTCSRC_EXTCLK + */ +static inline void sysclk_rtcsrc_enable(uint8_t id) +{ + Assert((id & ~CLK_RTCSRC_gm) == 0); + + switch (id) { + case SYSCLK_RTCSRC_RCOSC: +#if !XMEGA_A && !XMEGA_D + case SYSCLK_RTCSRC_RCOSC32: +#endif + osc_enable(OSC_ID_RC32KHZ); + osc_wait_ready(OSC_ID_RC32KHZ); + break; + case SYSCLK_RTCSRC_TOSC: + case SYSCLK_RTCSRC_TOSC32: +#if !XMEGA_A && !XMEGA_D + case SYSCLK_RTCSRC_EXTCLK: +#endif + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + break; + } + + CLK.RTCCTRL = id | CLK_RTCEN_bm; +} + +/** + * \brief Disable RTC clock + */ +static inline void sysclk_rtcsrc_disable(void) +{ + CLK.RTCCTRL = 0; +} + +/** @} */ + +//! \name System Clock Initialization +//@{ + +extern void sysclk_init(void); + +//@} + +#endif /* !__ASSEMBLY__ */ + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* XMEGA_SYSCLK_H_INCLUDED */ diff --git a/Fred_bootloader/src/ASF/common/services/ioport/ioport.h b/Fred_bootloader/src/ASF/common/services/ioport/ioport.h new file mode 100644 index 0000000000000000000000000000000000000000..7a7a32def9032b0df9257ba86a85d2a4b3efa143 --- /dev/null +++ b/Fred_bootloader/src/ASF/common/services/ioport/ioport.h @@ -0,0 +1,538 @@ +/** + * \file + * + * \brief Common IOPORT service main header file for AVR, UC3 and ARM + * architectures. + * + * Copyright (c) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_H +#define IOPORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <parts.h> +#include <compiler.h> + +/** + * \defgroup ioport_group Common IOPORT API + * + * See \ref ioport_quickstart. + * + * This is common IOPORT service for GPIO pin configuration and control in a + * standardized manner across the MEGA, MEGA_RF, XMEGA, UC3 and ARM devices. + * + * Port pin control code is optimized for each platform, and should produce + * both compact and fast execution times when used with constant values. + * + * \section dependencies Dependencies + * This driver depends on the following modules: + * - \ref sysclk_group for clock speed and functions. + * @{ + */ + +/** + * \def IOPORT_CREATE_PIN(port, pin) + * \brief Create IOPORT pin number + * + * Create a IOPORT pin number for use with the IOPORT functions. + * + * \param port IOPORT port (e.g. PORTA, PA or PIOA depending on chosen + * architecture) + * \param pin IOPORT zero-based index of the I/O pin + */ + +/** \brief IOPORT pin directions */ +enum ioport_direction { + IOPORT_DIR_INPUT, /*!< IOPORT input direction */ + IOPORT_DIR_OUTPUT, /*!< IOPORT output direction */ +}; + +/** \brief IOPORT levels */ +enum ioport_value { + IOPORT_PIN_LEVEL_LOW, /*!< IOPORT pin value low */ + IOPORT_PIN_LEVEL_HIGH, /*!< IOPORT pin value high */ +}; + +#if MEGA_RF +/** \brief IOPORT edge sense modes */ +enum ioport_sense { + IOPORT_SENSE_LEVEL, /*!< IOPORT sense low level */ + IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */ + IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */ + IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */ +}; +#elif SAM && !SAM4L +/** \brief IOPORT edge sense modes */ +enum ioport_sense { + IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */ + IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */ + IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */ + IOPORT_SENSE_LEVEL_LOW, /*!< IOPORT sense low level */ + IOPORT_SENSE_LEVEL_HIGH,/*!< IOPORT sense High level */ +}; +#else +enum ioport_sense { + IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */ + IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */ + IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */ +}; +#endif + + +#if XMEGA +# include "xmega/ioport.h" +# if defined(IOPORT_XMEGA_COMPAT) +# include "xmega/ioport_compat.h" +# endif +#elif MEGA +# include "mega/ioport.h" +#elif UC3 +# include "uc3/ioport.h" +#elif SAM +# if SAM4L +# include "sam/ioport_gpio.h" +# elif (SAMD20 | SAMD21) +# include "sam0/ioport.h" +# else +# include "sam/ioport_pio.h" +# endif +#endif + +/** + * \brief Initializes the IOPORT service, ready for use. + * + * This function must be called before using any other functions in the IOPORT + * service. + */ +static inline void ioport_init(void) +{ + arch_ioport_init(); +} + +/** + * \brief Enable an IOPORT pin, based on a pin created with \ref + * IOPORT_CREATE_PIN(). + * + * \param pin IOPORT pin to enable + */ +static inline void ioport_enable_pin(ioport_pin_t pin) +{ + arch_ioport_enable_pin(pin); +} + +/** + * \brief Enable multiple pins in a single IOPORT port. + * + * \param port IOPORT port to enable + * \param mask Mask of pins within the port to enable + */ +static inline void ioport_enable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_enable_port(port, mask); +} + +/** + * \brief Disable IOPORT pin, based on a pin created with \ref + * IOPORT_CREATE_PIN(). + * + * \param pin IOPORT pin to disable + */ +static inline void ioport_disable_pin(ioport_pin_t pin) +{ + arch_ioport_disable_pin(pin); +} + +/** + * \brief Disable multiple pins in a single IOPORT port. + * + * \param port IOPORT port to disable + * \param mask Pin mask of pins to disable + */ +static inline void ioport_disable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_disable_port(port, mask); +} + +/** + * \brief Set multiple pin modes in a single IOPORT port, such as pull-up, + * pull-down, etc. configuration. + * + * \param port IOPORT port to configure + * \param mask Pin mask of pins to configure + * \param mode Mode masks to configure for the specified pins (\ref + * ioport_modes) + */ +static inline void ioport_set_port_mode(ioport_port_t port, + ioport_port_mask_t mask, ioport_mode_t mode) +{ + arch_ioport_set_port_mode(port, mask, mode); +} + +/** + * \brief Set pin mode for one single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param mode Mode masks to configure for the specified pin (\ref ioport_modes) + */ +static inline void ioport_set_pin_mode(ioport_pin_t pin, ioport_mode_t mode) +{ + arch_ioport_set_pin_mode(pin, mode); +} + +/** + * \brief Reset multiple pin modes in a specified IOPORT port to defaults. + * + * \param port IOPORT port to configure + * \param mask Mask of pins whose mode configuration is to be reset + */ +static inline void ioport_reset_port_mode(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_set_port_mode(port, mask, 0); +} + +/** + * \brief Reset pin mode configuration for a single IOPORT pin + * + * \param pin IOPORT pin to configure + */ +static inline void ioport_reset_pin_mode(ioport_pin_t pin) +{ + arch_ioport_set_pin_mode(pin, 0); +} + +/** + * \brief Set I/O direction for a group of pins in a single IOPORT. + * + * \param port IOPORT port to configure + * \param mask Pin mask of pins to configure + * \param dir Direction to set for the specified pins (\ref ioport_direction) + */ +static inline void ioport_set_port_dir(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_direction dir) +{ + arch_ioport_set_port_dir(port, mask, dir); +} + +/** + * \brief Set direction for a single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param dir Direction to set for the specified pin (\ref ioport_direction) + */ +static inline void ioport_set_pin_dir(ioport_pin_t pin, + enum ioport_direction dir) +{ + arch_ioport_set_pin_dir(pin, dir); +} + +/** + * \brief Set an IOPORT pin to a specified logical value. + * + * \param pin IOPORT pin to configure + * \param level Logical value of the pin + */ +static inline void ioport_set_pin_level(ioport_pin_t pin, bool level) +{ + arch_ioport_set_pin_level(pin, level); +} + +/** + * \brief Set a group of IOPORT pins in a single port to a specified logical + * value. + * + * \param port IOPORT port to write to + * \param mask Pin mask of pins to modify + * \param level Level of the pins to be modified + */ +static inline void ioport_set_port_level(ioport_port_t port, + ioport_port_mask_t mask, ioport_port_mask_t level) +{ + arch_ioport_set_port_level(port, mask, level); +} + +/** + * \brief Get current value of an IOPORT pin, which has been configured as an + * input. + * + * \param pin IOPORT pin to read + * \return Current logical value of the specified pin + */ +static inline bool ioport_get_pin_level(ioport_pin_t pin) +{ + return arch_ioport_get_pin_level(pin); +} + +/** + * \brief Get current value of several IOPORT pins in a single port, which have + * been configured as an inputs. + * + * \param port IOPORT port to read + * \param mask Pin mask of pins to read + * \return Logical levels of the specified pins from the read port, returned as + * a mask. + */ +static inline ioport_port_mask_t ioport_get_port_level(ioport_pin_t port, + ioport_port_mask_t mask) +{ + return arch_ioport_get_port_level(port, mask); +} + +/** + * \brief Toggle the value of an IOPORT pin, which has previously configured as + * an output. + * + * \param pin IOPORT pin to toggle + */ +static inline void ioport_toggle_pin_level(ioport_pin_t pin) +{ + arch_ioport_toggle_pin_level(pin); +} + +/** + * \brief Toggle the values of several IOPORT pins located in a single port. + * + * \param port IOPORT port to modify + * \param mask Pin mask of pins to toggle + */ +static inline void ioport_toggle_port_level(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_toggle_port_level(port, mask); +} + +/** + * \brief Set the pin sense mode of a single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param pin_sense Edge to sense for the pin (\ref ioport_sense) + */ +static inline void ioport_set_pin_sense_mode(ioport_pin_t pin, + enum ioport_sense pin_sense) +{ + arch_ioport_set_pin_sense_mode(pin, pin_sense); +} + +/** + * \brief Set the pin sense mode of a multiple IOPORT pins on a single port. + * + * \param port IOPORT port to configure + * \param mask Bitmask if pins whose edge sense is to be configured + * \param pin_sense Edge to sense for the pins (\ref ioport_sense) + */ +static inline void ioport_set_port_sense_mode(ioport_port_t port, + ioport_port_mask_t mask, + enum ioport_sense pin_sense) +{ + arch_ioport_set_port_sense_mode(port, mask, pin_sense); +} + +/** + * \brief Convert a pin ID into a its port ID. + * + * \param pin IOPORT pin ID to convert + * \retval Port ID for the given pin ID + */ +static inline ioport_port_t ioport_pin_to_port_id(ioport_pin_t pin) +{ + return arch_ioport_pin_to_port_id(pin); +} + +/** + * \brief Convert a pin ID into a bitmask mask for the given pin on its port. + * + * \param pin IOPORT pin ID to convert + * \retval Bitmask with a bit set that corresponds to the given pin ID in its port + */ +static inline ioport_port_mask_t ioport_pin_to_mask(ioport_pin_t pin) +{ + return arch_ioport_pin_to_mask(pin); +} + +/** @} */ + +/** + * \page ioport_quickstart Quick start guide for the common IOPORT service + * + * This is the quick start guide for the \ref ioport_group, with + * step-by-step instructions on how to configure and use the service in a + * selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section ioport_quickstart_basic Basic use case + * In this use case we will configure one IO pin for button input and one for + * LED control. Then it will read the button state and output it on the LED. + * + * \section ioport_quickstart_basic_setup Setup steps + * + * \subsection ioport_quickstart_basic_setup_code Example code + * \code + #define MY_LED IOPORT_CREATE_PIN(PORTA, 5) + #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6) + + ioport_init(); + + ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); + ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); + ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); +\endcode + * + * \subsection ioport_quickstart_basic_setup_flow Workflow + * -# It's useful to give the GPIOs symbolic names and this can be done with + * the \ref IOPORT_CREATE_PIN macro. We define one for a LED and one for a + * button. + * - \code + #define MY_LED IOPORT_CREATE_PIN(PORTA, 5) + #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6) +\endcode + * - \note The usefulness of the \ref IOPORT_CREATE_PIN macro and port names + * differ between architectures: + * - MEGA, MEGA_RF and XMEGA: Use \ref IOPORT_CREATE_PIN macro with port definitions + * PORTA, PORTB ... + * - UC3: Most convenient to pick up the device header file pin definition + * and us it directly. E.g.: AVR32_PIN_PB06 + * - SAM: Most convenient to pick up the device header file pin definition + * and us it directly. E.g.: PIO_PA5_IDX<br> + * \ref IOPORT_CREATE_PIN can also be used with port definitions + * PIOA, PIOB ... + * -# Initialize the ioport service. This typically enables the IO module if + * needed. + * - \code ioport_init(); \endcode + * -# Set the LED GPIO as output: + * - \code ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); \endcode + * -# Set the button GPIO as input: + * - \code ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); \endcode + * -# Enable pull-up for the button GPIO: + * - \code ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); \endcode + * + * \section ioport_quickstart_basic_usage Usage steps + * + * \subsection ioport_quickstart_basic_usage_code Example code + * \code + bool value; + + value = ioport_get_pin_level(MY_BUTTON); + ioport_set_pin_level(MY_LED, value); +\endcode + * + * \subsection ioport_quickstart_basic_usage_flow Workflow + * -# Define a boolean variable for state storage: + * - \code bool value; \endcode + * -# Read out the button level into variable value: + * - \code value = ioport_get_pin_level(MY_BUTTON); \endcode + * -# Set the LED to read out value from the button: + * - \code ioport_set_pin_level(MY_LED, value); \endcode + * + * \section ioport_quickstart_advanced Advanced use cases + * - \subpage ioport_quickstart_use_case_1 : Port access + */ + +/** + * \page ioport_quickstart_use_case_1 Advanced use case doing port access + * + * In this case we will read out the pins from one whole port and write the + * read value to another port. + * + * \section ioport_quickstart_use_case_1_setup Setup steps + * + * \subsection ioport_quickstart_use_case_1_setup_code Example code + * \code + #define IN_PORT IOPORT_PORTA + #define OUT_PORT IOPORT_PORTB + #define MASK 0x00000060 + + ioport_init(); + + ioport_set_port_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); + ioport_set_port_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); +\endcode + * + * \subsection ioport_quickstart_basic_setup_flow Workflow + * -# It's useful to give the ports symbolic names: + * - \code + #define IN_PORT IOPORT_PORTA + #define OUT_PORT IOPORT_PORTB +\endcode + * - \note The port names differ between architectures: + * - MEGA_RF, MEGA and XMEGA: There are predefined names for ports: IOPORT_PORTA, + * IOPORT_PORTB ... + * - UC3: Use the index value of the different IO blocks: 0, 1 ... + * - SAM: There are predefined names for ports: IOPORT_PIOA, IOPORT_PIOB + * ... + * -# Also useful to define a mask for the bits to work with: + * - \code #define MASK 0x00000060 \endcode + * -# Initialize the ioport service. This typically enables the IO module if + * needed. + * - \code ioport_init(); \endcode + * -# Set one of the ports as input: + * - \code ioport_set_pin_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); \endcode + * -# Set the other port as output: + * - \code ioport_set_pin_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); \endcode + * + * \section ioport_quickstart_basic_usage Usage steps + * + * \subsection ioport_quickstart_basic_usage_code Example code + * \code + ioport_port_mask_t value; + + value = ioport_get_port_level(IN_PORT, MASK); + ioport_set_port_level(OUT_PORT, MASK, value); +\endcode + * + * \subsection ioport_quickstart_basic_usage_flow Workflow + * -# Define a variable for port date storage: + * - \code ioport_port_mask_t value; \endcode + * -# Read out from one port: + * - \code value = ioport_get_port_level(IN_PORT, MASK); \endcode + * -# Put the read data out on the other port: + * - \code ioport_set_port_level(OUT_PORT, MASK, value); \endcode + */ + +#ifdef __cplusplus +} +#endif + +#endif /* IOPORT_H */ diff --git a/Fred_bootloader/src/ASF/common/services/ioport/xmega/ioport.h b/Fred_bootloader/src/ASF/common/services/ioport/xmega/ioport.h new file mode 100644 index 0000000000000000000000000000000000000000..f0542b9eb3a969d7d59a686345460a663667c367 --- /dev/null +++ b/Fred_bootloader/src/ASF/common/services/ioport/xmega/ioport.h @@ -0,0 +1,361 @@ +/** + * \file + * + * \brief XMEGA architecture specific IOPORT service implementation header file. + * + * Copyright (c) 2012-2013 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_XMEGA_H +#define IOPORT_XMEGA_H + +#define IOPORT_CREATE_PIN(port, pin) ((IOPORT_ ## port) * 8 + (pin)) +#define IOPORT_BASE_ADDRESS 0x600 +#define IOPORT_PORT_OFFSET 0x20 + +/** \name IOPORT port numbers */ +/** @{ */ +#if !XMEGA_B3 +# define IOPORT_PORTA 0 +#endif + +#define IOPORT_PORTB 1 +#define IOPORT_PORTC 2 +#define IOPORT_PORTD 3 + +#if !XMEGA_B3 +# define IOPORT_PORTE 4 +#endif + +#if XMEGA_A1 || XMEGA_A1U || XMEGA_A3 || XMEGA_A3U || XMEGA_A3B || XMEGA_A3BU || \ + XMEGA_C3 || XMEGA_D3 +# define IOPORT_PORTF 5 +#endif + +#if XMEGA_B1 || XMEGA_B3 +# define IOPORT_PORTG 6 +#endif + +#if XMEGA_A1 || XMEGA_A1U +# define IOPORT_PORTH 7 +# define IOPORT_PORTJ 8 +# define IOPORT_PORTK 9 +#endif + +#if XMEGA_B1 || XMEGA_B3 +# define IOPORT_PORTM 11 +#endif + +#if XMEGA_A1 || XMEGA_A1U +# define IOPORT_PORTQ 14 +#endif + +#define IOPORT_PORTR 15 +/** @} */ + +/** + * \weakgroup ioport_group + * \section ioport_modes IOPORT Modes + * + * For details on these please see the XMEGA Manual. + * + * @{ + */ + +/** \name IOPORT Mode bit definitions */ +/** @{ */ +#define IOPORT_MODE_TOTEM (0x00 << 3) /*!< Totem-pole */ +#define IOPORT_MODE_BUSKEEPER (0x01 << 3) /*!< Buskeeper */ +#define IOPORT_MODE_PULLDOWN (0x02 << 3) /*!< Pull-down */ +#define IOPORT_MODE_PULLUP (0x03 << 3) /*!< Pull-up */ +#define IOPORT_MODE_WIREDOR (0x04 << 3) /*!< Wired OR */ +#define IOPORT_MODE_WIREDAND (0x05 << 3) /*!< Wired AND */ +#define IOPORT_MODE_WIREDORPULL (0x06 << 3) /*!< Wired OR with pull-down */ +#define IOPORT_MODE_WIREDANDPULL (0x07 << 3) /*!< Wired AND with pull-up */ +#define IOPORT_MODE_INVERT_PIN (0x01 << 6) /*!< Invert output and input */ +#define IOPORT_MODE_SLEW_RATE_LIMIT (0x01 << 7) /*!< Slew rate limiting */ +/** @} */ + +/** @} */ + +typedef uint8_t ioport_mode_t; +typedef uint8_t ioport_pin_t; +typedef uint8_t ioport_port_t; +typedef uint8_t ioport_port_mask_t; + +__always_inline static ioport_port_t arch_ioport_pin_to_port_id(ioport_pin_t pin) +{ + return pin >> 3; +} + +__always_inline static PORT_t *arch_ioport_port_to_base(ioport_port_t port) +{ + return (PORT_t *)((uintptr_t)IOPORT_BASE_ADDRESS + + (port * IOPORT_PORT_OFFSET)); +} + +__always_inline static PORT_t *arch_ioport_pin_to_base(ioport_pin_t pin) +{ + return arch_ioport_port_to_base(arch_ioport_pin_to_port_id(pin)); +} + +__always_inline static ioport_port_mask_t arch_ioport_pin_to_mask( + ioport_pin_t pin) +{ + return 1U << (pin & 0x07); +} + +__always_inline static ioport_port_mask_t arch_ioport_pin_to_index( + ioport_pin_t pin) +{ + return (pin & 0x07); +} + +__always_inline static void arch_ioport_init(void) +{ +} + +__always_inline static void arch_ioport_enable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] &= ~PORT_ISC_gm; + } + } + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_enable_pin(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl + = (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl &= ~PORT_ISC_gm; + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_disable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] |= PORT_ISC_INPUT_DISABLE_gc; + } + } + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_disable_pin(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl + = (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl |= PORT_ISC_INPUT_DISABLE_gc; + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_port_mode(ioport_port_t port, + ioport_port_mask_t mask, ioport_mode_t mode) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + uint8_t new_mode_bits = (mode & ~PORT_ISC_gm); + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] + = (pin_ctrl[i] & + PORT_ISC_gm) | new_mode_bits; + } + } + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_pin_mode(ioport_pin_t pin, + ioport_mode_t mode) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl + = (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl &= PORT_ISC_gm; + *pin_ctrl |= mode; + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_port_dir(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_direction dir) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + if (dir == IOPORT_DIR_OUTPUT) { + base->DIRSET = mask; + } else if (dir == IOPORT_DIR_INPUT) { + base->DIRCLR = mask; + } +} + +__always_inline static void arch_ioport_set_pin_dir(ioport_pin_t pin, + enum ioport_direction dir) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + if (dir == IOPORT_DIR_OUTPUT) { + base->DIRSET = arch_ioport_pin_to_mask(pin); + } else if (dir == IOPORT_DIR_INPUT) { + base->DIRCLR = arch_ioport_pin_to_mask(pin); + } +} + +__always_inline static void arch_ioport_set_pin_level(ioport_pin_t pin, + bool level) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + if (level) { + base->OUTSET = arch_ioport_pin_to_mask(pin); + } else { + base->OUTCLR = arch_ioport_pin_to_mask(pin); + } +} + +__always_inline static void arch_ioport_set_port_level(ioport_port_t port, + ioport_port_mask_t mask, ioport_port_mask_t level) +{ + PORT_t *base = arch_ioport_port_to_base(port); + if (level) { + base->OUTSET |= mask; + base->OUTCLR &= ~mask; + } else { + base->OUTSET &= ~mask; + base->OUTCLR |= mask; + } +} + +__always_inline static bool arch_ioport_get_pin_level(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + return base->IN & arch_ioport_pin_to_mask(pin); +} + +__always_inline static ioport_port_mask_t arch_ioport_get_port_level( + ioport_port_t port, ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + return base->IN & mask; +} + +__always_inline static void arch_ioport_toggle_pin_level(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + base->OUTTGL = arch_ioport_pin_to_mask(pin); +} + +__always_inline static void arch_ioport_toggle_port_level(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + base->OUTTGL = mask; +} + +__always_inline static void arch_ioport_set_pin_sense_mode(ioport_pin_t pin, + enum ioport_sense pin_sense) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl + = (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl &= ~PORT_ISC_gm; + *pin_ctrl |= (pin_sense & PORT_ISC_gm); + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_port_sense_mode(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_sense pin_sense) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + uint8_t new_sense_bits = (pin_sense & PORT_ISC_gm); + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] + = (pin_ctrl[i] & + ~PORT_ISC_gm) | new_sense_bits; + } + } + + cpu_irq_restore(flags); +} + +#endif /* IOPORT_XMEGA_H */ diff --git a/Fred_bootloader/src/ASF/common/services/ioport/xmega/ioport_compat.c b/Fred_bootloader/src/ASF/common/services/ioport/xmega/ioport_compat.c new file mode 100644 index 0000000000000000000000000000000000000000..4737249b862e85764b717e8af4d9fb039ccd3591 --- /dev/null +++ b/Fred_bootloader/src/ASF/common/services/ioport/xmega/ioport_compat.c @@ -0,0 +1,70 @@ +/** + * \file + * + * \brief XMEGA legacy IOPORT software compatibility driver interface. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#include "ioport_compat.h" + +#if defined(IOPORT_XMEGA_COMPAT) +void ioport_configure_port_pin(void *port, pin_mask_t pin_mask, + port_pin_flags_t flags) +{ + uint8_t pin; + + for (pin = 0; pin < 8; pin++) { + if (pin_mask & (1 << pin)) { + *((uint8_t *)port + PORT_PIN0CTRL + pin) = flags >> 8; + } + } + /* Select direction and initial pin state */ + if (flags & IOPORT_DIR_OUTPUT) { + if (flags & IOPORT_INIT_HIGH) { + *((uint8_t *)port + PORT_OUTSET) = pin_mask; + } else { + *((uint8_t *)port + PORT_OUTCLR) = pin_mask; + } + + *((uint8_t *)port + PORT_DIRSET) = pin_mask; + } else { + *((uint8_t *)port + PORT_DIRCLR) = pin_mask; + } +} + +#endif diff --git a/Fred_bootloader/src/ASF/common/services/ioport/xmega/ioport_compat.h b/Fred_bootloader/src/ASF/common/services/ioport/xmega/ioport_compat.h new file mode 100644 index 0000000000000000000000000000000000000000..b6a454dbb512a65d14b955d045c6bf0c7ffea1ea --- /dev/null +++ b/Fred_bootloader/src/ASF/common/services/ioport/xmega/ioport_compat.h @@ -0,0 +1,318 @@ +/** + * \file + * + * \brief XMEGA legacy IOPORT software compatibility driver interface header + * file. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_XMEGA_COMPAT_H_ +#define IOPORT_XMEGA_COMPAT_H_ + +#include "../ioport.h" + +/** + * \brief A pin mask + * + * This type is used to describe the port pin mask on the part. + */ +typedef uint8_t pin_mask_t; + +/** + * \brief A PORT pin + * + * This type is used to describe the PORT pins on the part. + */ +typedef uint8_t port_pin_t; + +/** + * \brief Pin configuration flags + * + * This is a bitmask containing configuration flags for the pins that shall be + * configured. + */ +typedef uint16_t port_pin_flags_t; + +/** + * \brief A port id + * + * This type is used to describe the port id on the part (0 is PORTA). + */ +typedef uint8_t port_id_t; + +/** \name Initial Output State Flags */ +/** @{ */ +#define IOPORT_INIT_LOW (0 << 1) /*!< Initial Output State Low */ +#define IOPORT_INIT_HIGH (1 << 1) /*!< Initial Output State High */ +/** @} */ + +/** \name Input/Sense Configuration Flags */ +/** @{ */ +#define IOPORT_BOTHEDGES (0 << 8) /*!< Sense Both Edges */ +#define IOPORT_RISING (1 << 8) /*!< Sense Rising Edge */ +#define IOPORT_FALLING (2 << 8) /*!< Sense Falling Edge */ +#define IOPORT_LEVEL (3 << 8) /*!< Sense Low Level */ +#if XMEGA_E +# define IOPORT_FORCE_ENABLE (6 << 8) /*!< Sense Force Input Enable Low Level */ +#endif +#define IOPORT_INPUT_DISABLE (7 << 8) /*!< Input Buffer Disabled */ +/** @} */ + +/** \name Output and Pull Configuration Flags */ +/** @{ */ +#define IOPORT_TOTEM (0 << 11) /*!< Normal push/pull output */ +#define IOPORT_BUSKEEPER (1 << 11) /*!< Bus Keeper */ +#define IOPORT_PULL_DOWN (2 << 11) /*!< Pull-Down (when input) */ +#define IOPORT_PULL_UP (3 << 11) /*!< Pull-Up (when input) */ +#define IOPORT_WIRED_OR (4 << 11) /*!< Wired OR */ +#define IOPORT_WIRED_AND (5 << 11) /*!< Wired AND */ +#define IOPORT_WIRED_OR_PULL_DOWN (6 << 11) /*!< Wired OR and Pull-Down */ +#define IOPORT_WIRED_AND_PULL_UP (7 << 11) /*!< Wired AND and Pull-Up */ +/** @} */ + +/** \name Inverted I/O Configuration Flags */ +/** @{ */ +#define IOPORT_INV_ENABLED (1 << 14) /*!< I/O is Inverted */ +#define IOPORT_INV_DISABLE (0 << 14) /*!< I/O is Not Inverted */ +/** @} */ + +/** \name Slew Rate Limit Configuration Flags */ +/** @{ */ +#define IOPORT_SRL_ENABLED (1 << 15) /*!< Slew Rate Limit Enabled */ +#define IOPORT_SRL_DISABLED (0 << 15) /*!< Slew Rate Limit Disabled */ +/** @} */ + +/** + * \internal + * \name PORT fields structure offset + * + * These macros are used to compute the field offset number with the PORT_t + * structure. + */ +/** @{ */ +#define PORT_DIR 0x00 /*!< Data Direction */ +#define PORT_DIRSET 0x01 /*!< Data Direction Set */ +#define PORT_DIRCLR 0x02 /*!< Data Direction Clear */ +#define PORT_DIRTGL 0x03 /*!< Data Direction Toggle */ +#define PORT_OUT 0x04 /*!< Data Output Value */ +#define PORT_OUTSET 0x05 /*!< Data Output Value Set */ +#define PORT_OUTCLR 0x06 /*!< Data Output Value Clear */ +#define PORT_OUTTGL 0x07 /*!< Data Output Value Toggle */ +#define PORT_IN 0x08 /*!< Data Input Value */ +#define PORT_INTCTRL 0x09 /*!< Interrupt Control */ +#define PORT_INT0MASK 0x0A /*!< Interrupt 0 Mask */ +#define PORT_INT1MASK 0x0B /*!< Interrupt 1 Mask */ +#define PORT_INTFLAGS 0x0C /*!< Interrupt Flags */ +#define PORT_PIN0CTRL 0x10 /*!< Pin 0 Configuration */ +#define PORT_PIN1CTRL 0x11 /*!< Pin 1 Configuration */ +#define PORT_PIN2CTRL 0x12 /*!< Pin 2 Configuration */ +#define PORT_PIN3CTRL 0x13 /*!< Pin 3 Configuration */ +#define PORT_PIN4CTRL 0x14 /*!< Pin 4 Configuration */ +#define PORT_PIN5CTRL 0x15 /*!< Pin 5 Configuration */ +#define PORT_PIN6CTRL 0x16 /*!< Pin 6 Configuration */ +#define PORT_PIN7CTRL 0x17 /*!< Pin 7 Configuration */ +/** @} */ + +static inline PORT_t *ioport_pin_to_port(port_pin_t pin) +{ + return arch_ioport_pin_to_base(pin); +} + +static inline PORT_t *ioport_id_pin_to_port(port_id_t port) +{ + return arch_ioport_port_to_base(port); +} + +/** + * \brief Configure the IO PORT pin function for a set of pins on a port + * + * \param port Pointer to the port + * \param pin_mask Mask containing the pins that should be configured + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +void ioport_configure_port_pin(void *port, pin_mask_t pin_mask, + port_pin_flags_t flags); + +/** + * \brief Select the port function for a single pin + * + * \param pin The pin to configure + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +static inline void ioport_configure_pin(port_pin_t pin, port_pin_flags_t flags) +{ + ioport_configure_port_pin(arch_ioport_pin_to_base(pin), + arch_ioport_pin_to_mask(pin), flags); +} + +/** + * \brief Configure a group of I/O pins on a specified port number + * + * \param port The port number + * \param pin_mask The pin mask to configure + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +static inline void ioport_configure_group(port_id_t port, pin_mask_t pin_mask, + port_pin_flags_t flags) +{ + ioport_configure_port_pin(arch_ioport_port_to_base(port), pin_mask, flags); +} + +/** + * \brief Drive a PORT pin to a given state + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + * \param value The desired state of the pin. \a true means drive the + * pin high (towards Vdd), while \a false means drive the pin low + * (towards Vss). + */ +static inline void ioport_set_value(port_pin_t pin, bool value) +{ + arch_ioport_set_pin_level(pin, value); +} + +/** + * \brief Drive a PORT pin to a low level + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_set_pin_low(port_pin_t pin) +{ + arch_ioport_set_pin_level(pin, false); +} + +/** + * \brief Drive a PORT pin to a high level + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_set_pin_high(port_pin_t pin) +{ + arch_ioport_set_pin_level(pin, true); +} + +/** + * \brief Read the current state of a PORT pin + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_get_value(port_pin_t pin) +{ + return arch_ioport_get_pin_level(pin); +} + +/** + * \brief Read the current state of a PORT pin and test high level + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_pin_is_high(port_pin_t pin) +{ + return (arch_ioport_get_pin_level(pin) == true); +} + +/** + * \brief Read the current state of a PORT pin and test high level + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_pin_is_low(port_pin_t pin) +{ + return (arch_ioport_get_pin_level(pin) == false); +} + +/** + * \brief Toggle the current state of a PORT pin + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_toggle_pin(port_pin_t pin) +{ + arch_ioport_toggle_pin_level(pin); +} + +/*! \brief Drives a group of I/O pin of a port to high level. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_set_group_high(port_id_t port_id, + pin_mask_t port_mask) +{ + arch_ioport_set_port_level(port_id, port_mask, port_mask); +} + +/*! \brief Drives a group of I/O pin of a port to low level. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_set_group_low(port_id_t port_id, pin_mask_t port_mask) +{ + arch_ioport_set_port_level(port_id, port_mask, 0); +} + +/*! \brief Toggles a group of I/O pin of a port. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_tgl_group(port_id_t port_id, pin_mask_t port_mask) +{ + arch_ioport_toggle_port_level(port_id, port_mask); +} + +#endif /* IOPORT_COMPAT_H_ */ diff --git a/Fred_bootloader/src/ASF/common/services/serial/serial.h b/Fred_bootloader/src/ASF/common/services/serial/serial.h new file mode 100644 index 0000000000000000000000000000000000000000..3c62e9250c95cd1f29454507eea796fe42ebf33e --- /dev/null +++ b/Fred_bootloader/src/ASF/common/services/serial/serial.h @@ -0,0 +1,266 @@ +/** + * \file + * + * \brief Serial Mode management + * + * Copyright (c) 2010 - 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef SERIAL_H_INCLUDED +#define SERIAL_H_INCLUDED + +#include <parts.h> +#include "status_codes.h" + +/** + * \typedef usart_if + * + * This type can be used independently to refer to USART module for the + * architecture used. It refers to the correct type definition for the + * architecture, ie. USART_t* for XMEGA or avr32_usart_t* for UC3. + */ + +#if XMEGA +# include "xmega_usart/usart_serial.h" +#elif MEGA_RF +# include "megarf_usart/usart_serial.h" +#elif UC3 +# include "uc3_usart/usart_serial.h" +#elif (SAMD20) || (SAMD21) || (SAMR21) || (SAMD10) || (SAMD11) +#include "sam0_usart/usart_serial.h" +#elif SAM +# include "sam_uart/uart_serial.h" +#else +# error Unsupported chip type +#endif + +/** + * + * \defgroup serial_group Serial Interface (Serial) + * + * See \ref serial_quickstart. + * + * This is the common API for serial interface. Additional features are available + * in the documentation of the specific modules. + * + * \section serial_group_platform Platform Dependencies + * + * The serial API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behaviour. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - usart_serial_init() + * - usart_serial_putchar() + * - usart_serial_getchar() + * - usart_serial_write_packet() + * - usart_serial_read_packet() + * + * + * @{ + */ + +//! @} + +/** + * \page serial_quickstart Quick start guide for Serial Interface service + * + * This is the quick start guide for the \ref serial_group "Serial Interface module", with + * step-by-step instructions on how to configure and use the serial in a + * selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section serial_use_cases Serial use cases + * - \ref serial_basic_use_case + * - \subpage serial_use_case_1 + * + * \section serial_basic_use_case Basic use case - transmit a character + * In this use case, the serial module is configured for: + * - Using USARTD0 + * - Baudrate: 9600 + * - Character length: 8 bit + * - Parity mode: Disabled + * - Stop bit: None + * - RS232 mode + * + * The use case waits for a received character on the configured USART and + * echoes the character back to the same USART. + * + * \section serial_basic_use_case_setup Setup steps + * + * \subsection serial_basic_use_case_setup_prereq Prerequisites + * -# \ref sysclk_group "System Clock Management (sysclk)" + * + * \subsection serial_basic_use_case_setup_code Example code + * The following configuration must be added to the project (typically to a + * conf_serial.h file, but it can also be added to your main application file.) + * \code + #define USART_SERIAL &USARTD0 + #define USART_SERIAL_BAUDRATE 9600 + #define USART_SERIAL_CHAR_LENGTH USART_CHSIZE_8BIT_gc + #define USART_SERIAL_PARITY USART_PMODE_DISABLED_gc + #define USART_SERIAL_STOP_BIT false +\endcode + * + * A variable for the received byte must be added: + * \code uint8_t received_byte; \endcode + * + * Add to application initialization: + * \code + sysclk_init(); + + static usart_serial_options_t usart_options = { + .baudrate = USART_SERIAL_BAUDRATE, + .charlength = USART_SERIAL_CHAR_LENGTH, + .paritytype = USART_SERIAL_PARITY, + .stopbits = USART_SERIAL_STOP_BIT + }; + + usart_serial_init(USART_SERIAL, &usart_options); +\endcode + * + * \subsection serial_basic_use_case_setup_flow Workflow + * -# Initialize system clock: + * - \code sysclk_init(); \endcode + * -# Create serial USART options struct: + * - \code + static usart_serial_options_t usart_options = { + .baudrate = USART_SERIAL_BAUDRATE, + .charlength = USART_SERIAL_CHAR_LENGTH, + .paritytype = USART_SERIAL_PARITY, + .stopbits = USART_SERIAL_STOP_BIT + }; +\endcode + * -# Initialize the serial service: + * - \code usart_serial_init(USART_SERIAL, &usart_options);\endcode + * + * \section serial_basic_use_case_usage Usage steps + * + * \subsection serial_basic_use_case_usage_code Example code + * Add to application C-file: + * \code + usart_serial_getchar(USART_SERIAL, &received_byte); + usart_serial_putchar(USART_SERIAL, received_byte); +\endcode + * + * \subsection serial_basic_use_case_usage_flow Workflow + * -# Wait for reception of a character: + * - \code usart_serial_getchar(USART_SERIAL, &received_byte); \endcode + * -# Echo the character back: + * - \code usart_serial_putchar(USART_SERIAL, received_byte); \endcode + */ + +/** + * \page serial_use_case_1 Advanced use case - Send a packet of serial data + * + * In this use case, the USART module is configured for: + * - Using USARTD0 + * - Baudrate: 9600 + * - Character length: 8 bit + * - Parity mode: Disabled + * - Stop bit: None + * - RS232 mode + * + * The use case sends a string of text through the USART. + * + * \section serial_use_case_1_setup Setup steps + * + * \subsection serial_use_case_1_setup_prereq Prerequisites + * -# \ref sysclk_group "System Clock Management (sysclk)" + * + * \subsection serial_use_case_1_setup_code Example code + * The following configuration must be added to the project (typically to a + * conf_serial.h file, but it can also be added to your main application file.): + * \code + #define USART_SERIAL &USARTD0 + #define USART_SERIAL_BAUDRATE 9600 + #define USART_SERIAL_CHAR_LENGTH USART_CHSIZE_8BIT_gc + #define USART_SERIAL_PARITY USART_PMODE_DISABLED_gc + #define USART_SERIAL_STOP_BIT false +\endcode + * + * Add to application initialization: + * \code + sysclk_init(); + + static usart_serial_options_t usart_options = { + .baudrate = USART_SERIAL_BAUDRATE, + .charlength = USART_SERIAL_CHAR_LENGTH, + .paritytype = USART_SERIAL_PARITY, + .stopbits = USART_SERIAL_STOP_BIT + }; + + usart_serial_init(USART_SERIAL, &usart_options); +\endcode + * + * \subsection serial_use_case_1_setup_flow Workflow + * -# Initialize system clock: + * - \code sysclk_init(); \endcode + * -# Create USART options struct: + * - \code + static usart_serial_options_t usart_options = { + .baudrate = USART_SERIAL_BAUDRATE, + .charlength = USART_SERIAL_CHAR_LENGTH, + .paritytype = USART_SERIAL_PARITY, + .stopbits = USART_SERIAL_STOP_BIT + }; +\endcode + * -# Initialize in RS232 mode: + * - \code usart_serial_init(USART_SERIAL_EXAMPLE, &usart_options); \endcode + * + * \section serial_use_case_1_usage Usage steps + * + * \subsection serial_use_case_1_usage_code Example code + * Add to, e.g., main loop in application C-file: + * \code + usart_serial_write_packet(USART_SERIAL, "Test String", strlen("Test String")); +\endcode + * + * \subsection serial_use_case_1_usage_flow Workflow + * -# Write a string of text to the USART: + * - \code usart_serial_write_packet(USART_SERIAL, "Test String", strlen("Test String")); \endcode + */ + +#endif /* SERIAL_H_INCLUDED */ diff --git a/Fred_bootloader/src/ASF/common/services/serial/usart_serial.c b/Fred_bootloader/src/ASF/common/services/serial/usart_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..de9024133f68647753cb443fbef81d8cb6eb2113 --- /dev/null +++ b/Fred_bootloader/src/ASF/common/services/serial/usart_serial.c @@ -0,0 +1,84 @@ +/** + * + * \file + * + * \brief USART Serial driver functions. + * + * + * Copyright (c) 2010-2013 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#include "serial.h" + +/** + * \brief Send a sequence of bytes to USART device + * + * \param usart Base address of the USART instance. + * \param data Data buffer to read + * \param len Length of data + * + */ +status_code_t usart_serial_write_packet(usart_if usart, const uint8_t *data, + size_t len) +{ + while (len) { + usart_serial_putchar(usart, *data); + len--; + data++; + } + return STATUS_OK; +} + + +/** + * \brief Receive a sequence of bytes from USART device + * + * \param usart Base address of the USART instance. + * \param data Data buffer to write + * \param len Length of data + * + */ +status_code_t usart_serial_read_packet(usart_if usart, uint8_t *data, + size_t len) +{ + while (len) { + usart_serial_getchar(usart, data); + len--; + data++; + } + return STATUS_OK; +} diff --git a/Fred_bootloader/src/ASF/common/services/serial/xmega_usart/usart_serial.h b/Fred_bootloader/src/ASF/common/services/serial/xmega_usart/usart_serial.h new file mode 100644 index 0000000000000000000000000000000000000000..9b6e78446d1889bd5f73ea238ac34055f7cbadb7 --- /dev/null +++ b/Fred_bootloader/src/ASF/common/services/serial/xmega_usart/usart_serial.h @@ -0,0 +1,170 @@ +/** + * \file + * + * This file defines a useful set of functions for the Serial interface on AVR + * XMEGA devices. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef _USART_SERIAL_H_ +#define _USART_SERIAL_H_ + +#include "compiler.h" +#include "sysclk.h" +#include "status_codes.h" +#include "usart.h" + +/*! \name Serial Management Configuration + */ +//! @{ +#include "conf_usart_serial.h" +//! @} + +typedef usart_rs232_options_t usart_serial_options_t; + +typedef USART_t *usart_if; + +/*! \brief Initializes the Usart in master mode. + * + * \param usart Base address of the USART instance. + * \param options Options needed to set up RS232 communication (see \ref usart_serial_options_t). + * + * \retval true if the initialization was successful + * \retval false if initialization failed (error in baud rate calculation) + */ +static inline bool usart_serial_init(usart_if usart, const + usart_serial_options_t *options) +{ + // USART options. + usart_rs232_options_t usart_rs232_options; + usart_rs232_options.charlength = options->charlength; + usart_rs232_options.paritytype = options->paritytype; + usart_rs232_options.stopbits = options->stopbits; + usart_rs232_options.baudrate = options->baudrate; + +#ifdef USARTC0 + if((uint16_t)usart == (uint16_t)&USARTC0) { + sysclk_enable_module(SYSCLK_PORT_C,PR_USART0_bm); + } +#endif +#ifdef USARTC1 + if((uint16_t)usart == (uint16_t)&USARTC1) { + sysclk_enable_module(SYSCLK_PORT_C,PR_USART1_bm); + } +#endif +#ifdef USARTD0 + if((uint16_t)usart == (uint16_t)&USARTD0) { + sysclk_enable_module(SYSCLK_PORT_D,PR_USART0_bm); + } +#endif +#ifdef USARTD1 + if((uint16_t)usart == (uint16_t)&USARTD1) { + sysclk_enable_module(SYSCLK_PORT_D,PR_USART1_bm); + } +#endif +#ifdef USARTE0 + if((uint16_t)usart == (uint16_t)&USARTE0) { + sysclk_enable_module(SYSCLK_PORT_E,PR_USART0_bm); + } +#endif +#ifdef USARTE1 + if((uint16_t)usart == (uint16_t)&USARTE1) { + sysclk_enable_module(SYSCLK_PORT_E,PR_USART1_bm); + } +#endif +#ifdef USARTF0 + if((uint16_t)usart == (uint16_t)&USARTF0) { + sysclk_enable_module(SYSCLK_PORT_F,PR_USART0_bm); + } +#endif +#ifdef USARTF1 + if((uint16_t)usart == (uint16_t)&USARTF1) { + sysclk_enable_module(SYSCLK_PORT_F,PR_USART1_bm); + } +#endif + if (usart_init_rs232(usart, &usart_rs232_options)) { + return true; + } + else { + return false; + } +} + +/*! \brief Sends a character with the USART. + * + * \param usart Base address of the USART instance. + * \param c Character to write. + * + * \return Status code + */ +static inline enum status_code usart_serial_putchar(usart_if usart, uint8_t c) +{ + return usart_putchar(usart, c); +} +/*! \brief Waits until a character is received, and returns it. + * + * \param usart Base address of the USART instance. + * \param data Data to read + * + */ +static inline void usart_serial_getchar(usart_if usart, uint8_t *data) +{ + *data = usart_getchar(usart); +} + +/** + * \brief Send a sequence of bytes to USART device + * + * \param usart Base address of the USART instance. + * \param data Data buffer to read + * \param len Length of data + * + */ +extern status_code_t usart_serial_write_packet(usart_if usart, const uint8_t *data, size_t len); + +/** + * \brief Receive a sequence of bytes from USART device + * + * \param usart Base address of the USART instance. + * \param data Data buffer to write + * \param len Length of data + * + */ +extern status_code_t usart_serial_read_packet(usart_if usart, uint8_t *data, size_t len); + +#endif // _USART_SERIAL_H_ diff --git a/Fred_bootloader/src/ASF/common/services/sleepmgr/sleepmgr.h b/Fred_bootloader/src/ASF/common/services/sleepmgr/sleepmgr.h new file mode 100644 index 0000000000000000000000000000000000000000..cd8a519c95c7869bb3edb164ae965ad2edf92002 --- /dev/null +++ b/Fred_bootloader/src/ASF/common/services/sleepmgr/sleepmgr.h @@ -0,0 +1,256 @@ +/** + * \file + * + * \brief Sleep manager + * + * Copyright (c) 2010 - 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef SLEEPMGR_H +#define SLEEPMGR_H + +#include <compiler.h> +#include <parts.h> + +#if (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM) +# include "sam/sleepmgr.h" +#elif XMEGA +# include "xmega/sleepmgr.h" +#elif UC3 +# include "uc3/sleepmgr.h" +#elif SAM4L +# include "sam4l/sleepmgr.h" +#elif MEGA +# include "mega/sleepmgr.h" +#elif (SAMD20 || SAMD21 || SAMR21 || SAMD11) +# include "samd/sleepmgr.h" +#else +# error Unsupported device. +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup sleepmgr_group Sleep manager + * + * The sleep manager is a service for ensuring that the device is not put to + * sleep in deeper sleep modes than the system (e.g., peripheral drivers, + * services or the application) allows at any given time. + * + * It is based on the use of lock counting for the individual sleep modes, and + * will put the device to sleep in the shallowest sleep mode that has a non-zero + * lock count. The drivers/services/application can change these counts by use + * of \ref sleepmgr_lock_mode and \ref sleepmgr_unlock_mode. + * Refer to \ref sleepmgr_mode for a list of the sleep modes available for + * locking, and the device datasheet for information on their effect. + * + * The application must supply the file \ref conf_sleepmgr.h. + * + * For the sleep manager to be enabled, the symbol \ref CONFIG_SLEEPMGR_ENABLE + * must be defined, e.g., in \ref conf_sleepmgr.h. If this symbol is not + * defined, the functions are replaced with dummy functions and no RAM is used. + * + * @{ + */ + +/** + * \def CONFIG_SLEEPMGR_ENABLE + * \brief Configuration symbol for enabling the sleep manager + * + * If this symbol is not defined, the functions of this service are replaced + * with dummy functions. This is useful for reducing code size and execution + * time if the sleep manager is not needed in the application. + * + * This symbol may be defined in \ref conf_sleepmgr.h. + */ +#if defined(__DOXYGEN__) && !defined(CONFIG_SLEEPMGR_ENABLE) +# define CONFIG_SLEEPMGR_ENABLE +#endif + +/** + * \enum sleepmgr_mode + * \brief Sleep mode locks + * + * Identifiers for the different sleep mode locks. + */ + +/** + * \brief Initialize the lock counts + * + * Sets all lock counts to 0, except the very last one, which is set to 1. This + * is done to simplify the algorithm for finding the deepest allowable sleep + * mode in \ref sleepmgr_enter_sleep. + */ +static inline void sleepmgr_init(void) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + uint8_t i; + + for (i = 0; i < SLEEPMGR_NR_OF_MODES - 1; i++) { + sleepmgr_locks[i] = 0; + } + sleepmgr_locks[SLEEPMGR_NR_OF_MODES - 1] = 1; +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +/** + * \brief Increase lock count for a sleep mode + * + * Increases the lock count for \a mode to ensure that the sleep manager does + * not put the device to sleep in the deeper sleep modes. + * + * \param mode Sleep mode to lock. + */ +static inline void sleepmgr_lock_mode(enum sleepmgr_mode mode) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + irqflags_t flags; + + Assert(sleepmgr_locks[mode] < 0xff); + + // Enter a critical section + flags = cpu_irq_save(); + + ++sleepmgr_locks[mode]; + + // Leave the critical section + cpu_irq_restore(flags); +#else + UNUSED(mode); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +/** + * \brief Decrease lock count for a sleep mode + * + * Decreases the lock count for \a mode. If the lock count reaches 0, the sleep + * manager can put the device to sleep in the deeper sleep modes. + * + * \param mode Sleep mode to unlock. + */ +static inline void sleepmgr_unlock_mode(enum sleepmgr_mode mode) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + irqflags_t flags; + + Assert(sleepmgr_locks[mode]); + + // Enter a critical section + flags = cpu_irq_save(); + + --sleepmgr_locks[mode]; + + // Leave the critical section + cpu_irq_restore(flags); +#else + UNUSED(mode); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + + /** + * \brief Retrieves the deepest allowable sleep mode + * + * Searches through the sleep mode lock counts, starting at the shallowest sleep + * mode, until the first non-zero lock count is found. The deepest allowable + * sleep mode is then returned. + */ +static inline enum sleepmgr_mode sleepmgr_get_sleep_mode(void) +{ + enum sleepmgr_mode sleep_mode = SLEEPMGR_ACTIVE; + +#ifdef CONFIG_SLEEPMGR_ENABLE + uint8_t *lock_ptr = sleepmgr_locks; + + // Find first non-zero lock count, starting with the shallowest modes. + while (!(*lock_ptr)) { + lock_ptr++; + sleep_mode = (enum sleepmgr_mode)(sleep_mode + 1); + } + + // Catch the case where one too many sleepmgr_unlock_mode() call has been + // performed on the deepest sleep mode. + Assert((uintptr_t)(lock_ptr - sleepmgr_locks) < SLEEPMGR_NR_OF_MODES); + +#endif /* CONFIG_SLEEPMGR_ENABLE */ + + return sleep_mode; +} + +/** + * \fn sleepmgr_enter_sleep + * \brief Go to sleep in the deepest allowed mode + * + * Searches through the sleep mode lock counts, starting at the shallowest sleep + * mode, until the first non-zero lock count is found. The device is then put to + * sleep in the sleep mode that corresponds to the lock. + * + * \note This function enables interrupts before going to sleep, and will leave + * them enabled upon return. This also applies if sleep is skipped due to ACTIVE + * mode being locked. + */ + +static inline void sleepmgr_enter_sleep(void) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + enum sleepmgr_mode sleep_mode; + + cpu_irq_disable(); + + // Find the deepest allowable sleep mode + sleep_mode = sleepmgr_get_sleep_mode(); + // Return right away if first mode (ACTIVE) is locked. + if (sleep_mode==SLEEPMGR_ACTIVE) { + cpu_irq_enable(); + return; + } + // Enter the deepest allowable sleep mode with interrupts enabled + sleepmgr_sleep(sleep_mode); +#else + cpu_irq_enable(); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* SLEEPMGR_H */ diff --git a/Fred_bootloader/src/ASF/common/services/sleepmgr/xmega/sleepmgr.c b/Fred_bootloader/src/ASF/common/services/sleepmgr/xmega/sleepmgr.c new file mode 100644 index 0000000000000000000000000000000000000000..23ccb3db3486eef12a2c0ec7efbc35f1b315fe46 --- /dev/null +++ b/Fred_bootloader/src/ASF/common/services/sleepmgr/xmega/sleepmgr.c @@ -0,0 +1,58 @@ +/** + * \file + * + * \brief Sleep manager + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#include <compiler.h> +#include <sleepmgr.h> + +#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__) + +uint8_t sleepmgr_locks[SLEEPMGR_NR_OF_MODES]; + +enum SLEEP_SMODE_enum sleepmgr_configs[SLEEPMGR_NR_OF_MODES] = { + SLEEP_SMODE_IDLE_gc, + SLEEP_SMODE_ESTDBY_gc, + SLEEP_SMODE_PSAVE_gc, + SLEEP_SMODE_STDBY_gc, + SLEEP_SMODE_PDOWN_gc, +}; + +#endif /* CONFIG_SLEEPMGR_ENABLE */ diff --git a/Fred_bootloader/src/ASF/common/services/sleepmgr/xmega/sleepmgr.h b/Fred_bootloader/src/ASF/common/services/sleepmgr/xmega/sleepmgr.h new file mode 100644 index 0000000000000000000000000000000000000000..13c5a0cb474a141ddd363d04b82e1a2c41311dae --- /dev/null +++ b/Fred_bootloader/src/ASF/common/services/sleepmgr/xmega/sleepmgr.h @@ -0,0 +1,114 @@ +/** + * \file + * + * \brief AVR XMEGA Sleep manager implementation + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_SLEEPMGR_H +#define XMEGA_SLEEPMGR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <compiler.h> +#include <conf_sleepmgr.h> +#include <sleep.h> + +/** + * \weakgroup sleepmgr_group + * @{ + */ + +enum sleepmgr_mode { + //! Active mode. + SLEEPMGR_ACTIVE = 0, + //! Idle mode. + SLEEPMGR_IDLE, + //! Extended Standby mode. + SLEEPMGR_ESTDBY, + //! Power Save mode. + SLEEPMGR_PSAVE, + //! Standby mode. + SLEEPMGR_STDBY, + //! Power Down mode. + SLEEPMGR_PDOWN, + SLEEPMGR_NR_OF_MODES, +}; + +/** + * \internal + * \name Internal arrays + * @{ + */ +#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__) +//! Sleep mode lock counters +extern uint8_t sleepmgr_locks[]; +/** + * \brief Look-up table with sleep mode configurations + * \note This is located in program memory (Flash) as it is constant. + */ +extern enum SLEEP_SMODE_enum sleepmgr_configs[]; +#endif /* CONFIG_SLEEPMGR_ENABLE */ +//! @} + +static inline void sleepmgr_sleep(const enum sleepmgr_mode sleep_mode) +{ + Assert(sleep_mode != SLEEPMGR_ACTIVE); +#ifdef CONFIG_SLEEPMGR_ENABLE + sleep_set_mode(sleepmgr_configs[sleep_mode-1]); + sleep_enable(); + + cpu_irq_enable(); + sleep_enter(); + + sleep_disable(); +#else + cpu_irq_enable(); +#endif /* CONFIG_SLEEPMGR_ENABLE */ + +} + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* XMEGA_SLEEPMGR_H */ diff --git a/Fred_bootloader/src/ASF/common/utils/interrupt.h b/Fred_bootloader/src/ASF/common/utils/interrupt.h new file mode 100644 index 0000000000000000000000000000000000000000..33ae88463a9790ccc5ab62973b4a3a15659b13b5 --- /dev/null +++ b/Fred_bootloader/src/ASF/common/utils/interrupt.h @@ -0,0 +1,139 @@ +/** + * \file + * + * \brief Global interrupt management for 8- and 32-bit AVR + * + * Copyright (c) 2010-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef UTILS_INTERRUPT_H +#define UTILS_INTERRUPT_H + +#include <parts.h> + +#if XMEGA || MEGA || TINY +# include "interrupt/interrupt_avr8.h" +#elif UC3 +# include "interrupt/interrupt_avr32.h" +#elif SAM +# include "interrupt/interrupt_sam_nvic.h" +#else +# error Unsupported device. +#endif + +/** + * \defgroup interrupt_group Global interrupt management + * + * This is a driver for global enabling and disabling of interrupts. + * + * @{ + */ + +#if defined(__DOXYGEN__) +/** + * \def CONFIG_INTERRUPT_FORCE_INTC + * \brief Force usage of the ASF INTC driver + * + * Predefine this symbol when preprocessing to force the use of the ASF INTC driver. + * This is useful to ensure compatibility across compilers and shall be used only when required + * by the application needs. + */ +# define CONFIG_INTERRUPT_FORCE_INTC +#endif + +//! \name Global interrupt flags +//@{ +/** + * \typedef irqflags_t + * \brief Type used for holding state of interrupt flag + */ + +/** + * \def cpu_irq_enable + * \brief Enable interrupts globally + */ + +/** + * \def cpu_irq_disable + * \brief Disable interrupts globally + */ + +/** + * \fn irqflags_t cpu_irq_save(void) + * \brief Get and clear the global interrupt flags + * + * Use in conjunction with \ref cpu_irq_restore. + * + * \return Current state of interrupt flags. + * + * \note This function leaves interrupts disabled. + */ + +/** + * \fn void cpu_irq_restore(irqflags_t flags) + * \brief Restore global interrupt flags + * + * Use in conjunction with \ref cpu_irq_save. + * + * \param flags State to set interrupt flag to. + */ + +/** + * \fn bool cpu_irq_is_enabled_flags(irqflags_t flags) + * \brief Check if interrupts are globally enabled in supplied flags + * + * \param flags Currents state of interrupt flags. + * + * \return True if interrupts are enabled. + */ + +/** + * \def cpu_irq_is_enabled + * \brief Check if interrupts are globally enabled + * + * \return True if interrupts are enabled. + */ +//@} + +//! @} + +/** + * \ingroup interrupt_group + * \defgroup interrupt_deprecated_group Deprecated interrupt definitions + */ + +#endif /* UTILS_INTERRUPT_H */ diff --git a/Fred_bootloader/src/ASF/common/utils/interrupt/interrupt_avr8.h b/Fred_bootloader/src/ASF/common/utils/interrupt/interrupt_avr8.h new file mode 100644 index 0000000000000000000000000000000000000000..7320475b18abcf9bada8b50e871fed11c0e52af5 --- /dev/null +++ b/Fred_bootloader/src/ASF/common/utils/interrupt/interrupt_avr8.h @@ -0,0 +1,145 @@ +/** + * \file + * + * \brief Global interrupt management for 8-bit AVR + * + * Copyright (C) 2010-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef UTILS_INTERRUPT_INTERRUPT_H +#define UTILS_INTERRUPT_INTERRUPT_H + +#include <compiler.h> +#include <parts.h> + +/** + * \weakgroup interrupt_group + * + * @{ + */ + +#ifdef ISR_CUSTOM_H +# include ISR_CUSTOM_H +#else + +/** + * \def ISR + * \brief Define service routine for specified interrupt vector + * + * Usage: + * \code + ISR(FOO_vect) + { + ... + } +\endcode + * + * \param vect Interrupt vector name as found in the device header files. + */ +#if defined(__DOXYGEN__) +# define ISR(vect) +#elif defined(__GNUC__) +# include <avr/interrupt.h> +#elif defined(__ICCAVR__) +# define __ISR(x) _Pragma(#x) +# define ISR(vect) __ISR(vector=vect) __interrupt void handler_##vect(void) +#endif +#endif // ISR_CUSTOM_H + +#if XMEGA +/** + * \brief Initialize interrupt vectors + * Enables all interrupt levels, with vectors located in the application section + * and fixed priority scheduling. + */ +#define irq_initialize_vectors() \ + PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; +#elif MEGA_RF +#define irq_initialize_vectors() +#endif + +#ifdef __GNUC__ +# define cpu_irq_enable() sei() +# define cpu_irq_disable() cli() +#else +# define cpu_irq_enable() __enable_interrupt() +# define cpu_irq_disable() __disable_interrupt() +#endif + +typedef uint8_t irqflags_t; + +static inline irqflags_t cpu_irq_save(void) +{ + irqflags_t flags = SREG; + cpu_irq_disable(); + return flags; +} + +static inline void cpu_irq_restore(irqflags_t flags) +{ + barrier(); + SREG = flags; +} + +static inline bool cpu_irq_is_enabled_flags(irqflags_t flags) +{ +#if XMEGA +# ifdef __GNUC__ + return flags & CPU_I_bm; +# else + return flags & I_bm; +# endif +#elif MEGA || TINY + return flags & (1 << SREG_I); +#endif +} + +#define cpu_irq_is_enabled() cpu_irq_is_enabled_flags(SREG) + +//! @} + +/** + * \weakgroup interrupt_deprecated_group + * @{ + */ +// Deprecated definitions. +#define Enable_global_interrupt() cpu_irq_enable() +#define Disable_global_interrupt() cpu_irq_disable() +#define Is_global_interrupt_enabled() cpu_irq_is_enabled() +//! @} + +#endif /* UTILS_INTERRUPT_INTERRUPT_H */ diff --git a/Fred_bootloader/src/ASF/common/utils/make/Makefile.avr.in b/Fred_bootloader/src/ASF/common/utils/make/Makefile.avr.in new file mode 100644 index 0000000000000000000000000000000000000000..38725050973fcfec80af3c95ed499951e5dd9582 --- /dev/null +++ b/Fred_bootloader/src/ASF/common/utils/make/Makefile.avr.in @@ -0,0 +1,483 @@ +# List of available make goals: +# +# all Default target, builds the project +# clean Clean up the project +# rebuild Rebuild the project +# +# doc Build the documentation +# cleandoc Clean up the documentation +# rebuilddoc Rebuild the documentation +# +# +# Copyright (c) 2009 - 2013 Atmel Corporation. All rights reserved. +# +# \asf_license_start +# +# \page License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. The name of Atmel may not be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# 4. This software may only be redistributed and used in connection with an +# Atmel microcontroller product. +# +# THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE +# EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# \asf_license_stop +# + +# Include the config.mk file from the current working path, e.g., where the +# user called make. +include config.mk + +# Tool to use to generate documentation from the source code +DOCGEN ?= doxygen + +# Look for source files relative to the top-level source directory +VPATH := $(PRJ_PATH) + +# Output target file +target := $(TARGET) + +# Output project name (target name minus suffix) +project := $(basename $(target)) + +# Output target file (typically ELF or static library) +ifeq ($(suffix $(target)),.a) +target_type := lib +else +ifeq ($(suffix $(target)),.elf) +target_type := elf +else +$(error "Target type $(target_type) is not supported") +endif +endif + +# Allow override of operating system detection. The user can add OS=Linux or +# OS=Windows on the command line to explicit set the host OS. +# +# This allows to work around broken uname utility on certain systems. +ifdef OS + ifeq ($(strip $(OS)), Linux) + os_type := Linux + endif + ifeq ($(strip $(OS)), Windows) + os_type := windows32_64 + endif +endif + +os_type ?= $(strip $(shell uname)) + +ifeq ($(os_type),windows32) +os := Windows +else +ifeq ($(os_type),windows64) +os := Windows +else +ifeq ($(os_type),windows32_64) +os ?= Windows +else +ifeq ($(os_type),) +os := Windows +else +# Default to Linux style operating system. Both Cygwin and mingw are fully +# compatible (for this Makefile) with Linux. +os := Linux +endif +endif +endif +endif + +# Output documentation directory and configuration file. +docdir := ../doxygen/html +doccfg := ../doxygen/doxyfile.doxygen + +CROSS ?= avr- +AR := $(CROSS)ar +AS := $(CROSS)as +CC := $(CROSS)gcc +CPP := $(CROSS)gcc -E +CXX := $(CROSS)g++ +LD := $(CROSS)gcc +NM := $(CROSS)nm +OBJCOPY := $(CROSS)objcopy +OBJDUMP := $(CROSS)objdump +SIZE := $(CROSS)size + +RM := rm +ifeq ($(os),Windows) +RMDIR := rmdir /S /Q +else +RMDIR := rmdir -p --ignore-fail-on-non-empty +endif + +# On Windows, we need to override the shell to force the use of cmd.exe +ifeq ($(os),Windows) +SHELL := cmd +endif + +# Strings for beautifying output +MSG_CLEAN_FILES = "RM *.o *.d" +MSG_CLEAN_DIRS = "RMDIR $(strip $(clean-dirs))" +MSG_CLEAN_DOC = "RMDIR $(docdir)" +MSG_MKDIR = "MKDIR $(dir $@)" + +MSG_INFO = "INFO " +MSG_PREBUILD = "PREBUILD $(PREBUILD_CMD)" +MSG_POSTBUILD = "POSTBUILD $(POSTBUILD_CMD)" + +MSG_ARCHIVING = "AR $@" +MSG_ASSEMBLING = "AS $@" +MSG_BINARY_IMAGE = "OBJCOPY $@" +MSG_COMPILING = "CC $@" +MSG_COMPILING_CXX = "CXX $@" +MSG_EEPROM_IMAGE = "OBJCOPY $@" +MSG_EXTENDED_LISTING = "OBJDUMP $@" +MSG_IHEX_IMAGE = "OBJCOPY $@" +MSG_LINKING = "LN $@" +MSG_PREPROCESSING = "CPP $@" +MSG_SIZE = "SIZE $@" +MSG_SYMBOL_TABLE = "NM $@" + +MSG_GENERATING_DOC = "DOXYGEN $(docdir)" + +# Don't use make's built-in rules and variables +MAKEFLAGS += -rR + +# Don't print 'Entering directory ...' +MAKEFLAGS += --no-print-directory + +# Function for reversing the order of a list +reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1)) + +# Hide command output by default, but allow the user to override this +# by adding V=1 on the command line. +# +# This is inspired by the Kbuild system used by the Linux kernel. +ifdef V + ifeq ("$(origin V)", "command line") + VERBOSE = $(V) + endif +endif +ifndef VERBOSE + VERBOSE = 0 +endif + +ifeq ($(VERBOSE), 1) + Q = +else + Q = @ +endif + +arflags-gnu-y := $(ARFLAGS) +asflags-gnu-y := $(ASFLAGS) +cflags-gnu-y := $(CFLAGS) +cxxflags-gnu-y := $(CXXFLAGS) +cppflags-gnu-y := $(CPPFLAGS) +cpuflags-gnu-y := +dbgflags-gnu-y := $(DBGFLAGS) +libflags-gnu-y := $(foreach LIB,$(LIBS),-l$(LIB)) +ldflags-gnu-y := $(LDFLAGS) +flashflags-gnu-y := $(FLASHFLAGS) +eepromflags-gnu-y := $(EEPROMFLAGS) +clean-files := +clean-dirs := + +clean-files += $(wildcard $(target) $(project).map) +clean-files += $(wildcard $(project).hex $(project).eep) +clean-files += $(wildcard $(project).lss $(project).sym) +clean-files += $(wildcard $(build)) + +# Use pipes instead of temporary files for communication between processes +cflags-gnu-y += -pipe +asflags-gnu-y += -pipe +ldflags-gnu-y += -pipe + +# Archiver flags. +arflags-gnu-y += rcs + +# Always enable warnings. And be very careful about implicit +# declarations. +cflags-gnu-y += -Wall -Wstrict-prototypes -Wmissing-prototypes +cflags-gnu-y += -Werror-implicit-function-declaration +cxxflags-gnu-y += -Wall +# IAR doesn't allow arithmetic on void pointers, so warn about that. +cflags-gnu-y += -Wpointer-arith +cxxflags-gnu-y += -Wpointer-arith + +# Preprocessor flags. +cppflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),-I$(INC)) +asflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),'-Wa,-I$(INC)') + +# CPU specific flags. +cpuflags-gnu-y += -mmcu=$(MCU) + +# Dependency file flags. +depflags = -MD -MP -MQ $@ + +# Debug specific flags. +ifdef BUILD_DEBUG_LEVEL +dbgflags-gnu-y += -g$(BUILD_DEBUG_LEVEL) +else +dbgflags-gnu-y += -gdwarf-2 +endif + +# Optimization specific flags. +ifdef BUILD_OPTIMIZATION +optflags-gnu-y = -O$(BUILD_OPTIMIZATION) +else +optflags-gnu-y = $(OPTIMIZATION) +endif + +# Relax compilation and linking. +cflags-gnu-y += -mrelax +cxxflags-gnu-y += -mrelax +asflags-gnu-y += -mrelax +ldflags-gnu-y += -Wl,--relax + +# Always preprocess assembler files. +asflags-gnu-y += -x assembler-with-cpp +# Compile C files using the GNU99 standard. +cflags-gnu-y += -std=gnu99 +# Compile C++ files using the GNU++98 standard. +cxxflags-gnu-y += -std=gnu++98 + +# Use unsigned character type when compiling. +cflags-gnu-y += -funsigned-char +cxxflags-gnu-y += -funsigned-char + +# Don't use strict aliasing (very common in embedded applications). +cflags-gnu-y += -fno-strict-aliasing +cxxflags-gnu-y += -fno-strict-aliasing + +# Separate each function and data into its own separate section to allow +# garbage collection of unused sections. +cflags-gnu-y += -ffunction-sections -fdata-sections +cxxflags-gnu-y += -ffunction-sections -fdata-sections + +# Garbage collect unreferred sections when linking. +ldflags-gnu-y += -Wl,--gc-sections + +# Output a link map file and a cross reference table +ldflags-gnu-y += -Wl,-Map=$(project).map,--cref + +# Add library search paths relative to the top level directory. +ldflags-gnu-y += $(foreach _LIB_PATH,$(addprefix $(PRJ_PATH)/,$(LIB_PATH)),-L$(_LIB_PATH)) + +a_flags = $(cpuflags-gnu-y) $(depflags) $(cppflags-gnu-y) $(asflags-gnu-y) -D__ASSEMBLY__ +c_flags = $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cflags-gnu-y) +cxx_flags= $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cxxflags-gnu-y) +l_flags = $(cpuflags-gnu-y) $(optflags-gnu-y) $(ldflags-gnu-y) +ar_flags = $(arflags-gnu-y) + +# Intel Hex file production flags +flashflags-gnu-y += -R .eeprom -R .usb_descriptor_table + +# Eeprom file production flags +eepromflags-gnu-y += -j .eeprom +eepromflags-gnu-y += --set-section-flags=.eeprom="alloc,load" +eepromflags-gnu-y += --change-section-lma .eeprom=0 + +# Source files list and part informations must already be included before +# running this makefile + +# If a custom build directory is specified, use it -- force trailing / in directory name. +ifdef BUILD_DIR + build-dir := $(dir $(BUILD_DIR))$(if $(notdir $(BUILD_DIR)),$(notdir $(BUILD_DIR))/) +else + build-dir = +endif + +# Create object files list from source files list. +obj-y := $(addprefix $(build-dir), $(addsuffix .o,$(basename $(CSRCS) $(ASSRCS)))) + +# Create dependency files list from source files list. +dep-files := $(wildcard $(foreach f,$(obj-y),$(basename $(f)).d)) + +clean-files += $(wildcard $(obj-y)) +clean-files += $(dep-files) + +clean-dirs += $(call reverse,$(sort $(wildcard $(dir $(obj-y))))) + +# Default target. +.PHONY: all +ifeq ($(target_type),lib) +all: $(target) $(project).lss $(project).sym +else +ifeq ($(target_type),elf) +all: prebuild $(target) $(project).lss $(project).sym $(project).hex $(project).bin postbuild +endif +endif + +prebuild: +ifneq ($(strip $(PREBUILD_CMD)),) + @echo $(MSG_PREBUILD) + $(Q)$(PREBUILD_CMD) +endif + +postbuild: +ifneq ($(strip $(POSTBUILD_CMD)),) + @echo $(MSG_POSTBUILD) + $(Q)$(POSTBUILD_CMD) +endif + +# Clean up the project. +.PHONY: clean +clean: + @$(if $(strip $(clean-files)),echo $(MSG_CLEAN_FILES)) + $(if $(strip $(clean-files)),$(Q)$(RM) $(clean-files),) + @$(if $(strip $(clean-dirs)),echo $(MSG_CLEAN_DIRS)) +# Remove created directories, and make sure we only remove existing +# directories, since recursive rmdir might help us a bit on the way. +ifeq ($(os),Windows) + $(Q)$(if $(strip $(clean-dirs)), \ + $(RMDIR) $(strip $(subst /,\,$(clean-dirs)))) +else + $(Q)$(if $(strip $(clean-dirs)), \ + for directory in $(strip $(clean-dirs)); do \ + if [ -d "$$directory" ]; then \ + $(RMDIR) $$directory; \ + fi \ + done \ + ) +endif + +# Rebuild the project. +.PHONY: rebuild +rebuild: clean all + +.PHONY: objfiles +objfiles: $(obj-y) + +# Create object files from C source files. +$(build-dir)%.o: %.c $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(patsubst %/,%,$(dir $@)) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_COMPILING) + $(Q)$(CC) $(c_flags) -c $< -o $@ + +# Create object files from C++ source files. +$(build-dir)%.o: %.cpp $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(patsubst %/,%,$(dir $@)) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_COMPILING_CXX) + $(Q)$(CXX) $(cxx_flags) -c $< -o $@ + +# Preprocess and assemble: create object files from assembler source files. +$(build-dir)%.o: %.s $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(patsubst %/,%,$(dir $@)) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_ASSEMBLING) + $(Q)$(CC) $(a_flags) -c $< -o $@ + +# Preprocess and assemble: create object files from assembler source files. +$(build-dir)%.o: %.S $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(patsubst %/,%,$(dir $@)) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_ASSEMBLING) + $(Q)$(CC) $(a_flags) -c $< -o $@ + +# Include all dependency files to add depedency to all header files in use. +include $(dep-files) + +ifeq ($(target_type),lib) +# Archive object files into an archive +$(target): $(MAKEFILE_PATH) config.mk $(obj-y) + @echo $(MSG_ARCHIVING) + $(Q)$(AR) $(ar_flags) $@ $(obj-y) + @echo $(MSG_SIZE) + $(Q)$(SIZE) -Bxt $@ +else +ifeq ($(target_type),elf) +# Link the object files into an ELF file. Also make sure the target is rebuilt +# if the common Makefile.avr.in or project config.mk is changed. +$(target): $(MAKEFILE_PATH) config.mk $(obj-y) + @echo $(MSG_LINKING) + $(Q)$(LD) $(l_flags) $(obj-y) $(libflags-gnu-y) -o $@ + @echo $(MSG_SIZE) + $(Q)$(SIZE) -Ax $@ + $(Q)$(SIZE) -Bx $@ +endif +endif + +# Create extended function listing from target output file. +%.lss: $(target) + @echo $(MSG_EXTENDED_LISTING) + $(Q)$(OBJDUMP) -h -S $< > $@ + +# Create symbol table from target output file. +%.sym: $(target) + @echo $(MSG_SYMBOL_TABLE) + $(Q)$(NM) -n $< > $@ + +# Create Intel HEX image from ELF output file. +%.hex: $(target) + @echo $(MSG_IHEX_IMAGE) + $(Q)$(OBJCOPY) -O ihex $(flashflags-gnu-y) $< $@ + +# Create EEPROM Intel HEX image from ELF output file. +%.eep: $(target) + @echo $(MSG_EEPROM_IMAGE) + $(Q)$(OBJCOPY) $(eepromflags-gnu-y) -O ihex $< $@ || exit 0 + +# Create binary image from ELF output file. +%.bin: $(target) + @echo $(MSG_BINARY_IMAGE) + $(Q)$(OBJCOPY) -O binary $< $@ + +# Provide information about the detected host operating system. +.SECONDARY: info-os +info-os: + @echo $(MSG_INFO)$(os) build host detected + +# Build Doxygen generated documentation. +.PHONY: doc +doc: + @echo $(MSG_GENERATING_DOC) + $(Q)cd $(dir $(doccfg)) && $(DOCGEN) $(notdir $(doccfg)) + +# Clean Doxygen generated documentation. +.PHONY: cleandoc +cleandoc: + @$(if $(wildcard $(docdir)),echo $(MSG_CLEAN_DOC)) + $(Q)$(if $(wildcard $(docdir)),$(RM) --recursive $(docdir)) + +# Rebuild the Doxygen generated documentation. +.PHONY: rebuilddoc +rebuilddoc: cleandoc doc diff --git a/Fred_bootloader/src/ASF/common/utils/parts.h b/Fred_bootloader/src/ASF/common/utils/parts.h new file mode 100644 index 0000000000000000000000000000000000000000..d2319ae4707dbcb730cfe31714a3ec04f641d4d2 --- /dev/null +++ b/Fred_bootloader/src/ASF/common/utils/parts.h @@ -0,0 +1,1242 @@ +/** + * \file + * + * \brief Atmel part identification macros + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef ATMEL_PARTS_H +#define ATMEL_PARTS_H + +/** + * \defgroup part_macros_group Atmel part identification macros + * + * This collection of macros identify which series and families that the various + * Atmel parts belong to. These can be used to select part-dependent sections of + * code at compile time. + * + * @{ + */ + +/** + * \name Convenience macros for part checking + * @{ + */ +/* ! Check GCC and IAR part definition for 8-bit AVR */ +#define AVR8_PART_IS_DEFINED(part) \ + (defined(__ ## part ## __) || defined(__AVR_ ## part ## __)) + +/* ! Check GCC and IAR part definition for 32-bit AVR */ +#define AVR32_PART_IS_DEFINED(part) \ + (defined(__AT32 ## part ## __) || defined(__AVR32_ ## part ## __)) + +/* ! Check GCC and IAR part definition for SAM */ +#define SAM_PART_IS_DEFINED(part) (defined(__ ## part ## __)) +/** @} */ + +/** + * \defgroup uc3_part_macros_group AVR UC3 parts + * @{ + */ + +/** + * \name AVR UC3 A series + * @{ + */ +#define UC3A0 ( \ + AVR32_PART_IS_DEFINED(UC3A0128) || \ + AVR32_PART_IS_DEFINED(UC3A0256) || \ + AVR32_PART_IS_DEFINED(UC3A0512) \ + ) + +#define UC3A1 ( \ + AVR32_PART_IS_DEFINED(UC3A1128) || \ + AVR32_PART_IS_DEFINED(UC3A1256) || \ + AVR32_PART_IS_DEFINED(UC3A1512) \ + ) + +#define UC3A3 ( \ + AVR32_PART_IS_DEFINED(UC3A364) || \ + AVR32_PART_IS_DEFINED(UC3A364S) || \ + AVR32_PART_IS_DEFINED(UC3A3128) || \ + AVR32_PART_IS_DEFINED(UC3A3128S) || \ + AVR32_PART_IS_DEFINED(UC3A3256) || \ + AVR32_PART_IS_DEFINED(UC3A3256S) \ + ) + +#define UC3A4 ( \ + AVR32_PART_IS_DEFINED(UC3A464) || \ + AVR32_PART_IS_DEFINED(UC3A464S) || \ + AVR32_PART_IS_DEFINED(UC3A4128) || \ + AVR32_PART_IS_DEFINED(UC3A4128S) || \ + AVR32_PART_IS_DEFINED(UC3A4256) || \ + AVR32_PART_IS_DEFINED(UC3A4256S) \ + ) +/** @} */ + +/** + * \name AVR UC3 B series + * @{ + */ +#define UC3B0 ( \ + AVR32_PART_IS_DEFINED(UC3B064) || \ + AVR32_PART_IS_DEFINED(UC3B0128) || \ + AVR32_PART_IS_DEFINED(UC3B0256) || \ + AVR32_PART_IS_DEFINED(UC3B0512) \ + ) + +#define UC3B1 ( \ + AVR32_PART_IS_DEFINED(UC3B164) || \ + AVR32_PART_IS_DEFINED(UC3B1128) || \ + AVR32_PART_IS_DEFINED(UC3B1256) || \ + AVR32_PART_IS_DEFINED(UC3B1512) \ + ) +/** @} */ + +/** + * \name AVR UC3 C series + * @{ + */ +#define UC3C0 ( \ + AVR32_PART_IS_DEFINED(UC3C064C) || \ + AVR32_PART_IS_DEFINED(UC3C0128C) || \ + AVR32_PART_IS_DEFINED(UC3C0256C) || \ + AVR32_PART_IS_DEFINED(UC3C0512C) \ + ) + +#define UC3C1 ( \ + AVR32_PART_IS_DEFINED(UC3C164C) || \ + AVR32_PART_IS_DEFINED(UC3C1128C) || \ + AVR32_PART_IS_DEFINED(UC3C1256C) || \ + AVR32_PART_IS_DEFINED(UC3C1512C) \ + ) + +#define UC3C2 ( \ + AVR32_PART_IS_DEFINED(UC3C264C) || \ + AVR32_PART_IS_DEFINED(UC3C2128C) || \ + AVR32_PART_IS_DEFINED(UC3C2256C) || \ + AVR32_PART_IS_DEFINED(UC3C2512C) \ + ) +/** @} */ + +/** + * \name AVR UC3 D series + * @{ + */ +#define UC3D3 ( \ + AVR32_PART_IS_DEFINED(UC64D3) || \ + AVR32_PART_IS_DEFINED(UC128D3) \ + ) + +#define UC3D4 ( \ + AVR32_PART_IS_DEFINED(UC64D4) || \ + AVR32_PART_IS_DEFINED(UC128D4) \ + ) +/** @} */ + +/** + * \name AVR UC3 L series + * @{ + */ +#define UC3L0 ( \ + AVR32_PART_IS_DEFINED(UC3L016) || \ + AVR32_PART_IS_DEFINED(UC3L032) || \ + AVR32_PART_IS_DEFINED(UC3L064) \ + ) + +#define UC3L0128 ( \ + AVR32_PART_IS_DEFINED(UC3L0128) \ + ) + +#define UC3L0256 ( \ + AVR32_PART_IS_DEFINED(UC3L0256) \ + ) + +#define UC3L3 ( \ + AVR32_PART_IS_DEFINED(UC64L3U) || \ + AVR32_PART_IS_DEFINED(UC128L3U) || \ + AVR32_PART_IS_DEFINED(UC256L3U) \ + ) + +#define UC3L4 ( \ + AVR32_PART_IS_DEFINED(UC64L4U) || \ + AVR32_PART_IS_DEFINED(UC128L4U) || \ + AVR32_PART_IS_DEFINED(UC256L4U) \ + ) + +#define UC3L3_L4 (UC3L3 || UC3L4) +/** @} */ + +/** + * \name AVR UC3 families + * @{ + */ +/** AVR UC3 A family */ +#define UC3A (UC3A0 || UC3A1 || UC3A3 || UC3A4) + +/** AVR UC3 B family */ +#define UC3B (UC3B0 || UC3B1) + +/** AVR UC3 C family */ +#define UC3C (UC3C0 || UC3C1 || UC3C2) + +/** AVR UC3 D family */ +#define UC3D (UC3D3 || UC3D4) + +/** AVR UC3 L family */ +#define UC3L (UC3L0 || UC3L0128 || UC3L0256 || UC3L3_L4) +/** @} */ + +/** AVR UC3 product line */ +#define UC3 (UC3A || UC3B || UC3C || UC3D || UC3L) + +/** @} */ + +/** + * \defgroup xmega_part_macros_group AVR XMEGA parts + * @{ + */ + +/** + * \name AVR XMEGA A series + * @{ + */ +#define XMEGA_A1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1) \ + ) + +#define XMEGA_A3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3) \ + ) + +#define XMEGA_A3B ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3B) \ + ) + +#define XMEGA_A4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA AU series + * @{ + */ +#define XMEGA_A1U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1U) \ + ) + +#define XMEGA_A3U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3U) \ + ) + +#define XMEGA_A3BU ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3BU) \ + ) + +#define XMEGA_A4U ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega64A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A4U) \ + ) +/** @} */ + +/** + * \name AVR XMEGA B series + * @{ + */ +#define XMEGA_B1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B1) || \ + AVR8_PART_IS_DEFINED(ATxmega128B1) \ + ) + +#define XMEGA_B3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B3) || \ + AVR8_PART_IS_DEFINED(ATxmega128B3) \ + ) +/** @} */ + +/** + * \name AVR XMEGA C series + * @{ + */ +#define XMEGA_C3 ( \ + AVR8_PART_IS_DEFINED(ATxmega384C3) || \ + AVR8_PART_IS_DEFINED(ATxmega256C3) || \ + AVR8_PART_IS_DEFINED(ATxmega192C3) || \ + AVR8_PART_IS_DEFINED(ATxmega128C3) || \ + AVR8_PART_IS_DEFINED(ATxmega64C3) || \ + AVR8_PART_IS_DEFINED(ATxmega32C3) \ + ) + +#define XMEGA_C4 ( \ + AVR8_PART_IS_DEFINED(ATxmega32C4) || \ + AVR8_PART_IS_DEFINED(ATxmega16C4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA D series + * @{ + */ +#define XMEGA_D3 ( \ + AVR8_PART_IS_DEFINED(ATxmega32D3) || \ + AVR8_PART_IS_DEFINED(ATxmega64D3) || \ + AVR8_PART_IS_DEFINED(ATxmega128D3) || \ + AVR8_PART_IS_DEFINED(ATxmega192D3) || \ + AVR8_PART_IS_DEFINED(ATxmega256D3) || \ + AVR8_PART_IS_DEFINED(ATxmega384D3) \ + ) + +#define XMEGA_D4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16D4) || \ + AVR8_PART_IS_DEFINED(ATxmega32D4) || \ + AVR8_PART_IS_DEFINED(ATxmega64D4) || \ + AVR8_PART_IS_DEFINED(ATxmega128D4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA E series + * @{ + */ +#define XMEGA_E5 ( \ + AVR8_PART_IS_DEFINED(ATxmega8E5) || \ + AVR8_PART_IS_DEFINED(ATxmega16E5) || \ + AVR8_PART_IS_DEFINED(ATxmega32E5) \ + ) +/** @} */ + + +/** + * \name AVR XMEGA families + * @{ + */ +/** AVR XMEGA A family */ +#define XMEGA_A (XMEGA_A1 || XMEGA_A3 || XMEGA_A3B || XMEGA_A4) + +/** AVR XMEGA AU family */ +#define XMEGA_AU (XMEGA_A1U || XMEGA_A3U || XMEGA_A3BU || XMEGA_A4U) + +/** AVR XMEGA B family */ +#define XMEGA_B (XMEGA_B1 || XMEGA_B3) + +/** AVR XMEGA C family */ +#define XMEGA_C (XMEGA_C3 || XMEGA_C4) + +/** AVR XMEGA D family */ +#define XMEGA_D (XMEGA_D3 || XMEGA_D4) + +/** AVR XMEGA E family */ +#define XMEGA_E (XMEGA_E5) +/** @} */ + + +/** AVR XMEGA product line */ +#define XMEGA (XMEGA_A || XMEGA_AU || XMEGA_B || XMEGA_C || XMEGA_D || XMEGA_E) + +/** @} */ + +/** + * \defgroup mega_part_macros_group megaAVR parts + * + * \note These megaAVR groupings are based on the groups in AVR Libc for the + * part header files. They are not names of official megaAVR device series or + * families. + * + * @{ + */ + +/** + * \name ATmegaxx0/xx1 subgroups + * @{ + */ +#define MEGA_XX0 ( \ + AVR8_PART_IS_DEFINED(ATmega640) || \ + AVR8_PART_IS_DEFINED(ATmega1280) || \ + AVR8_PART_IS_DEFINED(ATmega2560) \ + ) + +#define MEGA_XX1 ( \ + AVR8_PART_IS_DEFINED(ATmega1281) || \ + AVR8_PART_IS_DEFINED(ATmega2561) \ + ) +/** @} */ + +/** + * \name megaAVR groups + * @{ + */ +/** ATmegaxx0/xx1 group */ +#define MEGA_XX0_1 (MEGA_XX0 || MEGA_XX1) + +/** ATmegaxx4 group */ +#define MEGA_XX4 ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) || \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** ATmegaxx4 group */ +#define MEGA_XX4_A ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) \ + ) + +/** ATmegaxx8 group */ +#define MEGA_XX8 ( \ + AVR8_PART_IS_DEFINED(ATmega48) || \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx8A/P/PA group */ +#define MEGA_XX8_A ( \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx group */ +#define MEGA_XX ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxxA/P/PA group */ +#define MEGA_XX_A ( \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) +/** ATmegaxxRFA1 group */ +#define MEGA_RFA1 ( \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** ATmegaxxRFR2 group */ +#define MEGA_RFR2 ( \ + AVR8_PART_IS_DEFINED(ATmega64RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega128RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega256RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega644RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega1284RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega2564RFR2) \ + ) + + +/** ATmegaxxRFxx group */ +#define MEGA_RF (MEGA_RFA1 || MEGA_RFR2) + +/** + * \name ATmegaxx_un0/un1/un2 subgroups + * @{ + */ +#define MEGA_XX_UN0 ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN1 ( \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN2 ( \ + AVR8_PART_IS_DEFINED(ATmega169P) || \ + AVR8_PART_IS_DEFINED(ATmega169PA) || \ + AVR8_PART_IS_DEFINED(ATmega329P) || \ + AVR8_PART_IS_DEFINED(ATmega329PA) \ + ) + +/** Devices added to complete megaAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define MEGA_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(AT90CAN128) || \ + AVR8_PART_IS_DEFINED(AT90CAN32) || \ + AVR8_PART_IS_DEFINED(AT90CAN64) || \ + AVR8_PART_IS_DEFINED(AT90PWM1) || \ + AVR8_PART_IS_DEFINED(AT90PWM216) || \ + AVR8_PART_IS_DEFINED(AT90PWM2B) || \ + AVR8_PART_IS_DEFINED(AT90PWM316) || \ + AVR8_PART_IS_DEFINED(AT90PWM3B) || \ + AVR8_PART_IS_DEFINED(AT90PWM81) || \ + AVR8_PART_IS_DEFINED(AT90USB1286) || \ + AVR8_PART_IS_DEFINED(AT90USB1287) || \ + AVR8_PART_IS_DEFINED(AT90USB162) || \ + AVR8_PART_IS_DEFINED(AT90USB646) || \ + AVR8_PART_IS_DEFINED(AT90USB647) || \ + AVR8_PART_IS_DEFINED(AT90USB82) || \ + AVR8_PART_IS_DEFINED(ATmega1284) || \ + AVR8_PART_IS_DEFINED(ATmega162) || \ + AVR8_PART_IS_DEFINED(ATmega164P) || \ + AVR8_PART_IS_DEFINED(ATmega165A) || \ + AVR8_PART_IS_DEFINED(ATmega165P) || \ + AVR8_PART_IS_DEFINED(ATmega165PA) || \ + AVR8_PART_IS_DEFINED(ATmega168P) || \ + AVR8_PART_IS_DEFINED(ATmega169A) || \ + AVR8_PART_IS_DEFINED(ATmega16M1) || \ + AVR8_PART_IS_DEFINED(ATmega16U2) || \ + AVR8_PART_IS_DEFINED(ATmega16U4) || \ + AVR8_PART_IS_DEFINED(ATmega256RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega324P) || \ + AVR8_PART_IS_DEFINED(ATmega325) || \ + AVR8_PART_IS_DEFINED(ATmega3250) || \ + AVR8_PART_IS_DEFINED(ATmega3250A) || \ + AVR8_PART_IS_DEFINED(ATmega3250P) || \ + AVR8_PART_IS_DEFINED(ATmega3250PA) || \ + AVR8_PART_IS_DEFINED(ATmega325A) || \ + AVR8_PART_IS_DEFINED(ATmega325P) || \ + AVR8_PART_IS_DEFINED(ATmega325PA) || \ + AVR8_PART_IS_DEFINED(ATmega329) || \ + AVR8_PART_IS_DEFINED(ATmega3290) || \ + AVR8_PART_IS_DEFINED(ATmega3290A) || \ + AVR8_PART_IS_DEFINED(ATmega3290P) || \ + AVR8_PART_IS_DEFINED(ATmega3290PA) || \ + AVR8_PART_IS_DEFINED(ATmega329A) || \ + AVR8_PART_IS_DEFINED(ATmega32M1) || \ + AVR8_PART_IS_DEFINED(ATmega32U2) || \ + AVR8_PART_IS_DEFINED(ATmega32U4) || \ + AVR8_PART_IS_DEFINED(ATmega48P) || \ + AVR8_PART_IS_DEFINED(ATmega644P) || \ + AVR8_PART_IS_DEFINED(ATmega645) || \ + AVR8_PART_IS_DEFINED(ATmega6450) || \ + AVR8_PART_IS_DEFINED(ATmega6450A) || \ + AVR8_PART_IS_DEFINED(ATmega6450P) || \ + AVR8_PART_IS_DEFINED(ATmega645A) || \ + AVR8_PART_IS_DEFINED(ATmega645P) || \ + AVR8_PART_IS_DEFINED(ATmega649) || \ + AVR8_PART_IS_DEFINED(ATmega6490) || \ + AVR8_PART_IS_DEFINED(ATmega6490A) || \ + AVR8_PART_IS_DEFINED(ATmega6490P) || \ + AVR8_PART_IS_DEFINED(ATmega649A) || \ + AVR8_PART_IS_DEFINED(ATmega649P) || \ + AVR8_PART_IS_DEFINED(ATmega64M1) || \ + AVR8_PART_IS_DEFINED(ATmega64RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega8) || \ + AVR8_PART_IS_DEFINED(ATmega8515) || \ + AVR8_PART_IS_DEFINED(ATmega8535) || \ + AVR8_PART_IS_DEFINED(ATmega88P) || \ + AVR8_PART_IS_DEFINED(ATmega8A) || \ + AVR8_PART_IS_DEFINED(ATmega8U2) \ + ) + +/** Unspecified group */ +#define MEGA_UNSPECIFIED (MEGA_XX_UN0 || MEGA_XX_UN1 || MEGA_XX_UN2 || \ + MEGA_UNCATEGORIZED) + +/** @} */ + +/** megaAVR product line */ +#define MEGA (MEGA_XX0_1 || MEGA_XX4 || MEGA_XX8 || MEGA_XX || MEGA_RF || \ + MEGA_UNSPECIFIED) + +/** @} */ + +/** + * \defgroup tiny_part_macros_group tinyAVR parts + * + * @{ + */ + +/** + * \name tinyAVR groups + * @{ + */ + +/** Devices added to complete tinyAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define TINY_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(ATtiny10) || \ + AVR8_PART_IS_DEFINED(ATtiny13) || \ + AVR8_PART_IS_DEFINED(ATtiny13A) || \ + AVR8_PART_IS_DEFINED(ATtiny1634) || \ + AVR8_PART_IS_DEFINED(ATtiny167) || \ + AVR8_PART_IS_DEFINED(ATtiny20) || \ + AVR8_PART_IS_DEFINED(ATtiny2313) || \ + AVR8_PART_IS_DEFINED(ATtiny2313A) || \ + AVR8_PART_IS_DEFINED(ATtiny24) || \ + AVR8_PART_IS_DEFINED(ATtiny24A) || \ + AVR8_PART_IS_DEFINED(ATtiny25) || \ + AVR8_PART_IS_DEFINED(ATtiny26) || \ + AVR8_PART_IS_DEFINED(ATtiny261) || \ + AVR8_PART_IS_DEFINED(ATtiny261A) || \ + AVR8_PART_IS_DEFINED(ATtiny4) || \ + AVR8_PART_IS_DEFINED(ATtiny40) || \ + AVR8_PART_IS_DEFINED(ATtiny4313) || \ + AVR8_PART_IS_DEFINED(ATtiny43U) || \ + AVR8_PART_IS_DEFINED(ATtiny44) || \ + AVR8_PART_IS_DEFINED(ATtiny44A) || \ + AVR8_PART_IS_DEFINED(ATtiny45) || \ + AVR8_PART_IS_DEFINED(ATtiny461) || \ + AVR8_PART_IS_DEFINED(ATtiny461A) || \ + AVR8_PART_IS_DEFINED(ATtiny48) || \ + AVR8_PART_IS_DEFINED(ATtiny5) || \ + AVR8_PART_IS_DEFINED(ATtiny828) || \ + AVR8_PART_IS_DEFINED(ATtiny84) || \ + AVR8_PART_IS_DEFINED(ATtiny84A) || \ + AVR8_PART_IS_DEFINED(ATtiny85) || \ + AVR8_PART_IS_DEFINED(ATtiny861) || \ + AVR8_PART_IS_DEFINED(ATtiny861A) || \ + AVR8_PART_IS_DEFINED(ATtiny87) || \ + AVR8_PART_IS_DEFINED(ATtiny88) || \ + AVR8_PART_IS_DEFINED(ATtiny9) \ + ) + +/** @} */ + +/** tinyAVR product line */ +#define TINY (TINY_UNCATEGORIZED) + +/** @} */ + +/** + * \defgroup sam_part_macros_group SAM parts + * @{ + */ + +/** + * \name SAM3S series + * @{ + */ +#define SAM3S1 ( \ + SAM_PART_IS_DEFINED(SAM3S1A) || \ + SAM_PART_IS_DEFINED(SAM3S1B) || \ + SAM_PART_IS_DEFINED(SAM3S1C) \ + ) + +#define SAM3S2 ( \ + SAM_PART_IS_DEFINED(SAM3S2A) || \ + SAM_PART_IS_DEFINED(SAM3S2B) || \ + SAM_PART_IS_DEFINED(SAM3S2C) \ + ) + +#define SAM3S4 ( \ + SAM_PART_IS_DEFINED(SAM3S4A) || \ + SAM_PART_IS_DEFINED(SAM3S4B) || \ + SAM_PART_IS_DEFINED(SAM3S4C) \ + ) + +#define SAM3S8 ( \ + SAM_PART_IS_DEFINED(SAM3S8B) || \ + SAM_PART_IS_DEFINED(SAM3S8C) \ + ) + +#define SAM3SD8 ( \ + SAM_PART_IS_DEFINED(SAM3SD8B) || \ + SAM_PART_IS_DEFINED(SAM3SD8C) \ + ) +/** @} */ + +/** + * \name SAM3U series + * @{ + */ +#define SAM3U1 ( \ + SAM_PART_IS_DEFINED(SAM3U1C) || \ + SAM_PART_IS_DEFINED(SAM3U1E) \ + ) + +#define SAM3U2 ( \ + SAM_PART_IS_DEFINED(SAM3U2C) || \ + SAM_PART_IS_DEFINED(SAM3U2E) \ + ) + +#define SAM3U4 ( \ + SAM_PART_IS_DEFINED(SAM3U4C) || \ + SAM_PART_IS_DEFINED(SAM3U4E) \ + ) +/** @} */ + +/** + * \name SAM3N series + * @{ + */ +#define SAM3N00 ( \ + SAM_PART_IS_DEFINED(SAM3N00A) || \ + SAM_PART_IS_DEFINED(SAM3N00B) \ + ) + +#define SAM3N0 ( \ + SAM_PART_IS_DEFINED(SAM3N0A) || \ + SAM_PART_IS_DEFINED(SAM3N0B) || \ + SAM_PART_IS_DEFINED(SAM3N0C) \ + ) + +#define SAM3N1 ( \ + SAM_PART_IS_DEFINED(SAM3N1A) || \ + SAM_PART_IS_DEFINED(SAM3N1B) || \ + SAM_PART_IS_DEFINED(SAM3N1C) \ + ) + +#define SAM3N2 ( \ + SAM_PART_IS_DEFINED(SAM3N2A) || \ + SAM_PART_IS_DEFINED(SAM3N2B) || \ + SAM_PART_IS_DEFINED(SAM3N2C) \ + ) + +#define SAM3N4 ( \ + SAM_PART_IS_DEFINED(SAM3N4A) || \ + SAM_PART_IS_DEFINED(SAM3N4B) || \ + SAM_PART_IS_DEFINED(SAM3N4C) \ + ) +/** @} */ + +/** + * \name SAM3X series + * @{ + */ +#define SAM3X4 ( \ + SAM_PART_IS_DEFINED(SAM3X4C) || \ + SAM_PART_IS_DEFINED(SAM3X4E) \ + ) + +#define SAM3X8 ( \ + SAM_PART_IS_DEFINED(SAM3X8C) || \ + SAM_PART_IS_DEFINED(SAM3X8E) || \ + SAM_PART_IS_DEFINED(SAM3X8H) \ + ) +/** @} */ + +/** + * \name SAM3A series + * @{ + */ +#define SAM3A4 ( \ + SAM_PART_IS_DEFINED(SAM3A4C) \ + ) + +#define SAM3A8 ( \ + SAM_PART_IS_DEFINED(SAM3A8C) \ + ) +/** @} */ + +/** + * \name SAM4S series + * @{ + */ +#define SAM4S2 ( \ + SAM_PART_IS_DEFINED(SAM4S2A) || \ + SAM_PART_IS_DEFINED(SAM4S2B) || \ + SAM_PART_IS_DEFINED(SAM4S2C) \ + ) + +#define SAM4S4 ( \ + SAM_PART_IS_DEFINED(SAM4S4A) || \ + SAM_PART_IS_DEFINED(SAM4S4B) || \ + SAM_PART_IS_DEFINED(SAM4S4C) \ + ) + +#define SAM4S8 ( \ + SAM_PART_IS_DEFINED(SAM4S8B) || \ + SAM_PART_IS_DEFINED(SAM4S8C) \ + ) + +#define SAM4S16 ( \ + SAM_PART_IS_DEFINED(SAM4S16B) || \ + SAM_PART_IS_DEFINED(SAM4S16C) \ + ) + +#define SAM4SA16 ( \ + SAM_PART_IS_DEFINED(SAM4SA16B) || \ + SAM_PART_IS_DEFINED(SAM4SA16C) \ + ) + +#define SAM4SD16 ( \ + SAM_PART_IS_DEFINED(SAM4SD16B) || \ + SAM_PART_IS_DEFINED(SAM4SD16C) \ + ) + +#define SAM4SD32 ( \ + SAM_PART_IS_DEFINED(SAM4SD32B) || \ + SAM_PART_IS_DEFINED(SAM4SD32C) \ + ) +/** @} */ + +/** + * \name SAM4L series + * @{ + */ +#define SAM4LS ( \ + SAM_PART_IS_DEFINED(SAM4LS2A) || \ + SAM_PART_IS_DEFINED(SAM4LS2B) || \ + SAM_PART_IS_DEFINED(SAM4LS2C) || \ + SAM_PART_IS_DEFINED(SAM4LS4A) || \ + SAM_PART_IS_DEFINED(SAM4LS4B) || \ + SAM_PART_IS_DEFINED(SAM4LS4C) || \ + SAM_PART_IS_DEFINED(SAM4LS8A) || \ + SAM_PART_IS_DEFINED(SAM4LS8B) || \ + SAM_PART_IS_DEFINED(SAM4LS8C) \ + ) + +#define SAM4LC ( \ + SAM_PART_IS_DEFINED(SAM4LC2A) || \ + SAM_PART_IS_DEFINED(SAM4LC2B) || \ + SAM_PART_IS_DEFINED(SAM4LC2C) || \ + SAM_PART_IS_DEFINED(SAM4LC4A) || \ + SAM_PART_IS_DEFINED(SAM4LC4B) || \ + SAM_PART_IS_DEFINED(SAM4LC4C) || \ + SAM_PART_IS_DEFINED(SAM4LC8A) || \ + SAM_PART_IS_DEFINED(SAM4LC8B) || \ + SAM_PART_IS_DEFINED(SAM4LC8C) \ + ) +/** @} */ + +/** + * \name SAMD20 series + * @{ + */ +#define SAMD20J ( \ + SAM_PART_IS_DEFINED(SAMD20J14) || \ + SAM_PART_IS_DEFINED(SAMD20J15) || \ + SAM_PART_IS_DEFINED(SAMD20J16) || \ + SAM_PART_IS_DEFINED(SAMD20J17) || \ + SAM_PART_IS_DEFINED(SAMD20J18) \ + ) + +#define SAMD20G ( \ + SAM_PART_IS_DEFINED(SAMD20G14) || \ + SAM_PART_IS_DEFINED(SAMD20G15) || \ + SAM_PART_IS_DEFINED(SAMD20G16) || \ + SAM_PART_IS_DEFINED(SAMD20G17) || \ + SAM_PART_IS_DEFINED(SAMD20G17U) || \ + SAM_PART_IS_DEFINED(SAMD20G18) || \ + SAM_PART_IS_DEFINED(SAMD20G18U) \ + ) + +#define SAMD20E ( \ + SAM_PART_IS_DEFINED(SAMD20E14) || \ + SAM_PART_IS_DEFINED(SAMD20E15) || \ + SAM_PART_IS_DEFINED(SAMD20E16) || \ + SAM_PART_IS_DEFINED(SAMD20E17) || \ + SAM_PART_IS_DEFINED(SAMD20E18) || \ + SAM_PART_IS_DEFINED(SAMD20E1F) \ + ) +/** @} */ + +/** + * \name SAMD21 series + * @{ + */ +#define SAMD21J ( \ + SAM_PART_IS_DEFINED(SAMD21J15A) || \ + SAM_PART_IS_DEFINED(SAMD21J16A) || \ + SAM_PART_IS_DEFINED(SAMD21J17A) || \ + SAM_PART_IS_DEFINED(SAMD21J18A) \ + ) + +#define SAMD21G ( \ + SAM_PART_IS_DEFINED(SAMD21G15A) || \ + SAM_PART_IS_DEFINED(SAMD21G16A) || \ + SAM_PART_IS_DEFINED(SAMD21G17A) || \ + SAM_PART_IS_DEFINED(SAMD21G18A) \ + ) + +#define SAMD21E ( \ + SAM_PART_IS_DEFINED(SAMD21E15A) || \ + SAM_PART_IS_DEFINED(SAMD21E16A) || \ + SAM_PART_IS_DEFINED(SAMD21E17A) || \ + SAM_PART_IS_DEFINED(SAMD21E18A) \ + ) +/** @} */ + +/** + * \name SAMR21 series + * @{ + */ +#define SAMR21G ( \ + SAM_PART_IS_DEFINED(SAMR21G16A) || \ + SAM_PART_IS_DEFINED(SAMR21G17A) || \ + SAM_PART_IS_DEFINED(SAMR21G18A) \ + ) + +#define SAMR21E ( \ + SAM_PART_IS_DEFINED(SAMR21E16A) || \ + SAM_PART_IS_DEFINED(SAMR21E17A) || \ + SAM_PART_IS_DEFINED(SAMR21E18A) \ + ) +/** @} */ + +/** + * \name SAMD10 series + * @{ + */ +#define SAMD10C ( \ + SAM_PART_IS_DEFINED(SAMD10C12A) || \ + SAM_PART_IS_DEFINED(SAMD10C13A) || \ + SAM_PART_IS_DEFINED(SAMD10C14A) \ + ) + +#define SAMD10DS ( \ + SAM_PART_IS_DEFINED(SAMD10D12AS) || \ + SAM_PART_IS_DEFINED(SAMD10D13AS) || \ + SAM_PART_IS_DEFINED(SAMD10D14AS) \ + ) + +#define SAMD10DM ( \ + SAM_PART_IS_DEFINED(SAMD10D12AM) || \ + SAM_PART_IS_DEFINED(SAMD10D13AM) || \ + SAM_PART_IS_DEFINED(SAMD10D14AM) \ + ) +/** @} */ + +/** + * \name SAMD11 series + * @{ + */ +#define SAMD11C ( \ + SAM_PART_IS_DEFINED(SAMD11C14A) \ + ) + +#define SAMD11DS ( \ + SAM_PART_IS_DEFINED(SAMD11D14AS) \ + ) + +#define SAMD11DM ( \ + SAM_PART_IS_DEFINED(SAMD11D14AM) \ + ) +/** @} */ + +/** + * \name SAM4E series + * @{ + */ +#define SAM4E8 ( \ + SAM_PART_IS_DEFINED(SAM4E8C) || \ + SAM_PART_IS_DEFINED(SAM4E8E) \ + ) + +#define SAM4E16 ( \ + SAM_PART_IS_DEFINED(SAM4E16C) || \ + SAM_PART_IS_DEFINED(SAM4E16E) \ + ) +/** @} */ + +/** + * \name SAM4N series + * @{ + */ +#define SAM4N8 ( \ + SAM_PART_IS_DEFINED(SAM4N8A) || \ + SAM_PART_IS_DEFINED(SAM4N8B) || \ + SAM_PART_IS_DEFINED(SAM4N8C) \ + ) + +#define SAM4N16 ( \ + SAM_PART_IS_DEFINED(SAM4N16B) || \ + SAM_PART_IS_DEFINED(SAM4N16C) \ + ) +/** @} */ + +/** + * \name SAM4C series + * @{ + */ +#define SAM4C8_0 ( \ + SAM_PART_IS_DEFINED(SAM4C8C_0) \ + ) + +#define SAM4C8_1 ( \ + SAM_PART_IS_DEFINED(SAM4C8C_1) \ + ) + +#define SAM4C8 (SAM4C8_0 || SAM4C8_1) + +#define SAM4C16_0 ( \ + SAM_PART_IS_DEFINED(SAM4C16C_0) \ + ) + +#define SAM4C16_1 ( \ + SAM_PART_IS_DEFINED(SAM4C16C_1) \ + ) + +#define SAM4C16 (SAM4C16_0 || SAM4C16_1) + +#define SAM4C32_0 ( \ + SAM_PART_IS_DEFINED(SAM4C32C_0) ||\ + SAM_PART_IS_DEFINED(SAM4C32E_0) \ + ) + +#define SAM4C32_1 ( \ + SAM_PART_IS_DEFINED(SAM4C32C_1) ||\ + SAM_PART_IS_DEFINED(SAM4C32E_1) \ + ) + + +#define SAM4C32 (SAM4C32_0 || SAM4C32_1) + +/** @} */ + +/** + * \name SAM4CM series + * @{ + */ +#define SAM4CMP8_0 ( \ + SAM_PART_IS_DEFINED(SAM4CMP8C_0) \ + ) + +#define SAM4CMP8_1 ( \ + SAM_PART_IS_DEFINED(SAM4CMP8C_1) \ + ) + +#define SAM4CMP8 (SAM4CMP8_0 || SAM4CMP8_1) + +#define SAM4CMP16_0 ( \ + SAM_PART_IS_DEFINED(SAM4CMP16C_0) \ + ) + +#define SAM4CMP16_1 ( \ + SAM_PART_IS_DEFINED(SAM4CMP16C_1) \ + ) + +#define SAM4CMP16 (SAM4CMP16_0 || SAM4CMP16_1) + +#define SAM4CMP32_0 ( \ + SAM_PART_IS_DEFINED(SAM4CMP32C_0) \ + ) + +#define SAM4CMP32_1 ( \ + SAM_PART_IS_DEFINED(SAM4CMP32C_1) \ + ) + +#define SAM4CMP32 (SAM4CMP32_0 || SAM4CMP32_1) + +#define SAM4CMS8_0 ( \ + SAM_PART_IS_DEFINED(SAM4CMS8C_0) \ + ) + +#define SAM4CMS8_1 ( \ + SAM_PART_IS_DEFINED(SAM4CMS8C_1) \ + ) + +#define SAM4CMS8 (SAM4CMS8_0 || SAM4CMS8_1) + +#define SAM4CMS16_0 ( \ + SAM_PART_IS_DEFINED(SAM4CMS16C_0) \ + ) + +#define SAM4CMS16_1 ( \ + SAM_PART_IS_DEFINED(SAM4CMS16C_1) \ + ) + +#define SAM4CMS16 (SAM4CMS16_0 || SAM4CMS16_1) + +#define SAM4CMS32_0 ( \ + SAM_PART_IS_DEFINED(SAM4CMS32C_0) \ + ) + +#define SAM4CMS32_1 ( \ + SAM_PART_IS_DEFINED(SAM4CMS32C_1) \ + ) + +#define SAM4CMS32 (SAM4CMS32_0 || SAM4CMS32_1) + +/** @} */ + +/** + * \name SAM4CP series + * @{ + */ +#define SAM4CP16_0 ( \ + SAM_PART_IS_DEFINED(SAM4CP16B_0) \ + ) + +#define SAM4CP16_1 ( \ + SAM_PART_IS_DEFINED(SAM4CP16B_1) \ + ) + +#define SAM4CP16 (SAM4CP16_0 || SAM4CP16_1) +/** @} */ + +/** + * \name SAMG series + * @{ + */ +#define SAMG51 ( \ + SAM_PART_IS_DEFINED(SAMG51G18) \ + ) + +#define SAMG53 ( \ + SAM_PART_IS_DEFINED(SAMG53G19) ||\ + SAM_PART_IS_DEFINED(SAMG53N19) \ + ) + +#define SAMG54 ( \ + SAM_PART_IS_DEFINED(SAMG54G19) ||\ + SAM_PART_IS_DEFINED(SAMG54J19) ||\ + SAM_PART_IS_DEFINED(SAMG54N19) \ +) +/** @} */ +/** + * \name SAM families + * @{ + */ +/** SAM3S Family */ +#define SAM3S (SAM3S1 || SAM3S2 || SAM3S4 || SAM3S8 || SAM3SD8) + +/** SAM3U Family */ +#define SAM3U (SAM3U1 || SAM3U2 || SAM3U4) + +/** SAM3N Family */ +#define SAM3N (SAM3N00 || SAM3N0 || SAM3N1 || SAM3N2 || SAM3N4) + +/** SAM3XA Family */ +#define SAM3XA (SAM3X4 || SAM3X8 || SAM3A4 || SAM3A8) + +/** SAM4S Family */ +#define SAM4S (SAM4S2 || SAM4S4 || SAM4S8 || SAM4S16 || SAM4SA16 || SAM4SD16 || SAM4SD32) + +/** SAM4L Family */ +#define SAM4L (SAM4LS || SAM4LC) + +/** SAMD20 Family */ +#define SAMD20 (SAMD20J || SAMD20G || SAMD20E) + +/** SAMD21 Family */ +#define SAMD21 (SAMD21J || SAMD21G || SAMD21E) + +/** SAMD10 Family */ +#define SAMD10 (SAMD10C || SAMD10DS || SAMD10DM) + +/** SAMD11 Family */ +#define SAMD11 (SAMD11C || SAMD11DS || SAMD11DM) + +/** SAMD Family */ +#define SAMD (SAMD20 || SAMD21 || SAMD10 || SAMD11) + +/** SAMR21 Family */ +#define SAMR21 (SAMR21G || SAMR21E) + +/** SAM4E Family */ +#define SAM4E (SAM4E8 || SAM4E16) + +/** SAM4N Family */ +#define SAM4N (SAM4N8 || SAM4N16) + +/** SAM4C Family */ +#define SAM4C_0 (SAM4C8_0 || SAM4C16_0 || SAM4C32_0) +#define SAM4C_1 (SAM4C8_1 || SAM4C16_1 || SAM4C32_1) +#define SAM4C (SAM4C8 || SAM4C16 || SAM4C32) + +/** SAM4CM Family */ +#define SAM4CM_0 (SAM4CMP8_0 || SAM4CMP16_0 || SAM4CMP32_0 || SAM4CMS8_0 || \ + SAM4CMS16_0 || SAM4CMS32_0) +#define SAM4CM_1 (SAM4CMP8_1 || SAM4CMP16_1 || SAM4CMP32_1 || SAM4CMS8_1 || \ + SAM4CMS16_1 || SAM4CMS32_1) +#define SAM4CM (SAM4CMP8 || SAM4CMP16 || SAM4CMP32 || SAM4CMS8 || \ + SAM4CMS16 || SAM4CMS32) + +/** SAM4CP Family */ +#define SAM4CP_0 (SAM4CP16_0) +#define SAM4CP_1 (SAM4CP16_1) +#define SAM4CP (SAM4CP16) + +/** SAMG Family */ +#define SAMG (SAMG51 || SAMG53 || SAMG54) + +/** SAM0 product line (cortex-m0+) */ +#define SAM0 (SAMD20 || SAMD21 || SAMR21 || SAMD10 || SAMD11) + +/** @} */ + +/** SAM product line */ +#define SAM (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S || SAM4L || SAM4E || \ + SAM0 || SAM4N || SAM4C || SAM4CM || SAM4CP || SAMG) + +/** @} */ + +/** @} */ + +/** @} */ + +#endif /* ATMEL_PARTS_H */ diff --git a/Fred_bootloader/src/ASF/xmega/drivers/cpu/ccp.h b/Fred_bootloader/src/ASF/xmega/drivers/cpu/ccp.h new file mode 100644 index 0000000000000000000000000000000000000000..45bb10c7dfaca307a9b0c86c5ae51a609a9bee1d --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/drivers/cpu/ccp.h @@ -0,0 +1,120 @@ +/** + * \file + * + * \brief Configuration Change Protection write functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef CPU_CCP_H +#define CPU_CCP_H +#include <compiler.h> + +/** + * \defgroup ccp_group Configuration Change Protection + * + * See \ref xmega_ccp_quickstart. + * + * Function for writing to protected IO registers. + * @{ + */ + +#if defined(__DOXYGEN__) +//! \name IAR Memory Model defines. +//@{ + +/** + * \def CONFIG_MEMORY_MODEL_TINY + * \brief Configuration symbol to enable 8 bit pointers. + * + */ +# define CONFIG_MEMORY_MODEL_TINY + +/** + * \def CONFIG_MEMORY_MODEL_SMALL + * \brief Configuration symbol to enable 16 bit pointers. + * \note If no memory model is defined, SMALL is default. + * + */ +# define CONFIG_MEMORY_MODEL_SMALL + + +/** + * \def CONFIG_MEMORY_MODEL_LARGE + * \brief Configuration symbol to enable 24 bit pointers. + * + */ +# define CONFIG_MEMORY_MODEL_LARGE + +//@} +#endif + + +/** + * \brief Write to a CCP-protected 8-bit I/O register + * + * \param addr Address of the I/O register + * \param value Value to be written + * + * \note Using IAR Embedded workbench, the choice of memory model has an impact + * on calling convention. The memory model is not visible to the + * preprocessor, so it must be defined in the Assembler preprocessor directives. + */ +extern void ccp_write_io(void *addr, uint8_t value); + +/** @} */ + +/** + * \page xmega_ccp_quickstart Quick start guide for CCP driver + * + * This is the quick start guide for the \ref ccp_group + * "Configuration Change Protection (CCP) driver", with step-by-step + * instructions on how to use the driver. + * + * The use case contains a code fragment, and this can be copied into, e.g., + * the main application function. + * + * \section ccp_basic_use_case Basic use case + * In this use case, the CCP is used to write to the protected XMEGA Clock + * Control register. + * + * \subsection ccp_basic_use_case_setup_flow Workflow + * -# call CCP write io to change system clock selection: + * - \code ccp_write_io((uint8_t *)&CLK.CTRL, CLK_SCLKSEL_RC32M_gc); \endcode + */ + +#endif /* CPU_CCP_H */ diff --git a/Fred_bootloader/src/ASF/xmega/drivers/cpu/ccp.s b/Fred_bootloader/src/ASF/xmega/drivers/cpu/ccp.s new file mode 100644 index 0000000000000000000000000000000000000000..3f7e27979cb703e9afe1fc0987809dd6928070dd --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/drivers/cpu/ccp.s @@ -0,0 +1,100 @@ +/** + * \file + * + * \brief Configuration Change Protection + * + * Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#include <assembler.h> + +//! Value to write to CCP for access to protected IO registers. +#define CCP_IOREG 0xd8 + + /* + * GNU and IAR use different calling conventions. Since this is + * a very small and simple function to begin with, it's easier + * to implement it twice than to deal with the differences + * within a single implementation. + * + * Interrupts are disabled by hardware during the timed + * sequence, so there's no need to save/restore interrupt state. + */ + + PUBLIC_FUNCTION(ccp_write_io) + +#if defined(__GNUC__) + + out RAMPZ, r1 // Reset bits 23:16 of Z + movw r30, r24 // Load addr into Z + ldi r18, CCP_IOREG // Load magic CCP value + out CCP, r18 // Start CCP handshake + st Z, r22 // Write value to I/O register + ret // Return to caller + +#elif defined(__IAR_SYSTEMS_ASM__) + +# if !defined(CONFIG_MEMORY_MODEL_TINY) && !defined(CONFIG_MEMORY_MODEL_SMALL) \ + && !defined(CONFIG_MEMORY_MODEL_LARGE) +# define CONFIG_MEMORY_MODEL_SMALL +# endif + ldi r20, 0 + out RAMPZ, r20 // Reset bits 23:16 of Z +# if defined(CONFIG_MEMORY_MODEL_TINY) + mov r31, r20 // Reset bits 8:15 of Z + mov r30, r16 // Load addr into Z +# else + movw r30, r16 // Load addr into Z +# endif + ldi r21, CCP_IOREG // Load magic CCP value + out CCP, r21 // Start CCP handshake +# if defined(CONFIG_MEMORY_MODEL_TINY) + st Z, r17 // Write value to I/O register +# elif defined(CONFIG_MEMORY_MODEL_SMALL) + st Z, r18 // Write value to I/O register +# elif defined(CONFIG_MEMORY_MODEL_LARGE) + st Z, r19 // Write value to I/O register +# else +# error Unknown memory model in use, no idea how registers should be accessed +# endif + ret +#else +# error Unknown assembler +#endif + + END_FUNC(ccp_write_io) + END_FILE() diff --git a/Fred_bootloader/src/ASF/xmega/drivers/cpu/xmega_reset_cause.h b/Fred_bootloader/src/ASF/xmega/drivers/cpu/xmega_reset_cause.h new file mode 100644 index 0000000000000000000000000000000000000000..ed10d3b45929dceb3ec6d9d032bb35e702c49cc3 --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/drivers/cpu/xmega_reset_cause.h @@ -0,0 +1,105 @@ +/** + * \file + * + * \brief Chip-specific reset cause functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_DRIVERS_CPU_RESET_CAUSE_H +#define XMEGA_DRIVERS_CPU_RESET_CAUSE_H + +#include "compiler.h" +#include "ccp.h" + +/** + * \ingroup reset_cause_group + * \defgroup xmega_reset_cause_group XMEGA reset cause + * + * See \ref reset_cause_quickstart + * + * @{ + */ + +/** + * \brief Chip-specific reset cause type capable of holding all chip reset + * causes. Typically reflects the size of the reset cause register. + */ +typedef uint8_t reset_cause_t; + +//! \internal \name Chip-specific reset causes +//@{ +//! \internal External reset cause +#define CHIP_RESET_CAUSE_EXTRST RST_EXTRF_bm +//! \internal brown-out detected reset cause, same as for CPU +#define CHIP_RESET_CAUSE_BOD_IO RST_BORF_bm +//! \internal Brown-out detected reset cause, same as for I/O +#define CHIP_RESET_CAUSE_BOD_CPU RST_BORF_bm +//! \internal On-chip debug system reset cause +#define CHIP_RESET_CAUSE_OCD RST_PDIRF_bm +//! \internal Power-on-reset reset cause +#define CHIP_RESET_CAUSE_POR RST_PORF_bm +//! \internal Software reset reset cause +#define CHIP_RESET_CAUSE_SOFT RST_SRF_bm +//! \internal Spike detected reset cause +#define CHIP_RESET_CAUSE_SPIKE RST_SDRF_bm +//! \internal Watchdog timeout reset cause +#define CHIP_RESET_CAUSE_WDT RST_WDRF_bm +//@} + +static inline reset_cause_t reset_cause_get_causes(void) +{ + return (reset_cause_t)RST.STATUS; +} + +static inline void reset_cause_clear_causes(reset_cause_t causes) +{ + RST.STATUS = causes; +} + +static inline void reset_do_soft_reset(void) +{ + ccp_write_io((void *)&RST.CTRL, RST_SWRST_bm); + + while (1) { + /* Intentionally empty. */ + } +} + +//! @} + +#endif /* XMEGA_DRIVERS_CPU_RESET_CAUSE_H */ diff --git a/Fred_bootloader/src/ASF/xmega/drivers/nvm/nvm.c b/Fred_bootloader/src/ASF/xmega/drivers/nvm/nvm.c new file mode 100644 index 0000000000000000000000000000000000000000..8ebc18449a7d2fdadb319b0fb5afaf48ae68cf11 --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/drivers/nvm/nvm.c @@ -0,0 +1,707 @@ +/** + * \file + * + * \brief Non Volatile Memory controller driver + * + * Copyright (C) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#include "compiler.h" +#include "ccp.h" +#include "nvm.h" +#include <string.h> + +/** + * \weakgroup nvm_signature_group + * @{ + */ + +/** + * \brief Read the device serial + * + * This function returns the device serial stored in the device. + * + * \note This function is modifying the NVM.CMD register. + * If the application are using program space access in interrupts + * (__flash pointers in IAR EW or pgm_read_byte in GCC) interrupts + * needs to be disabled when running EEPROM access functions. If not + * the program space reads will be corrupted. + * + * \retval storage Pointer to the structure where to store the device serial + */ +void nvm_read_device_serial(struct nvm_device_serial *storage) +{ + storage->lotnum0 = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(LOTNUM0)); + storage->lotnum1 = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(LOTNUM1)); + storage->lotnum2 = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(LOTNUM2)); + storage->lotnum3 = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(LOTNUM3)); + storage->lotnum4 = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(LOTNUM4)); + storage->lotnum5 = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(LOTNUM5)); + + storage->wafnum = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(WAFNUM)); + + storage->coordx0 = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(COORDX0)); + storage->coordx1 = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(COORDX1)); + storage->coordy0 = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(COORDY0)); + storage->coordy1 = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(COORDY1)); +} + +//! @} + +/** + * \weakgroup nvm_eeprom_group + * @{ + */ + +/** + * \brief Read one byte from EEPROM using mapped access. + * + * This function reads one byte from EEPROM using mapped access. + * + * \param addr EEPROM address, between 0 and EEPROM_SIZE + * + * \return Byte value read from EEPROM. + */ +uint8_t nvm_eeprom_read_byte(eeprom_addr_t addr) +{ + uint8_t data; + Assert(addr <= EEPROM_SIZE); + + /* Wait until NVM is ready */ + nvm_wait_until_ready(); + eeprom_enable_mapping(); + data = *(uint8_t*)(addr + MAPPED_EEPROM_START), + eeprom_disable_mapping(); + return data; +} + +/** + * \brief Read buffer within the eeprom + * + * \param address the address to where to read + * \param buf pointer to the data + * \param len the number of bytes to read + */ +void nvm_eeprom_read_buffer(eeprom_addr_t address, void *buf, uint16_t len) +{ + nvm_wait_until_ready(); + eeprom_enable_mapping(); + memcpy( buf,(void*)(address+MAPPED_EEPROM_START), len ); + eeprom_disable_mapping(); +} + + +/** + * \brief Write one byte to EEPROM using IO mapping. + * + * This function writes one byte to EEPROM using IO-mapped access. + * This function will cancel all ongoing EEPROM page buffer loading + * operations, if any. + * + * \param address EEPROM address (max EEPROM_SIZE) + * \param value Byte value to write to EEPROM. + */ +void nvm_eeprom_write_byte(eeprom_addr_t address, uint8_t value) +{ + uint8_t old_cmd; + + Assert(address <= EEPROM_SIZE); + /* Flush buffer to make sure no unintentional data is written and load + * the "Page Load" command into the command register. + */ + old_cmd = NVM.CMD; + nvm_eeprom_flush_buffer(); + // Wait until NVM is ready + nvm_wait_until_ready(); + nvm_eeprom_load_byte_to_buffer(address, value); + + // Set address to write to + NVM.ADDR2 = 0x00; + NVM.ADDR1 = (address >> 8) & 0xFF; + NVM.ADDR0 = address & 0xFF; + + /* Issue EEPROM Atomic Write (Erase&Write) command. Load command, write + * the protection signature and execute command. + */ + NVM.CMD = NVM_CMD_ERASE_WRITE_EEPROM_PAGE_gc; + nvm_exec(); + NVM.CMD = old_cmd; +} + +/** + * \brief Write buffer within the eeprom + * + * \param address the address to where to write + * \param buf pointer to the data + * \param len the number of bytes to write + */ +void nvm_eeprom_erase_and_write_buffer(eeprom_addr_t address, const void *buf, uint16_t len) +{ + while (len) { + if (((address%EEPROM_PAGE_SIZE)==0) && (len>=EEPROM_PAGE_SIZE)) { + // A full page can be written + nvm_eeprom_load_page_to_buffer((uint8_t*)buf); + nvm_eeprom_atomic_write_page(address/EEPROM_PAGE_SIZE); + address += EEPROM_PAGE_SIZE; + buf = (uint8_t*)buf + EEPROM_PAGE_SIZE; + len -= EEPROM_PAGE_SIZE; + } else { + nvm_eeprom_write_byte(address++, *(uint8_t*)buf); + buf = (uint8_t*)buf + 1; + len--; + } + } +} + + +/** + * \brief Flush temporary EEPROM page buffer. + * + * This function flushes the EEPROM page buffers. This function will cancel + * any ongoing EEPROM page buffer loading operations, if any. + * This function also works for memory mapped EEPROM access. + * + * \note An EEPROM write operations will automatically flush the buffer for you. + * \note The function does not preserve the value of the NVM.CMD register + */ +void nvm_eeprom_flush_buffer(void) +{ + // Wait until NVM is ready + nvm_wait_until_ready(); + + // Flush EEPROM page buffer if necessary + if ((NVM.STATUS & NVM_EELOAD_bm) != 0) { + NVM.CMD = NVM_CMD_ERASE_EEPROM_BUFFER_gc; + nvm_exec(); + } +} + +/** + * \brief Load single byte into temporary page buffer. + * + * This function loads one byte into the temporary EEPROM page buffers. + * If memory mapped EEPROM is enabled, this function will not work. + * Make sure that the buffer is flushed before starting to load bytes. + * Also, if multiple bytes are loaded into the same location, they will + * be ANDed together, thus 0x55 and 0xAA will result in 0x00 in the buffer. + * + * \note Only one page buffer exist, thus only one page can be loaded with + * data and programmed into one page. If data needs to be written to + * different pages, the loading and writing needs to be repeated. + * + * \param byte_addr EEPROM Byte address, between 0 and EEPROM_PAGE_SIZE. + * \param value Byte value to write to buffer. + */ +void nvm_eeprom_load_byte_to_buffer(uint8_t byte_addr, uint8_t value) +{ + // Wait until NVM is ready + nvm_wait_until_ready(); + + eeprom_enable_mapping(); + *(uint8_t*)(byte_addr + MAPPED_EEPROM_START) = value; + eeprom_disable_mapping(); +} + + +/** + * \brief Load entire page into temporary EEPROM page buffer. + * + * This function loads an entire EEPROM page from an SRAM buffer to + * the EEPROM page buffers. If memory mapped EEPROM is enabled, this + * function will not work. Make sure that the buffer is flushed before + * starting to load bytes. + * + * \note Only the lower part of the address is used to address the buffer. + * Therefore, no address parameter is needed. In the end, the data + * is written to the EEPROM page given by the address parameter to the + * EEPROM write page operation. + * + * \param values Pointer to SRAM buffer containing an entire page. + */ +void nvm_eeprom_load_page_to_buffer(const uint8_t *values) +{ + // Wait until NVM is ready + nvm_wait_until_ready(); + + // Load multiple bytes into page buffer + uint8_t i; + for (i = 0; i < EEPROM_PAGE_SIZE; ++i) { + nvm_eeprom_load_byte_to_buffer(i, *values); + ++values; + } +} + +/** + * \brief Erase and write bytes from page buffer into EEPROM. + * + * This function writes the contents of an already loaded EEPROM page + * buffer into EEPROM memory. + * + * As this is an atomic write, the page in EEPROM will be erased + * automatically before writing. Note that only the page buffer locations + * that have been loaded will be used when writing to EEPROM. Page buffer + * locations that have not been loaded will be left untouched in EEPROM. + * + * \param page_addr EEPROM Page address, between 0 and EEPROM_SIZE/EEPROM_PAGE_SIZE + */ +void nvm_eeprom_atomic_write_page(uint8_t page_addr) +{ + // Wait until NVM is ready + nvm_wait_until_ready(); + + // Calculate page address + uint16_t address = (uint16_t)(page_addr * EEPROM_PAGE_SIZE); + + Assert(address <= EEPROM_SIZE); + + // Set address + NVM.ADDR2 = 0x00; + NVM.ADDR1 = (address >> 8) & 0xFF; + NVM.ADDR0 = address & 0xFF; + + // Issue EEPROM Atomic Write (Erase&Write) command + nvm_issue_command(NVM_CMD_ERASE_WRITE_EEPROM_PAGE_gc); +} + +/** + * \brief Write (without erasing) EEPROM page. + * + * This function writes the contents of an already loaded EEPROM page + * buffer into EEPROM memory. + * + * As this is a split write, the page in EEPROM will _not_ be erased + * before writing. + * + * \param page_addr EEPROM Page address, between 0 and EEPROM_SIZE/EEPROM_PAGE_SIZE + */ +void nvm_eeprom_split_write_page(uint8_t page_addr) +{ + // Wait until NVM is ready + nvm_wait_until_ready(); + + // Calculate page address + uint16_t address = (uint16_t)(page_addr * EEPROM_PAGE_SIZE); + + Assert(address <= EEPROM_SIZE); + + // Set address + NVM.ADDR2 = 0x00; + NVM.ADDR1 = (address >> 8) & 0xFF; + NVM.ADDR0 = address & 0xFF; + + // Issue EEPROM Split Write command + nvm_issue_command(NVM_CMD_WRITE_EEPROM_PAGE_gc); +} + +/** + * \brief Fill temporary EEPROM page buffer with value. + * + * This fills the the EEPROM page buffers with a given value. + * If memory mapped EEPROM is enabled, this function will not work. + * + * \note Only the lower part of the address is used to address the buffer. + * Therefore, no address parameter is needed. In the end, the data + * is written to the EEPROM page given by the address parameter to the + * EEPROM write page operation. + * + * \param value Value to copy to the page buffer. + */ +void nvm_eeprom_fill_buffer_with_value(uint8_t value) +{ + nvm_eeprom_flush_buffer(); + // Wait until NVM is ready + nvm_wait_until_ready(); + // Load multiple bytes into page buffer + uint8_t i; + for (i = 0; i < EEPROM_PAGE_SIZE; ++i) { + nvm_eeprom_load_byte_to_buffer(i, value); + } +} + +/** + * \brief Erase bytes from EEPROM page. + * + * This function erases bytes from one EEPROM page, so that every location + * written to in the page buffer reads 0xFF. + * + * \param page_addr EEPROM Page address, between 0 and EEPROM_SIZE/EEPROM_PAGE_SIZE + */ +void nvm_eeprom_erase_bytes_in_page(uint8_t page_addr) +{ + // Wait until NVM is ready + nvm_wait_until_ready(); + + // Calculate page address + uint16_t address = (uint16_t)(page_addr * EEPROM_PAGE_SIZE); + + Assert(address <= EEPROM_SIZE); + + // Set address + NVM.ADDR2 = 0x00; + NVM.ADDR1 = (address >> 8) & 0xFF; + NVM.ADDR0 = address & 0xFF; + + // Issue EEPROM Erase command + nvm_issue_command(NVM_CMD_ERASE_EEPROM_PAGE_gc); +} + +/** + * \brief Erase EEPROM page. + * + * This function erases one EEPROM page, so that every location reads 0xFF. + * + * \param page_addr EEPROM Page address, between 0 and EEPROM_SIZE/EEPROM_PAGE_SIZE + */ +void nvm_eeprom_erase_page(uint8_t page_addr) +{ + // Mark all addresses to be deleted + nvm_eeprom_fill_buffer_with_value(0xff); + // Erase bytes + nvm_eeprom_erase_bytes_in_page(page_addr); +} + + +/** + * \brief Erase bytes from all EEPROM pages. + * + * This function erases bytes from all EEPROM pages, so that every location + * written to in the page buffer reads 0xFF. + */ +void nvm_eeprom_erase_bytes_in_all_pages(void) +{ + // Wait until NVM is ready + nvm_wait_until_ready(); + + // Issue EEPROM Erase All command + nvm_issue_command(NVM_CMD_ERASE_EEPROM_gc); +} + +/** + * \brief Erase entire EEPROM memory. + * + * This function erases the entire EEPROM memory block to 0xFF. + */ +void nvm_eeprom_erase_all(void) +{ + // Mark all addresses to be deleted + nvm_eeprom_fill_buffer_with_value(0xff); + // Erase all pages + nvm_eeprom_erase_bytes_in_all_pages(); +} + +//! @} + + +//! @} + + +/** + * \weakgroup nvm_flash_group + * @{ + */ + +/** + * \brief Issue flash range CRC command + * + * This function sets the FLASH range CRC command in the NVM.CMD register. + * It then loads the start and end byte address of the part of FLASH to + * generate a CRC-32 for into the ADDR and DATA registers and finally performs + * the execute command. + * + * \note Should only be called from the CRC module. The function saves and + * restores the NVM.CMD register, but if this + * function is called from an interrupt, interrupts must be disabled + * before this function is called. + * + * \param start_addr end byte address + * \param end_addr start byte address + */ +void nvm_issue_flash_range_crc(flash_addr_t start_addr, flash_addr_t end_addr) +{ + uint8_t old_cmd; + // Save current nvm command + old_cmd = NVM.CMD; + + // Load the NVM CMD register with the Flash Range CRC command + NVM.CMD = NVM_CMD_FLASH_RANGE_CRC_gc; + + // Load the start byte address in the NVM Address Register + NVM.ADDR0 = start_addr & 0xFF; + NVM.ADDR1 = (start_addr >> 8) & 0xFF; +#if (FLASH_SIZE >= 0x10000UL) + NVM.ADDR2 = (start_addr >> 16) & 0xFF; +#endif + + // Load the end byte address in NVM Data Register + NVM.DATA0 = end_addr & 0xFF; + NVM.DATA1 = (end_addr >> 8) & 0xFF; +#if (FLASH_SIZE >= 0x10000UL) + NVM.DATA2 = (end_addr >> 16) & 0xFF; +#endif + + // Execute command + ccp_write_io((uint8_t *)&NVM.CTRLA, NVM_CMDEX_bm); + + // Restore command register + NVM.CMD = old_cmd; +} + +/** + * \brief Read buffer within the application section + * + * \param address the address to where to read + * \param buf pointer to the data + * \param len the number of bytes to read + */ +void nvm_flash_read_buffer(flash_addr_t address, void *buf, uint16_t len) +{ +#if (FLASH_SIZE>0x10000) + uint32_t opt_address = address; +#else + uint16_t opt_address = (uint16_t)address; +#endif + nvm_wait_until_ready(); + while ( len ) { + *(uint8_t*)buf = nvm_flash_read_byte(opt_address); + buf=(uint8_t*)buf+1; + opt_address++; + len--; + } +} + +/** + * \brief Read buffer within the user section + * + * \param address the address to where to read + * \param buf pointer to the data + * \param len the number of bytes to read + */ +void nvm_user_sig_read_buffer(flash_addr_t address, void *buf, uint16_t len) +{ + uint16_t opt_address = (uint16_t)address&(FLASH_PAGE_SIZE-1); + while ( len ) { + *(uint8_t*)buf = nvm_read_user_signature_row(opt_address); + buf=(uint8_t*)buf+1; + opt_address++; + len--; + } +} + +/** + * \brief Write specific parts of user flash section + * + * \param address the address to where to write + * \param buf pointer to the data + * \param len the number of bytes to write + * \param b_blank_check if True then the page flash is checked before write + * to run or not the erase page command. + * + * Set b_blank_check to false if all application flash is erased before. + */ +void nvm_user_sig_write_buffer(flash_addr_t address, const void *buf, + uint16_t len, bool b_blank_check) +{ + uint16_t w_value; + uint16_t page_pos; + uint16_t opt_address = (uint16_t)address; + bool b_flag_erase = false; + + while ( len ) { + for (page_pos=0; page_pos<FLASH_PAGE_SIZE; page_pos+=2 ) { + if (b_blank_check) { + // Read flash to know if the erase command is mandatory + LSB(w_value) = nvm_read_user_signature_row(page_pos); + MSB(w_value) = nvm_read_user_signature_row(page_pos+1); + if (w_value!=0xFFFF) { + b_flag_erase = true; // The page is not empty + } + }else{ + w_value = 0xFFFF; + } + // Update flash buffer + if (len) { + if (opt_address == page_pos) { + // The MSB of flash word must be changed + // because the address is even + len--; + opt_address++; + LSB(w_value)=*(uint8_t*)buf; + buf=(uint8_t*)buf+1; + } + } + if (len) { + if (opt_address == (page_pos+1)) { + // The LSB of flash word must be changed + // because the user buffer is not empty + len--; + opt_address++; + MSB(w_value)=*(uint8_t*)buf; + buf=(uint8_t*)buf+1; + } + } + // Load flash buffer + nvm_flash_load_word_to_buffer(page_pos,w_value); + } + } + // Write flash buffer + if (b_flag_erase) { + nvm_flash_erase_user_section(); + } + nvm_flash_write_user_page(); +} + +/** + * \brief Erase and write specific parts of application flash section + * + * \param address the address to where to write + * \param buf pointer to the data + * \param len the number of bytes to write + * \param b_blank_check if True then the page flash is checked before write + * to run or not the erase page command. + * + * Set b_blank_check to false if all application flash is erased before. + */ +void nvm_flash_erase_and_write_buffer(flash_addr_t address, const void *buf, + uint16_t len, bool b_blank_check) +{ + uint16_t w_value; + uint16_t page_pos; + bool b_flag_erase; +#if (FLASH_SIZE>0x10000) + uint32_t page_address; + uint32_t opt_address = address; +#else + uint16_t page_address; + uint16_t opt_address = (uint16_t)address; +#endif + + // Compute the start of the page to be modified + page_address = opt_address-(opt_address%FLASH_PAGE_SIZE); + + // For each page + while ( len ) { + b_flag_erase = false; + + nvm_wait_until_ready(); + for (page_pos=0; page_pos<FLASH_PAGE_SIZE; page_pos+=2 ) { + if (b_blank_check) { + // Read flash to know if the erase command is mandatory + w_value = nvm_flash_read_word(page_address); + if (w_value!=0xFFFF) { + b_flag_erase = true; // The page is not empty + } + }else{ + w_value = 0xFFFF; + } + + // Update flash buffer + if (len) { + if (opt_address == page_address) { + // The MSB of flash word must be changed + // because the address is even + len--; + opt_address++; + LSB(w_value)=*(uint8_t*)buf; + buf=(uint8_t*)buf+1; + } + } + if (len) { + if (opt_address == (page_address+1)) { + // The LSB of flash word must be changed + // because the user buffer is not empty + len--; + opt_address++; + MSB(w_value)=*(uint8_t*)buf; + buf=(uint8_t*)buf+1; + } + } + // Load flash buffer + nvm_flash_load_word_to_buffer(page_address,w_value); + page_address+=2; + } + + // Write flash buffer + if (b_flag_erase) { + nvm_flash_atomic_write_app_page(page_address-FLASH_PAGE_SIZE); + }else{ + nvm_flash_split_write_app_page(page_address-FLASH_PAGE_SIZE); + } + } +} + +//! @} + +/** + * \weakgroup nvm_fuse_lock_group + * @{ + */ + +/** + * \brief Read a fuse byte. + * + * This function reads and returns the value of a given fuse byte. + * + * \param fuse Fuse byte to read. + * + * \return Byte value of fuse. + */ +uint8_t nvm_fuses_read(enum fuse_byte_t fuse) +{ + // Wait until NVM is ready + nvm_wait_until_ready(); + + // Set address + NVM.ADDR0 = fuse; + + // Issue READ_FUSES command + nvm_issue_command(NVM_CMD_READ_FUSES_gc); + + return NVM.DATA0; +} + +//! @} diff --git a/Fred_bootloader/src/ASF/xmega/drivers/nvm/nvm.h b/Fred_bootloader/src/ASF/xmega/drivers/nvm/nvm.h new file mode 100644 index 0000000000000000000000000000000000000000..292f44f098767795fb65547d9791ba7cc15ea17c --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/drivers/nvm/nvm.h @@ -0,0 +1,1075 @@ +/** + * \file + * + * \brief Non Volatile Memory controller driver + * + * Copyright (c) 2010-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef NVM_H +#define NVM_H + +#include <compiler.h> +#include <ccp.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup nvm_group NVM driver + * + * See \ref xmega_nvm_quickstart + * + * \brief Low-level driver implementation for the AVR XMEGA Non Volatile + * Memory Controller (NVM). + * + * The XMEGA NVM controller interfaces the internal non-volatile memories + * in the XMEGA devices. Program memory, EEPROM and signature row is can be + * interfaced by the module. See the documentation of each sub-module for + * more information. + * + * \note If using GCC and the flash sub-module, remember to configure + * the boot section in the make file. More information in the sub-module + * documentation. + * + * \section xmega_nvm_quickstart_section Quick Start Guide + * See \ref xmega_nvm_quickstart + */ + +/** + * \defgroup nvm_generic_group NVM driver generic module handling + * \ingroup nvm_group + * \brief Support functions for the NVM driver. + * + * These functions are helper functions for the functions of the + * \ref nvm_group "NVM driver". + * + * @{ + */ + +/** + * \brief Wait for any NVM access to finish. + * + * This function is blocking and waits for any NVM access to finish. + * Use this function before any NVM accesses, if you are not certain that + * any previous operations are finished yet. + */ +static inline void nvm_wait_until_ready( void ) +{ + do { + // Block execution while waiting for the NVM to be ready + } while ((NVM.STATUS & NVM_NVMBUSY_bm) == NVM_NVMBUSY_bm); +} + +/** + * \brief Non-Volatile Memory Execute Command + * + * This function sets the CCP register before setting the CMDEX bit in the + * NVM.CTRLA register. + * + * \note The correct NVM command must be set in the NVM.CMD register before + * calling this function. + */ +static inline void nvm_exec(void) +{ + ccp_write_io((uint8_t *)&NVM.CTRLA, NVM_CMDEX_bm); +} + +/** + * \brief Non-Volatile Memory Execute Specific Command + * + * This function sets a command in the NVM.CMD register, then performs an + * execute command by writing the CMDEX bit to the NVM.CTRLA register. + * + * \note The function saves and restores the NVM.CMD register, but if this + * function is called from an interrupt, interrupts must be disabled + * before this function is called. + * + * \param nvm_command NVM Command to execute. + */ +static inline void nvm_issue_command(NVM_CMD_t nvm_command) +{ + uint8_t old_cmd; + + old_cmd = NVM.CMD; + NVM.CMD = nvm_command; + ccp_write_io((uint8_t *)&NVM.CTRLA, NVM_CMDEX_bm); + NVM.CMD = old_cmd; +} + +/** + * \brief Read one byte using the LDI instruction + * \internal + * + * This function sets the specified NVM_CMD, reads one byte using at the + * specified byte address with the LPM instruction. NVM_CMD is restored after + * use. + * + * \note Interrupts should be disabled before running this function + * if program memory/NVM controller is accessed from ISRs. + * + * \param nvm_cmd NVM command to load before running LPM + * \param address Byte offset into the signature row + */ +uint8_t nvm_read_byte(uint8_t nvm_cmd, uint16_t address); + + +/** + * \brief Perform SPM write + * \internal + * + * This function sets the specified NVM_CMD, sets CCP and then runs the SPM + * instruction to write to flash. + * + * \note Interrupts should be disabled before running this function + * if program memory/NVM controller is accessed from ISRs. + * + * \param addr Address to perform the SPM on. + * \param nvm_cmd NVM command to use in the NVM_CMD register + */ +void nvm_common_spm(uint32_t addr, uint8_t nvm_cmd); + +//! @} + +/** + * \defgroup nvm_signature_group NVM driver signature handling + * \ingroup nvm_group + * \brief Handling of signature rows + * + * Functions for handling signature rows. The following is supported: + * - Reading values from production and user signature row + * - Reading device id + * - Reading device revision + * - Reading device serial + * + * \note Some of these functions are modifying the NVM.CMD register. + * If the application are using program space access in interrupts + * (__flash pointers in IAR EW or pgm_read_byte in GCC) interrupts + * needs to be disabled when running EEPROM access functions. If not, + * the program space reads will be corrupted. See documentation for + * each individual function. + * \note Do not use the functions of this module in an interrupt service + * routine (ISR), since the functions can take several milliseconds to + * complete and hence block the interrupt for several milliseconds. + * In addition the functions of this module are modifying the page buffer + * which will corrupt any ongoing EEPROM handing used outside an ISR. + * @{ + */ + +/** + * \brief Structure containing the device ID + * + * This structure can be used to store the device ID of a device. + */ +struct nvm_device_id { + union { + struct { + uint8_t devid0; + uint8_t devid1; + uint8_t devid2; + }; + uint8_t byte[3]; + }; +}; + +/** + * \brief Structure containing the device serial + * + * This structure can be used to store the serial number of a device. + */ +struct nvm_device_serial { + union { + struct { + uint8_t lotnum0; + uint8_t lotnum1; + uint8_t lotnum2; + uint8_t lotnum3; + uint8_t lotnum4; + uint8_t lotnum5; + uint8_t wafnum; + uint8_t coordx0; + uint8_t coordx1; + uint8_t coordy0; + uint8_t coordy1; + }; + uint8_t byte[11]; + }; +}; + +/** + * \brief Get offset of calibration bytes in the production signature row + * + * \param regname Name of register within the production signature row + * \retval Offset of register into the production signature row + */ +#if defined(__GNUC__) +# define nvm_get_production_signature_row_offset(regname) \ + offsetof(NVM_PROD_SIGNATURES_t, regname) +#elif defined(__ICCAVR__) +# define nvm_get_production_signature_row_offset(regname) (regname##_offset) +#else +# error Unknown compiler +#endif + + +/** + * \brief Read one byte from the production signature row + * + * This function reads one byte from the production signature row of the device + * at the given address. + * + * \note This function is modifying the NVM.CMD register. + * If the application are using program space access in interrupts + * (__flash pointers in IAR EW or pgm_read_byte in GCC) interrupts + * needs to be disabled when running EEPROM access functions. If not + * the program space reads will be corrupted. + * + * \param address Byte offset into the signature row + */ +static inline uint8_t nvm_read_production_signature_row(uint8_t address) +{ + return nvm_read_byte(NVM_CMD_READ_CALIB_ROW_gc, address); +} + +/** + * \brief Read one byte from the user signature row + * + * This function reads one byte from the user signature row of the device + * at the given address. + * + * \note This function is modifying the NVM.CMD register. + * If the application are using program space access in interrupts + * (__flash pointers in IAR EW or pgm_read_byte in GCC) interrupts + * needs to be disabled when running EEPROM access functions. If not + * the program space reads will be corrupted. + * + * \param address Byte offset into the signature row + */ +static inline uint8_t nvm_read_user_signature_row(uint16_t address) +{ + return nvm_read_byte(NVM_CMD_READ_USER_SIG_ROW_gc, address); +} + +/** + * \brief Read the device id + * + * This function returns the device ID stored in the device. + * + * \retval storage Pointer to the structure where to store the device id + */ +static inline void nvm_read_device_id(struct nvm_device_id *storage) +{ + storage->devid0 = MCU.DEVID0; + storage->devid1 = MCU.DEVID1; + storage->devid2 = MCU.DEVID2; +} + +/** + * \brief Read the device revision + * + * This function returns the device revision stored in the device. + * + * \retval unsigned 8 bit value with the current device revision. + */ +static inline uint8_t nvm_read_device_rev(void) +{ + return MCU.REVID; +} + +void nvm_read_device_serial(struct nvm_device_serial *storage); + +//! @} + + +/** + * \defgroup nvm_eeprom_group NVM driver EEPROM handling + * \ingroup nvm_group + * \brief Functions for handling internal EEPROM memory. + * + * The internal EEPROM can be used to store data that will persist after + * power is removed. This can typically be used to store calibration data, + * application state, encryption keys or other data that need to be preserved + * when power is removed. + * + * The functions in this module uses IO register access to manipulate the + * EEPROM. + * + * \note The functions in this module are modifying the NVM.CMD register. + * If the application are using program space access in interrupts + * (__flash pointers in IAR EW or pgm_read_byte in GCC) interrupts + * needs to be disabled when running EEPROM access functions. If not + * the program space reads will be corrupted. + * @{ + */ + +#ifndef EEPROM_PAGE_SIZE +# if XMEGA_A || XMEGA_AU || XMEGA_B || XMEGA_C || XMEGA_D || XMEGA_E +# define EEPROM_PAGE_SIZE 32 +# else +# error Unknown EEPROM page size +# endif +#endif + +#ifndef CONFIG_NVM_IGNORE_XMEGA_A3_D3_REVB_ERRATA +# if XMEGA_A3 || XMEGA_D3 +# error This NVM driver does not support rev B of XMEGA A3/D3 devices. \ + Set CONFIG_NVM_IGNORE_XMEGA_A3_D3_REVB_ERRATA to disable this message +# endif +#endif + +/** + * Data type for holding eeprom memory addresses. + */ +typedef uint16_t eeprom_addr_t; + + +/*! \brief Enable EEPROM mapping into data space. + * + * This macro enables mapping of EEPROM into data space. + * EEPROM starts at EEPROM_START in data memory. Read access + * can be done similar to ordinary SRAM access. + * + * \note This disables IO-mapped access to EEPROM, although page erase and + * write operations still needs to be done through IO register. + */ +static inline void eeprom_enable_mapping(void) +{ +#if !XMEGA_E + NVM_CTRLB = NVM_CTRLB | NVM_EEMAPEN_bm; +#endif +} + + +/*! \brief Disable EEPROM mapping into data space. + * + * This macro disables mapping of EEPROM into data space. + * IO mapped access is now enabled. + */ +static inline void eeprom_disable_mapping(void) +{ +#if !XMEGA_E + NVM_CTRLB = NVM_CTRLB & ~NVM_EEMAPEN_bm; +#endif +} + + +uint8_t nvm_eeprom_read_byte(eeprom_addr_t addr); +void nvm_eeprom_write_byte(eeprom_addr_t address, uint8_t value); +void nvm_eeprom_read_buffer(eeprom_addr_t address, void *buf, uint16_t len); +void nvm_eeprom_erase_and_write_buffer(eeprom_addr_t address, const void *buf, uint16_t len); + +void nvm_eeprom_flush_buffer(void); +void nvm_eeprom_load_byte_to_buffer(uint8_t byte_addr, uint8_t value); +void nvm_eeprom_load_page_to_buffer(const uint8_t *values); +void nvm_eeprom_atomic_write_page(uint8_t page_addr); +void nvm_eeprom_split_write_page(uint8_t page_addr); +void nvm_eeprom_fill_buffer_with_value(uint8_t value); +void nvm_eeprom_erase_bytes_in_page(uint8_t page_addr); +void nvm_eeprom_erase_page(uint8_t page_addr); +void nvm_eeprom_erase_bytes_in_all_pages(void); +void nvm_eeprom_erase_all(void); + +//! @} + +/** + * \defgroup nvm_flash_group NVM driver flash handling + * \ingroup nvm_group + * \brief Functions for handling internal flash memory. + * + * The internal flash memory on the XMEGA devices consists of the application + * section, the application table section and the bootloader section. + * All these sections can store program code for the MCU, but if there is + * available space, they can be used for storing other persistent data. + * + * Writing the flash memory can only be done one page at a time. It consists + * of loading the data to the internal page buffer and then running one of + * the write commands. If the page has not been erased before writing, the + * data will not be written correctly. + * + * In order to be able to write to flash memory the programming commands need + * to be run from the boot section. + * - When using IAR this is handled automatically by the linker script. + * - When using GCC this needs to be specified manually in the make files. For + * example the ATxmega128A1 has the boot section at the word address 0x10000 + * the corresponding byte address of 0x20000 needs to be added to the + * config.mk makefile: + * LDFLAGS += -Wl,--section-start=.BOOT=0x20000 + * See the device datasheet for the correct address for other devices. + * + * \note If using GCC and the flash sub-module, remember to configure + * the boot section in the make file. + * + * \note The functions in this module are modifying the NVM.CMD register. + * If the application are using program space access in interrupts + * (__flash pointers in IAR EW or pgm_read_byte in GCC) interrupts + * needs to be disabled when running EEPROM access functions. If not + * the program space reads will be corrupted. + * @{ + */ + +/** + * \brief Size of a flash page in bytes + * + * The page size in bytes taken from the toolchain header files. + * + * \note Page size is currently missing from the IAR header files, so it needs + * to be defined in the driver until it is fixed. + */ +#ifdef __DOXYGEN__ +# define FLASH_SIZE +# define FLASH_PAGE_SIZE +#else + +// 8K devices +# if AVR8_PART_IS_DEFINED(ATxmega8E5) +# define FLASH_SIZE (8*1024L) +# define FLASH_PAGE_SIZE (128) + +// 16K devices +# elif AVR8_PART_IS_DEFINED(ATxmega16A4) | \ + AVR8_PART_IS_DEFINED(ATxmega16A4U) | \ + AVR8_PART_IS_DEFINED(ATxmega16D4) | \ + AVR8_PART_IS_DEFINED(ATxmega16C4) +# define FLASH_SIZE (16*1024L) +# define FLASH_PAGE_SIZE (256) + +# elif AVR8_PART_IS_DEFINED(ATxmega16E5) +# define FLASH_SIZE (16*1024L) +# define FLASH_PAGE_SIZE (128) + +// 32K devices +# elif AVR8_PART_IS_DEFINED(ATxmega32A4) | \ + AVR8_PART_IS_DEFINED(ATxmega32A4U) | \ + AVR8_PART_IS_DEFINED(ATxmega32D4) | \ + AVR8_PART_IS_DEFINED(ATxmega32C4) +# define FLASH_SIZE (32*1024L) +# define FLASH_PAGE_SIZE (256) + +# elif AVR8_PART_IS_DEFINED(ATxmega32E5) +# define FLASH_SIZE (32*1024L) +# define FLASH_PAGE_SIZE (128) + +// 64K devices +# elif AVR8_PART_IS_DEFINED(ATxmega64A1) | \ + AVR8_PART_IS_DEFINED(ATxmega64A1U) | \ + AVR8_PART_IS_DEFINED(ATxmega64A3) | \ + AVR8_PART_IS_DEFINED(ATxmega64A3U) | \ + AVR8_PART_IS_DEFINED(ATxmega64A4U) | \ + AVR8_PART_IS_DEFINED(ATxmega64B1) | \ + AVR8_PART_IS_DEFINED(ATxmega64B3) | \ + AVR8_PART_IS_DEFINED(ATxmega64C3) | \ + AVR8_PART_IS_DEFINED(ATxmega64D3) | \ + AVR8_PART_IS_DEFINED(ATxmega64D4) +# define FLASH_SIZE (64*1024L) +# define FLASH_PAGE_SIZE (256) + +// 128K devices +# elif AVR8_PART_IS_DEFINED(ATxmega128A1) | \ + AVR8_PART_IS_DEFINED(ATxmega128A1U) | \ + AVR8_PART_IS_DEFINED(ATxmega128A3) | \ + AVR8_PART_IS_DEFINED(ATxmega128A3U) | \ + AVR8_PART_IS_DEFINED(ATxmega128C3) | \ + AVR8_PART_IS_DEFINED(ATxmega128D3) | \ + AVR8_PART_IS_DEFINED(ATxmega128D4) +# define FLASH_SIZE (128*1024L) +# define FLASH_PAGE_SIZE (512) + +# elif AVR8_PART_IS_DEFINED(ATxmega128A4U) | \ + AVR8_PART_IS_DEFINED(ATxmega128B1) | \ + AVR8_PART_IS_DEFINED(ATxmega128B3) +# define FLASH_SIZE (128*1024L) +# define FLASH_PAGE_SIZE (256) + +// 192K devices +# elif AVR8_PART_IS_DEFINED(ATxmega192A3U) | \ + AVR8_PART_IS_DEFINED(ATxmega192C3) | \ + AVR8_PART_IS_DEFINED(ATxmega192D3) +# define FLASH_SIZE (192*1024L) +# define FLASH_PAGE_SIZE (512) + +// 256K devices +# elif AVR8_PART_IS_DEFINED(ATxmega256A3) | \ + AVR8_PART_IS_DEFINED(ATxmega256A3U) | \ + AVR8_PART_IS_DEFINED(ATxmega256A3B) | \ + AVR8_PART_IS_DEFINED(ATxmega256A3BU) | \ + AVR8_PART_IS_DEFINED(ATxmega256C3) | \ + AVR8_PART_IS_DEFINED(ATxmega256D3) +# define FLASH_SIZE (256*1024L) +# define FLASH_PAGE_SIZE (512) + +// 384K devices +# elif AVR8_PART_IS_DEFINED(ATxmega384C3) +# define FLASH_SIZE (384*1024L) +# define FLASH_PAGE_SIZE (512) +# elif AVR8_PART_IS_DEFINED(ATxmega384D3) +# define FLASH_SIZE (384*1024L) +# define FLASH_PAGE_SIZE (512) +# else +# error Flash page size needs to be defined. +# endif +#endif + +/** + * Data type for holding flash memory addresses. + * + */ +#if (FLASH_SIZE >= 0x10000UL) // Note: Xmega with 64KB of flash have 4KB boot flash +typedef uint32_t flash_addr_t; +#else +typedef uint16_t flash_addr_t; +#endif + +/** + * Flash pointer type to use for accessing flash memory with IAR + */ +#if (FLASH_SIZE >= 0x10000UL) // Note: Xmega with 64KB of flash have 4KB boot flash +# define IAR_FLASH_PTR __farflash +#else +# define IAR_FLASH_PTR __flash +#endif + +/** + * \brief Load byte from flash memory + * + * Load one word of flash using byte addressing. IAR has __flash pointers + * and GCC have pgm_read_byte_xx functions which load data from flash memory. + * This function used for compatibility between the compilers. + * + * \param addr Byte address to load + * \return Byte from program memory + */ +static inline uint8_t nvm_flash_read_byte(flash_addr_t addr) +{ +#if defined(__GNUC__) + return pgm_read_byte_far(addr); +#elif defined(__ICCAVR__) + uint8_t IAR_FLASH_PTR *flashptr = (uint8_t IAR_FLASH_PTR *)addr; + return *flashptr; +#else +# error Unknown compiler +#endif +} + +/** + * \brief Load word from flash memory + * + * Load one word of flash using byte addressing. IAR has __flash pointers + * and GCC have pgm_read_byte_xx functions which load data from flash memory. + * This function used for compatibility between the compilers. + * + * \param addr Byte address to load (last bit is ignored) + * \return Word from program memory + */ +static inline uint16_t nvm_flash_read_word(flash_addr_t addr) +{ +#if defined(__GNUC__) + return pgm_read_word_far(addr); +#elif defined(__ICCAVR__) + uint16_t IAR_FLASH_PTR *flashptr = (uint16_t IAR_FLASH_PTR *)addr; + return *flashptr; +#endif +} + + +/** + * \brief Flush flash page buffer + * + * Clear the NVM controller page buffer for flash. This needs to be called + * before using \ref nvm_flash_load_word_to_buffer if it has not already been + * cleared. + * + */ +static inline void nvm_flash_flush_buffer(void) +{ + nvm_wait_until_ready(); + nvm_common_spm(0, NVM_CMD_ERASE_FLASH_BUFFER_gc); +} + + +/** + * \brief Load word into flash page buffer + * + * Clear the NVM controller page buffer for flash. This needs to be called + * before using \ref nvm_flash_load_word_to_buffer if it has not already been + * cleared. + * + * \param word_addr Address to store data. The upper bits beyond the page size + * is ignored. \ref FLASH_PAGE_SIZE + * \param data Data word to load into the page buffer + */ +void nvm_flash_load_word_to_buffer(uint32_t word_addr, uint16_t data); + + +/** + * \brief Erase entire application section + * + * Erase all of the application section. + */ +static inline void nvm_flash_erase_app(void) +{ + nvm_wait_until_ready(); + nvm_common_spm(0, NVM_CMD_ERASE_APP_gc); +} + +/** + * \brief Erase a page within the application section + * + * Erase one page within the application section + * + * \param page_addr Byte address to the page to delete + */ +static inline void nvm_flash_erase_app_page(flash_addr_t page_addr) +{ + nvm_wait_until_ready(); + nvm_common_spm(page_addr, NVM_CMD_ERASE_APP_PAGE_gc); +} + +/** + * \brief Write a page within the application section + * + * Write a page within the application section with the data stored in the + * page buffer. The page needs to be erased before the write to avoid + * corruption of the data written. + * + * \param page_addr Byte address to the page to delete + */ +static inline void nvm_flash_split_write_app_page(flash_addr_t page_addr) +{ + nvm_wait_until_ready(); + nvm_common_spm(page_addr, NVM_CMD_WRITE_APP_PAGE_gc); +} + +/** + * \brief Erase and write a page within the application section + * + * Erase and the write a page within the application section with the data + * stored in the page buffer. Erase and write is done in an atomic operation. + * + * \param page_addr Byte address to the page to delete + */ +static inline void nvm_flash_atomic_write_app_page(flash_addr_t page_addr) +{ + nvm_wait_until_ready(); + nvm_common_spm(page_addr, NVM_CMD_ERASE_WRITE_APP_PAGE_gc); +} + +void nvm_issue_flash_range_crc(flash_addr_t start_addr, flash_addr_t end_addr); + +void nvm_flash_read_buffer(flash_addr_t address, void *buf, uint16_t len); + +void nvm_flash_erase_and_write_buffer(flash_addr_t address, const void *buf, + uint16_t len, bool b_blank_check); + +/** + * \brief Erase a page within the boot section + * + * Erase one page within the boot section + * + * \param page_addr Byte address to the page to delete + */ +static inline void nvm_flash_erase_boot_page(flash_addr_t page_addr) +{ + nvm_wait_until_ready(); + nvm_common_spm(page_addr, NVM_CMD_ERASE_BOOT_PAGE_gc); +} + +/** + * \brief Write a page within the boot section + * + * Write a page within the boot section with the data stored in the + * page buffer. The page needs to be erased before the write to avoid + * corruption of the data written. + * + * \param page_addr Byte address to the page to delete + */ +static inline void nvm_flash_split_write_boot_page(flash_addr_t page_addr) +{ + nvm_wait_until_ready(); + nvm_common_spm(page_addr, NVM_CMD_WRITE_BOOT_PAGE_gc); +} + +/** + * \brief Erase and write a page within the boot section + * + * Erase and the write a page within the boot section with the data + * stored in the page buffer. Erase and write is done in an atomic operation. + * + * \param page_addr Byte address to the page to delete + */ +static inline void nvm_flash_atomic_write_boot_page(flash_addr_t page_addr) +{ + nvm_wait_until_ready(); + nvm_common_spm(page_addr, NVM_CMD_ERASE_WRITE_BOOT_PAGE_gc); +} + +void nvm_user_sig_read_buffer(flash_addr_t address, void *buf, uint16_t len); +void nvm_user_sig_write_buffer(flash_addr_t address, const void *buf, + uint16_t len, bool b_blank_check); + +/** + * \brief Erase the user calibration section page + * + * Erase the user calibration section page. There is only one page, so no + * parameters are needed. + */ +static inline void nvm_flash_erase_user_section(void) +{ + nvm_wait_until_ready(); + nvm_common_spm(0, NVM_CMD_ERASE_USER_SIG_ROW_gc); +} + +/** + * \brief Write the user calibration section page + * + * Write a the user calibration section page with the data stored in the + * page buffer. The page needs to be erased before the write to avoid + * corruption of the data written. There is only one page, so no + * parameters are needed. + */ +static inline void nvm_flash_write_user_page(void) +{ + nvm_wait_until_ready(); + nvm_common_spm(0, NVM_CMD_WRITE_USER_SIG_ROW_gc); +} + +//! @} + +/** + * \defgroup nvm_fuse_lock_group NVM driver fuse and lock bits handling + * \ingroup nvm_group + * \brief Functions for reading fuses and writing lock bits. + * + * The Fuses are used to set important system functions and can only be written + * from an external programming interface. The application software can read + * the fuses. The fuses are used to configure reset sources such as Brown-out + * Detector and Watchdog, Start-up configuration, JTAG enable and JTAG user ID. + * + * The Lock bits are used to set protection level on the different flash + * sections. They are used to block read and/or write on the different flash + * sections. Lock bits can be written from en external programmer and from the + * application software to set a more strict protection level, but not to set a + * less strict protection level. Chip erase is the only way to erase the lock + * bits. The lock bits are erased after the rest of the flash memory is erased. + * An unprogrammed fuse or lock bit will have the value one, while a programmed + * fuse or lock bit will have the value zero. + * Both fuses and lock bits are reprogrammable like the Flash Program memory. + * + * \note The functions in this module are modifying the NVM.CMD register. + * If the application are using program space access in interrupts + * (__flash pointers in IAR EW or pgm_read_byte in GCC) interrupts + * needs to be disabled when running EEPROM access functions. If not + * the program space reads will be corrupted. + * @{ + */ + +// The different fuse bytes +enum fuse_byte_t { + FUSEBYTE0 = 0, + FUSEBYTE1 = 1, + FUSEBYTE2 = 2, + FUSEBYTE3 = 3, // not used on current devices + FUSEBYTE4 = 4, + FUSEBYTE5 = 5, +}; + +uint8_t nvm_fuses_read(enum fuse_byte_t fuse); + +/** + * \brief Program the lock bits. + * + * Program the lock bits to the given values. Lock bits can only be programmed + * to a more secure setting than previously programmed. To clear lock bits, a + * flash erase has to be issued. + * + * \param blbb_lock Boot loader section lock bits to program + * \param blba_lock Application section lock bits to program + * \param blbat_lock Application table section lock bits to program + * \param lb_lock Flash/eeprom lock bits to program + */ +static inline void nvm_lock_bits_write(enum NVM_BLBB_enum blbb_lock, + enum NVM_BLBA_enum blba_lock, enum NVM_BLBAT_enum blbat_lock, + enum NVM_LB_enum lb_lock) +{ + nvm_wait_until_ready(); + NVM.DATA0 = (uint8_t)blbb_lock | (uint8_t)blba_lock | (uint8_t)blbat_lock | + (uint8_t)lb_lock; + nvm_issue_command(NVM_CMD_WRITE_LOCK_BITS_gc); +} + +/** + * \brief Program the BLBB lock bits. + * + * Program the lock bits for the boot loader section (BLBB). Other lock bits + * (BLBA, BLBAT and LB) are not altered (ie. programmed to NOLOCK). + * + * \param blbb_lock Boot loader section lock bits to program + */ +static inline void nvm_blbb_lock_bits_write(enum NVM_BLBB_enum blbb_lock) +{ + nvm_lock_bits_write(blbb_lock, NVM_BLBA_NOLOCK_gc, NVM_BLBAT_NOLOCK_gc, + NVM_LB_NOLOCK_gc); +} + +/** + * \brief Program the BLBA lock bits. + * + * Program the lock bits for the application section (BLBA). Other lock bits + * (BLBB, BLBAT and LB) are not altered (ie. programmed to NOLOCK). + * + * \param blba_lock Application section lock bits to program + */ +static inline void nvm_blba_lock_bits_write(enum NVM_BLBA_enum blba_lock) +{ + nvm_lock_bits_write(NVM_BLBB_NOLOCK_gc, blba_lock, NVM_BLBAT_NOLOCK_gc, + NVM_LB_NOLOCK_gc); +} + +/** + * \brief Program the BLBAT lock bits. + * + * Program the lock bits for the application table section (BLBAT). Other lock + * bits (BLBB, BLBA and LB) are not altered (ie. programmed to NOLOCK). + * + * \param blbat_lock Application table section lock bits to program + */ +static inline void nvm_blbat_lock_bits_write(enum NVM_BLBAT_enum blbat_lock) +{ + nvm_lock_bits_write(NVM_BLBB_NOLOCK_gc, NVM_BLBA_NOLOCK_gc, blbat_lock, + NVM_LB_NOLOCK_gc); +} + +/** + * \brief Program the LB lock bits. + * + * Program the lock bits for the flash and eeprom (LB). Other lock bits + * (BLBB, BLBA and BLBAT) are not altered (ie. programmed to NOLOCK). + * + * \param lb_lock Flash/eeprom lock bits to program + */ +static inline void nvm_lb_lock_bits_write(enum NVM_LB_enum lb_lock) +{ + nvm_lock_bits_write(NVM_BLBB_NOLOCK_gc, NVM_BLBA_NOLOCK_gc, + NVM_BLBAT_NOLOCK_gc, lb_lock); +} + +//! @} + +/** + * \page xmega_nvm_quickstart Quick Start Guide for the XMEGA NVM Driver + * + * This is the quick start guide for the \ref nvm_group "NVM Driver", with + * step-by-step instructions on how to configure and use the driver for + * specific use cases. + * + * The section described below can be compiled into e.g. the main application + * loop or any other function that will need to interface non-volatile memory. + * + * \section xmega_nvm_quickstart_basic Basic usage of the NVM driver + * This section will present three use cases of the NVM driver. The first will + * write a page to EEPROM and verify that it has been written, the second will + * access the BOD-level fuse to verify that the level is correctly set, and the + * third will read a chunk from the user signature row. + * + * \section xmega_nvm_quickstart_eeprom_case Use case 1: EEPROM + * + * The NVM driver has functions for interfacing many types of non-volatile + * memory, including flash, EEPROM, fuses and lock bits. The example code + * below will write a page to the internal EEPROM, and read it back to verify, + * using memory mapped I/O. + * + * \section xmega_nvm_quickstart_eeprom_case_setup_steps Setup steps + * There are no setup steps required for this use case. + * + * \subsection nvm_quickstart_eeprom_case_example_code Example code + * + * \code + #define EXAMPLE_PAGE 2 + #define EXAMPLE_ADDR EXAMPLE_PAGE * EEPROM_PAGE_SIZE + + uint8_t write_page[EEPROM_PAGE_SIZE]; + uint8_t read_page[EEPROM_PAGE_SIZE]; + + fill_page_with_known_data(write_page); + fill_page_with_zeroes(read_page); + + nvm_eeprom_load_page_to_buffer(write_page); + nvm_eeprom_atomic_write_page(EXAMPLE_PAGE); + + nvm_eeprom_read_buffer(EXAMPLE_ADDR, + read_page, EEPROM_PAGE_SIZE); + + check_if_pages_are_equal(write_page, read_page); +\endcode + * + * \subsection nvm_quickstart_eeprom_case_workflow Workflow + * + * -# We define where we would like to store our data, and we arbitrarily + * choose page 2 of EEPROM: + * - \code + #define EXAMPLE_PAGE 2 + #define EXAMPLE_ADDR EXAMPLE_PAGE * EEPROM_PAGE_SIZE +\endcode + * -# Define two tables, one which contains the data which we will write, + * and one which we will read the data into: + * - \code + uint8_t write_page[EEPROM_PAGE_SIZE]; + uint8_t read_page[EEPROM_PAGE_SIZE]; +\endcode + * -# Fill the tables with our data, and zero out the read table: + * - \code + fill_page_with_known_data(write_page); + fill_page_with_zeroes(read_page); +\endcode + * - \note These functions are undeclared, you should replace them with + * your own appropriate functions. + * -# We load our page into a temporary EEPROM page buffer: + * - \code + nvm_eeprom_load_page_to_buffer(write_page); +\endcode + * - \attention The function used above will not work if memory mapping + * is enabled. + * -# Do an atomic write of the page from buffer into the specified page: + * - \code + nvm_eeprom_atomic_write_page(EXAMPLE_PAGE); +\endcode + * - \note The function \ref nvm_eeprom_atomic_write_page() erases the + * page before writing the new one. For non-atomic (split) + * writing without deleting, see \ref nvm_eeprom_split_write_page() + * -# Read the page back into our read_page[] table: + * - \code + nvm_eeprom_read_buffer(EXAMPLE_ADDR, + read_page, EEPROM_PAGE_SIZE); +\endcode + * -# Verify that the page is equal to the one that was written earlier: + * - \code + check_if_pages_are_equal(write_page, read_page); +\endcode + * - \note This function is not declared, you should replace it with your + * own appropriate function. + * + * \section xmega_nvm_quickstart_fuse_case Use case 2: Fuses + * + * The NVM driver has functions for reading fuses. + * See \ref nvm_fuse_lock_group. + * + * We would like to check whether the Brown-out Detection level is set to + * 2.1V. This is set by programming the fuses when the chip is connected + * to a suitable programmer. The fuse is a part of FUSEBYTE5. If the BODLVL + * is correct, we turn on LED0. + * + * \section xmega_nvm_quickstart_fuse_case_setup_steps Setup steps + * There are no setup steps required for this use case. + * + * \subsection nvm_quickstart_fuse_case_example_code Example code + * \code + uint8_t fuse_value; + fuse_value = nvm_fuses_read(FUSEBYTE5); + + if ((fuse_value & NVM_FUSES_BODLVL_gm) == BODLVL_2V1_gc) { + gpio_set_pin_low(LED0_GPIO); + } +\endcode + * + * \subsection nvm_quickstart_fuse_case_workflow Workflow + * + * -# Create a variable to store the fuse contents: + * - \code + uint8_t fuse_value; +\endcode + * -# The fuse value we are interested in, BODLVL, is stored in FUSEBYTE5. + * We call the function \ref nvm_fuses_read() to read the fuse into our + * variable: + * - \code + fuse_value = nvm_fuses_read(FUSEBYTE5); +\endcode + * -# This ends the reading portion, but we would like to see whether the + * BOD-level is correct, and if it is, light up an LED: + * - \code + if ((fuse_value & NVM_FUSES_BODLVL_gm) == BODLVL_2V1_gc) { + gpio_set_pin_low(LED0_GPIO); + } +\endcode + * + * \section xmega_nvm_quickstart_signature_case Use case 3: Signature row + * + * The NVM driver has functions for reading the signature row of the device. + * Here we will simply read 16 bytes from the user signature row, assuming + * we need what is stored there. + * + * \section xmega_nvm_quickstart_signature_row_setup_steps Setup steps + * There are no setup steps required for this use case. + * + * \subsection xmega_nvm_quickstart_signature_row_example_code Example code + * + * \code + #define START_ADDR 0x10 + #define DATA_LENGTH 16 + + uint8_t values[LENGTH]; + uint8_t i; + + for (i = 0; i < DATA_LENGTH; i++) { + values[i] = nvm_read_user_signature_row(START_ADDR + i); + } +\endcode + * + * \subsection nvm_quickstart_signature_case_workflow Workflow + * + * -# Define starting address and length of data segment, and create + * variables needed to store and process the data: + * - \code + #define START_ADDR 0x10 + #define DATA_LENGTH 16 + + uint8_t values[LENGTH]; + uint8_t i; +\endcode + * -# Iterate through the user signature row, and store our desired data: + * - \code + for (i = 0; i < DATA_LENGTH; i++) { + values[i] = nvm_read_user_signature_row(START_ADDR + i); + } +\endcode + * + */ + +#ifdef __cplusplus +} +#endif + +#endif /* NVM_H */ diff --git a/Fred_bootloader/src/ASF/xmega/drivers/nvm/nvm_asm.s b/Fred_bootloader/src/ASF/xmega/drivers/nvm/nvm_asm.s new file mode 100644 index 0000000000000000000000000000000000000000..700cd0705cb5f3b55036a52d558188a852db8dbe --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/drivers/nvm/nvm_asm.s @@ -0,0 +1,197 @@ +/** + * \file + * + * \brief Non Volatile Memory controller driver + * + * Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#include <assembler.h> + +#if defined(__GNUC__) +//! Value to write to CCP for access to protected IO registers. +# define CCP_SPM_gc 0x9D + +//! NVM busy flag +# define NVM_NVMBUSY_bp 7 + +//! NVM command for loading flash buffer +# define NVM_CMD_LOAD_FLASH_BUFFER_gc 0x23 +#elif defined(__IAR_SYSTEMS_ASM__) +// All values are defined for IAR +#else +# error Unknown assembler +#endif + +#ifndef __DOXYGEN__ + PUBLIC_FUNCTION(nvm_read_byte) +#if defined(__GNUC__) + lds r20, NVM_CMD ; Store NVM command register + mov ZL, r22 ; Load byte index into low byte of Z. + mov ZH, r23 ; Load high byte into Z. + sts NVM_CMD, r24 ; Load prepared command into NVM Command register. + lpm r24, Z ; Perform an LPM to read out byte + sts NVM_CMD, r20 ; Restore NVM command register +#elif defined(__IAR_SYSTEMS_ASM__) + lds r20, NVM_CMD ; Store NVM command register + mov ZL, r18 ; Load byte index into low byte of Z. + mov ZH, r19 ; Load high byte into Z. + sts NVM_CMD, r16 ; Load prepared command into NVM Command register. + lpm r16, Z ; Perform an LPM to read out byte + sts NVM_CMD, r20 ; Restore NVM command register +#endif + + ret + + END_FUNC(nvm_read_byte) + +// IAR forgets about include files after each module, so need to include again +#if defined(__IAR_SYSTEMS_ASM__) +# include <ioavr.h> +#endif + + /** + * \brief Perform SPM command + */ + PUBLIC_FUNCTION_SEGMENT(nvm_common_spm, BOOT) + +#if defined(__GNUC__) + /** + * For GCC: + * \param address uint32_t r22:r25 + * \param nvm_cmd uint8_t r20 + */ + in r25, RAMPZ ; Store RAMPZ. Highest address byte is ignored, so using that + out RAMPZ, r24 ; Load R24 into RAMPZ + movw ZL, r22 ; Load R22:R23 into Z. + lds r24, NVM_CMD ; Store NVM command register (r24 is no longer needed) + sts NVM_CMD, r20 ; Load prepared command into NVM Command register. + ldi r23, CCP_SPM_gc ; Prepare Protect SPM signature (r23 is no longer needed) + sts CCP, r23 ; Enable SPM operation (this disables interrupts for 4 cycles). + spm ; Self-program. + sts NVM_CMD, r24 ; Restore NVM command register + out RAMPZ, r25 ; Restore RAMPZ register. +#elif defined(__IAR_SYSTEMS_ASM__) + /** + * For IAR: + * \param address uint32_t r16:r19 + * \param nvm_cmd uint8_t r20 + */ + in r19, RAMPZ ; Store RAMPZ. Highest address byte is ignored, so using that + out RAMPZ, r18 ; Load R18 into RAMPZ + movw ZL, r16 ; Load R16:R17 into Z. + lds r18, NVM_CMD ; Store NVM command register (r18 is no longer needed) + sts NVM_CMD, r20 ; Load prepared command into NVM Command register. + ldi r19, CCP_SPM_gc ; Prepare Protect SPM signature (r19 is no longer needed) + sts CCP, r19 ; Enable SPM operation (this disables interrupts for 4 cycles). + spm ; Self-program. + sts NVM_CMD, r18 ; Restore NVM command register + out RAMPZ, r19 ; Restore RAMPZ register. +#endif + + ret + + END_FUNC(nvm_common_spm) + +// IAR forgets about include files after each module, so need to include again +#if defined(__IAR_SYSTEMS_ASM__) +# include <ioavr.h> +#endif + + /** + * \brief Load byte to page buffer + * + */ + PUBLIC_FUNCTION_SEGMENT(nvm_flash_load_word_to_buffer, BOOT) + +#if defined(__GNUC__) + /** + * For GCC: + * \param word_addr uint32_t r22:r25 + * \param data uint16_t r20:r21 + */ +wait_nvm: + lds r18, NVM_STATUS + sbrc r18, NVM_NVMBUSY_bp + rjmp wait_nvm + + in r25, RAMPZ ; Store RAMPZ. Highest address byte is ignored, so using that + out RAMPZ, r24 ; Load R24 into RAMPZ + movw ZL, r22 ; Load R22:R23 into Z. + + lds r24, NVM_CMD ; Store NVM command register (r24 is no longer needed) + ldi r18, NVM_CMD_LOAD_FLASH_BUFFER_gc + sts NVM_CMD, r18 ; Load prepared command into NVM Command register. + + movw r0, r20 ; Load R20:R21 into R0:R1 + spm ; Self-program. + + clr r1 ; Clear R1 for GCC _zero_reg_ to function properly. + sts NVM_CMD, r24 ; Restore NVM command register + out RAMPZ, r25 ; Restore RAMPZ register. +#elif defined(__IAR_SYSTEMS_ASM__) + /** + * For IAR: + * \param word_addr uint32_t r16:r19 + * \param data uint16_t r20:r21 + */ +wait_nvm: + lds r19, NVM_STATUS + sbrc r19, NVM_NVMBUSY_bp + rjmp wait_nvm + + in r19, RAMPZ ; Store RAMPZ. Highest byte is ignored, so using that + out RAMPZ, r18 ; Load R18 into RAMPZ + movw ZL, r16 ; Load R16:R17 into Z. + + lds r18, NVM_CMD ; Store NVM command register (r18 is no longer needed) + ldi r17, NVM_CMD_LOAD_FLASH_BUFFER_gc + sts NVM_CMD, r17 ; Load prepared command into NVM Command register. + + movw r0, r20 ; Load R20:R21 into R0:R1 + spm ; Self-program. + + sts NVM_CMD, r18 ; Restore NVM command register + out RAMPZ, r19 ; Restore RAMPZ register. +#endif + + ret + + END_FUNC(nvm_flash_load_word_to_buffer) + + END_FILE() +#endif // __DOXYGEN__ diff --git a/Fred_bootloader/src/ASF/xmega/drivers/pmic/pmic.h b/Fred_bootloader/src/ASF/xmega/drivers/pmic/pmic.h new file mode 100644 index 0000000000000000000000000000000000000000..e169e219ae192136f7cde46e5728619053f3be28 --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/drivers/pmic/pmic.h @@ -0,0 +1,349 @@ +/** + * \file + * + * \brief Programmable Multilevel Interrupt Controller driver + * + * Copyright (c) 2010-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef PMIC_H +#define PMIC_H + +#include <compiler.h> +#include <ccp.h> + +/** + * \defgroup pmic_group Programmable Multilevel Interrupt Controller + * + * See \ref xmega_pmic_quickstart. + * + * This is a low-level driver implementation for the AVR XMEGA Programmable + * Multilevel Interrupt Controller. + * + * \note If these functions are used in interrupt service routines (ISRs), any + * non-ISR code or ISR code for lower level interrupts must ensure that the + * operations are atomic, i.e., by disabling interrupts during the function + * calls. + * @{ + */ + +/** + * \brief Interrupt level bitmasks + * + * \note These may be OR'ed, e.g., if multiple levels are to be enabled or + * disabled. + */ +enum pmic_level { + PMIC_LVL_LOW = PMIC_LOLVLEN_bm, //!< Low-level interrupts + PMIC_LVL_MEDIUM = PMIC_MEDLVLEN_bm, //!< Medium-level interrupts + PMIC_LVL_HIGH = PMIC_HILVLEN_bm, //!< High-level interrupts + /** + * \brief Non-maskable interrupts + * \note These cannot be enabled nor disabled. + */ + PMIC_LVL_NMI = PMIC_NMIEX_bp, +}; + +//! Interrupt vector locations +enum pmic_vector { + PMIC_VEC_APPLICATION, //!< Application section + PMIC_VEC_BOOT, //!< Boot section + PMIC_NR_OF_VECTORS, //!< Number of interrupt vector locations +}; + +//! Interrupt scheduling schemes +enum pmic_schedule { + PMIC_SCH_FIXED_PRIORITY, //!< Default, fixed priority scheduling + PMIC_SCH_ROUND_ROBIN, //!< Round-robin scheduling + PMIC_NR_OF_SCHEDULES, //!< Number of interrupt scheduling schemes +}; + +/** + * \brief Initialize the PMIC + * + * Enables all interrupt levels, with vectors located in the application section + * and fixed priority scheduling. + */ +static inline void pmic_init(void) +{ + PMIC.CTRL = PMIC_LVL_LOW | PMIC_LVL_MEDIUM | + PMIC_LVL_HIGH; +} + +/** + * \brief Enable interrupts with specified \a level(s). + * + * \param level Interrupt level(s) to enable. + */ +static inline void pmic_enable_level(enum pmic_level level) +{ + Assert((level & PMIC_LVL_NMI)); + + PMIC.CTRL |= level; +} + +/** + * \brief Disable interrupts with specified \a level(s). + * + * \param level Interrupt level(s) to disable. + */ +static inline void pmic_disable_level(enum pmic_level level) +{ + Assert((level & PMIC_LVL_NMI)); + + PMIC.CTRL &= ~level; +} + +/** + * \brief Check if specified interrupt \a level(s) is enabled. + * + * \param level Interrupt level(s) to check. + * + * \return True if interrupt level(s) is enabled. + */ +static inline bool pmic_level_is_enabled(enum pmic_level level) +{ + Assert((level & PMIC_LVL_NMI)); + + return PMIC.CTRL & level; +} + +/** + * \brief Get currently enabled level(s) + * + * \return Bitmask with currently enabled levels. + */ +static inline enum pmic_level pmic_get_enabled_levels(void) +{ + return (enum pmic_level)(PMIC.CTRL & (PMIC_LVL_LOW | PMIC_LVL_MEDIUM + | PMIC_LVL_HIGH)); +} + +/** + * \brief Check if an interrupt level(s) is currently executing. + * + * \param level Interrupt level(s) to check. + * + * \return True if interrupt level(s) is currently executing. + */ +static inline bool pmic_level_is_executing(enum pmic_level level) +{ + return PMIC.STATUS & level; +} + +/** + * \brief Set interrupt scheduling for low-level interrupts. + * + * \param schedule Interrupt scheduling method to set. + * + * \note The low-priority vector, INTPRI, must be set to 0 when round-robin + * scheduling is disabled to return to default interrupt priority order. + */ +static inline void pmic_set_scheduling(enum pmic_schedule schedule) +{ + Assert(schedule < PMIC_NR_OF_SCHEDULES); + + switch (schedule) { + case PMIC_SCH_FIXED_PRIORITY: + PMIC.CTRL &= ~PMIC_RREN_bm; + PMIC.INTPRI = 0; + break; + + case PMIC_SCH_ROUND_ROBIN: + PMIC.CTRL |= PMIC_RREN_bm; + break; + + default: + break; + }; +} + +/** + * \brief Set location of interrupt vectors. + * + * \param vector Location to use for interrupt vectors. + */ +static inline void pmic_set_vector_location(enum pmic_vector vector) +{ + uint8_t ctrl = PMIC.CTRL; + + Assert(vector < PMIC_NR_OF_VECTORS); + + switch (vector) { + case PMIC_VEC_APPLICATION: + ctrl &= ~PMIC_IVSEL_bm; + break; + + case PMIC_VEC_BOOT: + ctrl |= PMIC_IVSEL_bm; + break; + + default: + break; + } + + ccp_write_io((uint8_t*)&PMIC.CTRL, ctrl); +} + +//! @} + +/** + * \page xmega_pmic_quickstart Quick start guide for PMIC driver + * + * This is the quick start guide for the \ref pmic_group "PMIC driver" and + * the closely related \ref interrupt_group "global interrupt driver", with + * step-by-step instructions on how to configure and use the drivers in a + * selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section pmic_basic_use_case Basic use case + * In this basic use case, the PMIC is configured for: + * - all interrupt levels enabled + * - round-robin scheduling + * + * This will allow for interrupts from other modules being used. + * + * \section pmic_basic_use_case_setup Setup steps + * + * \subsection pmic_basic_use_case_setup_prereq Prerequisites + * For the setup code of this use case to work, the following must + * be added to the project: + * -# Interrupts for the module requiring the PMIC module have to be + * enabled. + * -# An Interrupt Service Routine (ISR) for a given interrupt vector has to be + * defined, where the interrupt vectors available are defined by toolchain and + * listed in the subsection 'Interrupt Vector Summary' in the data sheet. + * \code + ISR(interrupt_vector){ + //Interrupt Service Routine + } +\endcode + * + * \subsection pmic_basic_use_case_setup_code Example code + * Add to the initialization code: + * \code + pmic_init(); + pmic_set_scheduling(PMIC_SCH_ROUND_ROBIN); + cpu_irq_enable(); +\endcode + * + * \subsection pmic_basic_use_case_setup_flow Workflow + * -# call the PMIC driver's own init function to enable all interrupt levels: + * - \code pmic_init(); \endcode + * -# enable round-robin instead of fixed priority interrupt scheduling: + * - \code pmic_set_scheduling(PMIC_SCH_ROUND_ROBIN); \endcode + * -# enable interrupts globally: + * - \code cpu_irq_enable(); \endcode + * - \attention Interrupts will not trigger without this step. + * + * \section pmic_use_cases Advanced use cases + * For more advanced use of the PMIC driver, see the following use cases: + * - \subpage pmic_use_case_1 : atomic operations + */ + +/** + * \page pmic_use_case_1 Use case #1 + * + * In this use case, the PMIC is configured for: + * - all interrupt levels enabled + * + * This will allow for interrupts from other modules being used. + * + * This use case shows how to make an operation which consists of multiple + * instructions uninterruptible, i.e., into an atomic operation. This is often + * necessary if there is a risk that data can be accessed by interrupt handlers + * while other code is accessing it, and at least one of them modifies it. + * + * \section pmic_use_case_1_setup Setup steps + * + * \subsection pmic_basic_use_case_setup_prereq Prerequisites + * For the setup code of this use case to work, the following must + * be added to the project: + * -# Interrupts for the module requiring the PMIC module have to be + * enabled. + * -# An Interrupt Service Routine (ISR) for a given interrupt vector has to be + * defined, where the interrupt vectors available are defined by toolchain and + * listed in the subsection 'Interrupt Vector Summary' in the data sheet. + * \code + ISR(interrupt_vector){ + //Interrupt Service Routine + } +\endcode + * + * \subsection pmic_use_case_1_setup_code Example code + * Add to application initialization: + * \code + pmic_init(); + cpu_irq_enable(); +\endcode + * + * \subsection pmic_use_case_1_setup_flow Workflow + * -# call the PMIC driver's own init function to enable all interrupt levels: + * - \code pmic_init(); \endcode + * -# set global interrupt enable flag: + * - \code cpu_irq_enable(); \endcode + * + * \section pmic_use_case_1_usage Usage steps + * + * \subsection pmic_use_case_1_usage_code Example code + * \code + Add to application: + void atomic_operation(void) + { + irqflags_t flags; + + flags = cpu_irq_save(); + + // Uninterruptible block of code + + cpu_irq_restore(flags); + } +\endcode + * + * \subsection pmic_use_case_1_usage_flow Workflow + * -# allocate temporary storage for interrupt enable: + * - \code irqflags_t flags; \endcode + * -# clear global interrupt enable flag while saving its previous state: + * - \code flags = cpu_irq_save(); \endcode + * -# restore the previous state of global interrupt flag after operation: + * - \code cpu_irq_restore(flags); \endcode + */ + +#endif /* PMIC_H */ diff --git a/Fred_bootloader/src/ASF/xmega/drivers/sleep/sleep.h b/Fred_bootloader/src/ASF/xmega/drivers/sleep/sleep.h new file mode 100644 index 0000000000000000000000000000000000000000..5a07591d7f4d763dd476bb70e08276a8f78e019e --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/drivers/sleep/sleep.h @@ -0,0 +1,166 @@ +/** + * \file + * + * \brief Sleep controller driver + * + * Copyright (c) 2010-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef SLEEP_H +#define SLEEP_H + +#include <compiler.h> + +/** + * \defgroup sleep_group Sleep controller driver + * + * This is a low-level driver implementation for the AVR XMEGA sleep controller. + * + * \note To minimize the code overhead, these functions do not feature + * interrupt-protected access since they are likely to be called inside + * interrupt handlers or in applications where such protection is not + * necessary. If such protection is needed, it must be ensured by the calling + * code. + * + * \section xmega_sleep_quickstart_section Quick Start Guide + * See \ref xmega_sleep_quickstart + * @{ + */ + +#if defined(__ICCAVR__) || defined(__DOXYGEN__) +# include <intrinsics.h> +//! Macro for issuing the sleep instruction. +# define sleep_enter() __sleep() + +/** + * \brief Enable sleep + */ +static inline void sleep_enable(void) +{ + SLEEP.CTRL |= SLEEP_SEN_bm; +} + +/** + * \brief Disable sleep + */ +static inline void sleep_disable(void) +{ + SLEEP.CTRL &= ~SLEEP_SEN_bm; +} + +#elif defined(__GNUC__) +# include <avr/sleep.h> +# define sleep_enter() sleep_cpu() + +#else +# error Unsupported compiler. +#endif + +/** + * \brief Set new sleep mode + * + * \param mode Sleep mode, from the device IO header file. + */ +static inline void sleep_set_mode(enum SLEEP_SMODE_enum mode) +{ + SLEEP.CTRL = mode | (SLEEP.CTRL & ~SLEEP_SMODE_gm); +} + +//! @} + +/** + * \page xmega_sleep_quickstart Quick Start Guide for the XMEGA Sleep Driver + * + * This is the quick start guide for the \ref sleep_group "Sleep Driver", with + * step-by-step instructions on how to configure and use the driver for a + * specific use case. + * + * The section described below can be copied into, e.g. the main application + * loop or any other function that will need to control and execute different + * sleep modes on the device. + * + * \section xmega_sleep_quickstart_basic Basic usage of the sleep driver + * This use case will prepare the device to enter the Power Down sleep mode and + * then enter the sleep mode. After waking up it will disable sleep. + * + * \section xmega_sleep_basic_usage Usage steps + * \subsection xmega_sleep_basic_usage_code Example code + * Add to, e.g., the main loop in the application C-file: + * \code + sleep_set_mode(SLEEP_SMODE_PDOWN_gc); + sleep_enable(); + sleep_enter(); + sleep_disable(); +\endcode + * + * \subsection xmega_sleep_basic_usage Workflow + * -# Set what sleep mode to use, the different sleep modes can be found in the + * device header file under the enum definition SLEEP_SMODE_enum: + * - \code sleep_set_mode(SLEEP_SMODE_PDOWN_gc); \endcode + * -# Enable that the device are allowed to go to sleep: + * - \code sleep_enable(); \endcode + * - \note This function has to be called in order for the device to go to + * sleep. This is a safety feature to stop the device to go to sleep + * unintentionally, even though it is possible to have this enabled at all times + * it is recommended to enable sleep mode only when you intend to go to sleep + * within a few clock cycles. + * -# Enter sleep mode: + * - \code sleep_enter(); \endcode + * - \attention Make sure to enable global interrupt and the interrupt you + * plan to use as wake-up source for your device, do also pay special + * attention to what wake-up sources are available for the different sleep + * modes. Failing to enable interrupts may result in indefinite sleep until + * power is cycled! + * -# When the device is woken from sleep it will execute the interrupt handler + * related to the wakeup-source (interrupt source) and continue on the next line + * of code after the \ref sleep_enter() call. Make sure to disable sleep when + * waking up. + * - \code sleep_disable(); \endcode + * + * \subsection xmega_sleep_basic_sleep_modes Sleep Modes + * Possible sleep modes depend on the device that is used. Please refer to the + * device datasheet and header file to find these definitions. + * + * As an example the ATxmega32A4U device has the following sleep modes: + * - Idle sleep: SLEEP_SMODE_IDLE_gc + * - Power Down: SLEEP_SMODE_PDOWN_gc + * - Power Save: SLEEP_SMODE_PSAVE_gc + * - Standby: SLEEP_SMODE_STDBY_gc + * - Extended standby: SLEEP_SMODE_ESTDBY_gc + */ + +#endif /* SLEEP_H */ diff --git a/Fred_bootloader/src/ASF/xmega/drivers/tc/tc.c b/Fred_bootloader/src/ASF/xmega/drivers/tc/tc.c new file mode 100644 index 0000000000000000000000000000000000000000..ca52b8df19a5c5230bcd52606e6c9e6c084e3106 --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/drivers/tc/tc.c @@ -0,0 +1,1078 @@ +/** + * \file + * + * \brief AVR XMEGA TC Driver + * + * Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#include <stdint.h> + +#include "interrupt.h" +#include "compiler.h" +#include "parts.h" + +#include "tc.h" +#include "sysclk.h" +#include "sleepmgr.h" +#include "status_codes.h" + +#if defined(TCC0) || defined(__DOXYGEN__) +//! \internal Local storage of Timer Counter TCC0 interrupt callback function +static tc_callback_t tc_tcc0_ovf_callback; +static tc_callback_t tc_tcc0_err_callback; +static tc_callback_t tc_tcc0_cca_callback; +static tc_callback_t tc_tcc0_ccb_callback; +static tc_callback_t tc_tcc0_ccc_callback; +static tc_callback_t tc_tcc0_ccd_callback; + + +/** + * \internal + * \brief Interrupt handler for Timer Counter C0 overflow + * + * This function will handle interrupt on Timer Counter CO overflow and + * call the callback function. + */ +ISR(TCC0_OVF_vect) +{ + if (tc_tcc0_ovf_callback) { + tc_tcc0_ovf_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter C0 error + * + * This function will handle interrupt on Timer Counter CO error and + * call the callback function. + */ +ISR(TCC0_ERR_vect) +{ + if (tc_tcc0_err_callback) { + tc_tcc0_err_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter C0 Compare/CaptureA + * + * This function will handle interrupt on Timer Counter CO Compare/CaptureA and + * call the callback function. + */ +ISR(TCC0_CCA_vect) +{ + if (tc_tcc0_cca_callback) { + tc_tcc0_cca_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter C0 Compare/CaptureB + * + * This function will handle interrupt on Timer Counter CO Compare/CaptureB and + * call the callback function. + */ +ISR(TCC0_CCB_vect) +{ + if (tc_tcc0_ccb_callback) { + tc_tcc0_ccb_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter C0 Compare/CaptureC + * + * This function will handle interrupt on Timer Counter CO Compare/CaptureC and + * call the callback function. + */ +ISR(TCC0_CCC_vect) +{ + if (tc_tcc0_ccc_callback) { + tc_tcc0_ccc_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter C0 Compare/CaptureD + * + * This function will handle interrupt on Timer Counter CO Compare/CaptureD and + * call the callback function. + */ +ISR(TCC0_CCD_vect) +{ + if (tc_tcc0_ccd_callback) { + tc_tcc0_ccd_callback(); + } +} + +#endif + +#if defined(TCC1) || defined(__DOXYGEN__) +//! \internal Local storage of Timer Counter TCC1 interrupt callback function +static tc_callback_t tc_tcc1_ovf_callback; +static tc_callback_t tc_tcc1_err_callback; +static tc_callback_t tc_tcc1_cca_callback; +static tc_callback_t tc_tcc1_ccb_callback; + +/** + * \internal + * \brief Interrupt handler for Timer Counter C1 overflow + * + * This function will handle interrupt on Timer Counter C1 overflow and + * call the callback function. + */ +ISR(TCC1_OVF_vect) +{ + if (tc_tcc1_ovf_callback) { + tc_tcc1_ovf_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter C1 error + * + * This function will handle interrupt on Timer Counter C1 error and + * call the callback function. + */ +ISR(TCC1_ERR_vect) +{ + if (tc_tcc1_err_callback) { + tc_tcc1_err_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter C1 Compare/CaptureA + * + * This function will handle interrupt on Timer Counter C1 Compare/CaptureA and + * call the callback function. + */ +ISR(TCC1_CCA_vect) +{ + if (tc_tcc1_cca_callback) { + tc_tcc1_cca_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter C1 Compare/CaptureB + * + * This function will handle interrupt on Timer Counter C1 Compare/CaptureB and + * call the callback function. + */ +ISR(TCC1_CCB_vect) +{ + if (tc_tcc1_ccb_callback) { + tc_tcc1_ccb_callback(); + } +} + +#endif + +#if defined(TCD0) || defined(__DOXYGEN__) +//! \internal Local storage of Timer Counter TCD0 interrupt callback function +static tc_callback_t tc_tcd0_ovf_callback; +static tc_callback_t tc_tcd0_err_callback; +static tc_callback_t tc_tcd0_cca_callback; +static tc_callback_t tc_tcd0_ccb_callback; +static tc_callback_t tc_tcd0_ccc_callback; +static tc_callback_t tc_tcd0_ccd_callback; + + +/** + * \internal + * \brief Interrupt handler for Timer Counter D0 overflow + * + * This function will handle interrupt on Timer Counter D0 overflow and + * call the callback function. + */ +ISR(TCD0_OVF_vect) +{ + if (tc_tcd0_ovf_callback) { + tc_tcd0_ovf_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter D0 error + * + * This function will handle interrupt on Timer Counter D0 error and + * call the callback function. + */ +ISR(TCD0_ERR_vect) +{ + if (tc_tcd0_err_callback) { + tc_tcd0_err_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter D0 Compare/CaptureA + * + * This function will handle interrupt on Timer Counter D0 Compare/CaptureA and + * call the callback function. + */ +ISR(TCD0_CCA_vect) +{ + if (tc_tcd0_cca_callback) { + tc_tcd0_cca_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter D0 Compare/CaptureB + * + * This function will handle interrupt on Timer Counter D0 Compare/CaptureB and + * call the callback function. + */ +ISR(TCD0_CCB_vect) +{ + if (tc_tcd0_ccb_callback) { + tc_tcd0_ccb_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter D0 Compare/CaptureC + * + * This function will handle interrupt on Timer Counter D0 Compare/CaptureC and + * call the callback function. + */ +ISR(TCD0_CCC_vect) +{ + if (tc_tcd0_ccc_callback) { + tc_tcd0_ccc_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter D0 Compare/CaptureD + * + * This function will handle interrupt on Timer Counter D0 Compare/CaptureD and + * call the callback function. + */ +ISR(TCD0_CCD_vect) +{ + if (tc_tcd0_ccd_callback) { + tc_tcd0_ccd_callback(); + } +} + +#endif + +#if defined(TCD1) || defined(__DOXYGEN__) +//! \internal Local storage of Timer Counter TCD1 interrupt callback function +static tc_callback_t tc_tcd1_ovf_callback; +static tc_callback_t tc_tcd1_err_callback; +static tc_callback_t tc_tcd1_cca_callback; +static tc_callback_t tc_tcd1_ccb_callback; + +/** + * \internal + * \brief Interrupt handler for Timer Counter D1 overflow + * + * This function will handle interrupt on Timer Counter D1 overflow and + * call the callback function. + */ +ISR(TCD1_OVF_vect) +{ + if (tc_tcd1_ovf_callback) { + tc_tcd1_ovf_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter D1 error + * + * This function will handle interrupt on Timer Counter D1 error and + * call the callback function. + */ +ISR(TCD1_ERR_vect) +{ + if (tc_tcd1_err_callback) { + tc_tcd1_err_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter D1 Compare/CaptureA + * + * This function will handle interrupt on Timer Counter D1 Compare/CaptureA and + * call the callback function. + */ +ISR(TCD1_CCA_vect) +{ + if (tc_tcd1_cca_callback) { + tc_tcd1_cca_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter D1 Compare/CaptureB + * + * This function will handle interrupt on Timer Counter D1 Compare/CaptureB and + * call the callback function. + */ +ISR(TCD1_CCB_vect) +{ + if (tc_tcd1_ccb_callback) { + tc_tcd1_ccb_callback(); + } +} + +#endif + + +#if defined(TCE0) || defined(__DOXYGEN__) +//! \internal Local storage of Timer Counter TCE0 interrupt callback function +static tc_callback_t tc_tce0_ovf_callback; +static tc_callback_t tc_tce0_err_callback; +static tc_callback_t tc_tce0_cca_callback; +static tc_callback_t tc_tce0_ccb_callback; +static tc_callback_t tc_tce0_ccc_callback; +static tc_callback_t tc_tce0_ccd_callback; + + +/** + * \internal + * \brief Interrupt handler for Timer Counter E0 overflow + * + * This function will handle interrupt on Timer Counter E0 overflow and + * call the callback function. + */ +ISR(TCE0_OVF_vect) +{ + if (tc_tce0_ovf_callback) { + tc_tce0_ovf_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter E0 error + * + * This function will handle interrupt on Timer Counter E0 error and + * call the callback function. + */ +ISR(TCE0_ERR_vect) +{ + if (tc_tce0_err_callback) { + tc_tce0_err_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter E0 Compare/CaptureA + * + * This function will handle interrupt on Timer Counter E0 Compare/CaptureA and + * call the callback function. + */ +ISR(TCE0_CCA_vect) +{ + if (tc_tce0_cca_callback) { + tc_tce0_cca_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter E0 Compare/CaptureB + * + * This function will handle interrupt on Timer Counter E0 Compare/CaptureB and + * call the callback function. + */ +ISR(TCE0_CCB_vect) +{ + if (tc_tce0_ccb_callback) { + tc_tce0_ccb_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter E0 Compare/CaptureC + * + * This function will handle interrupt on Timer Counter E0 Compare/CaptureC and + * call the callback function. + */ +ISR(TCE0_CCC_vect) +{ + if (tc_tce0_ccc_callback) { + tc_tce0_ccc_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter E0 Compare/CaptureD + * + * This function will handle interrupt on Timer Counter E0 Compare/CaptureD and + * call the callback function. + */ +ISR(TCE0_CCD_vect) +{ + if (tc_tce0_ccd_callback) { + tc_tce0_ccd_callback(); + } +} + +#endif + +#if defined(TCE1) || defined(__DOXYGEN__) +//! \internal Local storage of Timer Counter TCE1 interrupt callback function +static tc_callback_t tc_tce1_ovf_callback; +static tc_callback_t tc_tce1_err_callback; +static tc_callback_t tc_tce1_cca_callback; +static tc_callback_t tc_tce1_ccb_callback; + +/** + * \internal + * \brief Interrupt handler for Timer Counter E1 overflow + * + * This function will handle interrupt on Timer Counter E1 overflow and + * call the callback function. + */ +ISR(TCE1_OVF_vect) +{ + if (tc_tce1_ovf_callback) { + tc_tce1_ovf_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter E1 error + * + * This function will handle interrupt on Timer Counter E1 error and + * call the callback function. + */ +ISR(TCE1_ERR_vect) +{ + if (tc_tce1_err_callback) { + tc_tce1_err_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter E1 Compare/CaptureA + * + * This function will handle interrupt on Timer Counter E1 Compare/CaptureA and + * call the callback function. + */ +ISR(TCE1_CCA_vect) +{ + if (tc_tce1_cca_callback) { + tc_tce1_cca_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter E1 Compare/CaptureB + * + * This function will handle interrupt on Timer Counter E1 Compare/CaptureB and + * call the callback function. + */ +ISR(TCE1_CCB_vect) +{ + if (tc_tce1_ccb_callback) { + tc_tce1_ccb_callback(); + } +} + +#endif + +#if defined(TCF0) || defined(__DOXYGEN__) +//! \internal Local storage of Timer Counter TCF0 interrupt callback function +static tc_callback_t tc_tcf0_ovf_callback; +static tc_callback_t tc_tcf0_err_callback; +static tc_callback_t tc_tcf0_cca_callback; +static tc_callback_t tc_tcf0_ccb_callback; +static tc_callback_t tc_tcf0_ccc_callback; +static tc_callback_t tc_tcf0_ccd_callback; + + +/** + * \internal + * \brief Interrupt handler for Timer Counter E0 overflow + * + * This function will handle interrupt on Timer Counter F0 overflow and + * call the callback function. + */ +ISR(TCF0_OVF_vect) +{ + if (tc_tcf0_ovf_callback) { + tc_tcf0_ovf_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter F0 error + * + * This function will handle interrupt on Timer Counter F0 error and + * call the callback function. + */ +ISR(TCF0_ERR_vect) +{ + if (tc_tcf0_err_callback) { + tc_tcf0_err_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter F0 Compare/CaptureA + * + * This function will handle interrupt on Timer Counter F0 Compare/CaptureA and + * call the callback function. + */ +ISR(TCF0_CCA_vect) +{ + if (tc_tcf0_cca_callback) { + tc_tcf0_cca_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter F0 Compare/CaptureB + * + * This function will handle interrupt on Timer Counter F0 Compare/CaptureB and + * call the callback function. + */ +ISR(TCF0_CCB_vect) +{ + if (tc_tcf0_ccb_callback) { + tc_tcf0_ccb_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter F0 Compare/CaptureC + * + * This function will handle interrupt on Timer Counter F0 Compare/CaptureC and + * call the callback function. + */ +ISR(TCF0_CCC_vect) +{ + if (tc_tcf0_ccc_callback) { + tc_tcf0_ccc_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter F0 Compare/CaptureD + * + * This function will handle interrupt on Timer Counter F0 Compare/CaptureD and + * call the callback function. + */ +ISR(TCF0_CCD_vect) +{ + if (tc_tcf0_ccd_callback) { + tc_tcf0_ccd_callback(); + } +} + +#endif + +#if defined(TCF1) || defined(__DOXYGEN__) +//! \internal Local storage of Timer Counter TCF1 interrupt callback function +static tc_callback_t tc_tcf1_ovf_callback; +static tc_callback_t tc_tcf1_err_callback; +static tc_callback_t tc_tcf1_cca_callback; +static tc_callback_t tc_tcf1_ccb_callback; + +/** + * \internal + * \brief Interrupt handler for Timer Counter F1 overflow + * + * This function will handle interrupt on Timer Counter F1 overflow and + * call the callback function. + */ +ISR(TCF1_OVF_vect) +{ + if (tc_tcf1_ovf_callback) { + tc_tcf1_ovf_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter F1 error + * + * This function will handle interrupt on Timer Counter F1 error and + * call the callback function. + */ +ISR(TCF1_ERR_vect) +{ + if (tc_tcf1_err_callback) { + tc_tcf1_err_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter F1 Compare/CaptureA + * + * This function will handle interrupt on Timer Counter F1 Compare/CaptureA and + * call the callback function. + */ +ISR(TCF1_CCA_vect) +{ + if (tc_tcf1_cca_callback) { + tc_tcf1_cca_callback(); + } +} + +/** + * \internal + * \brief Interrupt handler for Timer Counter F1 Compare/CaptureB + * + * This function will handle interrupt on Timer Counter F1 Compare/CaptureB and + * call the callback function. + */ +ISR(TCF1_CCB_vect) +{ + if (tc_tcf1_ccb_callback) { + tc_tcf1_ccb_callback(); + } +} + +#endif + +/** + * \brief Enable TC + * + * Enables the TC. + * + * \param tc Pointer to TC module + * + * \note + * unmask TC clock (sysclk), but does not configure the TC clock source. + */ +void tc_enable(volatile void *tc) +{ + irqflags_t iflags = cpu_irq_save(); + +#ifdef TCC0 + if ((uintptr_t) tc == (uintptr_t) & TCC0) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC0); + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } else +#endif +#ifdef TCC1 + if ((uintptr_t) tc == (uintptr_t) & TCC1) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC1); + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } else +#endif +#ifdef TCD0 + if ((uintptr_t) tc == (uintptr_t) & TCD0) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC0); + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } else +#endif +#ifdef TCD1 + if ((uintptr_t) tc == (uintptr_t) & TCD1) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC1); + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } else +#endif +#ifdef TCE0 + if ((uintptr_t) tc == (uintptr_t) & TCE0) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC0); + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } else +#endif +#ifdef TCE1 + if ((uintptr_t) tc == (uintptr_t) & TCE1) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC1); + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } else +#endif +#ifdef TCF0 + if ((uintptr_t) tc == (uintptr_t) & TCF0) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC0); + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } else +#endif +#ifdef TCF1 + if ((uintptr_t) tc == (uintptr_t) & TCF1) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC1); + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } else +#endif + { + cpu_irq_restore(iflags); + return; + } + sleepmgr_lock_mode(SLEEPMGR_IDLE); + cpu_irq_restore(iflags); +} + + +/** + * \brief Disable TC + * + * Disables the TC. + * + * \param tc Pointer to TC module + * + * \note + * mask TC clock (sysclk). + */ +void tc_disable(volatile void *tc) +{ + irqflags_t iflags = cpu_irq_save(); + + sleepmgr_unlock_mode(SLEEPMGR_IDLE); + +#ifdef TCC0 + if ((uintptr_t) tc == (uintptr_t) & TCC0) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC0); + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } else +#endif +#ifdef TCC1 + if ((uintptr_t) tc == (uintptr_t) & TCC1) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC1); + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } else +#endif +#ifdef TCD0 + if ((uintptr_t) tc == (uintptr_t) & TCD0) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC0); + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } else +#endif +#ifdef TCD1 + if ((uintptr_t) tc == (uintptr_t) & TCD1) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC1); + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } else +#endif +#ifdef TCE0 + if ((uintptr_t) tc == (uintptr_t) & TCE0) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC0); + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } else +#endif +#ifdef TCE1 + if ((uintptr_t) tc == (uintptr_t) & TCE1) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC1); + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } else +#endif +#ifdef TCF0 + if ((uintptr_t) tc == (uintptr_t) & TCF0) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC0); + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } else +#endif +#ifdef TCF1 + if ((uintptr_t) tc == (uintptr_t) & TCF1) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC1); + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } else +#endif + { + cpu_irq_restore(iflags); + return; + } + cpu_irq_restore(iflags); +} + +void tc_set_overflow_interrupt_callback(volatile void *tc, + tc_callback_t callback) +{ +#ifdef TCC0 + if ((uintptr_t) tc == (uintptr_t) & TCC0) { + tc_tcc0_ovf_callback = callback; + } else +#endif +#ifdef TCC1 + if ((uintptr_t) tc == (uintptr_t) & TCC1) { + tc_tcc1_ovf_callback = callback; + } else +#endif +#ifdef TCD0 + if ((uintptr_t) tc == (uintptr_t) & TCD0) { + tc_tcd0_ovf_callback = callback; + } else +#endif +#ifdef TCD1 + if ((uintptr_t) tc == (uintptr_t) & TCD1) { + tc_tcd1_ovf_callback = callback; + } else +#endif +#ifdef TCE0 + if ((uintptr_t) tc == (uintptr_t) & TCE0) { + tc_tce0_ovf_callback = callback; + } else +#endif +#ifdef TCE1 + if ((uintptr_t) tc == (uintptr_t) & TCE1) { + tc_tce1_ovf_callback = callback; + } else +#endif +#ifdef TCF0 + if ((uintptr_t) tc == (uintptr_t) & TCF0) { + tc_tcf0_ovf_callback = callback; + } else +#endif +#ifdef TCF1 + if ((uintptr_t) tc == (uintptr_t) & TCF1) { + tc_tcf1_ovf_callback = callback; + } else +#endif + {} +} + +void tc_set_error_interrupt_callback(volatile void *tc, tc_callback_t callback) +{ +#ifdef TCC0 + if ((uintptr_t) tc == (uintptr_t) & TCC0) { + tc_tcc0_err_callback = callback; + } else +#endif +#ifdef TCC1 + if ((uintptr_t) tc == (uintptr_t) & TCC1) { + tc_tcc1_err_callback = callback; + } else +#endif +#ifdef TCD0 + if ((uintptr_t) tc == (uintptr_t) & TCD0) { + tc_tcd0_err_callback = callback; + } else +#endif +#ifdef TCD1 + if ((uintptr_t) tc == (uintptr_t) & TCD1) { + tc_tcd1_err_callback = callback; + } else +#endif +#ifdef TCE0 + if ((uintptr_t) tc == (uintptr_t) & TCE0) { + tc_tce0_err_callback = callback; + } else +#endif +#ifdef TCE1 + if ((uintptr_t) tc == (uintptr_t) & TCE1) { + tc_tce1_err_callback = callback; + } else +#endif +#ifdef TCF0 + if ((uintptr_t) tc == (uintptr_t) & TCF0) { + tc_tcf0_err_callback = callback; + } else +#endif +#ifdef TCF1 + if ((uintptr_t) tc == (uintptr_t) & TCF1) { + tc_tcf1_err_callback = callback; + } else +#endif + {} +} + +void tc_set_cca_interrupt_callback(volatile void *tc, tc_callback_t callback) +{ +#ifdef TCC0 + if ((uintptr_t) tc == (uintptr_t) & TCC0) { + tc_tcc0_cca_callback = callback; + } else +#endif +#ifdef TCC1 + if ((uintptr_t) tc == (uintptr_t) & TCC1) { + tc_tcc1_cca_callback = callback; + } else +#endif +#ifdef TCD0 + if ((uintptr_t) tc == (uintptr_t) & TCD0) { + tc_tcd0_cca_callback = callback; + } else +#endif +#ifdef TCD1 + if ((uintptr_t) tc == (uintptr_t) & TCD1) { + tc_tcd1_cca_callback = callback; + } else +#endif +#ifdef TCE0 + if ((uintptr_t) tc == (uintptr_t) & TCE0) { + tc_tce0_cca_callback = callback; + } else +#endif +#ifdef TCE1 + if ((uintptr_t) tc == (uintptr_t) & TCE1) { + tc_tce1_cca_callback = callback; + } else +#endif +#ifdef TCF0 + if ((uintptr_t) tc == (uintptr_t) & TCF0) { + tc_tcf0_cca_callback = callback; + } else +#endif +#ifdef TCF1 + if ((uintptr_t) tc == (uintptr_t) & TCF1) { + tc_tcf1_cca_callback = callback; + } else +#endif + {} +} + +void tc_set_ccb_interrupt_callback(volatile void *tc, tc_callback_t callback) +{ +#ifdef TCC0 + if ((uintptr_t) tc == (uintptr_t) & TCC0) { + tc_tcc0_ccb_callback = callback; + } else +#endif +#ifdef TCC1 + if ((uintptr_t) tc == (uintptr_t) & TCC1) { + tc_tcc1_ccb_callback = callback; + } else +#endif +#ifdef TCD0 + if ((uintptr_t) tc == (uintptr_t) & TCD0) { + tc_tcd0_ccb_callback = callback; + } else +#endif +#ifdef TCD1 + if ((uintptr_t) tc == (uintptr_t) & TCD1) { + tc_tcd1_ccb_callback = callback; + } else +#endif +#ifdef TCE0 + if ((uintptr_t) tc == (uintptr_t) & TCE0) { + tc_tce0_ccb_callback = callback; + } else +#endif +#ifdef TCE1 + if ((uintptr_t) tc == (uintptr_t) & TCE1) { + tc_tce1_ccb_callback = callback; + } else +#endif +#ifdef TCF0 + if ((uintptr_t) tc == (uintptr_t) & TCF0) { + tc_tcf0_ccb_callback = callback; + } else +#endif +#ifdef TCF1 + if ((uintptr_t) tc == (uintptr_t) & TCF1) { + tc_tcf1_ccb_callback = callback; + } else +#endif + {} +} + +void tc_set_ccc_interrupt_callback(volatile void *tc, tc_callback_t callback) +{ +#ifdef TCC0 + if ((uintptr_t) tc == (uintptr_t) & TCC0) { + tc_tcc0_ccc_callback = callback; + } else +#endif + +#ifdef TCD0 + if ((uintptr_t) tc == (uintptr_t) & TCD0) { + tc_tcd0_ccc_callback = callback; + } else +#endif + +#ifdef TCE0 + if ((uintptr_t) tc == (uintptr_t) & TCE0) { + tc_tce0_ccc_callback = callback; + } else +#endif + +#ifdef TCF0 + if ((uintptr_t) tc == (uintptr_t) & TCF0) { + tc_tcf0_ccc_callback = callback; + } else +#endif + {} + +} + + +void tc_set_ccd_interrupt_callback(volatile void *tc, tc_callback_t callback) +{ +#ifdef TCC0 + if ((uintptr_t) tc == (uintptr_t) & TCC0) { + tc_tcc0_ccd_callback = callback; + } else +#endif + +#ifdef TCD0 + if ((uintptr_t) tc == (uintptr_t) & TCD0) { + tc_tcd0_ccd_callback = callback; + } else +#endif + +#ifdef TCE0 + if ((uintptr_t) tc == (uintptr_t) & TCE0) { + tc_tce0_ccd_callback = callback; + } else +#endif + +#ifdef TCF0 + if ((uintptr_t) tc == (uintptr_t) & TCF0) { + tc_tcf0_ccd_callback = callback; + } else +#endif + {} +} diff --git a/Fred_bootloader/src/ASF/xmega/drivers/tc/tc.h b/Fred_bootloader/src/ASF/xmega/drivers/tc/tc.h new file mode 100644 index 0000000000000000000000000000000000000000..3fc6a2a5f0cbedb009b4a6799d7b7232807ebde2 --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/drivers/tc/tc.h @@ -0,0 +1,1635 @@ +/** + * \file + * + * \brief AVR XMEGA Timer Counter (TC) driver + * + * Copyright (c) 2010-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef _TC_H_ +#define _TC_H_ + +#include <compiler.h> +#include <parts.h> +#include "status_codes.h" +#include "pmic.h" +#include <sleepmgr.h> +#include <sysclk.h> + + +#ifdef __cplusplus +extern "C" { +#endif + + + +/** + * \defgroup tc_group Timer Counter (TC) + * + * See \ref xmega_tc_quickstart + * + * This is a driver for the AVR XMEGA Timer Counter (TC). It provides functions + * for enabling, disabling and configuring the TC modules. + * + * \section dependencies Dependencies + * This driver depends on the following modules: + * - \ref sysclk_group for peripheral clock control. + * - \ref sleepmgr_group for setting allowed sleep mode. + * - \ref interrupt_group for ISR definition and disabling interrupts during + * critical code sections. + * @{ + */ + + + +/** + * \brief Interrupt event callback function type + * + * The interrupt handler can be configured to do a function callback, + * the callback function must match the tc_callback_t type. + * + */ +typedef void (*tc_callback_t) (void); + +//! Timer Counter Capture Compare Channel index +enum tc_cc_channel_t { + //! Channel A + TC_CCA = 1, + //! Channel B + TC_CCB = 2, + //! Channel C + TC_CCC = 3, + //! Channel D + TC_CCD = 4, +}; + +//! Timer Counter Capture Compare Channel index +enum tc_cc_channel_mask_enable_t { + //! Channel A Enable mask + TC_CCAEN = TC0_CCAEN_bm, + //! Channel B Enable mask + TC_CCBEN = TC0_CCBEN_bm, + //! Channel C Enable mask + TC_CCCEN = TC0_CCCEN_bm, + //! Channel D Enable mask + TC_CCDEN = TC0_CCDEN_bm, +}; + +//! Timer Counter Direction +enum tc_dir_t { + //! Counting up + TC_UP = 0, + //! Down Counting B + TC_DOWN = 1 +}; +//! Timer Counter Waveform Generator mode +enum tc_wg_mode_t { + //! TC in normal Mode + TC_WG_NORMAL = TC_WGMODE_NORMAL_gc, + //! TC in Frequency Generator mode + TC_WG_FRQ = TC_WGMODE_FRQ_gc, + //! TC in single slope PWM mode + TC_WG_SS = TC_WGMODE_SS_gc, + //! TC in dual slope Top PWM mode + TC_WG_DS_T = TC_WGMODE_DS_T_gc, + //! TC in dual slope Top Bottom PWM mode + TC_WG_DS_TB = TC_WGMODE_DS_TB_gc, + //! TC in dual slope Bottom PWM mode + TC_WG_DS_B = TC_WGMODE_DS_B_gc +}; + +//! TC interrupt levels +enum TC_INT_LEVEL_t { + TC_INT_LVL_OFF = 0x00, + TC_INT_LVL_LO = 0x01, + TC_INT_LVL_MED = 0x02, + TC_INT_LVL_HI = 0x03, +}; + +//! Macro to check if type of passed TC is TC1_t +#define tc_is_tc1(void) ((uint16_t)tc&0x40 ? true : false) +//! Macro to check if type of passed TC is TC0_t +#define tc_is_tc0(void) ((uint16_t)tc&0x40 ? false : true) + +/** + * \brief Enable TC + * + * Enables the TC. + * + * \param tc Pointer to TC module + * + * \note + * unmask TC clock (sysclk), but does not configure the TC clock source. + */ +void tc_enable(volatile void *tc); + +/** + * \brief Disable TC + * + * Disables the TC. + * + * \param tc Pointer to TC module + * + * \note + * mask TC clock (sysclk). + */ +void tc_disable(volatile void *tc); + +/** + * \ingroup tc_group + * \defgroup tc_interrupt_group Timer Counter (TC) interrupt management + * This group provides functions to configure TC module interrupts + * + * + * @{ + */ +/** + * \brief Set TC overflow interrupt callback function + * + * This function allows the caller to set and change the interrupt callback + * function. Without setting a callback function the interrupt handler in the + * driver will only clear the interrupt flags. + * + * \note Once a callback function is set, the interrupt priority must be set + * via \ref tc_set_overflow_interrupt_level() for interrupts to be + * generated each time the timer overflows. + * + * \param tc Pointer to the Timer Counter (TC) base address + * \param callback Reference to a callback function + */ +void tc_set_overflow_interrupt_callback(volatile void *tc, + tc_callback_t callback); + +/** + * \brief Set TC error interrupt callback function + * + * This function allows the caller to set and change the interrupt callback + * function. Without setting a callback function the interrupt handler in the + * driver will only clear the interrupt flags. + * + * \note Once a callback function is set, the interrupt priority must be set + * via \ref tc_set_error_interrupt_level() for interrupts to be + * generated each time a timer error occurs. + * + * \param tc Pointer to the Timer Counter (TC) base address + * \param callback Reference to a callback function + */ +void tc_set_error_interrupt_callback(volatile void *tc, tc_callback_t callback); + +/** + * \brief Set TC Capture Compare Channel A interrupt callback function + * + * This function allows the caller to set and change the interrupt callback + * function. Without setting a callback function the interrupt handler in the + * driver will only clear the interrupt flags. + * + * \note Once a callback function is set, the interrupt priority must be set + * via \ref tc_set_cca_interrupt_level() for interrupts to be generated + * each time the timer channel A compare matches the current timer count. + * + * \param tc Pointer to the Timer Counter (TC) base address + * \param callback Reference to a callback function + */ +void tc_set_cca_interrupt_callback(volatile void *tc, tc_callback_t callback); + +/** + * \brief Set TC Capture Compare Channel B interrupt callback function + * + * This function allows the caller to set and change the interrupt callback + * function. Without setting a callback function the interrupt handler in the + * driver will only clear the interrupt flags. + * + * \note Once a callback function is set, the interrupt priority must be set + * via \ref tc_set_ccb_interrupt_level() for interrupts to be generated + * each time the timer channel B compare matches the current timer count. + * + * \param tc Pointer to the Timer Counter (TC) base address + * \param callback Reference to a callback function + */ +void tc_set_ccb_interrupt_callback(volatile void *tc, tc_callback_t callback); + +/** + * \brief Set TC Capture Compare Channel C interrupt callback function + * + * This function allows the caller to set and change the interrupt callback + * function. Without setting a callback function the interrupt handler in the + * driver will only clear the interrupt flags. + * + * \note Once a callback function is set, the interrupt priority must be set + * via \ref tc_set_ccc_interrupt_level() for interrupts to be generated + * each time the timer channel C compare matches the current timer count. + * + * \param tc Pointer to the Timer Counter (TC) base address + * \param callback Reference to a callback function + */ +void tc_set_ccc_interrupt_callback(volatile void *tc, tc_callback_t callback); + +/** + * \brief Set TC Capture Compare Channel D interrupt callback function + * + * This function allows the caller to set and change the interrupt callback + * function. Without setting a callback function the interrupt handler in the + * driver will only clear the interrupt flags. + * + * \note Once a callback function is set, the interrupt priority must be set + * via \ref tc_set_ccd_interrupt_level() for interrupts to be generated + * each time the timer channel D compare matches the current timer count. + * + * \param tc Pointer to the Timer Counter (TC) base address + * \param callback Reference to a callback function + */ +void tc_set_ccd_interrupt_callback(volatile void *tc, tc_callback_t callback); + +/** + * \brief Configures TC overflow Interrupt level + * + * \param tc Pointer to TC module. + * \param level Overflow interrupt level + * \note Configures OVFINTLVL in INTCTRLA + */ +static inline void tc_set_overflow_interrupt_level(volatile void *tc, + enum TC_INT_LEVEL_t level) +{ + ((TC0_t *)tc)->INTCTRLA = ((TC0_t *)tc)->INTCTRLA & ~TC0_OVFINTLVL_gm; + ((TC0_t *)tc)->INTCTRLA = + ((TC0_t *)tc)->INTCTRLA | (level << TC0_OVFINTLVL_gp); +} + +/** + * \brief Configures TC error Interrupt level + * + * \param tc Pointer to TC module. + * \param level Error interrupt level + * \note Configures ERRINTLVL in INTCTRLA + */ +static inline void tc_set_error_interrupt_level(volatile void *tc, + enum TC_INT_LEVEL_t level) +{ + ((TC0_t *)tc)->INTCTRLA = ((TC0_t *)tc)->INTCTRLA & ~TC0_ERRINTLVL_gm; + ((TC0_t *)tc)->INTCTRLA = + ((TC0_t *)tc)->INTCTRLA | (level << TC0_ERRINTLVL_gp); +} + +/** + * \brief Configures TC Capture Compare A Interrupt level + * + * \param tc Pointer to TC module. + * \param level CCA interrupt level + * \note Configures CCAINTLVL in INTCTRLB + */ +static inline void tc_set_cca_interrupt_level(volatile void *tc, + enum TC_INT_LEVEL_t level) +{ + ((TC0_t *)tc)->INTCTRLB = ((TC0_t *)tc)->INTCTRLB & ~TC0_CCAINTLVL_gm; + ((TC0_t *)tc)->INTCTRLB = + ((TC0_t *)tc)->INTCTRLB | (level << TC0_CCAINTLVL_gp); +} + +/** + * \brief Configures TC Capture Compare B Interrupt level + * + * \param tc Pointer to TC module. + * \param level CCB interrupt level + * \note Configures CCBINTLVL in INTCTRLB + */ +static inline void tc_set_ccb_interrupt_level(volatile void *tc, + enum TC_INT_LEVEL_t level) +{ + ((TC0_t *)tc)->INTCTRLB = ((TC0_t *)tc)->INTCTRLB & ~TC0_CCBINTLVL_gm; + ((TC0_t *)tc)->INTCTRLB = + ((TC0_t *)tc)->INTCTRLB | (level << TC0_CCBINTLVL_gp); +} + +/** + * \brief Configures TC Capture Compare C Interrupt level + * + * \param tc Pointer to TC module. + * \param level CCC interrupt level + * \note Configures CCCINTLVL in INTCTRLB + */ +static inline void tc_set_ccc_interrupt_level(volatile void *tc, + enum TC_INT_LEVEL_t level) +{ + ((TC0_t *)tc)->INTCTRLB = ((TC0_t *)tc)->INTCTRLB & ~TC0_CCCINTLVL_gm; + ((TC0_t *)tc)->INTCTRLB = + ((TC0_t *)tc)->INTCTRLB | (level << TC0_CCCINTLVL_gp); +} + + /** + * \brief Configures TC Capture Compare D Interrupt level + * + * \param tc Pointer to TC module. + * \param level CCD interrupt level + * \note Configures CCDINTLVL in INTCTRLB + */ +static inline void tc_set_ccd_interrupt_level(volatile void *tc, + enum TC_INT_LEVEL_t level) +{ + ((TC0_t *)tc)->INTCTRLB = ((TC0_t *)tc)->INTCTRLB & ~TC0_CCDINTLVL_gm; + ((TC0_t *)tc)->INTCTRLB = + ((TC0_t *)tc)->INTCTRLB | (level << TC0_CCDINTLVL_gp); +} + +//@} + +/** + * \brief Configure Timer Clock Source + * + * \param tc Pointer to TC module. + * \param TC_CLKSEL_enum Clock source selection + * \note Configuring the clock also starts the timer + */ +static inline void tc_write_clock_source(volatile void *tc, + TC_CLKSEL_t TC_CLKSEL_enum) +{ + ((TC0_t *)tc)->CTRLA = + (((TC0_t *)tc)->CTRLA & ~TC0_CLKSEL_gm) | + TC_CLKSEL_enum; +} + +/** + * \brief Read Timer Clock Source + * + * \param tc Pointer to TC module. + * \return TC_CLKSEL_enum Clock source selection + */ +static inline TC_CLKSEL_t tc_read_clock_source(volatile void *tc) +{ + return (TC_CLKSEL_t)(((TC0_t *)tc)->CTRLA & TC0_CLKSEL_gm); +} + +/** + * \brief Select clock for a specified TC and resolution. + * + * This function configures the clock selection, as prescaled CLKper, for a + * specified TC that gives a resolution at least as high as the one specified. + * The resolution of a TC is synonymous with its clock frequency. + * + * \note It is also possible to clock TCs with event channels. This is not + * handled by this implementation. + * + * \param tc ID of TC to get clock selection for. + * \param resolution Desired resolution for the TC in Hz. + */ +static inline void tc_set_resolution(volatile void *tc, uint32_t resolution) +{ + uint32_t tc_clk_rate = sysclk_get_per_hz(); + + if (resolution <= (tc_clk_rate / 1024)) { + tc_write_clock_source(tc, TC_CLKSEL_DIV1024_gc); + } else if (resolution <= (tc_clk_rate / 256)) { + tc_write_clock_source(tc, TC_CLKSEL_DIV256_gc); + } else if (resolution <= (tc_clk_rate / 64)) { + tc_write_clock_source(tc, TC_CLKSEL_DIV64_gc); + } else if (resolution <= (tc_clk_rate / 8)) { + tc_write_clock_source(tc, TC_CLKSEL_DIV8_gc); + } else if (resolution <= (tc_clk_rate / 4)) { + tc_write_clock_source(tc, TC_CLKSEL_DIV4_gc); + } else if (resolution <= (tc_clk_rate / 2)) { + tc_write_clock_source(tc, TC_CLKSEL_DIV2_gc); + } else { + tc_write_clock_source(tc, TC_CLKSEL_DIV1_gc); + } +} + +/** + * \brief Get real resolution for a specified TC. + * + * This function returns the resolution which the specified clock selection + * of TC will result in. The resolution of a TC is synonymous with its clock + * frequency. + * + * \note This function does not handle event channel clock selections. + * + * \param tc Pointer of TC module to get resolution for. + * + * \return The resolution of \a tc. + */ +static inline uint32_t tc_get_resolution(volatile void *tc) +{ + uint32_t tc_clk_rate = sysclk_get_per_hz(); + switch (tc_read_clock_source(tc)) { + case TC_CLKSEL_OFF_gc: + tc_clk_rate = 0; + break; + + case TC_CLKSEL_DIV1024_gc: + tc_clk_rate /= 1024; + break; + + case TC_CLKSEL_DIV256_gc: + tc_clk_rate /= 256; + break; + + case TC_CLKSEL_DIV64_gc: + tc_clk_rate /= 64; + break; + + case TC_CLKSEL_DIV8_gc: + tc_clk_rate /= 8; + break; + + case TC_CLKSEL_DIV4_gc: + tc_clk_rate /= 4; + break; + + case TC_CLKSEL_DIV2_gc: + tc_clk_rate /= 2; + break; + + case TC_CLKSEL_DIV1_gc: + break; + + default: + tc_clk_rate = 0; + break; + } + return (tc_clk_rate); +} + +/** + * \brief Configure Timer Direction + * + * \param tc Pointer to TC module. + * \param dir Timer direction : + */ +static inline void tc_set_direction(volatile void *tc, enum tc_dir_t dir) +{ + if (dir == TC_UP) { + ((TC0_t *)tc)->CTRLFCLR |= ~TC0_DIR_bm; + } else { + ((TC0_t *)tc)->CTRLFSET |= TC0_DIR_bm; + } +} + +/** + * \brief Write the Counter value of the Timer + * + * \param tc Pointer to TC module. + * \param cnt_value Counter value : + */ +static inline void tc_write_count(volatile void *tc, uint16_t cnt_value) +{ + ((TC0_t *)tc)->CNT = cnt_value; +} + +/** + * \brief Reads the Counter value of the Timer + * + * \param tc Pointer to TC module. + * \note Output the Counter value CNT + */ +static inline uint16_t tc_read_count(volatile void *tc) +{ + return (((TC0_t *)tc)->CNT); +} + +/** + * \brief Writes the Period value of the Timer + * + * \param tc Pointer to TC module. + * \param per_value Period value : PER + */ +static inline void tc_write_period(volatile void *tc, uint16_t per_value) +{ + ((TC0_t *)tc)->PER = per_value; +} + +/** + * \brief Reads the Period value of the Timer + * + * \param tc Pointer to TC module. + * \return Period value : PER + */ +static inline uint16_t tc_read_period(volatile void *tc) +{ + return (((TC0_t *)tc)->PER); +} + +/** + * \brief Writes the Period Buffer value of the Timer + * + * \param tc Pointer to TC module. + * \param per_buf Period Buffer value : PERH/PERL + */ +static inline void tc_write_period_buffer(volatile void *tc, uint16_t per_buf) +{ + ((TC0_t *)tc)->PERBUF = per_buf; +} + +/** + * \brief Reads the Period Buffer value of the Timer + * + * \param tc Pointer to TC module. + * \return Period Buffer value : PERH/PERL + */ +static inline uint16_t tc_read_period_buffer(volatile void *tc) +{ + return (((TC0_t *)tc)->PERBUF); +} + +/** + * \brief Tests if the Period Buffer is valid + * + * \param tc Pointer to TC module. + * \return period Buffer is valid or not:PERBV + */ +static inline bool tc_period_buffer_is_valid(volatile void *tc) +{ + return (((TC0_t *)tc)->CTRLGCLR & TC0_PERBV_bm); +} + +/** + * \brief Enables delay (used for 32bit timer mode) + * + * \param tc Pointer to TC module. + * \note enables Delay mode + */ +static inline void tc_enable_delay(volatile void *tc) +{ + ((TC0_t *)tc)->CTRLD = (((TC0_t *)tc)->CTRLD & + ~TC0_EVDLY_bm) | (1 << TC0_EVDLY_bp); +} + +/** + * \brief Disables delay + * + * \param tc Pointer to TC module. + * \note disables Delay mode + */ +static inline void tc_disable_delay(volatile void *tc) +{ + ((TC0_t *)tc)->CTRLD = ((TC0_t *)tc)->CTRLD & ~TC0_EVDLY_bm; +} + +/** + * \brief Tests if the Overflow flag is set + * + * \param tc Pointer to TC module. + * \return overflow has occurred or not : OVFIF + */ +static inline bool tc_is_overflow(volatile void *tc) +{ + return (((TC0_t *)tc)->INTFLAGS & TC0_OVFIF_bm); +} + +/** + * \brief Clears the Overflow flag + * + * \param tc Pointer to TC module. + * \note OVFIF is cleared + */ +static inline void tc_clear_overflow(volatile void *tc) +{ + ((TC0_t *)tc)->INTFLAGS |= TC0_OVFIF_bm; +} + +/** + * \brief Tests if the Error flag is set + * + * \param tc Pointer to TC module. + * \return Error has occurred or not : ERRIF + */ +static inline bool tc_read_error(volatile void *tc) +{ + return (((TC0_t *)tc)->INTFLAGS & TC0_ERRIF_bm); +} + +/** + * \brief Clears the Error flag + * + * \param tc Pointer to TC module. + * \note ERRIF is cleared + */ +static inline void tc_clear_error(volatile void *tc) +{ + ((TC0_t *)tc)->INTFLAGS |= TC0_ERRIF_bm; +} + +/** + * \brief Restart the Timer + * + * \param tc Pointer to TC module. + * \note CMD[3] in CTRLFSET is set to 1 and CMD[2] in CTRLFCLR is set + */ +static inline void tc_restart(volatile void *tc) +{ + ((TC0_t *)tc)->CTRLFSET = TC_CMD_RESTART_gc; +} + +/** + * \brief Reset the Timer + * + * \param tc Pointer to TC module. + * \note CMD[3:2] in CTRLFSET are set to 1 + */ +static inline void tc_reset(volatile void *tc) +{ + ((TC0_t *)tc)->CTRLFSET = TC_CMD_RESET_gc; +} + +/** + * \brief Update the Timer + * + * \param tc Pointer to TC module. + * \note CMD[2] in CTRLFSET is set to 1 and CMD[3] in CTRLFCLR is set + */ +static inline void tc_update(volatile void *tc) +{ + ((TC0_t *)tc)->CTRLFSET = TC_CMD_UPDATE_gc; +} + +/** + * \brief Configures the Timer in Byte mode + * + * \param tc Pointer to TC module. + * \note Configures BYTEM in CTRLE + */ +static inline void tc_set_8bits_mode(volatile void *tc) +{ +#ifdef TC0_BYTEM0_bm + ((TC0_t *)tc)->CTRLE |= TC0_BYTEM0_bm; +#else + ((TC0_t *)tc)->CTRLE |= TC0_BYTEM_bm; +#endif +} + +/** + * \brief Locks the Update of the Buffered registers + * + * \param tc Pointer to TC module. + * + * */ +static inline void tc_lock_update_buffers(volatile void *tc) +{ + ((TC0_t *)tc)->CTRLFSET |= TC0_LUPD_bm; +} + +/** + * \brief Unlocks the Update of the Buffered registers + * + * \param tc Pointer to TC module. + * \note Configures LUPD in CTRLFCLR + */ +static inline void tc_unlock_update_buffers(volatile void *tc) +{ + ((TC0_t *)tc)->CTRLFCLR |= TC0_LUPD_bm; +} + +/** + * \brief Enables Compare/Capture channel + * + * \param tc Pointer to TC module. + * \param enablemask CC channel + */ +static inline void tc_enable_cc_channels(volatile void *tc, + enum tc_cc_channel_mask_enable_t enablemask) +{ + if (tc_is_tc0(void *tc)) { + ((TC0_t *)tc)->CTRLB |= enablemask; + } else if (tc_is_tc1(void *tc)) { + ((TC1_t *)tc)->CTRLB |= + enablemask & (TC1_CCAEN_bm | TC1_CCBEN_bm); + } +} + +/** + * \brief Disables Compare/Capture channel + * + * \param tc Pointer to TC module. + * \param disablemask CC channel + */ +static inline void tc_disable_cc_channels(volatile void *tc, + enum tc_cc_channel_mask_enable_t disablemask) +{ + if (tc_is_tc0(void *tc)) { + ((TC0_t *)tc)->CTRLB &= ~disablemask; + } else if (tc_is_tc1(void *tc)) { + ((TC1_t *)tc)->CTRLB &= + ~(disablemask & TC0_CCAEN_bm & TC0_CCBEN_bm); + } +} + +/** + * \brief Enables Input capture mode + * + * \param tc Pointer to TC module. + * \param eventsource Source for the capture + * \param eventaction Event action capture type + */ +static inline void tc_set_input_capture(volatile void *tc, + TC_EVSEL_t eventsource, TC_EVACT_t eventaction) +{ + ((TC0_t *)tc)->CTRLD &= ~(TC0_EVSEL_gm | TC0_EVACT_gm); + ((TC0_t *)tc)->CTRLD |= ((uint8_t)eventsource | (uint8_t)eventaction); +} + +/** + * \brief Reads the Capture value + * + * \param tc Pointer to TC module. + * \param channel_index Channel x + * \return Read value of CCx + */ +static inline uint16_t tc_read_cc(volatile void *tc, + enum tc_cc_channel_t channel_index) +{ + if (tc_is_tc0(void *tc)) { + switch (channel_index) { + case TC_CCA: + return (((TC0_t *)tc)->CCA); + case TC_CCB: + return (((TC0_t *)tc)->CCB); + case TC_CCC: + return (((TC0_t *)tc)->CCC); + case TC_CCD: + return (((TC0_t *)tc)->CCD); + } + } else if (tc_is_tc1(void *tc)) { + switch (channel_index) { + case TC_CCA: + return (((TC1_t *)tc)->CCA); + case TC_CCB: + return (((TC1_t *)tc)->CCB); + default: + return (0); + } + } + return (0); +} + +/** + * \brief Writes the CC value + * + * \param tc Pointer to TC module. + * \param channel_index CC Channel + * \param value Counter value + */ +static inline void tc_write_cc(volatile void *tc, + enum tc_cc_channel_t channel_index, uint16_t value) +{ + if (tc_is_tc0(void *tc)) { + switch (channel_index) { + case TC_CCA: + ((TC0_t *)tc)->CCA = value; + break; + case TC_CCB: + ((TC0_t *)tc)->CCB = value; + break; + case TC_CCC: + ((TC0_t *)tc)->CCC = value; + break; + case TC_CCD: + ((TC0_t *)tc)->CCD = value; + break; + } + } else if (tc_is_tc1(void *tc)) { + switch (channel_index) { + case TC_CCA: + ((TC1_t *)tc)->CCA = value; + break; + case TC_CCB: + ((TC1_t *)tc)->CCB = value; + break; + default: + return ; + } + } +} + +/** + * \brief Writes the Capture/Compare Buffer value + * + * \param tc Pointer to TC module. + * \param channel_index CC Channel + * \param buffer_value Counter Buffer value + */ +static inline void tc_write_cc_buffer(volatile void *tc, + enum tc_cc_channel_t channel_index, uint16_t buffer_value) +{ + if (tc_is_tc0(void *tc)) { + switch (channel_index) { + case TC_CCA: + ((TC0_t *)tc)->CCABUF = buffer_value; + break; + case TC_CCB: + ((TC0_t *)tc)->CCBBUF = buffer_value; + break; + case TC_CCC: + ((TC0_t *)tc)->CCCBUF = buffer_value; + break; + case TC_CCD: + ((TC0_t *)tc)->CCDBUF = buffer_value; + break; + } + } else if (tc_is_tc1(void *tc)) { + switch (channel_index) { + case TC_CCA: + ((TC1_t *)tc)->CCABUF = buffer_value; + break; + case TC_CCB: + ((TC1_t *)tc)->CCBBUF = buffer_value; + break; + default: + return; + } + } +} + +/** + * \brief Reads the Capture/Compare Buffer value + * + * \param tc Pointer to TC module. + * \param channel_index CC Channel + * \return CCx Buffer value + */ +static inline uint16_t tc_read_cc_buffer(volatile void *tc, + enum tc_cc_channel_t channel_index) +{ + if (tc_is_tc0(void *tc)) { + switch (channel_index) { + case TC_CCA: + return (((TC0_t *)tc)->CCABUF); + case TC_CCB: + return (((TC0_t *)tc)->CCBBUF); + case TC_CCC: + return (((TC0_t *)tc)->CCCBUF); + case TC_CCD: + return (((TC0_t *)tc)->CCDBUF); + } + } else if (tc_is_tc1(void *tc)) { + switch (channel_index) { + case TC_CCA: + return (((TC1_t *)tc)->CCABUF); + case TC_CCB: + return (((TC1_t *)tc)->CCBBUF); + default: + return (0); + } + } + return (0); +} + +/** + * \brief Reports is Capture/Compare Buffer is valid + * + * \param tc Pointer to TC module. + * \param channel_index CC Channel + * \return CCx Buffer is valid or not + */ +static inline bool tc_cc_buffer_is_valid(volatile void *tc, + enum tc_cc_channel_t channel_index) +{ + if (tc_is_tc0(void *tc)) { + switch (channel_index) { + case TC_CCA: + return ((TC0_t *)tc)->CTRLGCLR & TC0_CCABV_bm; + case TC_CCB: + return ((TC0_t *)tc)->CTRLGCLR & TC0_CCBBV_bm; + case TC_CCC: + return ((TC0_t *)tc)->CTRLGCLR & TC0_CCCBV_bm; + case TC_CCD: + return ((TC0_t *)tc)->CTRLGCLR & TC0_CCDBV_bm; + } + } else if (tc_is_tc1(void *tc)) { + switch (channel_index) { + case TC_CCA: + return (((TC1_t *)tc)->CTRLGCLR & + TC1_CCABV_bm); + case TC_CCB: + return (((TC1_t *)tc)->CTRLGCLR & + TC1_CCBBV_bm); + default: + return (0); + } + } + return (0); +} + +/** + * \brief Reports if Capture/Compare interrupt has occurred + * + * \param tc Pointer to TC module. + * \param channel_index CC Channel + * \return CCx Interrupt or not + */ +static inline bool tc_is_cc_interrupt(volatile void *tc, + enum tc_cc_channel_t channel_index) +{ + if (tc_is_tc0(void *tc)) { + switch (channel_index) { + case TC_CCA: + return (((TC0_t *)tc)->INTFLAGS & TC0_CCAIF_bm); + case TC_CCB: + return (((TC0_t *)tc)->INTFLAGS & TC0_CCBIF_bm); + case TC_CCC: + return (((TC0_t *)tc)->INTFLAGS & TC0_CCCIF_bm); + case TC_CCD: + return (((TC0_t *)tc)->INTFLAGS & TC0_CCDIF_bm); + } + } else if (tc_is_tc1(void *tc)) { + switch (channel_index) { + case TC_CCA: + return (((TC1_t *)tc)->INTFLAGS & + TC1_CCAIF_bm); + case TC_CCB: + return (((TC1_t *)tc)->INTFLAGS & + TC1_CCBIF_bm); + default: + return (0); + } + } + return (0); +} + +/** + * \brief Clears Capture/Compare interrupt + * + * \param tc Pointer to TC module. + * \param channel_index CC Channel + */ +static inline void tc_clear_cc_interrupt(volatile void *tc, + enum tc_cc_channel_t channel_index) +{ + if (tc_is_tc0(void *tc)) { + switch (channel_index) { + case TC_CCA: + ((TC0_t *)tc)->INTFLAGS = TC0_CCAIF_bm; + break; + case TC_CCB: + ((TC0_t *)tc)->INTFLAGS = TC0_CCBIF_bm; + break; + case TC_CCC: + ((TC0_t *)tc)->INTFLAGS = TC0_CCCIF_bm; + break; + case TC_CCD: + ((TC0_t *)tc)->INTFLAGS = TC0_CCDIF_bm; + break; + } + } else if (tc_is_tc1(void *tc)) { + switch (channel_index) { + case TC_CCA: + ((TC1_t *)tc)->INTFLAGS = TC1_CCAIF_bm; + break; + case TC_CCB: + ((TC1_t *)tc)->INTFLAGS = TC1_CCBIF_bm; + break; + default: + return; + } + } +} + +/** + * \brief Configures TC in the specified Waveform generator mode + * + * \param tc Pointer to TC module. + * \param wgm : waveform generator + */ +static inline void tc_set_wgm(volatile void *tc, enum tc_wg_mode_t wgm) +{ + ((TC0_t *)tc)->CTRLB = (((TC0_t *)tc)->CTRLB & ~TC0_WGMODE_gm) | wgm; +} + +/** + * \ingroup tc_group + * \defgroup tc_awex_group AWeX extension driver + * This group provides low level drivers to configure AWeX extension + * @{ + */ + +/** + * \brief AWeX extension enable + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + */ +static inline void tc_awex_enable_cwcm(AWEX_t *awex) +{ + ((AWEX_t *)awex)->CTRL |= AWEX_CWCM_bm; +} + +/** + * \brief AWeX extension disable Common waveform mode + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + */ +static inline void tc_awex_disable_cwcm(AWEX_t *awex) +{ + ((AWEX_t *)awex)->CTRL &= ~AWEX_CWCM_bm; +} + +/** + * \brief AWeX extension enable pattern generator mode + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + */ +static inline void tc_awex_enable_pgm(AWEX_t *awex) +{ + ((AWEX_t *)awex)->CTRL |= AWEX_PGM_bm; +} + +/** + * \brief AWeX extension disable pattern generator mode + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + */ +static inline void tc_awex_disable_pgm(AWEX_t *awex) +{ + ((AWEX_t *)awex)->CTRL &= ~AWEX_PGM_bm; +} + +/** + * \brief AWeX extension : enable Deadtime insertion on ccA + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + */ +static inline void tc_awex_enable_cca_deadtime(AWEX_t *awex) +{ + ((AWEX_t *)awex)->CTRL |= AWEX_DTICCAEN_bm; +} + +/** + * \brief AWeX extension : disable Deadtime insertion on ccA + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + */ +static inline void tc_awex_disable_cca_deadtime(AWEX_t *awex) +{ + ((AWEX_t *)awex)->CTRL &= ~AWEX_DTICCAEN_bm; +} + +/** + * \brief AWeX extension : enable Deadtime insertion on ccB + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + */ +static inline void tc_awex_enable_ccb_deadtime(AWEX_t *awex) +{ + ((AWEX_t *)awex)->CTRL |= AWEX_DTICCBEN_bm; +} + +/** + * \brief AWeX extension : disable Deadtime insertion on ccB + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + */ +static inline void tc_awex_disable_ccb_deadtime(AWEX_t *awex) +{ + ((AWEX_t *)awex)->CTRL &= ~AWEX_DTICCBEN_bm; +} + +/** + * \brief AWeX extension : enable Deadtime insertion on ccC + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + */ +static inline void tc_awex_enable_ccc_deadtime(AWEX_t *awex) +{ + ((AWEX_t *)awex)->CTRL |= AWEX_DTICCCEN_bm; +} + +/** + * \brief AWeX extension : disable Deadtime insertion on ccD + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + */ +static inline void tc_awex_disable_ccc_deadtime(AWEX_t *awex) +{ + ((AWEX_t *)awex)->CTRL &= ~AWEX_DTICCCEN_bm; +} + +/** + * \brief AWeX extension : enable Deadtime insertion on ccD + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + */ +static inline void tc_awex_enable_ccd_deadtime(AWEX_t *awex) +{ + ((AWEX_t *)awex)->CTRL |= AWEX_DTICCDEN_bm; +} + +/** + * \brief AWeX extension : disable Deadtime insertion on ccD + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + */ +static inline void tc_awex_disable_ccd_deadtime(AWEX_t *awex) +{ + ((AWEX_t *)awex)->CTRL &= ~AWEX_DTICCDEN_bm; +} +/** + * \brief AWeX extension : configures high side deadtime + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + * \param value : deadtime value + */ +static inline void tc_awex_set_dti_high(AWEX_t *awex, int16_t value) +{ + ((AWEX_t *)awex)->DTHS = value; +} +/** + * \brief AWeX extension : configures low side deadtime + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + * \param value : deadtime value + */ +static inline void tc_awex_set_dti_low(AWEX_t *awex, int16_t value) +{ + ((AWEX_t *)awex)->DTLS = value; +} +/** + * \brief AWeX extension : configures symmetrical deadtime + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + * \param value : deadtime value + */ +static inline void tc_awex_set_dti_both(AWEX_t *awex, int16_t value) +{ + ((AWEX_t *)awex)->DTBOTH = value; +} + +/** + * \brief AWeX extension : configures symmetrical deadtime buffer + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + * \param value : deadtime buffer value + */ +static inline void tc_awex_set_dti_both_buffer(AWEX_t *awex, + int16_t value) +{ + ((AWEX_t *)awex)->DTBOTHBUF = value; +} + +/** + * \brief AWeX extension : returns the deadtime buffer high nibble + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + * \return Dead Time High value + */ +static inline int8_t tc_awex_get_dti_high_buffer(AWEX_t *awex) +{ + return (((AWEX_t *)awex)->DTHSBUF); +} + +/** + * \brief AWeX extension : returns the deadtime buffer low nibble + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + * \return Dead Time High value + */ +static inline int8_t tc_awex_get_dti_low_buffer(AWEX_t *awex) +{ + return (((AWEX_t *)awex)->DTLSBUF); +} + +/** + * \brief AWeX extension : returns if DTI high buffer is valid + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + * \return Dead Time High Buffer valid or not + */ +static inline bool tc_awex_is_dti_high_buffer_valid(AWEX_t *awex) +{ + return (((AWEX_t *)awex)->STATUS & AWEX_DTHSBUFV_bm); +} + +/** + * \brief AWeX extension : returns if DTI low buffer is valid + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + * \return Dead Time Low Buffer is valid or not + */ +static inline bool tc_awex_is_dti_low_buffer_valid(AWEX_t *awex) +{ + return (((AWEX_t *)awex)->STATUS & AWEX_DTLSBUFV_bm); +} + +/** + * \brief AWeX extension : configures the Fault restart in latched mode + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + */ +static inline void tc_awex_fdmode_restart_latched(AWEX_t *awex) +{ + ((AWEX_t *)awex)->FDCTRL &= ~AWEX_FDMODE_bm; +} + +/** + * \brief AWeX extension : configures the Fault restart in cycle to cycle mode + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + */ +static inline void tc_awex_fdmode_restart_cycle(AWEX_t *awex) +{ + ((AWEX_t *)awex)->FDCTRL |= AWEX_FDMODE_bm; +} + +/** + * \brief AWeX extension : returns if fault is detected + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + */ +static inline bool tc_awex_fault_is_detected(AWEX_t *awex) +{ + return (((AWEX_t *)awex)->STATUS & AWEX_FDF_bm); +} + +/** + * \brief AWeX extension : clears the Fault detection + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + */ +static inline void tc_awex_clear_fault(AWEX_t *awex) +{ + ((AWEX_t *)awex)->STATUS = AWEX_FDF_bm; +} + +/** + * \brief AWeX extension : configures fault action + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + * \param fd_act Fault action + */ +static inline void tc_awex_set_fault_detection_action(AWEX_t * + awex, AWEX_FDACT_t fd_act) +{ + ((AWEX_t *)awex)->FDCTRL = (((AWEX_t *)awex)->FDCTRL & ~AWEX_FDACT_gm) | + (fd_act & AWEX_FDACT_gm); + +} + +/** + * \brief AWeX extension : configures fault detection event + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + * \param eventmask Fault detection event + */ +static inline void tc_awex_set_fault_detection_event(AWEX_t *awex, + int8_t eventmask) +{ + ((AWEX_t *)awex)->FDEMASK = eventmask; +} + +/** + * \brief AWeX extension : configures the port overdrive + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + * \param value Output override configuration + */ +static inline void tc_awex_set_output_override(AWEX_t * awex, + int8_t value) +{ + ((AWEX_t *)awex)->OUTOVEN = value; +} + +/** + * \brief AWeX extension : enable fault detection on debug break detection + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + */ +static inline void tc_awex_enable_fault_debug_break(AWEX_t *awex) +{ + ((AWEX_t *)awex)->FDCTRL &= ~AWEX_FDDBD_bm; +} + +/** + * \brief AWeX extension : disable fault detection on debug break detection + * + * \param awex Pointer to AWeX module (AWEXC or AWEXE) + */ +static inline void tc_awex_disable_fault_debug_break(AWEX_t *awex) +{ + ((AWEX_t *)awex)->FDCTRL |= AWEX_FDDBD_bm; +} +//@} +/** + * \ingroup tc_group + * \defgroup tc_hires_group Hi-Res extension driver + * This group provides low level drivers to configure Hi-Res extension + * @{ + */ + +/** + * \brief Hi-Res Extension : configures the Hi-Res + * + * \param hires Pointer to AWeX module (AWEXC or AWEXE) + * \param hi_res_mode HIRES configuration + */ +static inline void tc_hires_set_mode(HIRES_t * hires, HIRES_HREN_t hi_res_mode) +{ + ((HIRES_t *)hires)->CTRLA = hi_res_mode; +} +//@} + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +/** + * \page xmega_tc_quickstart Quick Start Guide for the XMEGA TC Driver + * + * This is the quick start guide for the \ref tc_group , with step-by-step + * instructions on how to configure and use the driver for a specific use case. + * The code examples can be copied into e.g the main application loop or any + * other function that will need to control the timer/counters. + * + * + * \section xmega_tc_qs_use_cases Use cases + * - \ref xmega_tc_qs_ovf + * - \ref xmega_tc_qs_cc + * - \ref xmega_tc_qs_pwm + * + * + * \section xmega_tc_qs_ovf Timer/counter overflow (interrupt based) + * + * This use case will prepare a timer to trigger an interrupt when the timer + * overflows. The interrupt is handled by a cutomisable callback function. + * + * We will setup the timer in this mode: + * - Normal WGM mode (incrementing timer) + * - Use the system clock as clock source + * - No prescaling (clock divider set to 1) + * - Overflow interrupt after 1000 counts. This will be done by setting the top + * value to 1000. + * + * + * \section xmega_tc_qs_ovf_setup Setup steps + * + * \subsection xmega_tc_qs_ovf_usage_prereq Prequisites + * + * For the setup code of this use case to work, the following must + * be added to the project: + * - \ref interrupt_group "Global Interrupt Management" + * - \ref clk_group "Clock Management" + * + * \subsection xmega_tc_qs_ovf_setup_code Example code + * + * Add a callback function that will be executed when the overflow interrupt + * trigger. + * \code + static void my_callback(void) + { + // User code to execute when the overflow occurs here + } +\endcode + * Add to, e.g., the main loop in the application C-file: + * \code + pmic_init(); + sysclk_init(); + tc_enable(&TCC0); + tc_set_overflow_interrupt_callback(&TCC0, my_callback); + tc_set_wgm(&TCC0, TC_WG_NORMAL); + tc_write_period(&TCC0, 1000); + tc_set_overflow_interrupt_level(&TCC0, TC_INT_LVL_LO); + cpu_irq_enable(); + tc_write_clock_source(&TCC0, TC_CLKSEL_DIV1_gc); +\endcode + * + * \subsection xmega_tc_qs_ovf_setup_code_workflow Workflow + * + * -# Enable the interrupt controller: + * - \code pmic_init(); \endcode + * -# Enable the clock system: + * - \code sysclk_init(); \endcode + * -# Enable timer/counter TCC0 + * - \code tc_enable(&TCC0); \endcode + * \note This will enable the clock system for the module + * -# Set the callback function for overflow interrupt + * - \code tc_set_overflow_interrupt_callback(&TCC0, my_callback); \endcode + * \warning This function requires that the my_callback function is defined + * -# Set the desired waveform mode + * - \code tc_set_wgm(&TCC0, TC_WG_NORMAL); \endcode + * \note In this case, we use normal mode where the timer increments it + count value until the TOP value is reached. The timer then reset + its count value to 0. + * -# Set the period + * - \code tc_write_period(&TCC0, 1000); \endcode + * \note This will specify the TOP value of the counter. The timer will + * overflow and reset when this value is reached. + * -# Set the overflow interrupt level + * - \code tc_set_overflow_interrupt_level(&TCC0, TC_INT_LVL_LO); \endcode + * -# Enable interrupts: + * - \code cpu_irq_enable(); \endcode + * -# Set the clock source + * - \code tc_write_clock_source(&TCC0, TC_CLKSEL_DIV1_gc); \endcode + * \warning When the clock source is set, the timer will start counting + * + * \section xmega_tc_qs_ovf_usage Usage steps + * + * - None. The timer will run in the background, and the code written in the + * call back function will execute each time the timer overflows. + * + * + * \section xmega_tc_qs_cc Timer/counter compare match (interrupt based) + * + * This use case will prepare a timer to trigger two independent interrupts + * when it reaches two different compare values. The period of the timer + * is customizable and the two compare matches will be handled by two separate + * interrupts implemented in call back functions. + * + * We will setup the timer in this mode: + * - Normal WGM mode - incrementing timer + * - Use the system clock as clock source + * - No prescaling (divider set to 1) + * - Period of timer 10000 counts + * - Compare match A interrupt trigger after 100 counts + * - Compare match B interrupt trigger after 1000 counts + * - If compare A and compare B match occurs simultaneously, compare B + * should have higher priority + * + * + * \section xmega_tc_qs_cc_setup Setup steps + * + * \subsection xmega_tc_qs_cc_usage_prereq Prequisites + * For the setup code of this use case to work, the following must + * be added to the project: + * - \ref interrupt_group "Global Interrupt Management" + * - \ref clk_group "Clock Management" + * + * \subsection xmega_tc_qs_cc_setup_code Example code + * + * Add two callback functions that will be executed when compare match A and + * compare match B occurs + * \code + static void my_cca_callback(void) + { + // User code here to execute when a channel A compare match occurs + } + static void my_ccb_callback(void) + { + // User code here to execute when a channel B compare match occurs + } +\endcode + * Add to, e.g., the main loop in the application C-file: + * \code + pmic_init(); + sysclk_init(); + cpu_irq_enable(); + tc_enable(&TCC0); + tc_set_cca_interrupt_callback(&TCC0, my_cca_callback); + tc_set_ccb_interrupt_callback(&TCC0, my_ccb_callback); + tc_set_wgm(&TCC0, TC_WG_NORMAL); + tc_write_period(&TCC0, 10000); + tc_write_cc(&TCC0, TC_CCA, 100); + tc_write_cc(&TCC0, TC_CCB, 1000); + tc_enable_cc_channels(&TCC0,(TC_CCAEN | TC_CCBEN)); + tc_set_cca_interrupt_level(&TCC0, TC_INT_LVL_LO); + tc_set_ccb_interrupt_level(&TCC0, TC_INT_LVL_MED); + tc_write_clock_source(&TCC0, TC_CLKSEL_DIV1_gc); +\endcode + * + * \subsection xmega_tc_qs_cc_setup_code_workflow Workflow + * + * -# Enable the interrupt controller: + * - \code pmic_init(); \endcode + * -# Enable the clock system: + * - \code sysclk_init(); \endcode + * -# Enable interrupts: + * - \code cpu_irq_enable(); \endcode + * -# Enable timer/counter TCC0 + * - \code tc_enable(&TCC0); \endcode + * \note This will enable the clock system for the module + * -# Set call back function for CCA interrupt + * - \code tc_set_cca_interrupt_callback(&TCC0, my_cca_callback); \endcode + * \warning This function requires that the call back function is defined + * -# Set call back function for CCB interrupt + * - \code tc_set_ccb_interrupt_callback(&TCC0, my_ccb_callback); \endcode + * \warning This function requires that the call back function is defined + * -# Set the desired waveform mode + * - \code tc_set_wgm(&TCC0, TC_WG_NORMAL); \endcode + * \note In this case, we use normal mode where the timer increments it + count value until the TOP value is reached. The timer then reset + its count value to 0. + * -# Set the period + * - \code tc_write_period(&TCC0, 10000); \endcode + * \note This will specify the TOP value of the counter. The timer will + * overflow and reset when this value is reached. + * -# Set compare match value on CCA + * - \code tc_write_cc(&TCC0, TC_CCA, 100); \endcode + * -# Set compare match value on CCB + * - \code tc_write_cc(&TCC0, TC_CCB, 1000); \endcode + * -# Enable compare channel A and compare channel B + * -\code tc_enable_cc_channels(&TCC0, (TC_CCAEN | TC_CCBEN)); \endcode + * -# Set interrupt level on channel A (low priority, see \ref TC_INT_LEVEL_t) + * - \code tc_set_cca_interrupt_level(&TCC0, TC_INT_LVL_LO); \endcode + * -# Set interrupt level on channel B (medium priority \ref TC_INT_LEVEL_t) + * - \code tc_set_ccb_interrupt_level(&TCC0, TC_INT_LVL_MED); \endcode + * -# Set the clock source + * - \code tc_write_clock_source(&TCC0, TC_CLKSEL_DIV1_gc); \endcode + * \warning When the clock source is set, the timer will start counting + * + * \section xmega_tc_qs_cc_usage Usage steps + * + * - None. The timer will run in the background, and the code written in the + * call back functions will execute each time a compare match occur. + * + * + * \section xmega_tc_qs_pwm Timer/counter PWM + * + * This use case will setup a timer in PWM mode. For more details you can + * also look at the XMEGA PWM service. + * + * We will setup the timer in this mode: + * - Normal WGM mode - incrementing timer + * - Use the 2MHz oscillator as clock source (default) + * - 1Hz PWM frequency (2MHz clock, 1024x prescale, TOP value 1950) + * - 10% duty cycle (1:10 ratio between PER and CC register) + * - Output the PWM signal to a I/O port + * + * \section xmega_tc_qs_pwm_setup Setup steps + * + * \subsection xmega_tc_qs_pwm_usage_prereq Prequisites + * For the setup code of this use case to work, the following must + * be added to the project: + * - \ref clk_group "Clock Management" + * + * \subsection xmega_tc_qs_pwm_setup_code Example code + * + * Add to, e.g., the main loop in the application C-file: + * \code + board_init(); + sysclk_init(); + tc_enable(&TCE0); + tc_set_wgm(&TCE0, TC_WG_SS); + tc_write_period(&TCE0, 1950); + tc_write_cc(&TCE0, TC_CCA, 195); + tc_enable_cc_channels(&TCE0,TC_CCAEN); + tc_write_clock_source(&TCE0, TC_CLKSEL_DIV1024_gc); +\endcode + * + * \subsection xmega_tc_qs_pwm_setup_code_workflow Workflow + * + * -# Ensure that PWM I/O pin is configured as output + * - \code board_init(); \endcode + * \note The board_init(); function configures the I/O pins. If this function + * is not executed, the I/O pin must be configured as output manually + * -# Enable the clock system: + * - \code sysclk_init(); \endcode + * -# Enable timer/counter TCE0 + * - \code tc_enable(&TCE0); \endcode + * \note This will enable the clock system for the module + * -# Set the desired waveform mode + * - \code tc_set_wgm(&TCE0, TC_WG_NORMAL); \endcode + * \note In this case, we use normal mode where the timer increments it + * count value until the TOP value is reached. The timer then reset + * its count value to 0. + * -# Set the period + * - \code tc_write_period(&TCE0, 1950); \endcode + * \note This will specify the TOP value of the counter. The timer will + * overflow and reset when this value is reached. + * -# Set compare match value on CCA + * - \code tc_write_cc(&TCC0, TC_CCA, 195); \endcode + * \note The PWM duty cycle will be the ratio between PER and CCA, which + * is set by the tc_write_period() and tc_write_cc() functions. Use + * tc_write_cc() to change duty cycle run time (e.g to dim a LED). + * When CCA = 0, the duty cycle will be 0%. When CCA = PER (top value) + * the duty cycle will be 100%. + * -# Enable compare channel A + * -\code tc_enable_cc_channels(&TCE0,TC_CCAEN); \endcode + * -# Set the clock source + * - \code tc_write_clock_source(&TCE0, TC_CLKSEL_DIV1024_gc); \endcode + * \warning When the clock source is set, the timer will start counting + * + * \section xmega_tc_qs_pwm_usage Usage steps + * - Use tc_write_cc() to change the duty cycle of the PWM signal + * - Use tc_write_period() to change the PWM frequency + */ + +#endif /* _TC_H_ */ diff --git a/Fred_bootloader/src/ASF/xmega/drivers/usart/usart.c b/Fred_bootloader/src/ASF/xmega/drivers/usart/usart.c new file mode 100644 index 0000000000000000000000000000000000000000..4740bfcb1ddf877110d2aaefca0f09864d6f568b --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/drivers/usart/usart.c @@ -0,0 +1,464 @@ +/** + * \file + * + * \brief USART driver for AVR XMEGA. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#include <stdint.h> +#include "compiler.h" +#include "usart.h" +#include "sysclk.h" +#include "ioport.h" +#include "status_codes.h" + +/* + * Fix XMEGA header files + * USART.CTRLC bit masks and bit positions + */ +#ifndef USART_UCPHA_bm +# define USART_UCPHA_bm 0x02 +#endif +#ifndef USART_DORD_bm +# define USART_DORD_bm 0x04 +#endif + +/** + * \brief Initialize USART in RS232 mode. + * + * This function initializes the USART module in RS232 mode using the + * usart_rs232_options_t configuration structure and CPU frequency. + * + * \param usart The USART module. + * \param opt The RS232 configuration option. + * + * \retval true if the initialization was successfull + * \retval false if the initialization failed (error in baud rate calculation) + */ +bool usart_init_rs232(USART_t *usart, const usart_rs232_options_t *opt) +{ + bool result; + sysclk_enable_peripheral_clock(usart); + usart_set_mode(usart, USART_CMODE_ASYNCHRONOUS_gc); + usart_format_set(usart, opt->charlength, opt->paritytype, + opt->stopbits); + result = usart_set_baudrate(usart, opt->baudrate, sysclk_get_per_hz()); + usart_tx_enable(usart); + usart_rx_enable(usart); + + return result; +} + +/** + * \brief Initialize USART in SPI master mode. + * + * This function initializes the USART module in SPI master mode using the + * usart_spi_options_t configuration structure and CPU frequency. + * + * \param usart The USART module. + * \param opt The RS232 configuration option. + */ +void usart_init_spi(USART_t *usart, const usart_spi_options_t *opt) +{ + ioport_pin_t sck_pin; + bool invert_sck; + + sysclk_enable_peripheral_clock(usart); + + usart_rx_disable(usart); + + /* configure Clock polarity using INVEN bit of the correct SCK I/O port **/ + invert_sck = (opt->spimode == 2) || (opt->spimode == 3); + UNUSED(invert_sck); + +#ifdef USARTC0 + if ((uint16_t)usart == (uint16_t)&USARTC0) { +# ifdef PORT_USART0_bm + if (PORTC.REMAP & PORT_USART0_bm) { + sck_pin = IOPORT_CREATE_PIN(PORTC, 5); + } else { + sck_pin = IOPORT_CREATE_PIN(PORTC, 1); + } +# else + sck_pin = IOPORT_CREATE_PIN(PORTC, 1); +# endif + } +#endif +#ifdef USARTC1 + if ((uint16_t)usart == (uint16_t)&USARTC1) { + sck_pin = IOPORT_CREATE_PIN(PORTC, 5); + } +#endif +#ifdef USARTD0 + if ((uint16_t)usart == (uint16_t)&USARTD0) { +# ifdef PORT_USART0_bm + if (PORTD.REMAP & PORT_USART0_bm) { + sck_pin = IOPORT_CREATE_PIN(PORTD, 5); + } else { + sck_pin = IOPORT_CREATE_PIN(PORTD, 1); + } +# else + sck_pin = IOPORT_CREATE_PIN(PORTD, 1); +# endif + } +#endif +#ifdef USARTD1 + if ((uint16_t)usart == (uint16_t)&USARTD1) { + sck_pin = IOPORT_CREATE_PIN(PORTD, 5); + } +#endif +#ifdef USARTE0 + if ((uint16_t)usart == (uint16_t)&USARTE0) { +# ifdef PORT_USART0_bm + if(PORTE.REMAP & PORT_USART0_bm) { + sck_pin = IOPORT_CREATE_PIN(PORTE, 5); + } else { + sck_pin = IOPORT_CREATE_PIN(PORTE, 1); + } +# else + sck_pin = IOPORT_CREATE_PIN(PORTE, 1); +# endif + } +#endif +#ifdef USARTE1 + if ((uint16_t)usart == (uint16_t)&USARTE1) { + sck_pin = IOPORT_CREATE_PIN(PORTE, 5); + } +#endif +#ifdef USARTF0 + if ((uint16_t)usart == (uint16_t)&USARTF0) { +# ifdef PORT_USART0_bm + if(PORTF.REMAP & PORT_USART0_bm) { + sck_pin = IOPORT_CREATE_PIN(PORTF, 5); + } else { + sck_pin = IOPORT_CREATE_PIN(PORTF, 1); + } +# else + sck_pin = IOPORT_CREATE_PIN(PORTF, 1); +# endif + } +#endif +#ifdef USARTF1 + if ((uint16_t)usart == (uint16_t)&USARTF1) { + sck_pin = IOPORT_CREATE_PIN(PORTF, 5); + } +#endif + + /* Configure the USART output pin */ + ioport_set_pin_dir(sck_pin, IOPORT_DIR_OUTPUT); + ioport_set_pin_mode(sck_pin, + IOPORT_MODE_TOTEM | (invert_sck? IOPORT_MODE_INVERT_PIN : 0)); + ioport_set_pin_level(sck_pin, IOPORT_PIN_LEVEL_HIGH); + + usart_set_mode(usart, USART_CMODE_MSPI_gc); + + if (opt->spimode == 1 || opt->spimode == 3) { + usart->CTRLC |= USART_UCPHA_bm; + } else { + usart->CTRLC &= ~USART_UCPHA_bm; + } + if (opt->data_order) { + (usart)->CTRLC |= USART_DORD_bm; + } else { + (usart)->CTRLC &= ~USART_DORD_bm; + } + + usart_spi_set_baudrate(usart, opt->baudrate, sysclk_get_per_hz()); + usart_tx_enable(usart); + usart_rx_enable(usart); +} + +/** + * \brief Send a data with the USART module + * + * This function outputs a data using the USART module. + * + * \param usart The USART module. + * \param c The data to send. + * + * \return STATUS_OK + */ +enum status_code usart_putchar(USART_t *usart, uint8_t c) +{ + while (usart_data_register_is_empty(usart) == false) { + } + + (usart)->DATA = c; + return STATUS_OK; +} + +/** + * \brief Receive a data with the USART module + * + * This function returns the received data from the USART module. + * + * \param usart The USART module. + * + * \return The received data. + */ +uint8_t usart_getchar(USART_t *usart) +{ + while (usart_rx_is_complete(usart) == false) { + } + + return ((uint8_t)(usart)->DATA); +} + +/** + * \brief Get the offset for lookup in the baudrate table + * + * \param baud The requested baudrate + * + * \return The baudrate offset in PROGMEM table + * \retval USART_BAUD_UNDEFINED for baudrates not in lookup table + */ +static uint8_t usart_get_baud_offset(uint32_t baud) +{ + switch (baud) { + case 1200: + return (uint8_t)USART_BAUD_1200; + + case 2400: + return (uint8_t)USART_BAUD_2400; + + case 4800: + return (uint8_t)USART_BAUD_4800; + + case 9600: + return (uint8_t)USART_BAUD_9600; + + case 19200: + return (uint8_t)USART_BAUD_19200; + + case 38400: + return (uint8_t)USART_BAUD_38400; + + case 57600: + return (uint8_t)USART_BAUD_57600; + + default: + return (uint8_t)USART_BAUD_UNDEFINED; + } +} + +/** + * \brief Set the baudrate by setting the BSEL and BSCALE values in the USART + * + * This function sets the selected BSEL and BSCALE value in the BAUDCTRL + * registers with BSCALE 0. For calculation options, see table 21-1 in XMEGA A + * manual. + * + * \param usart The USART module. + * \param bsel Calculated BSEL value. + * \param bscale Calculated BSEL value. + * + */ +void usart_set_bsel_bscale_value(USART_t *usart, uint16_t bsel, uint8_t bscale) +{ + (usart)->BAUDCTRLA = (uint8_t)(bsel); + (usart)->BAUDCTRLB = (uint8_t)(((bsel >> 8) & 0X0F) | (bscale << 4)); +} + +/** + * \brief Set the baudrate using precalculated BAUDCTRL values from PROGMEM + * + * \note This function only works for cpu_hz 2Mhz or 32Mhz and baudrate values + * 1200, 2400, 4800, 9600, 19200, 38400 and 57600. + * + * \param usart The USART module. + * \param baud The baudrate. + * \param cpu_hz The CPU frequency. + * + */ +void usart_set_baudrate_precalculated(USART_t *usart, uint32_t baud, + uint32_t cpu_hz) +{ + uint8_t baud_offset; + uint16_t baudctrl = 0; + + baud_offset = usart_get_baud_offset(baud); + + if (cpu_hz == 2000000UL) { + baudctrl = PROGMEM_READ_WORD(baudctrl_2mhz + baud_offset); + } else if (cpu_hz == 32000000UL) { + baudctrl = PROGMEM_READ_WORD(baudctrl_32mhz + baud_offset); + } else { + /* Error, system clock speed or USART baud rate is not supported + * by the look-up table */ + Assert(false); + } + + if (baud_offset != USART_BAUD_UNDEFINED) { + (usart)->BAUDCTRLB = (uint8_t)((uint16_t)baudctrl); + (usart)->BAUDCTRLA = (uint8_t)((uint16_t)baudctrl >> 8); + } +} + +/** + * \brief Set the baudrate value in the USART module + * + * This function sets the baudrate register with scaling regarding the CPU + * frequency and makes sure the baud rate is supported by the hardware. + * The function can be used if you don't want to calculate the settings + * yourself or changes to baudrate at runtime is required. + * + * \param usart The USART module. + * \param baud The baudrate. + * \param cpu_hz The CPU frequency. + * + * \retval true if the hardware supports the baud rate + * \retval false if the hardware does not support the baud rate (i.e. it's + * either too high or too low.) + */ +bool usart_set_baudrate(USART_t *usart, uint32_t baud, uint32_t cpu_hz) +{ + int8_t exp; + uint32_t div; + uint32_t limit; + uint32_t ratio; + uint32_t min_rate; + uint32_t max_rate; + + /* + * Check if the hardware supports the given baud rate + */ + /* 8 = (2^0) * 8 * (2^0) = (2^BSCALE_MIN) * 8 * (BSEL_MIN) */ + max_rate = cpu_hz / 8; + /* 4194304 = (2^7) * 8 * (2^12) = (2^BSCALE_MAX) * 8 * (BSEL_MAX+1) */ + min_rate = cpu_hz / 4194304; + + if (!((usart)->CTRLB & USART_CLK2X_bm)) { + max_rate /= 2; + min_rate /= 2; + } + + if ((baud > max_rate) || (baud < min_rate)) { + return false; + } + + /* Check if double speed is enabled. */ + if (!((usart)->CTRLB & USART_CLK2X_bm)) { + baud *= 2; + } + + /* Find the lowest possible exponent. */ + limit = 0xfffU >> 4; + ratio = cpu_hz / baud; + + for (exp = -7; exp < 7; exp++) { + if (ratio < limit) { + break; + } + + limit <<= 1; + + if (exp < -3) { + limit |= 1; + } + } + + /* + * Depending on the value of exp, scale either the input frequency or + * the target baud rate. By always scaling upwards, we never introduce + * any additional inaccuracy. + * + * We are including the final divide-by-8 (aka. right-shift-by-3) in + * this operation as it ensures that we never exceeed 2**32 at any + * point. + * + * The formula for calculating BSEL is slightly different when exp is + * negative than it is when exp is positive. + */ + if (exp < 0) { + /* We are supposed to subtract 1, then apply BSCALE. We want to + * apply BSCALE first, so we need to turn everything inside the + * parenthesis into a single fractional expression. + */ + cpu_hz -= 8 * baud; + + /* If we end up with a left-shift after taking the final + * divide-by-8 into account, do the shift before the divide. + * Otherwise, left-shift the denominator instead (effectively + * resulting in an overall right shift.) + */ + if (exp <= -3) { + div = ((cpu_hz << (-exp - 3)) + baud / 2) / baud; + } else { + baud <<= exp + 3; + div = (cpu_hz + baud / 2) / baud; + } + } else { + /* We will always do a right shift in this case, but we need to + * shift three extra positions because of the divide-by-8. + */ + baud <<= exp + 3; + div = (cpu_hz + baud / 2) / baud - 1; + } + + (usart)->BAUDCTRLB = (uint8_t)(((div >> 8) & 0X0F) | (exp << 4)); + (usart)->BAUDCTRLA = (uint8_t)div; + + return true; +} + +/** + * \brief Set the baudrate value in the USART_SPI module + * + * This function sets the baudrate register regarding the CPU frequency. + * + * \param usart The USART(SPI) module. + * \param baud The baudrate. + * \param cpu_hz The CPU frequency. + */ +void usart_spi_set_baudrate(USART_t *usart, uint32_t baud, uint32_t cpu_hz) +{ + uint16_t bsel_value; + + /* Check if baudrate is less than the maximim limit specified in + * datasheet */ + if (baud < (cpu_hz / 2)) { + bsel_value = (cpu_hz / (baud * 2)) - 1; + } else { + /* If baudrate is not within the specfication in datasheet, + * assign maximum baudrate possible for the current CPU frequency */ + bsel_value = 0; + } + + (usart)->BAUDCTRLB = (uint8_t)((~USART_BSCALE_gm) & (bsel_value >> 8)); + (usart)->BAUDCTRLA = (uint8_t)(bsel_value); +} diff --git a/Fred_bootloader/src/ASF/xmega/drivers/usart/usart.h b/Fred_bootloader/src/ASF/xmega/drivers/usart/usart.h new file mode 100644 index 0000000000000000000000000000000000000000..4f81770d6ae13a519ad6870f7cb976792445d78b --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/drivers/usart/usart.h @@ -0,0 +1,555 @@ +/** + * \file + * + * \brief USART driver for AVR XMEGA. + * + * This file contains basic functions for the AVR XMEGA USART, with support for all + * modes, settings and clock speeds. + * + * Copyright (c) 2009-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef _USART_H_ +#define _USART_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "compiler.h" +#include "pmic.h" + +/** + * \defgroup usart_group USART module (USART) + * + * See \ref xmega_usart_quickstart. + * + * This is a driver for configuring, enabling, disabling and use of the on-chip + * USART. + * + * \section dependencies Dependencies + * + * The USART module depends on the following modules: + * - \ref sysclk_group for peripheral clock control. + * - \ref port_driver_group for peripheral io port control. + * + * @{ + */ + +//! Offset in lookup table for baudrate 1200 +#define USART_BAUD_1200 0x00 +//! Offset in lookup table for baudrate 2400 +#define USART_BAUD_2400 0x01 +//! Offset in lookup table for baudrate 4800 +#define USART_BAUD_4800 0x02 +//! Offset in lookup table for baudrate 9600 +#define USART_BAUD_9600 0x03 +//! Offset in lookup table for baudrate 19200 +#define USART_BAUD_19200 0x04 +//! Offset in lookup table for baudrate 38400 +#define USART_BAUD_38400 0x05 +//! Offset in lookup table for baudrate 57600 +#define USART_BAUD_57600 0x06 +//! Baudrate not in lookup table +#define USART_BAUD_UNDEFINED 0xFF + +//! Lookup table containing baudctrl values for CPU frequency 2 Mhz +static PROGMEM_DECLARE(uint16_t, baudctrl_2mhz[]) = { + 0xE5BC, // Baud: 1200 + 0xC5AC, // Baud: 2400 + 0x859C, // Baud: 4800 + 0x0396, // Baud: 9600 + 0xC192, // Baud: 19200 + 0x2191, // Baud: 38400 + 0x9690, // Baud: 57600 +}; + +//! Lookup table containing baudctrl values for CPU frequency 32 Mhz +static PROGMEM_DECLARE(uint16_t, baudctrl_32mhz[]) = { + 0x031D, // Baud: 1200 + 0x01ED, // Baud: 2400 + 0xFDDC, // Baud: 4800 + 0xF5CC, // Baud: 9600 + 0xE5BC, // Baud: 19200 + 0xC5AC, // Baud: 38400 + 0x6EA8, // Baud: 57600 +}; + + +//! Input parameters when initializing RS232 and similar modes. +typedef struct usart_rs232_options { + //! Set baud rate of the USART (unused in slave modes). + uint32_t baudrate; + + //! Number of bits to transmit as a character (5 to 9). + USART_CHSIZE_t charlength; + + //! Parity type: USART_PMODE_DISABLED_gc, USART_PMODE_EVEN_gc, + //! USART_PMODE_ODD_gc. + USART_PMODE_t paritytype; + + //! Number of stop bits between two characters: + //! true: 2 stop bits + //! false: 1 stop bit + bool stopbits; + +} usart_rs232_options_t; + +//! Input parameters when initializing SPI master mode. +typedef struct usart_spi_options { + //! Set baud rate of the USART in SPI mode. + uint32_t baudrate; + + //! SPI transmission mode. + uint8_t spimode; + + uint8_t data_order; +} usart_spi_options_t; + +//! USART interrupt levels +enum usart_int_level_t { + USART_INT_LVL_OFF = 0x00, + USART_INT_LVL_LO = 0x01, + USART_INT_LVL_MED = 0x02, + USART_INT_LVL_HI = 0x03, +}; + +/** + * \brief Enable USART receiver. + * + * \param usart Pointer to the USART module + */ +static inline void usart_rx_enable(USART_t *usart) +{ + (usart)->CTRLB |= USART_RXEN_bm; +} + +/** + * \brief Disable USART receiver. + * + * \param usart Pointer to the USART module. + */ +static inline void usart_rx_disable(USART_t *usart) +{ + (usart)->CTRLB &= ~USART_RXEN_bm; +} + +/** + * \brief Configure the USART frame format. + * + * Sets the frame format, Frame Size, parity mode and number of stop bits. + * + * \param usart Pointer to the USART module + * \param charSize The character size. Use USART_CHSIZE_t type. + * \param parityMode The parity Mode. Use USART_PMODE_t type. + * \param twoStopBits Enable two stop bit mode. Use bool type. + */ +static inline void usart_format_set(USART_t *usart, USART_CHSIZE_t charSize, + USART_PMODE_t parityMode, bool twoStopBits) +{ + (usart)->CTRLC = (uint8_t)charSize | parityMode + | (twoStopBits ? USART_SBMODE_bm : 0); +} + +/** + * \brief Enable USART transmitter. + * + * \param usart Pointer to the USART module. + */ +static inline void usart_tx_enable(USART_t *usart) +{ + (usart)->CTRLB |= USART_TXEN_bm; +} + +/** + * \brief Disable USART transmitter. + * + * \param usart Pointer to the USART module. + */ +static inline void usart_tx_disable(USART_t *usart) +{ + (usart)->CTRLB &= ~USART_TXEN_bm; +} + +/** + * \brief Set USART RXD interrupt level. + * + * Sets the interrupt level on RX Complete interrupt. + * + * \param usart Pointer to the USART module. + * \param level Interrupt level of the RXD interrupt. + */ +static inline void usart_set_rx_interrupt_level(USART_t *usart, + enum usart_int_level_t level) +{ + (usart)->CTRLA = ((usart)->CTRLA & ~USART_RXCINTLVL_gm) | + (level << USART_RXCINTLVL_gp); +} + +/** + * \brief Set USART TXD interrupt level. + * + * Sets the interrupt level on TX Complete interrupt. + * + * \param usart Pointer to the USART module. + * \param level Interrupt level of the TXD interrupt. + */ +static inline void usart_set_tx_interrupt_level(USART_t *usart, + enum usart_int_level_t level) +{ + (usart)->CTRLA = ((usart)->CTRLA & ~USART_TXCINTLVL_gm) | + (level << USART_TXCINTLVL_gp); +} + +/** + * \brief Set USART DRE interrupt level. + * + * Sets the interrupt level on Data Register interrupt. + * + * \param usart Pointer to the USART module. + * \param level Interrupt level of the DRE interrupt. + * Use USART_DREINTLVL_t type. + */ +static inline void usart_set_dre_interrupt_level(USART_t *usart, + enum usart_int_level_t level) +{ + (usart)->CTRLA = ((usart)->CTRLA & ~USART_DREINTLVL_gm) | + (level << USART_DREINTLVL_gp); +} + +/** + * \brief Set the mode the USART run in. + * + * Set the mode the USART run in. The default mode is asynchronous mode. + * + * \param usart Pointer to the USART module register section. + * \param usartmode Selects the USART mode. Use USART_CMODE_t type. + * + * USART modes: + * - 0x0 : Asynchronous mode. + * - 0x1 : Synchronous mode. + * - 0x2 : IrDA mode. + * - 0x3 : Master SPI mode. + */ +static inline void usart_set_mode(USART_t *usart, USART_CMODE_t usartmode) +{ + (usart)->CTRLC = ((usart)->CTRLC & (~USART_CMODE_gm)) | usartmode; +} + +/** + * \brief Check if data register empty flag is set. + * + * \param usart The USART module. + */ +static inline bool usart_data_register_is_empty(USART_t * usart) +{ + return (usart)->STATUS & USART_DREIF_bm; +} + +/** + * \brief Checks if the RX complete interrupt flag is set. + * + * Checks if the RX complete interrupt flag is set. + * + * \param usart The USART module. + */ +static inline bool usart_rx_is_complete(USART_t * usart) +{ + return (usart)->STATUS & USART_RXCIF_bm; +} + +/** + * \brief Checks if the TX complete interrupt flag is set. + * + * Checks if the TX complete interrupt flag is set. + * + * \param usart The USART module. + */ +static inline bool usart_tx_is_complete(USART_t * usart) +{ + return (usart)->STATUS & USART_TXCIF_bm; +} + +/** + * \brief Clear TX complete interrupt flag. + * + * \param usart The USART module. + */ +static inline void usart_clear_tx_complete(USART_t * usart) +{ + (usart)->STATUS = USART_TXCIF_bm; +} + +/** + * \brief Clear RX complete interrupt flag. + * + * \param usart The USART module. + */ +static inline void usart_clear_rx_complete(USART_t *usart) +{ + (usart)->STATUS = USART_RXCIF_bm; +} + +/** + * \brief Write a data to the USART data register. + * + * \param usart The USART module. + * \param txdata The data to be transmitted. + */ +static inline void usart_put(USART_t * usart, uint8_t txdata) +{ + (usart)->DATA = txdata; +} + +/** + * \brief Read a data to the USART data register. + * + * \param usart The USART module. + * + * \return The received data + */ +static inline uint8_t usart_get(USART_t * usart) +{ + return (usart)->DATA; +} + +/** + * \brief Performs a data transfer on the USART in SPI mode. + * + * \param usart The USART module. + * \param txdata The data to be transmitted. + * + * \return The received data + */ +static inline uint8_t usart_spi_transmit(USART_t * usart, + uint8_t txdata) +{ + while (usart_data_register_is_empty(usart) == false); + usart_put(usart, txdata); + while (!usart_tx_is_complete(usart)); + usart_clear_tx_complete(usart); + return usart_get(usart); +} + +bool usart_init_rs232(USART_t *usart, const usart_rs232_options_t *opt); +void usart_init_spi(USART_t * usart, const usart_spi_options_t * opt); + +enum status_code usart_putchar(USART_t * usart, uint8_t c); +uint8_t usart_getchar(USART_t * usart); + +void usart_set_bsel_bscale_value(USART_t *usart, uint16_t bsel, uint8_t bscale); +void usart_set_baudrate_precalculated(USART_t *usart, uint32_t baud, + uint32_t cpu_hz); +bool usart_set_baudrate(USART_t *usart, uint32_t baud, uint32_t cpu_hz); +void usart_spi_set_baudrate(USART_t * usart, uint32_t baud, uint32_t cpu_hz); +//! @} + +#ifdef __cplusplus +} +#endif + +/** + * \page xmega_usart_quickstart Quick start guide for USART module + * + * This is the quick start guide for the \ref usart_group "USART module", with + * step-by-step instructions on how to configure and use the driver in a + * selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section usart_basic_use_case Basic use case + * \section usart_use_cases USART use cases + * - \ref usart_basic_use_case + * - \subpage usart_use_case_1 + * + * \section usart_basic_use_case Basic use case - transmit a character + * In this use case, the USART module is configured for: + * - Using USARTD0 + * - Baudrate: 9600 + * - Character length: 8 bit + * - Parity mode: Disabled + * - Stop bit: None + * - RS232 mode + * + * \section usart_basic_use_case_setup Setup steps + * + * \subsection usart_basic_use_case_setup_prereq Prerequisites + * -# \ref sysclk_group + * \subsection usart_basic_use_case_setup_code Example code + * The following configuration must be added to the project (typically to a + * conf_usart.h file, but it can also be added to your main application file.) + * \code + #define USART_SERIAL &USARTD0 + #define USART_SERIAL_BAUDRATE 9600 + #define USART_SERIAL_CHAR_LENGTH USART_CHSIZE_8BIT_gc + #define USART_SERIAL_PARITY USART_PMODE_DISABLED_gc + #define USART_SERIAL_STOP_BIT false +\endcode + * + * Add to application initialization: + * \code + sysclk_init(); + static usart_rs232_options_t USART_SERIAL_OPTIONS = { + .baudrate = USART_SERIAL_BAUDRATE, + .charlength = USART_SERIAL_CHAR_LENGTH, + .paritytype = USART_SERIAL_PARITY, + .stopbits = USART_SERIAL_STOP_BIT + }; + sysclk_enable_module(SYSCLK_PORT_D, PR_USART0_bm); + usart_init_rs232(USART_SERIAL, &USART_SERIAL_OPTIONS); +\endcode + * + * \subsection usart_basic_use_case_setup_flow Workflow + * -# Initialize system clock: + * - \code sysclk_init(); \endcode + * - \note Not always required, but since the \ref usart_group driver is + * dependent on \ref sysclk_group it is good practise to initialize + * this module. + * -# Create USART options struct: + * - \code + static usart_rs232_options_t USART_SERIAL_OPTIONS = { + .baudrate = USART_SERIAL_BAUDRATE, + .charlength = USART_SERIAL_CHAR_LENGTH, + .paritytype = USART_SERIAL_PARITY, + .stopbits = USART_SERIAL_STOP_BIT + }; +\endcode + * -# Enable the clock for the USART module: + * - \code sysclk_enable_module(SYSCLK_PORT_D, PR_USART0_bm); \endcode + * -# Initialize in RS232 mode: + * - \code usart_init_rs232(USART_SERIAL, &USART_SERIAL_OPTIONS); +\endcode + * + * \section usart_basic_use_case_usage Usage steps + * + * \subsection usart_basic_use_case_usage_code Example code + * Add to application C-file: + * \code + usart_putchar(USART_SERIAL, 'a'); +\endcode + * + * \subsection usart_basic_use_case_usage_flow Workflow + * -# Send an 'a' character via USART + * - \code usart_putchar(USART_SERIAL, 'a'); \endcode + */ + +/** + * \page usart_use_case_1 USART receive character and echo back + * + * In this use case, the USART module is configured for: + * - Using USARTD0 + * - Baudrate: 9600 + * - Character length: 8 bit + * - Parity mode: Disabled + * - Stop bit: None + * - RS232 mode + * + * The use case waits for a received character on the configured USART and + * echoes the character back to the same USART. + * + * \section usart_use_case_1_setup Setup steps + * + * \subsection usart_use_case_1_setup_prereq Prerequisites + * -# \ref sysclk_group + * + * \subsection usart_use_case_1_setup_code Example code + * -# The following configuration must be added to the project (typically to a + * conf_usart.h file, but it can also be added to your main application file.): + * \code + #define USART_SERIAL &USARTD0 + #define USART_SERIAL_BAUDRATE 9600 + #define USART_SERIAL_CHAR_LENGTH USART_CHSIZE_8BIT_gc + #define USART_SERIAL_PARITY USART_PMODE_DISABLED_gc + #define USART_SERIAL_STOP_BIT false +\endcode + * + * A variable for the received byte must be added: + * \code uint8_t received_byte; \endcode + * + * Add to application initialization: + * \code + sysclk_init(); + static usart_rs232_options_t USART_SERIAL_OPTIONS = { + .baudrate = USART_SERIAL_BAUDRATE, + .charlength = USART_SERIAL_CHAR_LENGTH, + .paritytype = USART_SERIAL_PARITY, + .stopbits = USART_SERIAL_STOP_BIT + }; + sysclk_enable_module(SYSCLK_PORT_D, PR_USART0_bm); + usart_init_rs232(USART_SERIAL, &USART_SERIAL_OPTIONS); +\endcode + * + * \subsection usart_use_case_1_setup_flow Workflow + * -# Initialize system clock: + * - \code sysclk_init(); \endcode + * - \note Not always required, but since the \ref usart_group driver is + * dependent on \ref sysclk_group it is good practise to initialize + * this module. + * -# Create USART options struct: + * - \code + static usart_rs232_options_t USART_SERIAL_OPTIONS = { + .baudrate = USART_SERIAL_BAUDRATE, + .charlength = USART_SERIAL_CHAR_LENGTH, + .paritytype = USART_SERIAL_PARITY, + .stopbits = USART_SERIAL_STOP_BIT + }; +\endcode + * -# Enable the clock for the USART module: + * - \code sysclk_enable_module(SYSCLK_PORT_D, PR_USART0_bm); \endcode + * -# Initialize in RS232 mode: + * - \code usart_init_rs232(USART_SERIAL, &USART_SERIAL_OPTIONS); +\endcode + * + * \section usart_use_case_1_usage Usage steps + * + * \subsection usart_use_case_1_usage_code Example code + * Add to, e.g., main loop in application C-file: + * \code + received_byte = usart_getchar(USART_SERIAL); + usart_putchar(USART_SERIAL, received_byte); +\endcode + * + * \subsection usart_use_case_1_usage_flow Workflow + * -# Wait for reception of a character: + * - \code received_byte = usart_getchar(USART_SERIAL); \endcode + * -# Echo the character back: + * - \code usart_putchar(USART_SERIAL, received_byte); \endcode + */ + +#endif // _USART_H_ diff --git a/Fred_bootloader/src/ASF/xmega/drivers/wdt/wdt.c b/Fred_bootloader/src/ASF/xmega/drivers/wdt/wdt.c new file mode 100644 index 0000000000000000000000000000000000000000..a7c048e58b8a775f65619302671f6c897398943e --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/drivers/wdt/wdt.c @@ -0,0 +1,216 @@ +/** + * \file + * + * \brief AVR XMEGA WatchDog Timer driver. + * + * Copyright (c) 2011 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#include "compiler.h" +#include "ccp.h" +#include "wdt.h" + +/*! \brief Set Watchdog timeout period. + * + * This function sets the coded field of the WDT timeout period. + * + * The function writes the correct signature to the Configuration + * Change Protection register before writing the CTRL register. Interrupts are + * automatically ignored during the change enable period. The function will + * wait for the WDT to be synchronized to the WDT clock domain before + * proceeding + * + * \param to_period WDT timeout coded period + */ +void wdt_set_timeout_period(enum wdt_timeout_period_t to_period) +{ + uint8_t temp = (WDT_PER_gm & (to_period << WDT_PER_gp)) | + (WDT.CTRL & WDT_ENABLE_bm) | (1 << WDT_CEN_bp); + ccp_write_io((void *)&WDT.CTRL, temp); + wdt_wait_while_busy(); +} + + +/*! \brief Set Watchdog window period. + * + * This function sets the coded field of the WDT closed window period. + * Note that this setting is available only if the WDT is enabled (hardware + * behaviour relayed by software). + * + * The function writes the correct signature to the Configuration + * Change Protection register before writing the WINCTRL register. Interrupts + * are automatically ignored during the change enable period. The function will + * wait for the WDT to be synchronized to the WDT clock domain before + * proceeding + * + * \param win_period Window coded period + * + * \retval true The WDT was enabled and the setting is done. + * false The WDT is disabled and the setting is discarded. + */ +bool wdt_set_window_period(enum wdt_window_period_t win_period) +{ + if (!(wdt_is_enabled())) { + return false; + } + uint8_t temp = (WDT_WPER_gm & (win_period << WDT_WPER_gp)) | + (WDT.WINCTRL & WDT_WEN_bm) | (1 << WDT_WCEN_bp); + ccp_write_io((void *)&WDT.WINCTRL, temp); + wdt_wait_while_busy(); + return true; +} + + +/*! \brief Disable Watchdog. + * + * This function disables the WDT without changing period settings. + * + * The function writes the correct signature to the Configuration + * Change Protection register before writing the CTRL register. Interrupts are + * automatically ignored during the change enable period. Disable functions + * operate asynchronously with immediate effect. + */ +void wdt_disable(void) +{ + uint8_t temp = (WDT.CTRL & ~WDT_ENABLE_bm) | (1 << WDT_CEN_bp); + ccp_write_io((void *)&WDT.CTRL, temp); +} + + +/*! \brief Enable Watchdog. + * + * This function enables the WDT without changing period settings. + * + * The function writes the correct signature to the Configuration + * Change Protection register before writing the CTRL register. Interrupts are + * automatically ignored during the change enable period. The function will + * wait for the WDT to be synchronized to the WDT clock domain before + * proceeding + */ +void wdt_enable(void) +{ + uint8_t temp = (WDT.CTRL & WDT_PER_gm) | + (1 << WDT_ENABLE_bp) | (1 << WDT_CEN_bp); + ccp_write_io((void *)&WDT.CTRL, temp); + wdt_wait_while_busy(); +} + + +/*! \brief Disable Watchdog window mode without changing period settings. + * + * This function disables the WDT window mode without changing period settings. + * + * The function writes the correct signature to the Configuration + * Change Protection register before writing the WINCTRL register. Interrupts + * are automatically ignored during the change enable period. Disable functions + * operate asynchronously with immediate effect. + * + * \retval true The WDT was enabled and the window mode is disabled. + * false The WDT (& the window mode) is already disabled. + */ +bool wdt_disable_window_mode(void) +{ + if (!(wdt_is_enabled())) { + return false; + } + uint8_t temp = (WDT.WINCTRL & ~WDT_WEN_bm) | (1 << WDT_WCEN_bp); + ccp_write_io((void *)&WDT.WINCTRL, temp); + + return true; +} + + +/*! \brief Enable Watchdog window mode. + * + * This function enables the WDT window mode without changing period settings. + * + * The function writes the correct signature to the Configuration + * Change Protection register before writing the WINCTRL register. Interrupts + * are automatically ignored during the change enable period. The function will + * wait for the WDT to be synchronized to the WDT clock domain before + * proceeding + * + * \retval true The WDT was enabled and the setting is done. + * false The WDT is disabled and the setting is discarded. + */ +bool wdt_enable_window_mode(void) +{ + if (!(wdt_is_enabled())) { + return false; + } + uint8_t temp = (WDT.WINCTRL & WDT_WPER_gm) | + (1 << WDT_WEN_bp) | (1 << WDT_WCEN_bp); + ccp_write_io((void *)&WDT.WINCTRL, temp); + wdt_wait_while_busy(); + return true; +} + + +/*! \brief Reset MCU via Watchdog. + * + * This function generates an hardware microcontroller reset using the WDT. + * + * The function loads enables the WDT in window mode. Executing a "wdr" asm + * instruction when the windows is closed, provides a quick mcu reset. + * + */ +void wdt_reset_mcu(void) +{ +uint8_t temp; + /* + * WDT enabled (minimum timeout period for max. security) + */ + temp = WDT_PER_8CLK_gc | (1 << WDT_ENABLE_bp) | (1 << WDT_CEN_bp); + ccp_write_io((void *)&WDT.CTRL, temp); + wdt_wait_while_busy(); + /* + * WDT enabled (maximum window period for max. security) + */ + temp = WDT_WPER_8KCLK_gc | (1 << WDT_WEN_bp) | (1 << WDT_WCEN_bp); + ccp_write_io((void *)&WDT.WINCTRL, temp); + wdt_wait_while_busy(); + /* + * WDT Reset during window => WDT generates an Hard Reset. + */ + wdt_reset(); + /* + * No exit to prevent the execution of the following instructions. + */ + while (true) { + /* Wait for Watchdog reset. */ + } +} diff --git a/Fred_bootloader/src/ASF/xmega/drivers/wdt/wdt.h b/Fred_bootloader/src/ASF/xmega/drivers/wdt/wdt.h new file mode 100644 index 0000000000000000000000000000000000000000..b597678cdc5246c53b9774fd47c099045bb7f2da --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/drivers/wdt/wdt.h @@ -0,0 +1,420 @@ +/** + * \file + * + * \brief AVR XMEGA WatchDog Timer driver. + * + * Copyright (c) 2011-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef _WDT_H_ +#define _WDT_H_ + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +#include "compiler.h" + +/** + * \defgroup wdt_group Watchdog Timer (WDT) + * + * See \ref wdt_quickstart. + * + * This is a driver for configuring, enabling, disabling and use of the on-chip + * WDT. + * + * \section dependencies Dependencies + * + * The WDT module depends on the following modules: + * - \ref ccp_group for writing in a CCP-protected 8-bit I/O register. + * + * @{ + */ + + +//! Watchdog timeout period setting +enum wdt_timeout_period_t { + //! Timeout period = 8 cycles or 8 ms @ 3.3V + WDT_TIMEOUT_PERIOD_8CLK = (0x00), + //! Timeout period = 16 cycles or 16 ms @ 3.3V + WDT_TIMEOUT_PERIOD_16CLK = (0x01), + //! Timeout period = 32 cycles or 32m s @ 3.3V + WDT_TIMEOUT_PERIOD_32CLK = (0x02), + //! Timeout period = 64 cycles or 64ms @ 3.3V + WDT_TIMEOUT_PERIOD_64CLK = (0x03), + //! Timeout period = 125 cycles or 125ms @ 3.3V + WDT_TIMEOUT_PERIOD_125CLK = (0x04), + //! 250 cycles or 250ms @ 3.3V) + WDT_TIMEOUT_PERIOD_250CLK = (0x05), + //! Timeout period = 500 cycles or 500ms @ 3.3V + WDT_TIMEOUT_PERIOD_500CLK = (0x06), + //! Timeout period =1K cycles or 1s @ 3.3V + WDT_TIMEOUT_PERIOD_1KCLK = (0x07), + //! Timeout period = 2K cycles or 2s @ 3.3V + WDT_TIMEOUT_PERIOD_2KCLK = (0x08), + //! Timeout period = 4K cycles or 4s @ 3.3V + WDT_TIMEOUT_PERIOD_4KCLK = (0x09), + //! Timeout period = 8K cycles or 8s @ 3.3V + WDT_TIMEOUT_PERIOD_8KCLK = (0x0A), +}; + +//! Watchdog window period setting +enum wdt_window_period_t { + //! Window period = 8 cycles or 8 ms @ 3.3V + WDT_WINDOW_PERIOD_8CLK = (0x00), + //! Window period = 16 cycles or 16 ms @ 3.3V + WDT_WINDOW_PERIOD_16CLK = (0x01), + //! Window period = 32 cycles or 32m s @ 3.3V + WDT_WINDOW_PERIOD_32CLK = (0x02), + //! Window period = 64 cycles or 64ms @ 3.3V + WDT_WINDOW_PERIOD_64CLK = (0x03), + //! Window period = 125 cycles or 125ms @ 3.3V + WDT_WINDOW_PERIOD_125CLK = (0x04), + //! 250 cycles or 250ms @ 3.3V) + WDT_WINDOW_PERIOD_250CLK = (0x05), + //! Window period = 500 cycles or 500ms @ 3.3V + WDT_WINDOW_PERIOD_500CLK = (0x06), + //! Window period =1K cycles or 1s @ 3.3V + WDT_WINDOW_PERIOD_1KCLK = (0x07), + //! Window period = 2K cycles or 2s @ 3.3V + WDT_WINDOW_PERIOD_2KCLK = (0x08), + //! Window period = 4K cycles or 4s @ 3.3V + WDT_WINDOW_PERIOD_4KCLK = (0x09), + //! Window period = 8K cycles or 8s @ 3.3V + WDT_WINDOW_PERIOD_8KCLK = (0x0A), +}; + + +/*! \brief This macro resets (clears/refreshes) the Watchdog Timer. + */ +#if defined(__GNUC__) +#define wdt_reset() __asm__ __volatile__("wdr"); +#elif defined(__ICCAVR__) +#define wdt_reset() __watchdog_reset(); +#else +#error Unsupported compiler. +#endif + + +/*! \brief Wait until WD settings are synchronized to the WD clock domain. + * + */ +static inline void wdt_wait_while_busy(void) +{ + while ((WDT.STATUS & WDT_SYNCBUSY_bm) == WDT_SYNCBUSY_bm) { + // Wait until synchronization + } +} + + +/*! \brief Check if the Watchdog Enable flag is set. + * + * \retval false WDT disabled + * true WDT enabled + */ +static inline bool wdt_is_enabled(void) +{ + return ((WDT.CTRL & WDT_ENABLE_bm) == WDT_ENABLE_bm); +} + + +/*! \brief Check if the Watchdog Window mode flag is set. + * + * \retval false WDT Window disabled + * true WDT Window enabled + */ +static inline bool wdt_window_mode_is_enabled(void) +{ + return ((WDT.WINCTRL & WDT_WEN_bm) == WDT_WEN_bm); +} + + +/*! \brief Gets the Watchdog timeout period. + * + * This function reads the value of the WDT timeout period. + * + * \retval The WDT timeout period. + */ +static inline enum wdt_timeout_period_t wdt_get_timeout_period(void) +{ + return ((enum wdt_timeout_period_t) + ((WDT.CTRL & WDT_PER_gm) >> WDT_PER_gp)); +} + + +/*! \brief Gets the Watchdog window period. + * + * This function reads the value of the WDT closed window coded period. + * + * \retval The WDT window period. + */ +static inline enum wdt_window_period_t wdt_get_window_period(void) +{ + return ((enum wdt_window_period_t) + ((WDT.WINCTRL & WDT_WPER_gm) >> WDT_WPER_gp)); +} + + +/*! \brief Set Watchdog timeout period. + * + * This function sets the coded field of the WDT timeout period. + * + * The function writes the correct signature to the Configuration + * Change Protection register before writing the CTRL register. Interrupts are + * automatically ignored during the change enable period. The function will + * wait for the WDT to be synchronized to the WDT clock domain before + * proceeding + * + * \param to_period WDT timeout coded period + */ +void wdt_set_timeout_period(enum wdt_timeout_period_t to_period); + + +/*! \brief Set Watchdog window period. + * + * This function sets the coded field of the WDT closed window period. + * Note that this setting is available only if the WDT is enabled (hardware + * behaviour relayed by software). + * + * The function writes the correct signature to the Configuration + * Change Protection register before writing the WINCTRL register. Interrupts + * are automatically ignored during the change enable period. The function will + * wait for the WDT to be synchronized to the WDT clock domain before + * proceeding + * + * \param win_period Window coded period + * + * \retval true The WDT was enabled and the setting is done. + * false The WDT is disabled and the setting is discarded. + */ +bool wdt_set_window_period(enum wdt_window_period_t win_period); + + +/*! \brief Disable Watchdog. + * + * This function disables the WDT without changing period settings. + * + * The function writes the correct signature to the Configuration + * Change Protection register before writing the CTRL register. Interrupts are + * automatically ignored during the change enable period. Disable functions + * operate asynchronously with immediate effect. + */ +void wdt_disable(void); + + +/*! \brief Enable Watchdog. + * + * This function enables the WDT without changing period settings. + * + * The function writes the correct signature to the Configuration + * Change Protection register before writing the CTRL register. Interrupts are + * automatically ignored during the change enable period. The function will + * wait for the WDT to be synchronized to the WDT clock domain before + * proceeding + */ +void wdt_enable(void); + + +/*! \brief Disable Watchdog window mode without changing period settings. + * + * This function disables the WDT window mode without changing period settings. + * + * The function writes the correct signature to the Configuration + * Change Protection register before writing the WINCTRL register. Interrupts + * are automatically ignored during the change enable period. Disable functions + * operate asynchronously with immediate effect. + * + * \retval true The WDT was enabled and the window mode is disabled. + * false The WDT (& the window mode) is already disabled. + */ +bool wdt_disable_window_mode(void); + + +/*! \brief Enable Watchdog window mode. + * + * This function enables the WDT window mode without changing period settings. + * + * The function writes the correct signature to the Configuration + * Change Protection register before writing the WINCTRL register. Interrupts + * are automatically ignored during the change enable period. The function will + * wait for the WDT to be synchronized to the WDT clock domain before + * proceeding + * + * \retval true The WDT was enabled and the setting is done. + * false The WDT is disabled and the setting is discarded. + */ +bool wdt_enable_window_mode(void); + + +/*! \brief Reset MCU via Watchdog. + * + * This function generates an hardware microcontroller reset using the WDT. + * + * The function loads enables the WDT in window mode. Executing a "wdr" asm + * instruction when the windows is closed, provides a quick mcu reset. + * + */ +void wdt_reset_mcu(void); + + +//! @} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond + +/** + * \page wdt_quickstart Quick start guide for WDT driver + * + * This is the quick start guide for the \ref wdt_group, with + * step-by-step instructions on how to configure and use the driver in a + * selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section wdt_basic_use_case Basic use case + * \section wdt_use_cases WDT use cases + * - \ref wdt_basic_use_case + * - \subpage wdt_use_case_1 + * + * \section wdt_basic_use_case Basic use case - Reset WDT in standard mode + * In this use case, the WDT is configured for: + * - Standard mode + * - Timeout period of 8 ms + * + * The use case enables the WDT, and resets it after 5 ms to prevent system + * reset after time out period of 8 ms. + * + * \section wdt_basic_use_case_setup Setup steps + * + * \subsection wdt_basic_use_case_setup_prereq Prerequisites + * For the setup code of this use case to work, the following must + * be added to the project: + * -# \ref group_common_services_delay "Busy-Wait Delay Routines" + * + * \subsection wdt_basic_use_case_setup_code Example code + * Add to application initialization: + * \code + wdt_set_timeout_period(WDT_TIMEOUT_PERIOD_8CLK); + wdt_enable(); +\endcode + * + * \subsection wdt_basic_use_case_setup_flow Workflow + * -# Set timeout period to 8 cycles or 8 ms: + * - \code wdt_set_timeout_period(WDT_TIMEOUT_PERIOD_8CLK); \endcode + * -# Enable WDT: + * - \code wdt_enable(); \endcode + * \section wdt_basic_use_case_usage Usage steps + * + * \subsection wdt_basic_use_case_usage_code Example code + * Add to, e.g., main loop in application C-file: + * \code + delay_ms(5); + wdt_reset(); +\endcode + * + * \subsection wdt_basic_use_case_usage_flow Workflow + * -# Wait for 5 ms: + * - \code delay_ms(5); \endcode + * -# Reset the WDT before the timeout period is over to prevent system reset: + * - \code wdt_reset(); \endcode + */ + +/** + * \page wdt_use_case_1 Reset WDT in window mode + * + * In this use case, the WDT is configured for: + * - Window mode + * - Timeout period of 16 ms + * + * The use case enables the WDT in window mode, and resets it after 10 ms to + * prevent system reset before window timeout after 8 ms and after time out + * period of 16 ms. + * + * \section wdt_use_case_1_setup Setup steps + * + * \subsection usart_use_case_1_setup_prereq Prerequisites + * For the setup code of this use case to work, the following must + * be added to the project: + * -# \ref group_common_services_delay "Busy-Wait Delay Routines" + * + * \subsection wdt_use_case_1_setup_code Example code + * Add to application initialization: + * \code + wdt_set_timeout_period(WDT_TIMEOUT_PERIOD_16CLK); + wdt_enable(); + wdt_set_window_period(WDT_TIMEOUT_PERIOD_8CLK); + wdt_enable_window_mode(); +\endcode + * + * \subsection wdt_use_case_1_setup_flow Workflow + * -# Set timeout period to 16 cycles or 16 ms: + * - \code wdt_set_timeout_period(WDT_TIMEOUT_PERIOD_16CLK); \endcode + * -# Enable WDT: + * - \code wdt_enable(); \endcode + * -# Set window period to 8 cycles or 8 ms: + * - \code wdt_set_window_period(WDT_TIMEOUT_PERIOD_8CLK); \endcode + * -# Enable window mode: + * - \code wdt_enable_window_mode(); \endcode + * + * \section wdt_use_case_1_usage Usage steps + * + * \subsection wdt_use_case_1_usage_code Example code + * Add to, e.g., main loop in application C-file: + * \code + delay_ms(10); + wdt_reset(); +\endcode + * + * \subsection wdt_use_case_1_usage_flow Workflow + * -# Wait for 10 ms to not reset the WDT before window timeout: + * - \code delay_ms(10); \endcode + * -# Reset the WDT before the timeout period is over to prevent system reset: + * - \code wdt_reset(); \endcode + */ + +#endif // _WDT_H_ diff --git a/Fred_bootloader/src/ASF/xmega/utils/assembler.h b/Fred_bootloader/src/ASF/xmega/utils/assembler.h new file mode 100644 index 0000000000000000000000000000000000000000..c4451b3f2b00e6c7ea1e6909e2c205afff426e2c --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/utils/assembler.h @@ -0,0 +1,156 @@ +/** + * \file + * + * \brief Assembler abstraction layer and utilities + * + * Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef ASSEMBLER_H_INCLUDED +#define ASSEMBLER_H_INCLUDED + +#if !defined(__ASSEMBLER__) && !defined(__IAR_SYSTEMS_ASM__) \ + && !defined(__DOXYGEN__) +# error This file may only be included from assembly files +#endif + +#if defined(__ASSEMBLER__) +# include "assembler/gas.h" +# include <avr/io.h> +#elif defined(__IAR_SYSTEMS_ASM__) +# include "assembler/iar.h" +# include <ioavr.h> +#endif + +/** + * \ingroup group_xmega_utils + * \defgroup assembler_group Assembler Support + * + * This group provides a good handful of macros intended to smooth out + * the differences between various assemblers, similar to what compiler.h does + * for compilers, except that assemblers tend to be much less standardized than + * compilers. + * + * @{ + */ + +//! \name Control Statements +//@{ +/** + * \def REPEAT(count) + * \brief Repeat the following statements \a count times + */ +/** + * \def END_REPEAT() + * \brief Mark the end of the statements to be repeated + */ +/** + * \def SET_LOC(offset) + * \brief Set the location counter to \a offset + */ +/** + * \def END_FILE() + * \brief Mark the end of the file + */ +//@} + +//! \name Data Objects +//@{ +/** + * \def FILL_BYTES(count) + * \brief Allocate space for \a count bytes + */ +//@} + +//! \name Symbol Definition +//@{ +/** + * \def L(name) + * \brief Turn \a name into a local symbol, if possible + */ +/** + * \def EXTERN_SYMBOL(name) + * \brief Declare \a name as an external symbol referenced by this file + */ +/** + * \def FUNCTION(name) + * \brief Define a file-local function called \a name + */ +/** + * \def PUBLIC_FUNCTION(name) + * \brief Define a globally visible function called \a name + */ +/** + * \def WEAK_FUNCTION(name) + * \brief Define a weak function called \a name + * + * Weak functions are only referenced if no strong definitions are found + */ +/** + * \def WEAK_FUNCTION_ALIAS(name, strong_name) + * \brief Define \a name as a weak alias for the function \a strong_name + * \sa WEAK_FUNCTION + */ +/** + * \def END_FUNC(name) + * \brief Mark the end of the function called \a name + */ +//@} + +//! \name Section Definition +//@{ +/** + * \def TEXT_SECTION(name) + * \brief Start a new section containing executable code + */ +/** + * \def RODATA_SECTION(name) + * \brief Start a new section containing read-only data + */ +/** + * \def DATA_SECTION(name) + * \brief Start a new section containing writeable initialized data + */ +/** + * \def BSS_SECTION(name) + * \brief Start a new section containing writeable zero-initialized data + */ +//@} + +//! @} + +#endif /* ASSEMBLER_H_INCLUDED */ diff --git a/Fred_bootloader/src/ASF/xmega/utils/assembler/gas.h b/Fred_bootloader/src/ASF/xmega/utils/assembler/gas.h new file mode 100644 index 0000000000000000000000000000000000000000..b2760b88bdcdd73df73926fc1f2b398f92f5bfed --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/utils/assembler/gas.h @@ -0,0 +1,121 @@ +/** + * \file + * + * \brief Assembler abstraction layer: GNU Assembler specifics + * + * Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef ASSEMBLER_GAS_H_INCLUDED +#define ASSEMBLER_GAS_H_INCLUDED + +#ifndef __DOXYGEN__ + + /* IAR doesn't accept dots in macro names */ + .macro ld_addr, reg, sym + lda.w \reg, \sym + .endm + + /* Define a function \a name that is either globally visible or only + * file-local. + */ + .macro gas_begin_func name, is_public + .if \is_public + .global \name + .endif + .section .text.\name, "ax", @progbits + .type \name, @function + \name : + .endm + + /* Define a function \a name that is either globally visible or only + * file-local in a given segment. + */ + .macro gas_begin_func_segm name, is_public, segment + .if \is_public + .global \name + .endif + .section .\segment, "ax", @progbits + .type \name, @function + \name : + .endm + + /* Define \a name as a weak alias for the function \a strong_name */ + .macro gas_weak_function_alias name, strong_name + .global \name + .weak \name + .type \name, @function + .set \name, \strong_name + .endm + + /* Define a weak function called \a name */ + .macro gas_weak_function name + .weak \name + gas_begin_func \name 1 + .endm + +#define REPEAT(count) .rept count +#define END_REPEAT() .endr +#define FILL_BYTES(count) .fill count +#define SET_LOC(offset) .org offset +#define L(name) .L##name +#define EXTERN_SYMBOL(name) + +#define TEXT_SECTION(name) \ + .section name, "ax", @progbits +#define RODATA_SECTION(name) \ + .section name, "a", @progbits +#define DATA_SECTION(name) \ + .section name, "aw", @progbits +#define BSS_SECTION(name) \ + .section name, "aw", @nobits + +#define FUNCTION(name) gas_begin_func name 0 +#define PUBLIC_FUNCTION(name) gas_begin_func name 1 +#define PUBLIC_FUNCTION_SEGMENT(name, segment) \ + gas_begin_func_segm name 1 segment +#define WEAK_FUNCTION(name) gas_weak_function name +#define WEAK_FUNCTION_ALIAS(name, strong_name) \ + gas_weak_function_alias name strong_name +#define END_FUNC(name) \ + .size name, . - name + +#define END_FILE() + +#endif /* __DOXYGEN__ */ + +#endif /* ASSEMBLER_GAS_H_INCLUDED */ diff --git a/Fred_bootloader/src/ASF/xmega/utils/bit_handling/clz_ctz.h b/Fred_bootloader/src/ASF/xmega/utils/bit_handling/clz_ctz.h new file mode 100644 index 0000000000000000000000000000000000000000..c43f6c5beab46be87f0887ed492c2ebf5cac22f7 --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/utils/bit_handling/clz_ctz.h @@ -0,0 +1,212 @@ +/** + * \file + * + * \brief CLZ/CTZ C implementation. + * + * Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef CLZ_CTH_H +#define CLZ_CTH_H + +/** + * \brief Count leading zeros in unsigned integer + * + * This macro takes unsigned integers of any size, and evaluates to a call to + * the clz-function for its size. These functions count the number of zeros, + * starting with the MSB, before a one occurs in the integer. + * + * \param x Unsigned integer to count the leading zeros in. + * + * \return The number of leading zeros in \a x. + */ +#define clz(x) compiler_demux_size(sizeof(x), clz, (x)) + +/** + * \internal + * \brief Count leading zeros in unsigned, 8-bit integer + * + * \param x Unsigned byte to count the leading zeros in. + * + * \return The number of leading zeros in \a x. + */ +__always_inline static uint8_t clz8(uint8_t x) +{ + uint8_t bit = 0; + + if (x & 0xf0) { + x >>= 4; + } else { + bit += 4; + } + + if (x & 0x0c) { + x >>= 2; + } else { + bit += 2; + } + + if (!(x & 0x02)) { + bit++; + } + + return bit; + +} + +/** + * \internal + * \brief Count leading zeros in unsigned, 16-bit integer + * + * \param x Unsigned word to count the leading zeros in. + * + * \return The number of leading zeros in \a x. + */ +__always_inline static uint8_t clz16(uint16_t x) +{ + uint8_t bit = 0; + + if (x & 0xff00) { + x >>= 8; + } else { + bit += 8; + } + + return bit + clz8(x); +} + +/** + * \internal + * \brief Count leading zeros in unsigned, 32-bit integer + * + * \param x Unsigned double word to count the leading zeros in. + * + * \return The number of leading zeros in \a x. + */ +__always_inline static uint8_t clz32(uint32_t x) +{ + uint8_t bit = 0; + + if (x & 0xffff0000) { + x >>= 16; + } else { + bit += 16; + } + + return bit + clz16(x); +} + +/** + * \brief Count trailing zeros in unsigned integer + * + * This macro takes unsigned integers of any size, and evaluates to a call to + * the ctz-function for its size. These functions count the number of zeros, + * starting with the LSB, before a one occurs in the integer. + * + * \param x Unsigned integer to count the trailing zeros in. + * + * \return The number of trailing zeros in \a x. + */ +#define ctz(x) compiler_demux_size(sizeof(x), ctz, (x)) + +/** + * \internal + * \brief Count trailing zeros in unsigned, 8-bit integer + * + * \param x Unsigned byte to count the trailing zeros in. + * + * \return The number of leading zeros in \a x. + */ +__always_inline static uint8_t ctz8(uint8_t x) +{ + uint8_t bit = 0; + + if (!(x & 0x0f)) { + bit += 4; + x >>= 4; + } + if (!(x & 0x03)) { + bit += 2; + x >>= 2; + } + if (!(x & 0x01)) + bit++; + + return bit; +} + +/** + * \internal + * \brief Count trailing zeros in unsigned, 16-bit integer + * + * \param x Unsigned word to count the trailing zeros in. + * + * \return The number of trailing zeros in \a x. + */ +__always_inline static uint8_t ctz16(uint16_t x) +{ + uint8_t bit = 0; + + if (!(x & 0x00ff)) { + bit += 8; + x >>= 8; + } + + return bit + ctz8(x); +} + +/** + * \internal + * \brief Count trailing zeros in unsigned, 32-bit integer + * + * \param x Unsigned double word to count the trailing zeros in. + * + * \return The number of trailing zeros in \a x. + */ +__always_inline static uint8_t ctz32(uint32_t x) +{ + uint8_t bit = 0; + + if (!(x & 0x0000ffff)) { + bit += 16; + x >>= 16; + } + + return bit + ctz16(x); +} + +#endif /* CLZ_CTZ_H */ diff --git a/Fred_bootloader/src/ASF/xmega/utils/compiler.h b/Fred_bootloader/src/ASF/xmega/utils/compiler.h new file mode 100644 index 0000000000000000000000000000000000000000..aae91716f2c6a8302773ee961d6131a9239c19e4 --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/utils/compiler.h @@ -0,0 +1,1186 @@ +/** + * \file + * + * \brief Commonly used includes, types and macros. + * + * Copyright (c) 2010-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef UTILS_COMPILER_H +#define UTILS_COMPILER_H + +/** + * \defgroup group_xmega_utils XMEGA compiler driver + * + * Compiler abstraction layer and code utilities for 8-bit AVR. + * This module provides various abstraction layers and utilities to make code compatible between different compilers. + * + * \{ + */ + +#if defined(__GNUC__) +# include <avr/io.h> +# include <avr/builtins.h> +#elif defined(__ICCAVR__) +# include <ioavr.h> +# include <intrinsics.h> +#else +# error Unsupported compiler. +#endif + +#include <stdbool.h> +#include <stdint.h> +#include <stddef.h> +#include <stdlib.h> + +#include <parts.h> + +#ifdef __ICCAVR__ +/*! \name Compiler Keywords + * + * Port of some keywords from GCC to IAR Embedded Workbench. + */ +//! @{ +#define __asm__ asm +#define __inline__ inline +#define __volatile__ +//! @} +#endif + +/** + * \def UNUSED + * \brief Marking \a v as a unused parameter or value. + */ +#define UNUSED(v) (void)(v) + +/** + * \def unused + * \brief Marking \a v as a unused parameter or value. + */ +#define unused(v) do { (void)(v); } while(0) + +/** + * \def barrier + * \brief Memory barrier + */ +#ifdef __GNUC__ +# define barrier() asm volatile("" ::: "memory") +#else +# define barrier() asm ("") +#endif + +/** + * \brief Emit the compiler pragma \a arg. + * + * \param arg The pragma directive as it would appear after \e \#pragma + * (i.e. not stringified). + */ +#define COMPILER_PRAGMA(arg) _Pragma(#arg) + +/* + * AVR arch does not care about alignment anyway. + */ +#define COMPILER_PACK_RESET(alignment) +#define COMPILER_PACK_SET(alignment) + +/** + * \brief Set aligned boundary. + */ +#if (defined __GNUC__) +#define COMPILER_ALIGNED(a) __attribute__((__aligned__(a))) +#elif (defined __ICCAVR__) +#define COMPILER_ALIGNED(a) COMPILER_PRAGMA(data_alignment = a) +#endif + +/** + * \brief Set word-aligned boundary. + */ +#if (defined __GNUC__) +#define COMPILER_WORD_ALIGNED __attribute__((__aligned__(2))) +#elif (defined __ICCAVR__) +#define COMPILER_WORD_ALIGNED COMPILER_PRAGMA(data_alignment = 2) +#endif + +/** + * \name Tag functions as deprecated + * + * Tagging a function as deprecated will produce a warning when and only + * when the function is called. + * + * Usage is to add the __DEPRECATED__ symbol before the function definition. + * E.g.: + * __DEPRECATED__ uint8_t some_deprecated_function (void) + * { + * ... + * } + * + * \note Only supported by GCC 3.1 and above, no IAR support + * @{ + */ +#if ((defined __GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >=1))) +#define __DEPRECATED__ __attribute__((__deprecated__)) +#else +#define __DEPRECATED__ +#endif +//! @} + +/*! \name Usual Types + */ +//! @{ +typedef unsigned char Bool; //!< Boolean. +#ifndef __cplusplus +#if !defined(__bool_true_false_are_defined) +typedef unsigned char bool; //!< Boolean. +#endif +#endif +typedef int8_t S8 ; //!< 8-bit signed integer. +typedef uint8_t U8 ; //!< 8-bit unsigned integer. +typedef int16_t S16; //!< 16-bit signed integer. +typedef uint16_t U16; //!< 16-bit unsigned integer. +typedef uint16_t le16_t; +typedef uint16_t be16_t; +typedef int32_t S32; //!< 32-bit signed integer. +typedef uint32_t U32; //!< 32-bit unsigned integer. +typedef uint32_t le32_t; +typedef uint32_t be32_t; +typedef int64_t S64; //!< 64-bit signed integer. +typedef uint64_t U64; //!< 64-bit unsigned integer. +typedef float F32; //!< 32-bit floating-point number. +typedef double F64; //!< 64-bit floating-point number. +typedef uint16_t iram_size_t; +//! @} + + +/*! \name Status Types + */ +//! @{ +typedef Bool Status_bool_t; //!< Boolean status. +typedef U8 Status_t; //!< 8-bit-coded status. +//! @} + + +/*! \name Aliasing Aggregate Types + */ +//! @{ + +//! 16-bit union. +typedef union +{ + S16 s16 ; + U16 u16 ; + S8 s8 [2]; + U8 u8 [2]; +} Union16; + +//! 32-bit union. +typedef union +{ + S32 s32 ; + U32 u32 ; + S16 s16[2]; + U16 u16[2]; + S8 s8 [4]; + U8 u8 [4]; +} Union32; + +//! 64-bit union. +typedef union +{ + S64 s64 ; + U64 u64 ; + S32 s32[2]; + U32 u32[2]; + S16 s16[4]; + U16 u16[4]; + S8 s8 [8]; + U8 u8 [8]; +} Union64; + +//! Union of pointers to 64-, 32-, 16- and 8-bit unsigned integers. +typedef union +{ + S64 *s64ptr; + U64 *u64ptr; + S32 *s32ptr; + U32 *u32ptr; + S16 *s16ptr; + U16 *u16ptr; + S8 *s8ptr ; + U8 *u8ptr ; +} UnionPtr; + +//! Union of pointers to volatile 64-, 32-, 16- and 8-bit unsigned integers. +typedef union +{ + volatile S64 *s64ptr; + volatile U64 *u64ptr; + volatile S32 *s32ptr; + volatile U32 *u32ptr; + volatile S16 *s16ptr; + volatile U16 *u16ptr; + volatile S8 *s8ptr ; + volatile U8 *u8ptr ; +} UnionVPtr; + +//! Union of pointers to constant 64-, 32-, 16- and 8-bit unsigned integers. +typedef union +{ + const S64 *s64ptr; + const U64 *u64ptr; + const S32 *s32ptr; + const U32 *u32ptr; + const S16 *s16ptr; + const U16 *u16ptr; + const S8 *s8ptr ; + const U8 *u8ptr ; +} UnionCPtr; + +//! Union of pointers to constant volatile 64-, 32-, 16- and 8-bit unsigned integers. +typedef union +{ + const volatile S64 *s64ptr; + const volatile U64 *u64ptr; + const volatile S32 *s32ptr; + const volatile U32 *u32ptr; + const volatile S16 *s16ptr; + const volatile U16 *u16ptr; + const volatile S8 *s8ptr ; + const volatile U8 *u8ptr ; +} UnionCVPtr; + +//! Structure of pointers to 64-, 32-, 16- and 8-bit unsigned integers. +typedef struct +{ + S64 *s64ptr; + U64 *u64ptr; + S32 *s32ptr; + U32 *u32ptr; + S16 *s16ptr; + U16 *u16ptr; + S8 *s8ptr ; + U8 *u8ptr ; +} StructPtr; + +//! Structure of pointers to volatile 64-, 32-, 16- and 8-bit unsigned integers. +typedef struct +{ + volatile S64 *s64ptr; + volatile U64 *u64ptr; + volatile S32 *s32ptr; + volatile U32 *u32ptr; + volatile S16 *s16ptr; + volatile U16 *u16ptr; + volatile S8 *s8ptr ; + volatile U8 *u8ptr ; +} StructVPtr; + +//! Structure of pointers to constant 64-, 32-, 16- and 8-bit unsigned integers. +typedef struct +{ + const S64 *s64ptr; + const U64 *u64ptr; + const S32 *s32ptr; + const U32 *u32ptr; + const S16 *s16ptr; + const U16 *u16ptr; + const S8 *s8ptr ; + const U8 *u8ptr ; +} StructCPtr; + +//! Structure of pointers to constant volatile 64-, 32-, 16- and 8-bit unsigned integers. +typedef struct +{ + const volatile S64 *s64ptr; + const volatile U64 *u64ptr; + const volatile S32 *s32ptr; + const volatile U32 *u32ptr; + const volatile S16 *s16ptr; + const volatile U16 *u16ptr; + const volatile S8 *s8ptr ; + const volatile U8 *u8ptr ; +} StructCVPtr; + +//! @} + + +//_____ M A C R O S ________________________________________________________ + +/*! \name Usual Constants + */ +//! @{ +#define DISABLE 0 +#define ENABLE 1 +#ifndef __cplusplus +#if !defined(__bool_true_false_are_defined) +#define false 0 +#define true 1 +#endif +#endif +#define PASS 0 +#define FAIL 1 +#define LOW 0 +#define HIGH 1 +//! @} + + +//! \name Compile time error handling +//@{ + +/** + * \internal + * \def ERROR_FUNC(name, msg) + * \brief Fail compilation if function call isn't eliminated + * + * If the compiler fails to optimize away all calls to the function \a + * name, terminate compilation and display \a msg to the user. + * + * \note Not all compilers support this, so this is best-effort only. + * Sometimes, there may be a linker error instead, and when optimization + * is disabled, this mechanism will be completely disabled. + */ +#ifndef ERROR_FUNC +# define ERROR_FUNC(name, msg) \ + extern int name(void) +#endif + +//@} + +//! \name Function call demultiplexing +//@{ + +//! Error function for failed demultiplexing. +ERROR_FUNC(compiler_demux_bad_size, "Invalid parameter size"); + +/** + * \internal + * \brief Demultiplex function call based on size of datatype + * + * Evaluates to a function call to a function name with suffix 8, 16 or 32 + * depending on the size of the datatype. Any number of parameters can be + * passed to the function. + * + * Usage: + * \code + void foo8(uint8_t a, void *b); + void foo16(uint16_t a, void *b); + void foo32(uint32_t a, void *b); + + #define foo(x, y) compiler_demux_size(sizeof(x), foo, x, y) +\endcode + * + * \param size Size of the datatype. + * \param func Base function name. + * \param ... List of parameters to pass to the function. + */ +#define compiler_demux_size(size, func, ...) \ + (((size) == 1) ? func##8(__VA_ARGS__) : \ + ((size) == 2) ? func##16(__VA_ARGS__) : \ + ((size) == 4) ? func##32(__VA_ARGS__) : \ + compiler_demux_bad_size()) + +//@} + +/** + * \def __always_inline + * \brief The function should always be inlined. + * + * This annotation instructs the compiler to ignore its inlining + * heuristics and inline the function no matter how big it thinks it + * becomes. + */ +#if (defined __GNUC__) + #define __always_inline inline __attribute__((__always_inline__)) +#elif (defined __ICCAVR__) + #define __always_inline _Pragma("inline=forced") +#endif + +//! \name Optimization Control +//@{ + +/** + * \def __always_optimize + * \brief The function should always be optimized. + * + * This annotation instructs the compiler to ignore global optimization + * settings and always compile the function with a high level of + * optimization. + */ +#if (defined __GNUC__) + #define __always_optimize __attribute__((optimize(3))) +#elif (defined __ICCAVR__) + #define __always_optimize _Pragma("optimize=high") +#endif + +/** + * \def likely(exp) + * \brief The expression \a exp is likely to be true + */ +#ifndef likely +# define likely(exp) (exp) +#endif + +/** + * \def unlikely(exp) + * \brief The expression \a exp is unlikely to be true + */ +#ifndef unlikely +# define unlikely(exp) (exp) +#endif + +/** + * \def is_constant(exp) + * \brief Determine if an expression evaluates to a constant value. + * + * \param exp Any expression + * + * \return true if \a exp is constant, false otherwise. + */ +#ifdef __GNUC__ +# define is_constant(exp) __builtin_constant_p(exp) +#else +# define is_constant(exp) (0) +#endif + +//! @} + +/*! \name Bit-Field Handling + */ +#include "bit_handling/clz_ctz.h" +//! @{ + +/*! \brief Reads the bits of a value specified by a given bit-mask. + * + * \param value Value to read bits from. + * \param mask Bit-mask indicating bits to read. + * + * \return Read bits. + */ +#define Rd_bits( value, mask) ((value)&(mask)) + +/*! \brief Writes the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue to write bits to. + * \param mask Bit-mask indicating bits to write. + * \param bits Bits to write. + * + * \return Resulting value with written bits. + */ +#define Wr_bits(lvalue, mask, bits) ((lvalue) = ((lvalue) & ~(mask)) |\ + ((bits ) & (mask))) + +/*! \brief Tests the bits of a value specified by a given bit-mask. + * + * \param value Value of which to test bits. + * \param mask Bit-mask indicating bits to test. + * + * \return \c 1 if at least one of the tested bits is set, else \c 0. + */ +#define Tst_bits( value, mask) (Rd_bits(value, mask) != 0) + +/*! \brief Clears the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue of which to clear bits. + * \param mask Bit-mask indicating bits to clear. + * + * \return Resulting value with cleared bits. + */ +#define Clr_bits(lvalue, mask) ((lvalue) &= ~(mask)) + +/*! \brief Sets the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue of which to set bits. + * \param mask Bit-mask indicating bits to set. + * + * \return Resulting value with set bits. + */ +#define Set_bits(lvalue, mask) ((lvalue) |= (mask)) + +/*! \brief Toggles the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue of which to toggle bits. + * \param mask Bit-mask indicating bits to toggle. + * + * \return Resulting value with toggled bits. + */ +#define Tgl_bits(lvalue, mask) ((lvalue) ^= (mask)) + +/*! \brief Reads the bit-field of a value specified by a given bit-mask. + * + * \param value Value to read a bit-field from. + * \param mask Bit-mask indicating the bit-field to read. + * + * \return Read bit-field. + */ +#define Rd_bitfield( value,mask) (Rd_bits( value, (uint32_t)mask) >> ctz(mask)) + +/*! \brief Writes the bit-field of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue to write a bit-field to. + * \param mask Bit-mask indicating the bit-field to write. + * \param bitfield Bit-field to write. + * + * \return Resulting value with written bit-field. + */ +#define Wr_bitfield(lvalue, mask, bitfield) (Wr_bits(lvalue, mask, (uint32_t)(bitfield) << ctz(mask))) + +//! @} + + +/*! \brief This macro is used to test fatal errors. + * + * The macro tests if the expression is false. If it is, a fatal error is + * detected and the application hangs up. If TEST_SUITE_DEFINE_ASSERT_MACRO + * is defined, a unit test version of the macro is used, to allow execution + * of further tests after a false expression. + * + * \param expr Expression to evaluate and supposed to be nonzero. + */ +#if defined(_ASSERT_ENABLE_) +# if defined(TEST_SUITE_DEFINE_ASSERT_MACRO) + // Assert() is defined in unit_test/suite.h +# include "unit_test/suite.h" +# else +# define Assert(expr) \ + {\ + if (!(expr)) while (true);\ + } +# endif +#else +# define Assert(expr) ((void) 0) +#endif + +/*! \name Bit Reversing + */ +//! @{ + +/*! \brief Reverses the bits of \a u8. + * + * \param u8 U8 of which to reverse the bits. + * + * \return Value resulting from \a u8 with reversed bits. + */ +#define bit_reverse8(u8) ((U8)(bit_reverse32((U8)(u8)) >> 24)) + +/*! \brief Reverses the bits of \a u16. + * + * \param u16 U16 of which to reverse the bits. + * + * \return Value resulting from \a u16 with reversed bits. + */ +#define bit_reverse16(u16) ((U16)(bit_reverse32((U16)(u16)) >> 16)) + +/*! \brief Reverses the bits of \a u32. + * + * \param u32 U32 of which to reverse the bits. + * + * \return Value resulting from \a u32 with reversed bits. + */ +#if (defined __GNUC__) + #define bit_reverse32(u32) \ + (\ + {\ + unsigned int __value = (U32)(u32);\ + __asm__ ("brev\t%0" : "+r" (__value) : : "cc");\ + (U32)__value;\ + }\ + ) +#elif (defined __ICCAVR__) + #define bit_reverse32(u32) ((U32)__bit_reverse((U32)(u32))) +#endif + +/*! \brief Reverses the bits of \a u64. + * + * \param u64 U64 of which to reverse the bits. + * + * \return Value resulting from \a u64 with reversed bits. + */ +#define bit_reverse64(u64) ((U64)(((U64)bit_reverse32((U64)(u64) >> 32)) |\ + ((U64)bit_reverse32((U64)(u64)) << 32))) + +//! @} + +//! \name Logarithmic functions +//! @{ + +/** + * \internal + * Undefined function. Will cause a link failure if ilog2() is called + * with an invalid constant value. + */ +int_fast8_t ilog2_undefined(void); + +/** + * \brief Calculate the base-2 logarithm of a number rounded down to + * the nearest integer. + * + * \param x A 32-bit value + * \return The base-2 logarithm of \a x, or -1 if \a x is 0. + */ +static inline int_fast8_t ilog2(uint32_t x) +{ + if (is_constant(x)) + return ((x) & (1ULL << 31) ? 31 : + (x) & (1ULL << 30) ? 30 : + (x) & (1ULL << 29) ? 29 : + (x) & (1ULL << 28) ? 28 : + (x) & (1ULL << 27) ? 27 : + (x) & (1ULL << 26) ? 26 : + (x) & (1ULL << 25) ? 25 : + (x) & (1ULL << 24) ? 24 : + (x) & (1ULL << 23) ? 23 : + (x) & (1ULL << 22) ? 22 : + (x) & (1ULL << 21) ? 21 : + (x) & (1ULL << 20) ? 20 : + (x) & (1ULL << 19) ? 19 : + (x) & (1ULL << 18) ? 18 : + (x) & (1ULL << 17) ? 17 : + (x) & (1ULL << 16) ? 16 : + (x) & (1ULL << 15) ? 15 : + (x) & (1ULL << 14) ? 14 : + (x) & (1ULL << 13) ? 13 : + (x) & (1ULL << 12) ? 12 : + (x) & (1ULL << 11) ? 11 : + (x) & (1ULL << 10) ? 10 : + (x) & (1ULL << 9) ? 9 : + (x) & (1ULL << 8) ? 8 : + (x) & (1ULL << 7) ? 7 : + (x) & (1ULL << 6) ? 6 : + (x) & (1ULL << 5) ? 5 : + (x) & (1ULL << 4) ? 4 : + (x) & (1ULL << 3) ? 3 : + (x) & (1ULL << 2) ? 2 : + (x) & (1ULL << 1) ? 1 : + (x) & (1ULL << 0) ? 0 : + ilog2_undefined()); + + return 31 - clz(x); +} + +//! @} + +/*! \name Alignment + */ +//! @{ + +/*! \brief Tests alignment of the number \a val with the \a n boundary. + * + * \param val Input value. + * \param n Boundary. + * + * \return \c 1 if the number \a val is aligned with the \a n boundary, else \c 0. + */ +#define Test_align(val, n ) (!Tst_bits( val, (n) - 1 ) ) + +/*! \brief Gets alignment of the number \a val with respect to the \a n boundary. + * + * \param val Input value. + * \param n Boundary. + * + * \return Alignment of the number \a val with respect to the \a n boundary. + */ +#define Get_align( val, n ) ( Rd_bits( val, (n) - 1 ) ) + +/*! \brief Sets alignment of the lvalue number \a lval to \a alg with respect to the \a n boundary. + * + * \param lval Input/output lvalue. + * \param n Boundary. + * \param alg Alignment. + * + * \return New value of \a lval resulting from its alignment set to \a alg with respect to the \a n boundary. + */ +#define Set_align(lval, n, alg) ( Wr_bits(lval, (n) - 1, alg) ) + +/*! \brief Aligns the number \a val with the upper \a n boundary. + * + * \param val Input value. + * \param n Boundary. + * + * \return Value resulting from the number \a val aligned with the upper \a n boundary. + */ +#define Align_up( val, n ) (((val) + ((n) - 1)) & ~((n) - 1)) + +/*! \brief Aligns the number \a val with the lower \a n boundary. + * + * \param val Input value. + * \param n Boundary. + * + * \return Value resulting from the number \a val aligned with the lower \a n boundary. + */ +#define Align_down(val, n ) ( (val) & ~((n) - 1)) + +//! @} + + +/*! \name Mathematics + * + * Compiler optimization for non-constant expressions, only for abs under WinAVR + */ +//! @{ + +/*! \brief Takes the absolute value of \a a. + * + * \param a Input value. + * + * \return Absolute value of \a a. + * + * \note More optimized if only used with values known at compile time. + */ +#define Abs(a) (((a) < 0 ) ? -(a) : (a)) +#ifndef abs +#define abs(a) Abs(a) +#endif + +/*! \brief Takes the minimal value of \a a and \a b. + * + * \param a Input value. + * \param b Input value. + * + * \return Minimal value of \a a and \a b. + * + * \note More optimized if only used with values known at compile time. + */ +#define Min(a, b) (((a) < (b)) ? (a) : (b)) +#define min(a, b) Min(a, b) + +/*! \brief Takes the maximal value of \a a and \a b. + * + * \param a Input value. + * \param b Input value. + * + * \return Maximal value of \a a and \a b. + * + * \note More optimized if only used with values known at compile time. + */ +#define Max(a, b) (((a) > (b)) ? (a) : (b)) +#define max(a, b) Max(a, b) + +//! @} + + +/*! \brief Calls the routine at address \a addr. + * + * It generates a long call opcode. + * + * For example, `Long_call(0x80000000)' generates a software reset on a UC3 if + * it is invoked from the CPU supervisor mode. + * + * \param addr Address of the routine to call. + * + * \note It may be used as a long jump opcode in some special cases. + */ +#define Long_call(addr) ((*(void (*)(void))(addr))()) + +/*! \name System Register Access + */ +//! @{ + +/*! \brief Gets the value of the \a sysreg system register. + * + * \param sysreg Address of the system register of which to get the value. + * + * \return Value of the \a sysreg system register. + */ +#if (defined __GNUC__) + #define Get_system_register(sysreg) __builtin_mfsr(sysreg) +#elif (defined __ICCAVR__) + #define Get_system_register(sysreg) __get_system_register(sysreg) +#endif + +/*! \brief Sets the value of the \a sysreg system register to \a value. + * + * \param sysreg Address of the system register of which to set the value. + * \param value Value to set the \a sysreg system register to. + */ +#if (defined __GNUC__) + #define Set_system_register(sysreg, value) __builtin_mtsr(sysreg, value) +#elif (defined __ICCAVR__) + #define Set_system_register(sysreg, value) __set_system_register(sysreg, value) +#endif + +//! @} + +/*! \name Debug Register Access + */ +//! @{ + +/*! \brief Gets the value of the \a dbgreg debug register. + * + * \param dbgreg Address of the debug register of which to get the value. + * + * \return Value of the \a dbgreg debug register. + */ +#if (defined __GNUC__) + #define Get_debug_register(dbgreg) __builtin_mfdr(dbgreg) +#elif (defined __ICCAVR__) + #define Get_debug_register(dbgreg) __get_debug_register(dbgreg) +#endif + +/*! \brief Sets the value of the \a dbgreg debug register to \a value. + * + * \param dbgreg Address of the debug register of which to set the value. + * \param value Value to set the \a dbgreg debug register to. + */ +#if (defined __GNUC__) + #define Set_debug_register(dbgreg, value) __builtin_mtdr(dbgreg, value) +#elif (defined __ICCAVR__) + #define Set_debug_register(dbgreg, value) __set_debug_register(dbgreg, value) +#endif + +//! @} + + +/*! \name MCU Endianism Handling + * xmega is a MCU little endianism. + */ +//! @{ +#define MSB(u16) (((uint8_t* )&u16)[1]) +#define LSB(u16) (((uint8_t* )&u16)[0]) + +#define MSW(u32) (((uint16_t*)&u32)[1]) +#define LSW(u32) (((uint16_t*)&u32)[0]) +#define MSB0W(u32) (((uint8_t*)&(u32))[3]) //!< Most significant byte of 1st rank of \a u32. +#define MSB1W(u32) (((uint8_t*)&(u32))[2]) //!< Most significant byte of 2nd rank of \a u32. +#define MSB2W(u32) (((uint8_t*)&(u32))[1]) //!< Most significant byte of 3rd rank of \a u32. +#define MSB3W(u32) (((uint8_t*)&(u32))[0]) //!< Most significant byte of 4th rank of \a u32. +#define LSB3W(u32) MSB0W(u32) //!< Least significant byte of 4th rank of \a u32. +#define LSB2W(u32) MSB1W(u32) //!< Least significant byte of 3rd rank of \a u32. +#define LSB1W(u32) MSB2W(u32) //!< Least significant byte of 2nd rank of \a u32. +#define LSB0W(u32) MSB3W(u32) //!< Least significant byte of 1st rank of \a u32. + +#define MSB0(u32) (((uint8_t*)&u32)[3]) +#define MSB1(u32) (((uint8_t*)&u32)[2]) +#define MSB2(u32) (((uint8_t*)&u32)[1]) +#define MSB3(u32) (((uint8_t*)&u32)[0]) +#define LSB0(u32) MSB3(u32) +#define LSB1(u32) MSB2(u32) +#define LSB2(u32) MSB1(u32) +#define LSB3(u32) MSB0(u32) + +#define LE16(x) (x) +#define le16_to_cpu(x) (x) +#define cpu_to_le16(x) (x) +#define LE16_TO_CPU(x) (x) +#define CPU_TO_LE16(x) (x) + +#define BE16(x) Swap16(x) +#define be16_to_cpu(x) swap16(x) +#define cpu_to_be16(x) swap16(x) +#define BE16_TO_CPU(x) Swap16(x) +#define CPU_TO_BE16(x) Swap16(x) + +#define LE32(x) (x) +#define le32_to_cpu(x) (x) +#define cpu_to_le32(x) (x) +#define LE32_TO_CPU(x) (x) +#define CPU_TO_LE32(x) (x) + +#define BE32(x) Swap32(x) +#define be32_to_cpu(x) swap32(x) +#define cpu_to_be32(x) swap32(x) +#define BE32_TO_CPU(x) Swap32(x) +#define CPU_TO_BE32(x) Swap32(x) + + + +//! @} + + +/*! \name Endianism Conversion + * + * The same considerations as for clz and ctz apply here but AVR32-GCC's + * __builtin_bswap_16 and __builtin_bswap_32 do not behave like macros when + * applied to constant expressions, so two sets of macros are defined here: + * - Swap16, Swap32 and Swap64 to apply to constant expressions (values known + * at compile time); + * - swap16, swap32 and swap64 to apply to non-constant expressions (values + * unknown at compile time). + */ +//! @{ + +/*! \brief Toggles the endianism of \a u16 (by swapping its bytes). + * + * \param u16 U16 of which to toggle the endianism. + * + * \return Value resulting from \a u16 with toggled endianism. + * + * \note More optimized if only used with values known at compile time. + */ +#define Swap16(u16) ((U16)(((U16)(u16) >> 8) |\ + ((U16)(u16) << 8))) + +/*! \brief Toggles the endianism of \a u32 (by swapping its bytes). + * + * \param u32 U32 of which to toggle the endianism. + * + * \return Value resulting from \a u32 with toggled endianism. + * + * \note More optimized if only used with values known at compile time. + */ +#define Swap32(u32) ((U32)(((U32)Swap16((U32)(u32) >> 16)) |\ + ((U32)Swap16((U32)(u32)) << 16))) + +/*! \brief Toggles the endianism of \a u64 (by swapping its bytes). + * + * \param u64 U64 of which to toggle the endianism. + * + * \return Value resulting from \a u64 with toggled endianism. + * + * \note More optimized if only used with values known at compile time. + */ +#define Swap64(u64) ((U64)(((U64)Swap32((U64)(u64) >> 32)) |\ + ((U64)Swap32((U64)(u64)) << 32))) + +/*! \brief Toggles the endianism of \a u16 (by swapping its bytes). + * + * \param u16 U16 of which to toggle the endianism. + * + * \return Value resulting from \a u16 with toggled endianism. + * + * \note More optimized if only used with values unknown at compile time. + */ +#define swap16(u16) Swap16(u16) + +/*! \brief Toggles the endianism of \a u32 (by swapping its bytes). + * + * \param u32 U32 of which to toggle the endianism. + * + * \return Value resulting from \a u32 with toggled endianism. + * + * \note More optimized if only used with values unknown at compile time. + */ +#define swap32(u32) Swap32(u32) + +/*! \brief Toggles the endianism of \a u64 (by swapping its bytes). + * + * \param u64 U64 of which to toggle the endianism. + * + * \return Value resulting from \a u64 with toggled endianism. + * + * \note More optimized if only used with values unknown at compile time. + */ +#define swap64(u64) ((U64)(((U64)swap32((U64)(u64) >> 32)) |\ + ((U64)swap32((U64)(u64)) << 32))) + +//! @} + + +/*! \name Target Abstraction + */ +//! @{ + +#define _GLOBEXT_ extern //!< extern storage-class specifier. +#define _CONST_TYPE_ const //!< const type qualifier. +#define _MEM_TYPE_SLOW_ //!< Slow memory type. +#define _MEM_TYPE_MEDFAST_ //!< Fairly fast memory type. +#define _MEM_TYPE_FAST_ //!< Fast memory type. + +typedef U8 Byte; //!< 8-bit unsigned integer. + +#define memcmp_ram2ram memcmp //!< Target-specific memcmp of RAM to RAM. +#define memcmp_code2ram memcmp //!< Target-specific memcmp of RAM to NVRAM. +#define memcpy_ram2ram memcpy //!< Target-specific memcpy from RAM to RAM. +#define memcpy_code2ram memcpy //!< Target-specific memcpy from NVRAM to RAM. + +//! @} + +/** + * \brief Calculate \f$ \left\lceil \frac{a}{b} \right\rceil \f$ using + * integer arithmetic. + * + * \param a An integer + * \param b Another integer + * + * \return (\a a / \a b) rounded up to the nearest integer. + */ +#define div_ceil(a, b) (((a) + (b) - 1) / (b)) + +#include "preprocessor.h" +#include "progmem.h" +#include "interrupt.h" + + +#if (defined __GNUC__) + #define SHORTENUM __attribute__ ((packed)) +#elif (defined __ICCAVR__) + #define SHORTENUM /**/ +#endif + +#if (defined __GNUC__) + #define FUNC_PTR void * +#elif (defined __ICCAVR__) +#if (FLASHEND > 0x1FFFF) // Required for program code larger than 128K + #define FUNC_PTR void __farflash * +#else + #define FUNC_PTR void * +#endif /* ENABLE_FAR_FLASH */ +#endif + + +#if (defined __GNUC__) + #define FLASH_DECLARE(x) const x __attribute__((__progmem__)) +#elif (defined __ICCAVR__) + #define FLASH_DECLARE(x) const __flash x +#endif + +#if (defined __GNUC__) + #define FLASH_EXTERN(x) extern const x +#elif (defined __ICCAVR__) + #define FLASH_EXTERN(x) extern const __flash x +#endif + + +/*Defines the Flash Storage for the request and response of MAC*/ +#define CMD_ID_OCTET (0) + +/* Converting of values from CPU endian to little endian. */ +#define CPU_ENDIAN_TO_LE16(x) (x) +#define CPU_ENDIAN_TO_LE32(x) (x) +#define CPU_ENDIAN_TO_LE64(x) (x) + +/* Converting of values from little endian to CPU endian. */ +#define LE16_TO_CPU_ENDIAN(x) (x) +#define LE32_TO_CPU_ENDIAN(x) (x) +#define LE64_TO_CPU_ENDIAN(x) (x) + +/* Converting of constants from little endian to CPU endian. */ +#define CLE16_TO_CPU_ENDIAN(x) (x) +#define CLE32_TO_CPU_ENDIAN(x) (x) +#define CLE64_TO_CPU_ENDIAN(x) (x) + +/* Converting of constants from CPU endian to little endian. */ +#define CCPU_ENDIAN_TO_LE16(x) (x) +#define CCPU_ENDIAN_TO_LE32(x) (x) +#define CCPU_ENDIAN_TO_LE64(x) (x) + +#if (defined __GNUC__) + #define ADDR_COPY_DST_SRC_16(dst, src) memcpy((&(dst)), (&(src)), sizeof(uint16_t)) + #define ADDR_COPY_DST_SRC_64(dst, src) memcpy((&(dst)), (&(src)), sizeof(uint64_t)) + +/* Converts a 2 Byte array into a 16-Bit value */ +#define convert_byte_array_to_16_bit(data) \ + (*(uint16_t *)(data)) + +/* Converts a 4 Byte array into a 32-Bit value */ +#define convert_byte_array_to_32_bit(data) \ + (*(uint32_t *)(data)) + +/* Converts a 8 Byte array into a 64-Bit value */ +#define convert_byte_array_to_64_bit(data) \ + (*(uint64_t *)(data)) + +/* Converts a 16-Bit value into a 2 Byte array */ +#define convert_16_bit_to_byte_array(value, data) \ + ((*(uint16_t *)(data)) = (uint16_t)(value)) + +/* Converts spec 16-Bit value into a 2 Byte array */ +#define convert_spec_16_bit_to_byte_array(value, data) \ + ((*(uint16_t *)(data)) = (uint16_t)(value)) + +/* Converts spec 16-Bit value into a 2 Byte array */ +#define convert_16_bit_to_byte_address(value, data) \ + ((*(uint16_t *)(data)) = (uint16_t)(value)) + +/* Converts a 32-Bit value into a 4 Byte array */ +#define convert_32_bit_to_byte_array(value, data) \ + ((*(uint32_t *)(data)) = (uint32_t)(value)) + +/* Converts a 64-Bit value into a 8 Byte array */ +/* Here memcpy requires much less footprint */ +#define convert_64_bit_to_byte_array(value, data) \ + memcpy((data), (&(value)), sizeof(uint64_t)) + +#elif (defined __ICCAVR__) + #define ADDR_COPY_DST_SRC_16(dst, src) ((dst) = (src)) + #define ADDR_COPY_DST_SRC_64(dst, src) ((dst) = (src)) + +/* Converts a 2 Byte array into a 16-Bit value */ +#define convert_byte_array_to_16_bit(data) \ + (*(uint16_t *)(data)) + +/* Converts a 4 Byte array into a 32-Bit value */ +#define convert_byte_array_to_32_bit(data) \ + (*(uint32_t *)(data)) + +/* Converts a 8 Byte array into a 64-Bit value */ +#define convert_byte_array_to_64_bit(data) \ + (*(uint64_t *)(data)) + +/* Converts a 16-Bit value into a 2 Byte array */ +#define convert_16_bit_to_byte_array(value, data) \ + ((*(uint16_t *)(data)) = (uint16_t)(value)) + +/* Converts spec 16-Bit value into a 2 Byte array */ +#define convert_spec_16_bit_to_byte_array(value, data) \ + ((*(uint16_t *)(data)) = (uint16_t)(value)) + +/* Converts spec 16-Bit value into a 2 Byte array */ +#define convert_16_bit_to_byte_address(value, data) \ + ((*(uint16_t *)(data)) = (uint16_t)(value)) + +/* Converts a 32-Bit value into a 4 Byte array */ +#define convert_32_bit_to_byte_array(value, data) \ + ((*(uint32_t *)(data)) = (uint32_t)(value)) + +/* Converts a 64-Bit value into a 8 Byte array */ +#define convert_64_bit_to_byte_array(value, data) \ + ((*(uint64_t *)(data)) = (uint64_t)(value)) +#endif + +#define MEMCPY_ENDIAN memcpy +#define PGM_READ_BLOCK(dst, src, len) memcpy_P((dst), (src), (len)) + +#if (defined __GNUC__) + #define PGM_READ_BYTE(x) pgm_read_byte(x) + #define PGM_READ_WORD(x) pgm_read_word(x) +#elif (defined __ICCAVR__) + #define PGM_READ_BYTE(x) *(x) + #define PGM_READ_WORD(x) *(x) +#endif + + +#if (defined __GNUC__) + #define nop() do { __asm__ __volatile__ ("nop"); } while (0) +#elif (defined __ICCAVR__) + #define nop() __no_operation() +#endif + + +/** + * \} + */ + +#endif // UTILS_COMPILER_H diff --git a/Fred_bootloader/src/ASF/xmega/utils/preprocessor/mrepeat.h b/Fred_bootloader/src/ASF/xmega/utils/preprocessor/mrepeat.h new file mode 100644 index 0000000000000000000000000000000000000000..baab4d5e6be6c79e91d38a68c4bc9dd38d0ca910 --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/utils/preprocessor/mrepeat.h @@ -0,0 +1,335 @@ +/** + * \file + * + * \brief Preprocessor macro repeating utils. + * + * Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef _MREPEAT_H_ +#define _MREPEAT_H_ + +/** + * \defgroup group_xmega_utils_mrepeat Macro Repeat + * + * \ingroup group_xmega_utils + * + * \{ + */ + +#include "preprocessor.h" + + +//! Maximal number of repetitions supported by MREPEAT. +#define MREPEAT_LIMIT 256 + +/*! \brief Macro repeat. + * + * This macro represents a horizontal repetition construct. + * + * \param count The number of repetitious calls to macro. Valid values range from 0 to MREPEAT_LIMIT. + * \param macro A binary operation of the form macro(n, data). This macro is expanded by MREPEAT with + * the current repetition number and the auxiliary data argument. + * \param data Auxiliary data passed to macro. + * + * \return <tt>macro(0, data) macro(1, data) ... macro(count - 1, data)</tt> + */ +#define MREPEAT(count, macro, data) TPASTE2(MREPEAT, count)(macro, data) + +#define MREPEAT0( macro, data) +#define MREPEAT1( macro, data) MREPEAT0( macro, data) macro( 0, data) +#define MREPEAT2( macro, data) MREPEAT1( macro, data) macro( 1, data) +#define MREPEAT3( macro, data) MREPEAT2( macro, data) macro( 2, data) +#define MREPEAT4( macro, data) MREPEAT3( macro, data) macro( 3, data) +#define MREPEAT5( macro, data) MREPEAT4( macro, data) macro( 4, data) +#define MREPEAT6( macro, data) MREPEAT5( macro, data) macro( 5, data) +#define MREPEAT7( macro, data) MREPEAT6( macro, data) macro( 6, data) +#define MREPEAT8( macro, data) MREPEAT7( macro, data) macro( 7, data) +#define MREPEAT9( macro, data) MREPEAT8( macro, data) macro( 8, data) +#define MREPEAT10( macro, data) MREPEAT9( macro, data) macro( 9, data) +#define MREPEAT11( macro, data) MREPEAT10( macro, data) macro( 10, data) +#define MREPEAT12( macro, data) MREPEAT11( macro, data) macro( 11, data) +#define MREPEAT13( macro, data) MREPEAT12( macro, data) macro( 12, data) +#define MREPEAT14( macro, data) MREPEAT13( macro, data) macro( 13, data) +#define MREPEAT15( macro, data) MREPEAT14( macro, data) macro( 14, data) +#define MREPEAT16( macro, data) MREPEAT15( macro, data) macro( 15, data) +#define MREPEAT17( macro, data) MREPEAT16( macro, data) macro( 16, data) +#define MREPEAT18( macro, data) MREPEAT17( macro, data) macro( 17, data) +#define MREPEAT19( macro, data) MREPEAT18( macro, data) macro( 18, data) +#define MREPEAT20( macro, data) MREPEAT19( macro, data) macro( 19, data) +#define MREPEAT21( macro, data) MREPEAT20( macro, data) macro( 20, data) +#define MREPEAT22( macro, data) MREPEAT21( macro, data) macro( 21, data) +#define MREPEAT23( macro, data) MREPEAT22( macro, data) macro( 22, data) +#define MREPEAT24( macro, data) MREPEAT23( macro, data) macro( 23, data) +#define MREPEAT25( macro, data) MREPEAT24( macro, data) macro( 24, data) +#define MREPEAT26( macro, data) MREPEAT25( macro, data) macro( 25, data) +#define MREPEAT27( macro, data) MREPEAT26( macro, data) macro( 26, data) +#define MREPEAT28( macro, data) MREPEAT27( macro, data) macro( 27, data) +#define MREPEAT29( macro, data) MREPEAT28( macro, data) macro( 28, data) +#define MREPEAT30( macro, data) MREPEAT29( macro, data) macro( 29, data) +#define MREPEAT31( macro, data) MREPEAT30( macro, data) macro( 30, data) +#define MREPEAT32( macro, data) MREPEAT31( macro, data) macro( 31, data) +#define MREPEAT33( macro, data) MREPEAT32( macro, data) macro( 32, data) +#define MREPEAT34( macro, data) MREPEAT33( macro, data) macro( 33, data) +#define MREPEAT35( macro, data) MREPEAT34( macro, data) macro( 34, data) +#define MREPEAT36( macro, data) MREPEAT35( macro, data) macro( 35, data) +#define MREPEAT37( macro, data) MREPEAT36( macro, data) macro( 36, data) +#define MREPEAT38( macro, data) MREPEAT37( macro, data) macro( 37, data) +#define MREPEAT39( macro, data) MREPEAT38( macro, data) macro( 38, data) +#define MREPEAT40( macro, data) MREPEAT39( macro, data) macro( 39, data) +#define MREPEAT41( macro, data) MREPEAT40( macro, data) macro( 40, data) +#define MREPEAT42( macro, data) MREPEAT41( macro, data) macro( 41, data) +#define MREPEAT43( macro, data) MREPEAT42( macro, data) macro( 42, data) +#define MREPEAT44( macro, data) MREPEAT43( macro, data) macro( 43, data) +#define MREPEAT45( macro, data) MREPEAT44( macro, data) macro( 44, data) +#define MREPEAT46( macro, data) MREPEAT45( macro, data) macro( 45, data) +#define MREPEAT47( macro, data) MREPEAT46( macro, data) macro( 46, data) +#define MREPEAT48( macro, data) MREPEAT47( macro, data) macro( 47, data) +#define MREPEAT49( macro, data) MREPEAT48( macro, data) macro( 48, data) +#define MREPEAT50( macro, data) MREPEAT49( macro, data) macro( 49, data) +#define MREPEAT51( macro, data) MREPEAT50( macro, data) macro( 50, data) +#define MREPEAT52( macro, data) MREPEAT51( macro, data) macro( 51, data) +#define MREPEAT53( macro, data) MREPEAT52( macro, data) macro( 52, data) +#define MREPEAT54( macro, data) MREPEAT53( macro, data) macro( 53, data) +#define MREPEAT55( macro, data) MREPEAT54( macro, data) macro( 54, data) +#define MREPEAT56( macro, data) MREPEAT55( macro, data) macro( 55, data) +#define MREPEAT57( macro, data) MREPEAT56( macro, data) macro( 56, data) +#define MREPEAT58( macro, data) MREPEAT57( macro, data) macro( 57, data) +#define MREPEAT59( macro, data) MREPEAT58( macro, data) macro( 58, data) +#define MREPEAT60( macro, data) MREPEAT59( macro, data) macro( 59, data) +#define MREPEAT61( macro, data) MREPEAT60( macro, data) macro( 60, data) +#define MREPEAT62( macro, data) MREPEAT61( macro, data) macro( 61, data) +#define MREPEAT63( macro, data) MREPEAT62( macro, data) macro( 62, data) +#define MREPEAT64( macro, data) MREPEAT63( macro, data) macro( 63, data) +#define MREPEAT65( macro, data) MREPEAT64( macro, data) macro( 64, data) +#define MREPEAT66( macro, data) MREPEAT65( macro, data) macro( 65, data) +#define MREPEAT67( macro, data) MREPEAT66( macro, data) macro( 66, data) +#define MREPEAT68( macro, data) MREPEAT67( macro, data) macro( 67, data) +#define MREPEAT69( macro, data) MREPEAT68( macro, data) macro( 68, data) +#define MREPEAT70( macro, data) MREPEAT69( macro, data) macro( 69, data) +#define MREPEAT71( macro, data) MREPEAT70( macro, data) macro( 70, data) +#define MREPEAT72( macro, data) MREPEAT71( macro, data) macro( 71, data) +#define MREPEAT73( macro, data) MREPEAT72( macro, data) macro( 72, data) +#define MREPEAT74( macro, data) MREPEAT73( macro, data) macro( 73, data) +#define MREPEAT75( macro, data) MREPEAT74( macro, data) macro( 74, data) +#define MREPEAT76( macro, data) MREPEAT75( macro, data) macro( 75, data) +#define MREPEAT77( macro, data) MREPEAT76( macro, data) macro( 76, data) +#define MREPEAT78( macro, data) MREPEAT77( macro, data) macro( 77, data) +#define MREPEAT79( macro, data) MREPEAT78( macro, data) macro( 78, data) +#define MREPEAT80( macro, data) MREPEAT79( macro, data) macro( 79, data) +#define MREPEAT81( macro, data) MREPEAT80( macro, data) macro( 80, data) +#define MREPEAT82( macro, data) MREPEAT81( macro, data) macro( 81, data) +#define MREPEAT83( macro, data) MREPEAT82( macro, data) macro( 82, data) +#define MREPEAT84( macro, data) MREPEAT83( macro, data) macro( 83, data) +#define MREPEAT85( macro, data) MREPEAT84( macro, data) macro( 84, data) +#define MREPEAT86( macro, data) MREPEAT85( macro, data) macro( 85, data) +#define MREPEAT87( macro, data) MREPEAT86( macro, data) macro( 86, data) +#define MREPEAT88( macro, data) MREPEAT87( macro, data) macro( 87, data) +#define MREPEAT89( macro, data) MREPEAT88( macro, data) macro( 88, data) +#define MREPEAT90( macro, data) MREPEAT89( macro, data) macro( 89, data) +#define MREPEAT91( macro, data) MREPEAT90( macro, data) macro( 90, data) +#define MREPEAT92( macro, data) MREPEAT91( macro, data) macro( 91, data) +#define MREPEAT93( macro, data) MREPEAT92( macro, data) macro( 92, data) +#define MREPEAT94( macro, data) MREPEAT93( macro, data) macro( 93, data) +#define MREPEAT95( macro, data) MREPEAT94( macro, data) macro( 94, data) +#define MREPEAT96( macro, data) MREPEAT95( macro, data) macro( 95, data) +#define MREPEAT97( macro, data) MREPEAT96( macro, data) macro( 96, data) +#define MREPEAT98( macro, data) MREPEAT97( macro, data) macro( 97, data) +#define MREPEAT99( macro, data) MREPEAT98( macro, data) macro( 98, data) +#define MREPEAT100(macro, data) MREPEAT99( macro, data) macro( 99, data) +#define MREPEAT101(macro, data) MREPEAT100(macro, data) macro(100, data) +#define MREPEAT102(macro, data) MREPEAT101(macro, data) macro(101, data) +#define MREPEAT103(macro, data) MREPEAT102(macro, data) macro(102, data) +#define MREPEAT104(macro, data) MREPEAT103(macro, data) macro(103, data) +#define MREPEAT105(macro, data) MREPEAT104(macro, data) macro(104, data) +#define MREPEAT106(macro, data) MREPEAT105(macro, data) macro(105, data) +#define MREPEAT107(macro, data) MREPEAT106(macro, data) macro(106, data) +#define MREPEAT108(macro, data) MREPEAT107(macro, data) macro(107, data) +#define MREPEAT109(macro, data) MREPEAT108(macro, data) macro(108, data) +#define MREPEAT110(macro, data) MREPEAT109(macro, data) macro(109, data) +#define MREPEAT111(macro, data) MREPEAT110(macro, data) macro(110, data) +#define MREPEAT112(macro, data) MREPEAT111(macro, data) macro(111, data) +#define MREPEAT113(macro, data) MREPEAT112(macro, data) macro(112, data) +#define MREPEAT114(macro, data) MREPEAT113(macro, data) macro(113, data) +#define MREPEAT115(macro, data) MREPEAT114(macro, data) macro(114, data) +#define MREPEAT116(macro, data) MREPEAT115(macro, data) macro(115, data) +#define MREPEAT117(macro, data) MREPEAT116(macro, data) macro(116, data) +#define MREPEAT118(macro, data) MREPEAT117(macro, data) macro(117, data) +#define MREPEAT119(macro, data) MREPEAT118(macro, data) macro(118, data) +#define MREPEAT120(macro, data) MREPEAT119(macro, data) macro(119, data) +#define MREPEAT121(macro, data) MREPEAT120(macro, data) macro(120, data) +#define MREPEAT122(macro, data) MREPEAT121(macro, data) macro(121, data) +#define MREPEAT123(macro, data) MREPEAT122(macro, data) macro(122, data) +#define MREPEAT124(macro, data) MREPEAT123(macro, data) macro(123, data) +#define MREPEAT125(macro, data) MREPEAT124(macro, data) macro(124, data) +#define MREPEAT126(macro, data) MREPEAT125(macro, data) macro(125, data) +#define MREPEAT127(macro, data) MREPEAT126(macro, data) macro(126, data) +#define MREPEAT128(macro, data) MREPEAT127(macro, data) macro(127, data) +#define MREPEAT129(macro, data) MREPEAT128(macro, data) macro(128, data) +#define MREPEAT130(macro, data) MREPEAT129(macro, data) macro(129, data) +#define MREPEAT131(macro, data) MREPEAT130(macro, data) macro(130, data) +#define MREPEAT132(macro, data) MREPEAT131(macro, data) macro(131, data) +#define MREPEAT133(macro, data) MREPEAT132(macro, data) macro(132, data) +#define MREPEAT134(macro, data) MREPEAT133(macro, data) macro(133, data) +#define MREPEAT135(macro, data) MREPEAT134(macro, data) macro(134, data) +#define MREPEAT136(macro, data) MREPEAT135(macro, data) macro(135, data) +#define MREPEAT137(macro, data) MREPEAT136(macro, data) macro(136, data) +#define MREPEAT138(macro, data) MREPEAT137(macro, data) macro(137, data) +#define MREPEAT139(macro, data) MREPEAT138(macro, data) macro(138, data) +#define MREPEAT140(macro, data) MREPEAT139(macro, data) macro(139, data) +#define MREPEAT141(macro, data) MREPEAT140(macro, data) macro(140, data) +#define MREPEAT142(macro, data) MREPEAT141(macro, data) macro(141, data) +#define MREPEAT143(macro, data) MREPEAT142(macro, data) macro(142, data) +#define MREPEAT144(macro, data) MREPEAT143(macro, data) macro(143, data) +#define MREPEAT145(macro, data) MREPEAT144(macro, data) macro(144, data) +#define MREPEAT146(macro, data) MREPEAT145(macro, data) macro(145, data) +#define MREPEAT147(macro, data) MREPEAT146(macro, data) macro(146, data) +#define MREPEAT148(macro, data) MREPEAT147(macro, data) macro(147, data) +#define MREPEAT149(macro, data) MREPEAT148(macro, data) macro(148, data) +#define MREPEAT150(macro, data) MREPEAT149(macro, data) macro(149, data) +#define MREPEAT151(macro, data) MREPEAT150(macro, data) macro(150, data) +#define MREPEAT152(macro, data) MREPEAT151(macro, data) macro(151, data) +#define MREPEAT153(macro, data) MREPEAT152(macro, data) macro(152, data) +#define MREPEAT154(macro, data) MREPEAT153(macro, data) macro(153, data) +#define MREPEAT155(macro, data) MREPEAT154(macro, data) macro(154, data) +#define MREPEAT156(macro, data) MREPEAT155(macro, data) macro(155, data) +#define MREPEAT157(macro, data) MREPEAT156(macro, data) macro(156, data) +#define MREPEAT158(macro, data) MREPEAT157(macro, data) macro(157, data) +#define MREPEAT159(macro, data) MREPEAT158(macro, data) macro(158, data) +#define MREPEAT160(macro, data) MREPEAT159(macro, data) macro(159, data) +#define MREPEAT161(macro, data) MREPEAT160(macro, data) macro(160, data) +#define MREPEAT162(macro, data) MREPEAT161(macro, data) macro(161, data) +#define MREPEAT163(macro, data) MREPEAT162(macro, data) macro(162, data) +#define MREPEAT164(macro, data) MREPEAT163(macro, data) macro(163, data) +#define MREPEAT165(macro, data) MREPEAT164(macro, data) macro(164, data) +#define MREPEAT166(macro, data) MREPEAT165(macro, data) macro(165, data) +#define MREPEAT167(macro, data) MREPEAT166(macro, data) macro(166, data) +#define MREPEAT168(macro, data) MREPEAT167(macro, data) macro(167, data) +#define MREPEAT169(macro, data) MREPEAT168(macro, data) macro(168, data) +#define MREPEAT170(macro, data) MREPEAT169(macro, data) macro(169, data) +#define MREPEAT171(macro, data) MREPEAT170(macro, data) macro(170, data) +#define MREPEAT172(macro, data) MREPEAT171(macro, data) macro(171, data) +#define MREPEAT173(macro, data) MREPEAT172(macro, data) macro(172, data) +#define MREPEAT174(macro, data) MREPEAT173(macro, data) macro(173, data) +#define MREPEAT175(macro, data) MREPEAT174(macro, data) macro(174, data) +#define MREPEAT176(macro, data) MREPEAT175(macro, data) macro(175, data) +#define MREPEAT177(macro, data) MREPEAT176(macro, data) macro(176, data) +#define MREPEAT178(macro, data) MREPEAT177(macro, data) macro(177, data) +#define MREPEAT179(macro, data) MREPEAT178(macro, data) macro(178, data) +#define MREPEAT180(macro, data) MREPEAT179(macro, data) macro(179, data) +#define MREPEAT181(macro, data) MREPEAT180(macro, data) macro(180, data) +#define MREPEAT182(macro, data) MREPEAT181(macro, data) macro(181, data) +#define MREPEAT183(macro, data) MREPEAT182(macro, data) macro(182, data) +#define MREPEAT184(macro, data) MREPEAT183(macro, data) macro(183, data) +#define MREPEAT185(macro, data) MREPEAT184(macro, data) macro(184, data) +#define MREPEAT186(macro, data) MREPEAT185(macro, data) macro(185, data) +#define MREPEAT187(macro, data) MREPEAT186(macro, data) macro(186, data) +#define MREPEAT188(macro, data) MREPEAT187(macro, data) macro(187, data) +#define MREPEAT189(macro, data) MREPEAT188(macro, data) macro(188, data) +#define MREPEAT190(macro, data) MREPEAT189(macro, data) macro(189, data) +#define MREPEAT191(macro, data) MREPEAT190(macro, data) macro(190, data) +#define MREPEAT192(macro, data) MREPEAT191(macro, data) macro(191, data) +#define MREPEAT193(macro, data) MREPEAT192(macro, data) macro(192, data) +#define MREPEAT194(macro, data) MREPEAT193(macro, data) macro(193, data) +#define MREPEAT195(macro, data) MREPEAT194(macro, data) macro(194, data) +#define MREPEAT196(macro, data) MREPEAT195(macro, data) macro(195, data) +#define MREPEAT197(macro, data) MREPEAT196(macro, data) macro(196, data) +#define MREPEAT198(macro, data) MREPEAT197(macro, data) macro(197, data) +#define MREPEAT199(macro, data) MREPEAT198(macro, data) macro(198, data) +#define MREPEAT200(macro, data) MREPEAT199(macro, data) macro(199, data) +#define MREPEAT201(macro, data) MREPEAT200(macro, data) macro(200, data) +#define MREPEAT202(macro, data) MREPEAT201(macro, data) macro(201, data) +#define MREPEAT203(macro, data) MREPEAT202(macro, data) macro(202, data) +#define MREPEAT204(macro, data) MREPEAT203(macro, data) macro(203, data) +#define MREPEAT205(macro, data) MREPEAT204(macro, data) macro(204, data) +#define MREPEAT206(macro, data) MREPEAT205(macro, data) macro(205, data) +#define MREPEAT207(macro, data) MREPEAT206(macro, data) macro(206, data) +#define MREPEAT208(macro, data) MREPEAT207(macro, data) macro(207, data) +#define MREPEAT209(macro, data) MREPEAT208(macro, data) macro(208, data) +#define MREPEAT210(macro, data) MREPEAT209(macro, data) macro(209, data) +#define MREPEAT211(macro, data) MREPEAT210(macro, data) macro(210, data) +#define MREPEAT212(macro, data) MREPEAT211(macro, data) macro(211, data) +#define MREPEAT213(macro, data) MREPEAT212(macro, data) macro(212, data) +#define MREPEAT214(macro, data) MREPEAT213(macro, data) macro(213, data) +#define MREPEAT215(macro, data) MREPEAT214(macro, data) macro(214, data) +#define MREPEAT216(macro, data) MREPEAT215(macro, data) macro(215, data) +#define MREPEAT217(macro, data) MREPEAT216(macro, data) macro(216, data) +#define MREPEAT218(macro, data) MREPEAT217(macro, data) macro(217, data) +#define MREPEAT219(macro, data) MREPEAT218(macro, data) macro(218, data) +#define MREPEAT220(macro, data) MREPEAT219(macro, data) macro(219, data) +#define MREPEAT221(macro, data) MREPEAT220(macro, data) macro(220, data) +#define MREPEAT222(macro, data) MREPEAT221(macro, data) macro(221, data) +#define MREPEAT223(macro, data) MREPEAT222(macro, data) macro(222, data) +#define MREPEAT224(macro, data) MREPEAT223(macro, data) macro(223, data) +#define MREPEAT225(macro, data) MREPEAT224(macro, data) macro(224, data) +#define MREPEAT226(macro, data) MREPEAT225(macro, data) macro(225, data) +#define MREPEAT227(macro, data) MREPEAT226(macro, data) macro(226, data) +#define MREPEAT228(macro, data) MREPEAT227(macro, data) macro(227, data) +#define MREPEAT229(macro, data) MREPEAT228(macro, data) macro(228, data) +#define MREPEAT230(macro, data) MREPEAT229(macro, data) macro(229, data) +#define MREPEAT231(macro, data) MREPEAT230(macro, data) macro(230, data) +#define MREPEAT232(macro, data) MREPEAT231(macro, data) macro(231, data) +#define MREPEAT233(macro, data) MREPEAT232(macro, data) macro(232, data) +#define MREPEAT234(macro, data) MREPEAT233(macro, data) macro(233, data) +#define MREPEAT235(macro, data) MREPEAT234(macro, data) macro(234, data) +#define MREPEAT236(macro, data) MREPEAT235(macro, data) macro(235, data) +#define MREPEAT237(macro, data) MREPEAT236(macro, data) macro(236, data) +#define MREPEAT238(macro, data) MREPEAT237(macro, data) macro(237, data) +#define MREPEAT239(macro, data) MREPEAT238(macro, data) macro(238, data) +#define MREPEAT240(macro, data) MREPEAT239(macro, data) macro(239, data) +#define MREPEAT241(macro, data) MREPEAT240(macro, data) macro(240, data) +#define MREPEAT242(macro, data) MREPEAT241(macro, data) macro(241, data) +#define MREPEAT243(macro, data) MREPEAT242(macro, data) macro(242, data) +#define MREPEAT244(macro, data) MREPEAT243(macro, data) macro(243, data) +#define MREPEAT245(macro, data) MREPEAT244(macro, data) macro(244, data) +#define MREPEAT246(macro, data) MREPEAT245(macro, data) macro(245, data) +#define MREPEAT247(macro, data) MREPEAT246(macro, data) macro(246, data) +#define MREPEAT248(macro, data) MREPEAT247(macro, data) macro(247, data) +#define MREPEAT249(macro, data) MREPEAT248(macro, data) macro(248, data) +#define MREPEAT250(macro, data) MREPEAT249(macro, data) macro(249, data) +#define MREPEAT251(macro, data) MREPEAT250(macro, data) macro(250, data) +#define MREPEAT252(macro, data) MREPEAT251(macro, data) macro(251, data) +#define MREPEAT253(macro, data) MREPEAT252(macro, data) macro(252, data) +#define MREPEAT254(macro, data) MREPEAT253(macro, data) macro(253, data) +#define MREPEAT255(macro, data) MREPEAT254(macro, data) macro(254, data) +#define MREPEAT256(macro, data) MREPEAT255(macro, data) macro(255, data) + +/** + * \} + */ + +#endif // _MREPEAT_H_ diff --git a/Fred_bootloader/src/ASF/xmega/utils/preprocessor/preprocessor.h b/Fred_bootloader/src/ASF/xmega/utils/preprocessor/preprocessor.h new file mode 100644 index 0000000000000000000000000000000000000000..2cae8e072b341632efdda50f6c4729088dc2a498 --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/utils/preprocessor/preprocessor.h @@ -0,0 +1,51 @@ +/** + * \file + * + * \brief Preprocessor utils. + * + * Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef _PREPROCESSOR_H_ +#define _PREPROCESSOR_H_ + +#include "tpaste.h" +#include "stringz.h" +#include "mrepeat.h" + + +#endif // _PREPROCESSOR_H_ diff --git a/Fred_bootloader/src/ASF/xmega/utils/preprocessor/stringz.h b/Fred_bootloader/src/ASF/xmega/utils/preprocessor/stringz.h new file mode 100644 index 0000000000000000000000000000000000000000..2940eff7960fbba52c4a76ba7d23feca48cd0848 --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/utils/preprocessor/stringz.h @@ -0,0 +1,81 @@ +/** + * \file + * + * \brief Preprocessor stringizing utils. + * + * Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef _STRINGZ_H_ +#define _STRINGZ_H_ + +/** + * \defgroup group_xmega_utils_stringz Stringize + * + * \ingroup group_xmega_utils + * + * \{ + */ + +/*! \brief Stringize. + * + * Stringize a preprocessing token, this token being allowed to be \#defined. + * + * May be used only within macros with the token passed as an argument if the token is \#defined. + * + * For example, writing STRINGZ(PIN) within a macro \#defined by PIN_NAME(PIN) + * and invoked as PIN_NAME(PIN0) with PIN0 \#defined as A0 is equivalent to + * writing "A0". + */ +#define STRINGZ(x) #x + +/*! \brief Absolute stringize. + * + * Stringize a preprocessing token, this token being allowed to be \#defined. + * + * No restriction of use if the token is \#defined. + * + * For example, writing ASTRINGZ(PIN0) anywhere with PIN0 \#defined as A0 is + * equivalent to writing "A0". + */ +#define ASTRINGZ(x) STRINGZ(x) + +/** + * \} + */ + +#endif // _STRINGZ_H_ diff --git a/Fred_bootloader/src/ASF/xmega/utils/preprocessor/tpaste.h b/Fred_bootloader/src/ASF/xmega/utils/preprocessor/tpaste.h new file mode 100644 index 0000000000000000000000000000000000000000..88bed2b66c4fc8deb5924e5c3e7df99e789b9937 --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/utils/preprocessor/tpaste.h @@ -0,0 +1,101 @@ +/** + * \file + * + * \brief Preprocessor token pasting utils. + * + * Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef _TPASTE_H_ +#define _TPASTE_H_ + +/** + * \defgroup group_xmega_utils_tpaste Token Paste + * + * \ingroup group_xmega_utils + * + * \{ + */ + +/*! \name Token Paste + * + * Paste N preprocessing tokens together, these tokens being allowed to be \#defined. + * + * May be used only within macros with the tokens passed as arguments if the tokens are \#defined. + * + * For example, writing TPASTE2(U, WIDTH) within a macro \#defined by + * UTYPE(WIDTH) and invoked as UTYPE(UL_WIDTH) with UL_WIDTH \#defined as 32 is + * equivalent to writing U32. + */ +//! @{ +#define TPASTE2( a, b) a##b +#define TPASTE3( a, b, c) a##b##c +#define TPASTE4( a, b, c, d) a##b##c##d +#define TPASTE5( a, b, c, d, e) a##b##c##d##e +#define TPASTE6( a, b, c, d, e, f) a##b##c##d##e##f +#define TPASTE7( a, b, c, d, e, f, g) a##b##c##d##e##f##g +#define TPASTE8( a, b, c, d, e, f, g, h) a##b##c##d##e##f##g##h +#define TPASTE9( a, b, c, d, e, f, g, h, i) a##b##c##d##e##f##g##h##i +#define TPASTE10(a, b, c, d, e, f, g, h, i, j) a##b##c##d##e##f##g##h##i##j +//! @} + +/*! \name Absolute Token Paste + * + * Paste N preprocessing tokens together, these tokens being allowed to be \#defined. + * + * No restriction of use if the tokens are \#defined. + * + * For example, writing ATPASTE2(U, UL_WIDTH) anywhere with UL_WIDTH \#defined + * as 32 is equivalent to writing U32. + */ +//! @{ +#define ATPASTE2( a, b) TPASTE2( a, b) +#define ATPASTE3( a, b, c) TPASTE3( a, b, c) +#define ATPASTE4( a, b, c, d) TPASTE4( a, b, c, d) +#define ATPASTE5( a, b, c, d, e) TPASTE5( a, b, c, d, e) +#define ATPASTE6( a, b, c, d, e, f) TPASTE6( a, b, c, d, e, f) +#define ATPASTE7( a, b, c, d, e, f, g) TPASTE7( a, b, c, d, e, f, g) +#define ATPASTE8( a, b, c, d, e, f, g, h) TPASTE8( a, b, c, d, e, f, g, h) +#define ATPASTE9( a, b, c, d, e, f, g, h, i) TPASTE9( a, b, c, d, e, f, g, h, i) +#define ATPASTE10(a, b, c, d, e, f, g, h, i, j) TPASTE10(a, b, c, d, e, f, g, h, i, j) +//! @} + +/** + * \} + */ + +#endif // _TPASTE_H_ diff --git a/Fred_bootloader/src/ASF/xmega/utils/progmem.h b/Fred_bootloader/src/ASF/xmega/utils/progmem.h new file mode 100644 index 0000000000000000000000000000000000000000..320ca5dac0b6f8eb8891575e4e6b1b1b72eae296 --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/utils/progmem.h @@ -0,0 +1,99 @@ +/** + * \file + * + * \brief Program memory access + * + * Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef UTILS_PROGMEM_H +#define UTILS_PROGMEM_H + +/** + * \defgroup group_xmega_utils_progmem Program memory + * + * \ingroup group_xmega_utils + * + * \{ + */ + +/*! \name Program memory + * + * Macros for locating and accessing data in program memory. + * + * @{ + */ +#if defined(__GNUC__) || defined(__DOXYGEN__) +# include <avr/pgmspace.h> +# define PROGMEM_LOCATION(type, name, loc) \ + type name __attribute__((section (#loc))) +# define PROGMEM_DECLARE(type, name) const type name __attribute__((__progmem__)) +# define PROGMEM_STRING(x) PSTR(x) +# define PROGMEM_STRING_T PGM_P +# define PROGMEM_T const +# define PROGMEM_PTR_T const * +# define PROGMEM_BYTE_ARRAY_T uint8_t* +# define PROGMEM_WORD_ARRAY_T uint16_t* +# define PROGMEM_READ_BYTE(x) pgm_read_byte(x) +# define PROGMEM_READ_WORD(x) pgm_read_word(x) + +#elif defined(__ICCAVR__) +# include <pgmspace.h> +# ifndef __HAS_ELPM__ +# define _MEMATTR_ASF __flash +# else /* __HAS_ELPM__ */ +# define _MEMATTR_ASF __hugeflash +# endif /* __HAS_ELPM__ */ +# define PROGMEM_LOCATION(type, name, loc) const _MEMATTR_ASF type name @ loc +# define PROGMEM_DECLARE(type, name) _MEMATTR_ASF type name +# define PROGMEM_STRING(x) ((_MEMATTR_ASF const char *)(x)) +# define PROGMEM_STRING_T char const _MEMATTR_ASF * +# define PROGMEM_T const _MEMATTR_ASF +# define PROGMEM_PTR_T const _MEMATTR_ASF * +# define PROGMEM_BYTE_ARRAY_T uint8_t const _MEMATTR_ASF * +# define PROGMEM_WORD_ARRAY_T uint16_t const _MEMATTR_ASF * +# define PROGMEM_READ_BYTE(x) *(x) +# define PROGMEM_READ_WORD(x) *(x) +#endif +//! @} + +/** + * \} + */ + +#endif /* UTILS_PROGMEM_H */ diff --git a/Fred_bootloader/src/ASF/xmega/utils/status_codes.h b/Fred_bootloader/src/ASF/xmega/utils/status_codes.h new file mode 100644 index 0000000000000000000000000000000000000000..108678bbfa502c18229bb2c32ec357bb54b0e3ea --- /dev/null +++ b/Fred_bootloader/src/ASF/xmega/utils/status_codes.h @@ -0,0 +1,118 @@ +/** + * \file + * + * \brief Status code definitions. + * + * This file defines various status codes returned by functions, + * indicating success or failure as well as what kind of failure. + * + * Copyright (c) 2009-2013 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef STATUS_CODES_H_INCLUDED +#define STATUS_CODES_H_INCLUDED + +/** + * \defgroup group_xmega_utils_status_codes Status Codes + * + * \ingroup group_xmega_utils + * + * \{ + */ + +/* Note: this is a local workaround to avoid a pre-processor clash due to the + * lwIP macro ERR_TIMEOUT. */ +#if defined(__LWIP_ERR_H__) && defined(ERR_TIMEOUT) +#if (ERR_TIMEOUT != -3) + +/* Internal check to make sure that the later restore of lwIP's ERR_TIMEOUT + * macro is set to the correct value. Note that it is highly improbable that + * this value ever changes in lwIP. */ +#error ASF developers: check lwip err.h new value for ERR_TIMEOUT +#endif +#undef ERR_TIMEOUT +#endif + +/** + * Status code that may be returned by shell commands and protocol + * implementations. + * + * \note Any change to these status codes and the corresponding + * message strings is strictly forbidden. New codes can be added, + * however, but make sure that any message string tables are updated + * at the same time. + */ +enum status_code { + STATUS_OK = 0, //!< Success + ERR_IO_ERROR = -1, //!< I/O error + ERR_FLUSHED = -2, //!< Request flushed from queue + ERR_TIMEOUT = -3, //!< Operation timed out + ERR_BAD_DATA = -4, //!< Data integrity check failed + ERR_PROTOCOL = -5, //!< Protocol error + ERR_UNSUPPORTED_DEV = -6, //!< Unsupported device + ERR_NO_MEMORY = -7, //!< Insufficient memory + ERR_INVALID_ARG = -8, //!< Invalid argument + ERR_BAD_ADDRESS = -9, //!< Bad address + ERR_BUSY = -10, //!< Resource is busy + ERR_BAD_FORMAT = -11, //!< Data format not recognized + ERR_NO_TIMER = -12, //!< No timer available + ERR_TIMER_ALREADY_RUNNING = -13, //!< Timer already running + ERR_TIMER_NOT_RUNNING = -14, //!< Timer not running + + /** + * \brief Operation in progress + * + * This status code is for driver-internal use when an operation + * is currently being performed. + * + * \note Drivers should never return this status code to any + * callers. It is strictly for internal use. + */ + OPERATION_IN_PROGRESS = -128, +}; + +typedef enum status_code status_code_t; + +#if defined(__LWIP_ERR_H__) +#define ERR_TIMEOUT -3 +#endif + +/** + * \} + */ + +#endif /* STATUS_CODES_H_INCLUDED */ diff --git a/Fred_bootloader/src/asf.h b/Fred_bootloader/src/asf.h new file mode 100644 index 0000000000000000000000000000000000000000..ee9a98407fd39e9be3a41bb2ed9686fb0504ee9e --- /dev/null +++ b/Fred_bootloader/src/asf.h @@ -0,0 +1,106 @@ +/** + * \file + * + * \brief Autogenerated API include file for the Atmel Software Framework (ASF) + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef ASF_H +#define ASF_H + +/* + * This file includes all API header files for the selected drivers from ASF. + * Note: There might be duplicate includes required by more than one driver. + * + * The file is automatically generated and will be re-written when + * running the ASF driver selector tool. Any changes will be discarded. + */ + +// From module: CPU specific features +#include <ccp.h> +#include <xmega_reset_cause.h> + +// From module: Common build items for user board support templates +#include <user_board.h> + +// From module: Generic board support +#include <board.h> + +// From module: IOPORT - General purpose I/O service +#include <ioport.h> + +// From module: Interrupt management - XMEGA implementation +#include <interrupt.h> + +// From module: NVM - Non Volatile Memory +#include <nvm.h> + +// From module: PMIC - Programmable Multi-level Interrupt Controller +#include <pmic.h> + +// From module: Part identification macros +#include <parts.h> + +// From module: Sleep Controller driver +#include <sleep.h> + +// From module: Sleep manager - XMEGA A/AU/B/D implementation +#include <sleepmgr.h> +#include <xmega/sleepmgr.h> + +// From module: System Clock Control - XMEGA A1U/A3U/A3BU/A4U/B/C implementation +#include <sysclk.h> + +// From module: TC - Timer Counter +#include <tc.h> + +// From module: USART - Serial interface - XMEGA implementation +#include <serial.h> + +// From module: USART - Universal Synchronous/Asynchronous Receiver/Transmitter +#include <usart.h> + +// From module: WDT - Watchdog Timer +#include <wdt.h> + +// From module: XMEGA compiler driver +#include <compiler.h> +#include <status_codes.h> + +#endif // ASF_H diff --git a/Fred_bootloader/src/bootloader.c b/Fred_bootloader/src/bootloader.c new file mode 100644 index 0000000000000000000000000000000000000000..31fd88cd8ac03a7b521e84855044902e4f46aad6 --- /dev/null +++ b/Fred_bootloader/src/bootloader.c @@ -0,0 +1,211 @@ +/* + * bootloader.c + * + * Created: 2015-04-12 13:07:41 + * Author: Paweł + */ +#include "bootloader.h" +#include "timer_lib.h" +#include "usart_lib.h" +#include <avr/eeprom.h> +#include <asf.h> +#include <ccp.h> + +BootloaderState state = INIT; +uint8_t page_nr = 0; +uint8_t page[FLASH_PAGE_SIZE] = {0}; +uint8_t checksum = 0; +uint8_t handshake = 0; + +void start_firmware() +{ + void (*app_start)( void ) = APP_SECTION_START; // Set up function pointer to RESET vector. + uint8_t temp; + + /*Set interrupt vector location to application section of flash */ + temp = PMIC.CTRL & ~PMIC_IVSEL_bm; + CCP = CCP_IOREG_gc; + PMIC.CTRL = temp; + + EIND = 0x00; /* disable extended indirect jump */ + + app_start(); /* jump to application */ +} + +void start_bootloader() +{ + uint8_t chr = 0, temp, error_counter = 0; + bool err = false, escape = false; + while(true) + { + switch (state) + { + case INIT: + if (eeprom_read_upgrade() == false) + { + usart_putchar(USART_SERIAL, eeprom_read_byte(EEPROM_ADDR_FWUPGRADE)); + start_firmware(); + } + state = HANDSHAKE; + break; + + /////////////////////////////////////// + case HANDSHAKE: + + do + { + usart_serial_getchar(USART_SERIAL, &chr); + } while (chr != BOOTLDR_HANDSHAKE); + usart_serial_getchar(USART_SERIAL, &handshake); + usart_putchar(USART_SERIAL, BOOTLDR_RES_OK); + usart_putchar(USART_SERIAL, handshake); + timer_reset_counter(); + state = DATA; + break; + + ////////////////////////////////////// + case DATA: + checksum = 0; + err = false; + do + { + usart_serial_getchar(USART_SERIAL, &chr); + } while (chr != handshake); + //checksum_add_byte(chr); + //command - data, finish, reset + usart_serial_getchar(USART_SERIAL, &chr); + checksum_add_byte(chr); + if (chr == BOOTLDR_DATA) + { + usart_serial_getchar(USART_SERIAL, &page_nr); + checksum_add_byte(page_nr); + for (int i = 0; i < FLASH_PAGE_SIZE; i++) + { + usart_serial_getchar(USART_SERIAL, &chr); + checksum_add_byte(chr); + if (!escape && chr == BOOTLDR_ESCAPE) + { + i--; + escape = true; + continue; + } + //check for forbidden char + else if (!escape && (chr == BOOTLDR_DATA || chr == BOOTLDR_HANDSHAKE || chr == BOOTLDR_FINISH || chr == BOOTLDR_RESET)) + { + usart_putchar(USART_SERIAL, 0x55); + err = true; + error_counter++; + } + else + escape = false; + if (!escape) + page[i] = chr; + escape = false; + + timer_reset_counter(); + } + if (read_compare_checksum()) + { + //usart_putchar(USART_SERIAL, BOOTLDR_RES_OK); + //for (int i = 0; i < 512; ++i) + // usart_putchar(USART_SERIAL, page[i]); + //TODO write page to memory + nvm_flash_erase_and_write_buffer(page_nr * FLASH_PAGE_SIZE, page, FLASH_PAGE_SIZE, true); + + } + else + { + usart_putchar(USART_SERIAL, 0x66); + usart_putchar(USART_SERIAL, checksum); + err = true; + error_counter++; + } + } + else if (chr == BOOTLDR_FINISH) + { + if (read_compare_checksum()) + { + state = FINISH; + } + else + { + err = true; + error_counter++; + } + } + else if (chr == BOOTLDR_RESET) + { + if (read_compare_checksum()) + ccp_write_io((void *)&RST.CTRL, RST_SWRST_bm); + else + { + err = true; + error_counter++; + } + } + else + { + err = true; + error_counter++; + } + + if (!err) + { + usart_putchar(USART_SERIAL, BOOTLDR_RES_OK); + timer_reset_counter(); + } + else + { + if (error_counter < BOOTLDR_ERR_MAX) + usart_putchar(USART_SERIAL, BOOTLDR_RES_FAIL); + else + { + usart_putchar(USART_SERIAL, BOOTLDR_RES_ABORT); + printString("Resetting CPU - too many errors"); + ccp_write_io((void *)&RST.CTRL, RST_SWRST_bm); + } + } + + + break; + + //////////////////////////////////// + case FINISH: + //eeprom_write_ready(); + start_firmware(); + break; + default: + break; + } + } +} + +void checksum_add_byte(uint8_t byte) +{ + checksum = (checksum ^ byte) % 256; +} + +void eeprom_write_upgrade( void ) +{ + eeprom_write_byte(EEPROM_ADDR_FWUPGRADE, EEPROM_FWUPGRADE_VALUE); +} + +void eeprom_write_ready( void ) +{ + eeprom_write_byte(EEPROM_ADDR_FWUPGRADE, EEPROM_FWREADY_VALUE); +} + +bool eeprom_read_upgrade( void ) +{ + //return false; + // return true; + //usart_putchar(USART_SERIAL, eeprom_read_byte((EEPROM_ADDR_FWUPGRADE))); + return eeprom_read_byte(EEPROM_ADDR_FWUPGRADE) != EEPROM_FWREADY_VALUE; +} + +bool read_compare_checksum(void) +{ + uint8_t chr; + usart_serial_getchar(USART_SERIAL, &chr); + return (chr == checksum); +} diff --git a/Fred_bootloader/src/bootloader.h b/Fred_bootloader/src/bootloader.h new file mode 100644 index 0000000000000000000000000000000000000000..e67b4812b75ae99aef8bd711de9b29b8c56309e8 --- /dev/null +++ b/Fred_bootloader/src/bootloader.h @@ -0,0 +1,42 @@ +/* + * bootloader.h + * + * Created: 2015-04-12 13:07:31 + * Author: Paweł + */ + + +#ifndef BOOTLOADER_H_ +#define BOOTLOADER_H_ + +#include <stdbool.h> +#include <stdint.h> + +typedef enum {INIT, HANDSHAKE, DATA, FINISH} BootloaderState; + +#define BOOTLDR_ESCAPE 0x01 +#define BOOTLDR_HANDSHAKE 0x02 +#define BOOTLDR_DATA 0x03 +#define BOOTLDR_FINISH 0x04 +#define BOOTLDR_RESET 0x05 + +#define BOOTLDR_RES_OK 0x01 +#define BOOTLDR_RES_FAIL 0x02 +#define BOOTLDR_RES_ABORT 0x03 + +#define BOOTLDR_ERR_MAX 20 + + +#define EEPROM_ADDR_FWUPGRADE (uint8_t *) 63 +#define EEPROM_FWUPGRADE_VALUE (uint8_t) 0x56 +#define EEPROM_FWREADY_VALUE (uint8_t) 0x55 + +void start_bootloader(void); +void start_firmware(void); +void eeprom_write_upgrade(void); +void eeprom_write_ready(void); +bool eeprom_read_upgrade(void); +void checksum_add_byte(uint8_t byte); +bool read_compare_checksum(void); + +#endif /* BOOTLOADER_H_ */ \ No newline at end of file diff --git a/Fred_bootloader/src/config/conf_board.h b/Fred_bootloader/src/config/conf_board.h new file mode 100644 index 0000000000000000000000000000000000000000..3275aab04fbceea0a26f767fbd4cf198309b3bda --- /dev/null +++ b/Fred_bootloader/src/config/conf_board.h @@ -0,0 +1,11 @@ +/** + * \file + * + * \brief User board configuration template + * + */ + +#ifndef CONF_BOARD_H +#define CONF_BOARD_H + +#endif // CONF_BOARD_H diff --git a/Fred_bootloader/src/config/conf_clock.h b/Fred_bootloader/src/config/conf_clock.h new file mode 100644 index 0000000000000000000000000000000000000000..02d0369aa5f177206c8325dc2fc59973dedf756c --- /dev/null +++ b/Fred_bootloader/src/config/conf_clock.h @@ -0,0 +1,98 @@ +/** + * \file + * + * \brief Chip-specific system clock manager configuration + * + * Copyright (c) 2011-2013 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef CONF_CLOCK_H_INCLUDED +#define CONF_CLOCK_H_INCLUDED + +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ +#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC32MHZ +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC32KHZ +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_XOSC +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL + +/* Fbus = Fsys / (2 ^ BUS_div) */ +#define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 +#define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 + +//#define CONFIG_PLL0_SOURCE PLL_SRC_XOSC +//#define CONFIG_PLL0_SOURCE PLL_SRC_RC2MHZ +//#define CONFIG_PLL0_SOURCE PLL_SRC_RC32MHZ + +/* Fpll = (Fclk * PLL_mul) / PLL_div */ +//#define CONFIG_PLL0_MUL (24000000UL / BOARD_XOSC_HZ) +//#define CONFIG_PLL0_DIV 1 + +/* External oscillator frequency range */ +/** 0.4 to 2 MHz frequency range */ +//#define CONFIG_XOSC_RANGE XOSC_RANGE_04TO2 +/** 2 to 9 MHz frequency range */ +//#define CONFIG_XOSC_RANGE XOSC_RANGE_2TO9 +/** 9 to 12 MHz frequency range */ +//#define CONFIG_XOSC_RANGE XOSC_RANGE_9TO12 +/** 12 to 16 MHz frequency range */ +//#define CONFIG_XOSC_RANGE XOSC_RANGE_12TO16 + +/* DFLL autocalibration */ +//#define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ +//#define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_XOSC + +/* The following example clock configuration definitions can be used in XMEGA + * devices that contain a USB controller. It configures the USB controller clock + * source to use the internal (nominally) 32MHz RC oscillator, up-calibrated to + * run at 48MHz via the periodic 1ms USB Start Of Frame packets sent by the + * host. The USB controller requires 48MHz for Full Speed operation, or 6MHz + * for USB Low Speed operation. + * + * Note that when the 32MHz RC oscillator is tuned to 48MHz, it cannot be used + * directly as the system clock source; it must either be prescaled down to a + * speed below the maximum operating frequency given in the datasheet, or an + * alternative clock source (e.g. the internal 2MHz RC Oscillator, multiplied + * to a higher frequency via the internal PLL module) must be used instead. + */ +#define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC +//#define CONFIG_OSC_RC32_CAL 48000000UL +//#define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + +/* Use to enable and select RTC clock source */ +//#define CONFIG_RTC_SOURCE SYSCLK_RTCSRC_ULP + +#endif /* CONF_CLOCK_H_INCLUDED */ diff --git a/Fred_bootloader/src/config/conf_sleepmgr.h b/Fred_bootloader/src/config/conf_sleepmgr.h new file mode 100644 index 0000000000000000000000000000000000000000..6427730696577f27fe8b37db48b9c426787c23b5 --- /dev/null +++ b/Fred_bootloader/src/config/conf_sleepmgr.h @@ -0,0 +1,49 @@ +/** + * \file + * + * \brief Chip-specific sleep manager configuration + * + * Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef CONF_SLEEPMGR_H +#define CONF_SLEEPMGR_H + +// Sleep manager options +#define CONFIG_SLEEPMGR_ENABLE + +#endif /* CONF_SLEEPMGR_H */ diff --git a/Fred_bootloader/src/config/conf_usart_serial.h b/Fred_bootloader/src/config/conf_usart_serial.h new file mode 100644 index 0000000000000000000000000000000000000000..7bb30f890c2fdd2bf8c435f01674b27a2a8afc4a --- /dev/null +++ b/Fred_bootloader/src/config/conf_usart_serial.h @@ -0,0 +1,53 @@ +/** + * \file ********************************************************************* + * + * \brief USART Serial configuration + * + * Copyright (c) 2011 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef CONF_USART_SERIAL_H_INCLUDED +#define CONF_USART_SERIAL_H_INCLUDED + +#define USART_SERIAL &USARTF0 +#define USART_SERIAL_BAUDRATE 9600 +#define USART_SERIAL_CHAR_LENGTH USART_CHSIZE_8BIT_gc +#define USART_SERIAL_PARITY USART_PMODE_DISABLED_gc +#define USART_SERIAL_STOP_BIT false + +#endif /* CONF_USART_SERIAL_H_INCLUDED */ diff --git a/Fred_bootloader/src/main.c b/Fred_bootloader/src/main.c new file mode 100644 index 0000000000000000000000000000000000000000..7f87e43414588d90fa440a20507863f043229fb9 --- /dev/null +++ b/Fred_bootloader/src/main.c @@ -0,0 +1,61 @@ +/** + * \file + * + * \brief Empty user application template + * + */ + +/** + * \mainpage User Application template doxygen documentation + * + * \par Empty user application template + * + * Bare minimum empty user application template + * + * \par Content + * + * -# Include the ASF header files (through asf.h) + * -# "Insert system clock initialization code here" comment + * -# Minimal main function that starts with a call to board_init() + * -# "Insert application code here" comment + * + */ + +/* + * Include header files for all drivers that have been imported from + * Atmel Software Framework (ASF). + */ +#include <asf.h> +#include <util/delay.h> +#include "usart_lib.h" +#include "timer_lib.h" +#include "bootloader.h" +#include <ccp.h> +int main (void) +{ + // Insert system clock initialization code here (sysclk_init()). + + board_init(); + sysclk_init(); + + /* Set interrupt vector location to boot section of flash */ + uint8_t temp = 0x00; + temp = PMIC.CTRL | PMIC_IVSEL_bm; + CCP = CCP_IOREG_gc; + PMIC.CTRL = temp; + + timer_init(); + + pmic_init(); + pmic_set_scheduling(PMIC_SCH_FIXED_PRIORITY);//PMIC_SCH_ROUND_ROBIN); + cpu_irq_enable(); + + usart_init(); + + printString("Bootloader\r\n"); + start_bootloader(); + //reset processor + //ccp_write_io((void *)&RST.CTRL, RST_SWRST_bm); + // Insert application code here, after the board has been initialized. + start_firmware(); +} diff --git a/Fred_bootloader/src/timer_lib.c b/Fred_bootloader/src/timer_lib.c new file mode 100644 index 0000000000000000000000000000000000000000..6f623ae161321f276a3158e1fdde9eb8ce0c0c2d --- /dev/null +++ b/Fred_bootloader/src/timer_lib.c @@ -0,0 +1,86 @@ +/** + * @file timer_lib.C + * @brief ATXMEGA timer support library + * + * @copyright (C) 2014 Lodz University of Technology, Lodz, Poland (TUL) + * @copyright (C) 2014 Deutsches Elektronen-Synchrotron, Hamburg, Germany (DESY) + * @author Pawel Plewinski (TUL) + * @author Piotr Perek (TUL) + * @author Dariusz Makowski (TUL) + * @par License + * + * Redistribution and use in source and binary forms, with or without + * modification is not allowed. Exceptions are regulated by separate License document. In all cases it is requested to provide the above header. + * + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <asf.h> + +#include "timer_lib.h" +#include "usart_lib.h" + +#define PERIOD_10MS 1250 +#define PERIOD_100MS 12500 + +extern uint16_t events; +volatile bool timer_100ms_flag = false; +volatile uint16_t idle_counter = 0; + + +void timer_reset_counter(void) +{ + idle_counter = 0; +} + +static void tc_overflow_callback(void) //100 ms +{ + static volatile uint8_t sec_counter = 0; + sec_counter++; + idle_counter++; + timer_100ms_flag = true; + if(sec_counter == 5) + { + ioport_toggle_pin(MMC_LED); + sec_counter = 0; + } + //RESET after 20 s of inactivity + if (idle_counter == 200) + { + //printString("Reset"); + //reset processor + ccp_write_io((void *)&RST.CTRL, RST_SWRST_bm); + } +} + + +static void tc_cca_callback(void) //10 ms +{ + uint16_t tmp = tc_read_cc(&TCC0, TC_CCA); + tc_write_cc(&TCC0, TC_CCA, (tmp+PERIOD_10MS) % PERIOD_100MS); +} + + +void timer_init(void) +{ + tc_enable(&TCC0); + tc_set_overflow_interrupt_callback(&TCC0, tc_overflow_callback); + tc_set_wgm(&TCC0, TC_WG_NORMAL); + tc_write_period(&TCC0, PERIOD_100MS); + //tc_write_cc(&TCC0, TC_CCA, PERIOD_10MS); + //tc_enable_cc_channels(&TCC0, TC_CCAEN); + tc_set_overflow_interrupt_level(&TCC0, TC_INT_LVL_LO); + tc_write_clock_source(&TCC0, TC_CLKSEL_DIV256_gc); + //tc_set_cca_interrupt_level(&TCC0, TC_INT_LVL_HI); + //tc_set_cca_interrupt_callback(&TCC0, tc_cca_callback); +} \ No newline at end of file diff --git a/Fred_bootloader/src/timer_lib.h b/Fred_bootloader/src/timer_lib.h new file mode 100644 index 0000000000000000000000000000000000000000..a097601e20c21dac5540f9c6996f01e793d88c7b --- /dev/null +++ b/Fred_bootloader/src/timer_lib.h @@ -0,0 +1,36 @@ +/** + * @file timer_lib.h + * @brief ATXMEGA timer support library header + * + * @copyright (C) 2014 Lodz University of Technology, Lodz, Poland (TUL) + * @copyright (C) 2014 Deutsches Elektronen-Synchrotron, Hamburg, Germany (DESY) + * @author Pawel Plewinski (TUL) + * @author Piotr Perek (TUL) + * @author Dariusz Makowski (TUL) + * @par License + * + * Redistribution and use in source and binary forms, with or without + * modification is not allowed. Exceptions are regulated by separate License document. In all cases it is requested to provide the above header. + * + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TIMER_LIB_H_ +#define TIMER_LIB_H_ + +extern volatile bool timer_100ms_flag; + +void timer_init(void); +void timer_reset_counter(void); + +#endif /* TIMER_LIB_H_ */ \ No newline at end of file diff --git a/Fred_bootloader/src/usart_lib.c b/Fred_bootloader/src/usart_lib.c new file mode 100644 index 0000000000000000000000000000000000000000..07cc6fe6d72d61e954f2c2f8621dbcd57fb03214 --- /dev/null +++ b/Fred_bootloader/src/usart_lib.c @@ -0,0 +1,76 @@ +/** + * @file usart_lib.C + * @brief USART support library + * + * @copyright (C) 2014 Lodz University of Technology, Lodz, Poland (TUL) + * @copyright (C) 2014 Deutsches Elektronen-Synchrotron, Hamburg, Germany (DESY) + * @author Pawel Plewinski (TUL) + * @author Piotr Perek (TUL) + * @author Dariusz Makowski (TUL) + * @par License + * + * Redistribution and use in source and binary forms, with or without + * modification is not allowed. Exceptions are regulated by separate License document. In all cases it is requested to provide the above header. + * + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <usart.h> +#include <usart_serial.h> +#include <conf_usart_serial.h> +#include <asf.h> +#include <ctype.h> +#include "usart_lib.h" +#include "config/conf_usart_serial.h" +#include <stdio.h> + +#include <util/delay.h> + +volatile bool usartEcho = false; + +void usart_init(void) +{ + //cli(); + //sysclk_init(); + static usart_serial_options_t usart_options = { + .baudrate = USART_SERIAL_BAUDRATE, + .charlength = USART_SERIAL_CHAR_LENGTH, + .paritytype = USART_SERIAL_PARITY, + .stopbits = USART_SERIAL_STOP_BIT + }; + + usart_serial_init(USART_SERIAL, &usart_options); + //usart_set_rx_interrupt_level(USART_SERIAL, PMIC_LOLVLEN_bm); + //printString("HELLO"); +} + +/*ISR (USARTF0_RXC_vect) +{ + ioport_toggle_pin(MMC_LED); + uint8_t ch; + usart_serial_getchar((USART_SERIAL), &ch); + if (usartEcho) + { + usart_serial_putchar((USART_SERIAL), ch); + if (ch == '\r') usart_serial_putchar((USART_SERIAL), '\n'); + } +}*/ + +void printString( char *string ) +{ + while (*string) + { + usart_serial_putchar(USART_SERIAL, *(string++)); +// _delay_us(1000); + } +} diff --git a/Fred_bootloader/src/usart_lib.h b/Fred_bootloader/src/usart_lib.h new file mode 100644 index 0000000000000000000000000000000000000000..04ae5bdd330a1c99146a72f42d7af22f92dcf47f --- /dev/null +++ b/Fred_bootloader/src/usart_lib.h @@ -0,0 +1,38 @@ +/** + * @file usart_lib.h + * @brief USART support library header + * + * @copyright (C) 2014 Lodz University of Technology, Lodz, Poland (TUL) + * @copyright (C) 2014 Deutsches Elektronen-Synchrotron, Hamburg, Germany (DESY) + * @author Pawel Plewinski (TUL) + * @author Piotr Perek (TUL) + * @author Dariusz Makowski (TUL) + * @par License + * + * Redistribution and use in source and binary forms, with or without + * modification is not allowed. Exceptions are regulated by separate License document. In all cases it is requested to provide the above header. + * + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef INCFILE1_H_ +#define INCFILE1_H_ + +#include "config/conf_usart_serial.h" + +volatile extern bool usartEcho; + +void usart_init(void); +void printString(char *string); + +#endif /* INCFILE1_H_ */ \ No newline at end of file