From 9f05f3ccd216ab29f3d11a88046f25c7a3abd106 Mon Sep 17 00:00:00 2001 From: "@shinhub" Date: Tue, 13 Aug 2019 00:23:42 +0200 Subject: [PATCH 1/6] Add DFU bootloader Atmel source and @exander77 PINing patch, as discovered by @slurdge and @exander77 in issue #11. --- .gitignore | 2 +- .../atxmega32a4u_104_PA6.hex | 251 ++ .../common/boards/board.h | 288 +++ .../common/services/clock/genclk.h | 174 ++ .../common/services/clock/osc.h | 160 ++ .../common/services/clock/pll.h | 316 +++ .../common/services/clock/sysclk.h | 167 ++ .../common/services/clock/xmega/osc.h | 461 ++++ .../common/services/clock/xmega/pll.h | 262 ++ .../common/services/clock/xmega/sysclk.c | 240 ++ .../common/services/clock/xmega/sysclk.h | 1326 ++++++++++ .../common/services/isp/flip/flip_protocol.h | 250 ++ .../common/services/isp/flip/isp.h | 226 ++ .../services/isp/flip/xmega/cstartup.s90 | 232 ++ .../common/services/isp/flip/xmega/isp.c | 281 +++ .../bootloader/xmega/atxmega32a4u/iar/asf.h | 82 + .../atxmega32a4u/iar/atxmega32a4u_boot.xcl | 102 + .../xmega/atxmega32a4u/iar/xmega_small.ewd | 1847 ++++++++++++++ .../xmega/atxmega32a4u/iar/xmega_small.ewp | 2156 +++++++++++++++++ .../xmega/atxmega32a4u/iar/xmega_small.eww | 6 + .../device/bootloader/xmega/conf/conf_board.h | 47 + .../device/bootloader/xmega/conf/conf_clock.h | 61 + .../device/bootloader/xmega/conf/conf_isp.h | 100 + .../device/bootloader/xmega/conf/conf_usb.h | 218 ++ .../dfu_flip/device/bootloader/xmega/main.c | 80 + .../dfu_flip/device/bootloader/xmega/main.h | 47 + .../device/bootloader/xmega/sysclk_opt.c | 98 + .../usb/class/dfu_flip/device/udi_dfu_atmel.c | 976 ++++++++ .../usb/class/dfu_flip/device/udi_dfu_atmel.h | 126 + .../dfu_flip/device/udi_dfu_atmel_conf.h | 76 + .../dfu_flip/device/udi_dfu_atmel_desc.c | 146 ++ .../usb/class/dfu_flip/usb_protocol_dfu.h | 192 ++ .../common/services/usb/udc/udc.h | 726 ++++++ .../common/services/usb/udc/udc_desc.h | 131 + .../common/services/usb/udc/udc_dfu_small.c | 488 ++++ .../common/services/usb/udc/udd.h | 392 +++ .../common/services/usb/udc/udi.h | 130 + .../common/services/usb/usb_atmel.h | 185 ++ .../common/services/usb/usb_protocol.h | 410 ++++ .../common/utils/interrupt.h | 139 ++ .../common/utils/interrupt/interrupt_avr8.h | 138 ++ .../Atmel DFU Bootloader/common/utils/parts.h | 644 +++++ .../xmega/boards/dummy/dummy_board.h | 53 + .../xmega/drivers/cpu/ccp.h | 120 + .../xmega/drivers/cpu/ccp.s | 100 + .../xmega/drivers/cpu/xmega_reset_cause.h | 105 + .../xmega/drivers/nvm/nvm.c | 757 ++++++ .../xmega/drivers/nvm/nvm.h | 1057 ++++++++ .../xmega/drivers/nvm/nvm_asm.s | 197 ++ .../xmega/drivers/usb/usb_device.c | 1448 +++++++++++ .../xmega/drivers/usb/usb_device.h | 387 +++ .../xmega/utils/assembler.h | 156 ++ .../xmega/utils/assembler/iar.h | 109 + .../xmega/utils/bit_handling/clz_ctz.h | 212 ++ .../xmega/utils/compiler.h | 1039 ++++++++ .../xmega/utils/preprocessor/mrepeat.h | 335 +++ .../xmega/utils/preprocessor/preprocessor.h | 51 + .../xmega/utils/preprocessor/stringz.h | 81 + .../xmega/utils/preprocessor/tpaste.h | 101 + .../xmega/utils/progmem.h | 99 + .../xmega/utils/status_codes.h | 115 + 61 files changed, 20900 insertions(+), 1 deletion(-) create mode 100644 Firmware/Atmel DFU Bootloader/atxmega32a4u_104_PA6.hex create mode 100644 Firmware/Atmel DFU Bootloader/common/boards/board.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/clock/genclk.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/clock/osc.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/clock/pll.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/clock/sysclk.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/clock/xmega/osc.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/clock/xmega/pll.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/clock/xmega/sysclk.c create mode 100644 Firmware/Atmel DFU Bootloader/common/services/clock/xmega/sysclk.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/isp/flip/flip_protocol.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/isp/flip/isp.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/isp/flip/xmega/cstartup.s90 create mode 100644 Firmware/Atmel DFU Bootloader/common/services/isp/flip/xmega/isp.c create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/asf.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/atxmega32a4u_boot.xcl create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewd create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewp create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.eww create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_board.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_clock.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_isp.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_usb.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/main.c create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/main.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/sysclk_opt.c create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel.c create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel_conf.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel_desc.c create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/usb_protocol_dfu.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/udc/udc.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/udc/udc_desc.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/udc/udc_dfu_small.c create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/udc/udd.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/udc/udi.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/usb_atmel.h create mode 100644 Firmware/Atmel DFU Bootloader/common/services/usb/usb_protocol.h create mode 100644 Firmware/Atmel DFU Bootloader/common/utils/interrupt.h create mode 100644 Firmware/Atmel DFU Bootloader/common/utils/interrupt/interrupt_avr8.h create mode 100644 Firmware/Atmel DFU Bootloader/common/utils/parts.h create mode 100644 Firmware/Atmel DFU Bootloader/xmega/boards/dummy/dummy_board.h create mode 100644 Firmware/Atmel DFU Bootloader/xmega/drivers/cpu/ccp.h create mode 100644 Firmware/Atmel DFU Bootloader/xmega/drivers/cpu/ccp.s create mode 100644 Firmware/Atmel DFU Bootloader/xmega/drivers/cpu/xmega_reset_cause.h create mode 100644 Firmware/Atmel DFU Bootloader/xmega/drivers/nvm/nvm.c create mode 100644 Firmware/Atmel DFU Bootloader/xmega/drivers/nvm/nvm.h create mode 100644 Firmware/Atmel DFU Bootloader/xmega/drivers/nvm/nvm_asm.s create mode 100644 Firmware/Atmel DFU Bootloader/xmega/drivers/usb/usb_device.c create mode 100644 Firmware/Atmel DFU Bootloader/xmega/drivers/usb/usb_device.h create mode 100644 Firmware/Atmel DFU Bootloader/xmega/utils/assembler.h create mode 100644 Firmware/Atmel DFU Bootloader/xmega/utils/assembler/iar.h create mode 100644 Firmware/Atmel DFU Bootloader/xmega/utils/bit_handling/clz_ctz.h create mode 100644 Firmware/Atmel DFU Bootloader/xmega/utils/compiler.h create mode 100644 Firmware/Atmel DFU Bootloader/xmega/utils/preprocessor/mrepeat.h create mode 100644 Firmware/Atmel DFU Bootloader/xmega/utils/preprocessor/preprocessor.h create mode 100644 Firmware/Atmel DFU Bootloader/xmega/utils/preprocessor/stringz.h create mode 100644 Firmware/Atmel DFU Bootloader/xmega/utils/preprocessor/tpaste.h create mode 100644 Firmware/Atmel DFU Bootloader/xmega/utils/progmem.h create mode 100644 Firmware/Atmel DFU Bootloader/xmega/utils/status_codes.h diff --git a/.gitignore b/.gitignore index a29dcd3..236ecba 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,7 @@ *.s19 *.map *.bin -*.hex +Firmware/Chameleon-Mini/*.hex *.dll *.sym *.lss diff --git a/Firmware/Atmel DFU Bootloader/atxmega32a4u_104_PA6.hex b/Firmware/Atmel DFU Bootloader/atxmega32a4u_104_PA6.hex new file mode 100644 index 0000000..8fd91c3 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/atxmega32a4u_104_PA6.hex @@ -0,0 +1,251 @@ +:020000020000FC +:1080000000C00091780005FD6AC0F092000608E10A +:10801000009316060FEF0A950023E9F70091080672 +:1080200006FFECC0E0E0F0E0079116910F3F19F475 +:108030001F3F09F4E3C053C03091CF0137FDFCCF9F +:108040003BB72BBFF8012091CA0113E21093CA017C +:108050000A01E8952093CA013BBF08953BB72BBFA7 +:10806000F8012091CA014093CA013DE930933400E0 +:10807000E8952093CA013BBF089520E006D0E9F7B8 +:108080000895259102D0E9F708952D9301501040ED +:10809000202F212B089584E39FE8FC010591149182 +:1080A000FC013296A591B491FC013496259134914E +:1080B000422F432B19F0F901E4DF01C0DEDF069601 +:1080C0001FE88034910748F3089501E70DBF00E2EF +:1080D0000EBFC4E2DAE20E944B400E942E41F092B1 +:1080E000530600910020109101200A3A154511F025 +:1080F0000C940000F0920020F092012000E2009326 +:108100007800F6CFAA84998488847F806E805D8011 +:108110004C80BB81AA8199818881F0E0EC0FFD1F22 +:10812000EF010895BD01D801F90104C021912D93FB +:1081300041505040242F252BC9F7DB010895AA9206 +:108140009A928A927A926A925A924A92BA93AA938D +:108150009A938A930895AF93BF93D80101900D929B +:1081600041505040D9F7BF91AF9108954091CA0155 +:10817000E22FF32F0093CA0104914093CA0108959E +:1081800040E04BBFF80158ED54BF208308954A9555 +:108190001AF0000F111FFBCF08954A951AF016959B +:0681A0000795FBCF0895D6 +:1081F4000C945C450C94944566CF0FBF08954FB71B +:10820400F8941095F0E0E02FE059FF4F008101232E +:108214000083042FF2CFB90198018B0163C361E09D +:1082240078C3B90198018B019FC2CFC262E770E2A3 +:10823400260F371F0C94924068EE70E2F9CFF89441 +:108244000AEA15E5E0E0F0E2008311832091790069 +:10825400216009E739D0FFCF27E402EA35D005D001 +:108264007894C9D303D4FFCFC8CF24E001E42CD041 +:108274002DE126D0009362002CE122D0009363000C +:108284000FB7F894E0E5F0E0108112601083ECDFA2 +:108294000091510001FBE6F721E000E415D0E6E58A +:1082A400F0E00081097F008300E807870BEB008B77 +:1082B400008104600083E0E600810160008308958A +:1082C40030E002E00C94B64010E00C94C04000E0B2 +:1082D4000093EC2053D0009190000093E82000918B +:1082E40091000093E920009192000093EA2000910C +:1082F40093000093EB200091D00101FB16F001E004 +:1083040001C000E0DEC00ED2A6E0B1E20091062179 +:108314000076003289F5109107210C91569707FFDA +:108324000FC0125041F01A9529F526E030E09E96D0 +:108334008D0180D01DC0D49675D5E1F009951DC07E +:108344001A9521F01350B1F419D012C00091EC2009 +:10835400002321F001E211E4929608C020E430E009 +:108364000FE211E267D00CEC11E494960D931C9388 +:1083740001E003C00FE05FD000E061C100C097D10D +:1083840000E006A702E002AB00E004A305A302A3F9 +:1083940003A30895F3DF10E08AD114AB15ABEFE229 +:1083A400F1E230812181203001E0300709F422C05C +:1083B400203003E0300709F444C02130300709F4C9 +:1083C40060C0203004E0300749F4A0D207FDFDCF9F +:1083D40040E200E0FDD277D200E073C023303007E2 +:1083E40021F401E00093EC2008952330364009F491 +:1083F40057C05BC197D135D011F082D018C0ACE121 +:10840400B1E22D913C919D972030304019F403E066 +:1084140012D002C02CD011F400E009C020E038E0F2 +:1084240007D00BE013E494960D931C9301E007C16D +:1084340000E711E239C300931E210AE000932221D0 +:10844400089515D019F025D011F416D02EC109D0F5 +:1084540019F002E812E402C00DEA12E404AB15AB11 +:1084640032C00091ED201091EE200123089501E324 +:1084740011E24DD00023089503E006A70AE002AB01 +:108484000895F5DF19F005D011F4F6DF0EC170D0B0 +:108494001AC0E0EFF0E222A533A520303040089561 +:1084A400EFE2F1E20281002359F40381013118F073 +:1084B40008E0C1DFFAC009D000E0F9D006AB07AB91 +:1084C40002C00093ED2001E00895033041F0023032 +:1084D40031F0043021F0053011F011E001C010E05A +:1084E4001093EE2012E0019FF001E356FF4D6081EE +:1084F400F18106E111E2E62F48E050E00C94AB4034 +:1085040003E000931E2102E000932221CEC0BD01AE +:10851400D8015C91F8010181402FC9D006AB57AB5B +:1085240012961D9130E00C9120E006A017A020A423 +:1085340031A4001511052205330520F008E09DDF64 +:1085440000E007C0041B150B0F5F1F4F00AF11AFF6 +:1085540001E0DB01089576D040AD51AD4AD09A9642 +:1085640051D49B970995FD0120AD31AD61DF66C003 +:1085740023D1A0EFB0E2FD0100AD11AD012B39F420 +:1085840000E018EF00AF11AF80E098E010C0FD01EB +:1085940000AD11AD202F212B59F1183010F4C80172 +:1085A40002C080E098E0081B190B00AF11AFAC01CA +:1085B40020D062A5F3A5E62F099500E711E207C0D4 +:1085C400FD0126A937A92F5F3F4F26AB37AB9C018E +:1085D4000197232BE1F2F80121918F012F3F81F3C1 +:1085E40005E000931E2100E013E4FD0104AB15AB8C +:1085F400B0C326A937A900E711E2089558D026A9E7 +:1086040007A9009370212093712122E030E010DF4C +:108614005ACF18D006A917A940AD51AD202F2F73FA +:10862400622F70E020E731E2260F371F9C96EAD3D1 +:108634009D97099500E0FD0104A305A301E0A9911C +:10864400B9910895BA93AA93A0EFB0E2FD010895F9 +:10865400009108210F770093C304089528D0208D3A +:10866400018D0A9529F00A95A1F00A95B9F01DC06B +:10867400E0ECF0E2228930E072968F01DBDE17D065 +:1086840013D320A131A10217130710F400A311A3DF +:108694001ACFE0ECF0E222813381EFCF222329F4D8 +:1086A40024E030E004EE10E2E9CF00E00895E0EFCA +:1086B400F0E2089537D0FBDF06890F7189F5178939 +:1086C400068907FF14C0112329F0165041F01250F7 +:1086D40041F026C022E030E000E719E206C0BEDF28 +:1086E40020C021E030E002E719E2A4DE17C01550F3 +:1086F40019F0145031F014C00AE213E402A313A3D6 +:108704000DC001E010E0A0E7B9E20D931C93008DC9 +:1087140000937229002311F0DADD03C001E001C0E7 +:1087240000E08DCFBA93AA930895C1DF00E000A3BF +:1087340001A302A303A304A305A3068907FF03C09F +:10874400B3D2012B81F000910621007619F4B2DF37 +:10875400002341F4009106210F71013021F4D3DD8F +:10876400002309F0B0CEA1CFB90161D0208127FD4B +:10877400FDCFECEC208128602083105F98018B01F1 +:1087840059DDECECF1E00081077F98CD15D0C801EC +:10879400A22FB091CA0141D04AD0008107FDFDCF7C +:1087A4000DD09093C1018093C001A093C40105E34F +:1087B40041D0B093CA01CDC20C94A64003E3009308 +:1087C400CA0100E00093C20108950E94A440C801B8 +:1087D400D9012A010DC08D0133D045E08C010E94DE +:1087E400CD4049D08096909600EE400E0FEF501E7B +:1087F400042D052979F0082F0F7129F400E24016A1 +:1088040000E0500640F72D918C01C0DF01960FEF78 +:10881400400EEDCFE6E00C94874009D0008107FDBF +:10882400FDCF008101FF02C006E304D00895EFEC00 +:10883400F1E008950093CA0121E00BEC11E045CD6D +:108844003091CA012091CF0127FDFCCF23E320936F +:10885400CA0120E02093C2012093C1012093C001EA +:10886400F80141918F014093C40123952032B0F364 +:108874003093CA0108958A93DADF108117FDFDCF82 +:1088840010E2019F9EDF1092C1010092C00180910D +:10889400CA0105E322C09A938A93802F9091CA015A +:1088A400BCDF34D007FDFDCF89DF0093C101009305 +:1088B400C0018093C40103950032C8F39093CA01A8 +:1088C4008991999108958A930FEFE5DFB0DF0081D4 +:1088D40007FDFDCF8091CA0100E3ACDF8093CA019C +:1088E40089910895BC01C80111D007FDFDCF042F63 +:1088F400052B51F0FC010491F90100832F5F3F4FD8 +:10890400019641505040F3CFCB0108950091CF011F +:1089140008950E949F402297D9013A01A62E28016A +:10892400912F80E006C02091CF0127FDFCCF45E2C6 +:108934004FD0062D0729F9F19924E8DF07FDFDCF73 +:1089440000E8802EAA2061F0FC01059114910883AF +:10895400198308810F3F1F4F31F09924939403C06A +:108964000FEF08830983062D072979F04816590665 +:1089740029F425D00883062D072939F0FC01319606 +:108984004E165F0611F41BD00983488159818C016E +:1089940020E030E00E941C4002968A9499F69C01E3 +:1089A4003A959920890109F0BECF2091CF0127FD86 +:1089B400FCCF44E2BDCF2296EBE00C9482400FEF53 +:1089C400600E701E01E0400E00E0501E0D910895EF +:1089D40020E030E00C942E4010CC2AE107D0009324 +:1089E400FA042BE103D00093FB04089569DC0F3FE4 +:1089F40009F40FE108950E94A74000E0009360008D +:108A040010E4FDDB23E004E45FDC7BD2006400833C +:108A140001E000936000AFB7F89400E010E028E0B4 +:108A2400029FF001E051FF4D158303950230C0F31E +:108A3400D4DF0091C0040093C00463D200680083B3 +:108A440000810061008380EF90E20496E6EC80836D +:108A54009183E0EC33D10FEF0583E8EC00810160F2 +:108A640000830A2FB9DFE3E00C948A400FB7F8942F +:108A740010E41093CA0410E21093CA04E1ECF4E089 +:108A8400108111601083E9EC108112601083E8EC0E +:108A9400108110641083E9EC108111601083E8ECFC +:108AA40010811068108398CF02DE068F178F20A3E1 +:108AB40031A3089564D00091CB0407FF02C000E8FD +:108AC4002EC005D2002361F5EBEC1CD204FF1EC0BE +:108AD40000E114D200E00093722901E010E0009359 +:108AE40070291093712900E00093C30420E430E05E +:108AF40059D020E430E010E000E854D003E719E254 +:108B04000093F8201093F92028D10AC0008106FFB1 +:108B140002C000E404C0008105FF02C000E2EED1FF +:108B24001ED018952CD0A1D101FD02C08ED1B1F474 +:108B340002E00093CC040091C50432D0F801008116 +:108B440005FF06C02DD020E2F80126930DD106C002 +:108B540000E827D020E2F8012693B3D0E1CF8FBFFD +:108B64000991199129913991499159916991799171 +:108B74000990199029903990E991F991B1CE8A938D +:108B8400FA93EA933A922A921A920A927A936A93FD +:108B94005A934A933A932A931A930A938FB7089550 +:108BA40000E01AC08A932051304041F020513040F7 +:108BB40039F02052304031F080E005C081E003C03C +:108BC40082E001C083E0EDDF20E0F801218326E0AC +:108BD40020838064818384CE64EF70E2202F2F7021 +:108BE400220F402F440F00E010E0001F020F43E06B +:108BF4000E94C740060F171F08959D01E8EC82D11B +:108C04000F7D008300810F7D00834DD102E0059329 +:108C1400AEEFB0E200E010E00D930C93539600E247 +:108C2400069300E4069349D1069300E406931D934A +:108C34001D931D931C9315971D931C9312AFD9017B +:108C4400089570DD8CD0002331F0033011F004302E +:108C540009F436D182D0FD0106811781083050E035 +:108C6400104009F548E023E739E206E011E2E2DAD0 +:108C7400E8ECF4E023D022D058DD002311F4F8D03E +:108C840012C0FD01068907FF05C011D002E006AF3E +:108C940018D009C009D0012B11F4F6D004C007D0B4 +:108CA40001E006AF06D1CBCC048D158D089500E00C +:108CB40002AF03AFDC960D930C930895008100621C +:108CC400FDCA4CD0033011F447D043C0A7D080A1D3 +:108CD40091A1801B910B282F292BE9F496D0E4DF76 +:108CE4000217130721F00091B329002311F0DED0FD +:108CF40030C004A115A120E00030120799F0F8015A +:108D04000995002379F000E0FD0104AFFC9601838E +:108D1400FD0180A191A1803400E0900718F080E467 +:108D240090E001C001E00093B329FD018687978795 +:108D3400068D178D24AD35AD020F131F008B118BDB +:108D4400DC960D91132F080F191F1C930E93ABD0B3 +:108D5400B1D0E4E00C948940B3D04FCF2DDDA0EF27 +:108D6400B0E200912E210895F9DF043011F4F4DF0C +:108D740048C0FD018681978164AD75AD20A131A104 +:108D84008B01080F191F2017310718F4C901861B1E +:108D9400970BAC0123E739E2068D178D060F171FD9 +:108DA40049DA3CD0080F191F04AF15AF8034904046 +:108DB40031F42FD0448D558D2417350750F000A37E +:108DC40011A394962FD019F00995002389F05CD053 +:108DD40018C020A131A12017310791F4949612D024 +:108DE400959700E0E030F00719F00995002311F49D +:108DF4003FD007C013D009D000E0DC960D930C934C +:108E040058D0A7CFED91FC91089503D022AF33AF92 +:108E1400089522AD33AD200F311F0895FD0104AD37 +:108E240015AD0895EFDF00E0E030F00708951DD0A0 +:108E340001FD0AC00AD041F400912E21013009F449 +:108E440023C0043009F417D008955FD013CB0DD09C +:108E540001FD0AC0FADF41F400912E21023009F429 +:108E640025C0033009F407D008950091CC04089577 +:108E740005E000932E21EDEFF0E204E00593E5EF29 +:108E8400F0E204E0059308951B2F2A2F10DC03E081 +:108E9400DF01DE960C9300E00687078704D00AD032 +:108EA400A22FB12F0895ECEFF0E2089504E00093AF +:108EB4002E2103D002E006930895E4EFF0E2089532 +:108EC40031DCA2E1B1E2AEDF09F00995B8CBEBECFD +:108ED40019D002FF08C0F093CA040091FC2006FFD9 +:108EE4000BC0A5DF09C0008101FF07C002E006D066 +:108EF4000091F42006FDABDFE6CAD7CB0093CA0489 +:108F04000895E0ECF4E000810895AFDF00FFCDCBDD +:108F140001E00093CC04D1DF00E80693C4DF00E84D +:108F2400069301E0EBDFC9DF00E106938ADECBCADA +:108F3400CC08E820000076007220408F0400000076 +:108F44008000000D4111410004000013411741034A +:108F540000000018410000040000001E4100000051 +:108F64000000000000000075207D209520952085DC +:108F7400208D20952095209520952095209520954D +:108F840020952095209520952000090212000101CA +:108F940000C0320904000000FF00000012010002BA +:108FA40000000040EB03E42F040000000001040370 +:028FB4000904AE +:040000030000800079 +:00000001FF diff --git a/Firmware/Atmel DFU Bootloader/common/boards/board.h b/Firmware/Atmel DFU Bootloader/common/boards/board.h new file mode 100644 index 0000000..26ca01a --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/boards/board.h @@ -0,0 +1,288 @@ +/** + * \file + * + * \brief Standard board header file. + * + * This file includes the appropriate board header file according to the + * defined board (parameter BOARD). + * + * 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 _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 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 //!< AT86RF231 RF board in RZ600 +#define RZ600_AT86RF212 10 //!< AT86RF231 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_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_XPLAINED +# include "sam4s_xplained/sam4s_xplained.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 == 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 == 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 == SIMULATOR_XMEGA_A1 +# include "simulator/xmega_a1/simulator_xmega_a1.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 "user_board.h" +#elif BOARD == DUMMY_BOARD +# include "dummy/dummy_board.h" +#else +# error No known AVR 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/Firmware/Atmel DFU Bootloader/common/services/clock/genclk.h b/Firmware/Atmel DFU Bootloader/common/services/clock/genclk.h new file mode 100644 index 0000000..0e86480 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/clock/genclk.h @@ -0,0 +1,174 @@ +/** + * \file + * + * \brief Generic clock management + * + * Copyright (c) 2010-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 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 (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/Firmware/Atmel DFU Bootloader/common/services/clock/osc.h b/Firmware/Atmel DFU Bootloader/common/services/clock/osc.h new file mode 100644 index 0000000..fe77b9b --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/clock/osc.h @@ -0,0 +1,160 @@ +/** + * \file + * + * \brief Oscillator management + * + * 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 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 (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__HZ: The nominal frequency of the oscillator. + * - \b BOARD__STARTUP_US: The startup time of the + * oscillator in microseconds. + * - \b BOARD__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/Firmware/Atmel DFU Bootloader/common/services/clock/pll.h b/Firmware/Atmel DFU Bootloader/common/services/clock/pll.h new file mode 100644 index 0000000..e81884d --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/clock/pll.h @@ -0,0 +1,316 @@ +/** + * \file + * + * \brief PLL management + * + * Copyright (c) 2010-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 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 (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/Firmware/Atmel DFU Bootloader/common/services/clock/sysclk.h b/Firmware/Atmel DFU Bootloader/common/services/clock/sysclk.h new file mode 100644 index 0000000..dec704c --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/clock/sysclk.h @@ -0,0 +1,167 @@ +/** + * \file + * + * \brief System clock management + * + * 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 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 (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" +#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 sysclk API covers the system clock and all + * clocks derived from it. The system clock is a chip-internal clock on + * which all synchronous clocks, 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 synchronous clocks, since they + * always run synchronously with respect to each other, as opposed to + * generic clocks 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/Firmware/Atmel DFU Bootloader/common/services/clock/xmega/osc.h b/Firmware/Atmel DFU Bootloader/common/services/clock/xmega/osc.h new file mode 100644 index 0000000..a12e2ee --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/clock/xmega/osc.h @@ -0,0 +1,461 @@ +/** + * \file + * + * \brief Chip-specific oscillator management 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_OSC_H_INCLUDED +#define XMEGA_OSC_H_INCLUDED + +#include +#include + +/** + * \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 +/** + * \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; + 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 + OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) | + CONFIG_XOSC_RANGE; +#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: + 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; + break; + + case OSC_ID_RC32MHZ: +#if XMEGA_AU || XMEGA_B || XMEGA_C + Assert((ref_id == OSC_ID_RC32KHZ) + || (ref_id == OSC_ID_XOSC) + || (ref_id == OSC_ID_USBSOF)); + + 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; + } + 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; + } +#else + 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_RC32MCREF_bm; + } + else if (ref_id == OSC_ID_RC32KHZ) { + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_bm); + } +#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: + DFLLRC2M.CTRL = 0; + 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: + DFLLRC2M.CALA=LSB(calib); + DFLLRC2M.CALB=MSB(calib); + break; + + case OSC_ID_RC32MHZ: + DFLLRC32M.CALA=LSB(calib); + DFLLRC32M.CALB=MSB(calib); + break; + + 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/Firmware/Atmel DFU Bootloader/common/services/clock/xmega/pll.h b/Firmware/Atmel DFU Bootloader/common/services/clock/xmega/pll.h new file mode 100644 index 0000000..e37c9e9 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/clock/xmega/pll.h @@ -0,0 +1,262 @@ +/** + * \file + * + * \brief Chip-specific PLL management 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_PLL_H_INCLUDED +#define XMEGA_PLL_H_INCLUDED + +#include + +/** + * \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); + } + 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/Firmware/Atmel DFU Bootloader/common/services/clock/xmega/sysclk.c b/Firmware/Atmel DFU Bootloader/common/services/clock/xmega/sysclk.c new file mode 100644 index 0000000..010c70d --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/clock/xmega/sysclk.c @@ -0,0 +1,240 @@ +/** + * \file + * + * \brief Chip-specific system clock management 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 + * + */ + +#include + +#include +#include +#include + +#if XMEGA_AU || XMEGA_B || XMEGA_C +# include +#endif + + +void sysclk_init(void) +{ + uint8_t *reg = (uint8_t *)&PR.PRGEN; + uint8_t i; +#ifdef CONFIG_OSC_RC32_CAL + uint16_t 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 + 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); + } +} + +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 + 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/Firmware/Atmel DFU Bootloader/common/services/clock/xmega/sysclk.h b/Firmware/Atmel DFU Bootloader/common/services/clock/xmega/sysclk.h new file mode 100644 index 0000000..7b8dc5d --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/clock/xmega/sysclk.h @@ -0,0 +1,1326 @@ +/** + * \file + * + * \brief Chip-specific system clock management 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_SYSCLK_H_INCLUDED +#define XMEGA_SYSCLK_H_INCLUDED + +#include +#include +#include +#include +#include +#include + +// Include clock configuration for the project. +#include + +#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 +//@} + +//! \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 +//@} + +//! \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_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 +//@} + +/*! \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_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 +//@} + + +#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; + + 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 (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 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 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 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 + 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 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 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 + 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 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 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 + 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 System Clock Sources 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 System Clock Initialization +//@{ + +extern void sysclk_init(void); + +//@} + +#endif /* !__ASSEMBLY__ */ + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* XMEGA_SYSCLK_H_INCLUDED */ diff --git a/Firmware/Atmel DFU Bootloader/common/services/isp/flip/flip_protocol.h b/Firmware/Atmel DFU Bootloader/common/services/isp/flip/flip_protocol.h new file mode 100644 index 0000000..d457c37 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/isp/flip/flip_protocol.h @@ -0,0 +1,250 @@ +/** + * \file + * + * \brief FLIP protocol definitions. + * + * Copyright (c) 2011-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 _FLIP_PROTOCOL_H_ +#define _FLIP_PROTOCOL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup flip_protocol Atmel FLIP Protocol definitions + * + * To perform firmware upgrade, Atmel has developed an application called “FLIP”. + * This software is a flexible application which lets you program and + * configure Atmel's microcontroller devices in their final environment + * without needing any dedicated hardware. + * @{ + */ + +//! \defgroup FLIP Protocol versions +//@{ +#define FLIP_PROTOCOL_VERSION_2 2 // Used by UC3 parts and Xmega parts +#define FLIP_PROTOCOL_VERSION_1 1 // Used by Mega +#define FLIP_PROTOCOL_VERSION_0 0 // Used by C51 parts +//@} + + +/** + * \defgroup flip_pv1 Definitions for FLIP Protocol version 1 + * + * Note: Used by Mega parts. + * + * @{ + */ + +COMPILER_PACK_SET(1) +/** + * \brief FLIP message structure + */ +typedef struct { + uint8_t cmd_id; + uint8_t arg[5]; +} flip_msg_v1_t; +COMPILER_PACK_RESET() + +//! Size of buffer used by FLIP to receive or send data +#define FLIP_V1_BUF_TRANS_SIZE 1024 + +//! \name FLIP commands +//@{ +#define FLIP_V1_CMD_PROG_START 0x01 +#define FLIP_V1_CMD_READ 0x03 +#define FLIP_V1_CMD_WRITE 0x04 +#define FLIP_V1_CMD_READ_ID 0x05 +#define FLIP_V1_CMD_CHANGE_BASE_ADDR 0x06 + +//! \name FLIP_V1_CMD_PROG_START first argument +//@{ +#define FLIP_V1_CMD_PROG_START_ARG_FLASH 0x00 +#define FLIP_V1_CMD_PROG_START_ARG_EEPROM 0x01 +#define FLIP_V1_CMD_PROG_START_ARG_CUSTOM 0x08 +//@} + +//! \name FLIP_V1_CMD_READ first argument +//@{ +#define FLIP_V1_CMD_READ_ARG_FLASH 0x00 +#define FLIP_V1_CMD_READ_ARG_FLASHCHECK 0x01 +#define FLIP_V1_CMD_READ_ARG_EEPROM 0x02 +#define FLIP_V1_CMD_READ_ARG_CUSTOM 0x03 +//@} + +//! \name FLIP_V1_CMD_WRITE first argument +//@{ +#define FLIP_V1_CMD_WRITE_ARG_ERASE 0x00 +#define FLIP_V1_CMD_WRITE_ARG_RST 0x03 +//! \name FLIP_V1_CMD_WRITE_ARG_ERASE following argument +//@{ +#define FLIP_V1_CMD_WRITE_ARG_ERASE_CHIP 0xFF +//@} +//! \name FLIP_V1_CMD_WRITE_ARG_RST following arguments +//@{ +#define FLIP_V1_CMD_WRITE_ARG_RST_HW 0x00 +#define FLIP_V1_CMD_WRITE_ARG_RST_SF 0x01 +//@} +//@} + +//! \name FLIP_V1_CMD_READ_ID first argument +//@{ +#define FLIP_V1_CMD_READ_ID_ARG_BOOTLOADER 0x00 +#define FLIP_V1_CMD_READ_ID_ARG_SIGNATURE 0x01 +//! \name FLIP_V1_CMD_READ_ID_ARG_SIGNATURE following arguments +//@{ +#define FLIP_V1_CMD_READ_ID_SIGNATURE_ARG_MANUF 0x30 +#define FLIP_V1_CMD_READ_ID_SIGNATURE_ARG_FAMILY 0x31 +#define FLIP_V1_CMD_READ_ID_SIGNATURE_ARG_PRODUCT 0x60 +#define FLIP_V1_CMD_READ_ID_SIGNATURE_ARG_REVISION 0x61 +//@} +//@} + +//! \name FLIP_V1_CMD_CHANGE_BASE_ADDR first argument +//@{ +#define FLIP_V1_CMD_CHANGE_BASE_ADDR_ARG0 0x03 +#define FLIP_V1_CMD_CHANGE_BASE_ADDR_ARG1 0x00 +//@} + +//@} +//@} + + +/** + * \defgroup flip_pv2 Definitions for Atmel FLIP Protocol version 2 + * + * Note: Used by uc3 and Xmega parts + * + * @{ + */ + +COMPILER_PACK_SET(1) +/** + * \brief FLIP message structure + */ +typedef struct { + uint8_t group; + uint8_t cmd_id; + uint8_t arg[4]; +} flip_msg_v2_t; +COMPILER_PACK_RESET() + +//! Size of buffer used by FLIP to receive or send data +//! Note: Write uses 2K and Read uses 1KB +#define FLIP_V2_BUF_TRANS_SIZE (2*1024) + +//! \name Command Groups +//@{ +#define FLIP_V2_CMD_GRP_DNLOAD 0x01 +#define FLIP_V2_CMD_GRP_UPLOAD 0x03 +#define FLIP_V2_CMD_GRP_EXEC 0x04 +#define FLIP_V2_CMD_GRP_SELECT 0x06 +//@} + +//! \name FLIP_V2_CMD_GRP_DNLOAD first argument +//@{ +#define FLIP_V2_CMD_PROGRAM_START 0x00 +//@} + + +//! \name FLIP_V2_CMD_GRP_UPLOAD first argument +//@{ +#define FLIP_V2_CMD_READ_MEMORY 0x00 +#define FLIP_V2_CMD_BLANK_CHECK 0x01 +//@} + +//! \name FLIP_V2_CMD_GRP_EXEC first argument +//@{ +#define FLIP_V2_CMD_ERASE 0x00 +#define FLIP_V2_CMD_START_APPLI 0x03 +//! \name FLIP_V2_CMD_ERASE following argument +//@{ +#define FLIP_V2_CMD_ERASE_ARG_CHIP 0xFF +//@} +//! \name FLIP_V2_CMD_START_APPLI following arguments +//@{ +#define FLIP_V2_CMD_START_APPLI_ARG_RESET 0x00 +#define FLIP_V2_CMD_START_APPLI_ARG_NO_RESET 0x01 +//@} +//@} + +//! \name FLIP_V2_CMD_GRP_SELECT first argument +//@{ +#define FLIP_V2_CMD_SELECT_MEMORY 0x03 +//! \name FLIP_V2_CMD_SELECT_MEMORY following arguments +//@{ +#define FLIP_V2_CMD_SELECT_MEMORY_ARG_UNIT 0x00 +#define FLIP_V2_CMD_SELECT_MEMORY_ARG_PAGE 0x01 +//@} +//! \name FLIP_V2_CMD_SELECT_MEMORY_ARG_UNIT following arguments +//! Memory units field +//@{ +#define FLIP_V2_CMD_SELECT_MEM_FLASH 0x00 +#define FLIP_V2_CMD_SELECT_MEM_EEPROM 0x01 +#define FLIP_V2_CMD_SELECT_MEM_SECURITY 0x02 +#define FLIP_V2_CMD_SELECT_MEM_CONFIGURATION 0x03 +#define FLIP_V2_CMD_SELECT_MEM_BOOTLOADER 0x04 +#define FLIP_V2_CMD_SELECT_MEM_SIGNATURE 0x05 +#define FLIP_V2_CMD_SELECT_MEM_USER 0x06 +#define FLIP_V2_CMD_SELECT_MEM_INT_RAM 0x07 +#define FLIP_V2_CMD_SELECT_MEM_EXT_MEM_CS0 0x08 +#define FLIP_V2_CMD_SELECT_MEM_EXT_MEM_CS1 0x09 +#define FLIP_V2_CMD_SELECT_MEM_EXT_MEM_CS2 0x0A +#define FLIP_V2_CMD_SELECT_MEM_EXT_MEM_CS3 0x0B +#define FLIP_V2_CMD_SELECT_MEM_EXT_MEM_CS4 0x0C +#define FLIP_V2_CMD_SELECT_MEM_EXT_MEM_CS5 0x0D +#define FLIP_V2_CMD_SELECT_MEM_EXT_MEM_CS6 0x0E +#define FLIP_V2_CMD_SELECT_MEM_EXT_MEM_CS7 0x0F +#define FLIP_V2_CMD_SELECT_MEM_EXT_MEM_DF 0x10 +#define FLIP_V2_CMD_SELECT_MEM_COUNT 0x11 // Number of memory units +//@} +//@} + +//@} + +//@} + + +#ifdef __cplusplus +} +#endif + +#endif // _FLIP_PROTOCOL_H_ diff --git a/Firmware/Atmel DFU Bootloader/common/services/isp/flip/isp.h b/Firmware/Atmel DFU Bootloader/common/services/isp/flip/isp.h new file mode 100644 index 0000000..e7de876 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/isp/flip/isp.h @@ -0,0 +1,226 @@ +/** + * \file + * + * \brief In System Programming API + * + * Copyright (c) 2011 - 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 _ISP_H_ +#define _ISP_H_ + +#include "conf_isp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup isp In System Programming API + * + * @{ + */ + +/** + * \name Main In System Programming functions + * @{ + */ + +/** + * \brief Initializes the ISP interface + * + * Example, load the JTAG ID in signature memory + */ +void isp_init(void); + +/** + * \brief Gives the security state of the chip + * + * \return \c 1 if chip is secured, otherwise \c 0. + */ +bool isp_is_security(void); + +/** + * \brief Change the boot process configuration + * to enable/disable the ISP mode for the next startup. + * + * \param force Enable the ISP mode for the next startup if true + */ +void isp_force_boot_isp(bool force); + +/** + * \brief Erase the application flash area and eventually the eeprom + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool isp_erase_chip(void); + +/** + * \brief Erase a part of the application flash area + * This function must be called again as long as it returns 0. + * + * \return \c 1 if the whole application flash area is erased, otherwise it is + * not finished. + * + * This function has been created to split a long erase so that + * the ISP application is able to answer external pending requests. + */ + +bool isp_erase_chip_split(void); + +/** + * \brief Resets the device to start the user application + * + * The ISP mode must be disabled before (See isp_force_boot_isp(false)) + * to allow the boot process to jump to the user application. + * + * \note: this function is usually implemented by using a watchdog reset + * or a software reset to restart the CPU. + */ +void isp_start_appli(void); +//! @} + + +//! Data type for holding flash memory addresses +#ifdef ISP_SMALL_MEMORY_SIZE + typedef uint16_t isp_addr_t; +#else + typedef uint32_t isp_addr_t; +#endif + +//! Memory API definition +typedef struct { + //! Size of the memory (unit Byte) + uint32_t size; + //! Function to read memory + void (*fnct_read) (void *dst, isp_addr_t src, uint16_t nbytes); + //! Function to write memory + void (*fnct_write) (isp_addr_t dst, const void *src, uint16_t nbytes); +} isp_mem_t; + +/** + * \name Memory units index values + * Used to access at a memory through \ref isp_memories list. + * @{ + */ +#define ISP_MEM_FLASH 0x00 +#define ISP_MEM_EEPROM 0x01 +#define ISP_MEM_SECURITY 0x02 +#define ISP_MEM_CONFIGURATION 0x03 +#define ISP_MEM_BOOTLOADER 0x04 +#define ISP_MEM_SIGNATURE 0x05 +#define ISP_MEM_USER 0x06 +#define ISP_MEM_INT_RAM 0x07 +#define ISP_MEM_EXT_MEM_CS0 0x08 +#define ISP_MEM_EXT_MEM_CS1 0x09 +#define ISP_MEM_EXT_MEM_CS2 0x0A +#define ISP_MEM_EXT_MEM_CS3 0x0B +#define ISP_MEM_EXT_MEM_CS4 0x0C +#define ISP_MEM_EXT_MEM_CS5 0x0D +#define ISP_MEM_EXT_MEM_CS6 0x0E +#define ISP_MEM_EXT_MEM_CS7 0x0F +#define ISP_MEM_EXT_MEM_DF 0x10 +#define ISP_MEM_COUNT 0x11 // Number of memory units +//! @} + +//! Memories list structure +typedef union { + isp_mem_t const *mem[ISP_MEM_COUNT]; + struct { + isp_mem_t const *flash; + isp_mem_t const *eeprom; + isp_mem_t const *security; + isp_mem_t const *conf; + isp_mem_t const *bootloader; + isp_mem_t const *signature; + isp_mem_t const *user; + isp_mem_t const *int_ram; + isp_mem_t const *ext_mem_cs0; + isp_mem_t const *ext_mem_cs1; + isp_mem_t const *ext_mem_cs2; + isp_mem_t const *ext_mem_cs3; + isp_mem_t const *ext_mem_cs4; + isp_mem_t const *ext_mem_cs5; + isp_mem_t const *ext_mem_cs6; + isp_mem_t const *ext_mem_cs7; + isp_mem_t const *ext_mem_df; + }list; +} isp_mems_t; + +//! Memories list declaration +extern const isp_mems_t isp_memories; + +COMPILER_PACK_SET(1) // alignment requested to simulate a memory + +//! Memory signature structure to store JTAG ID +typedef union { + uint8_t mem[4]; + struct { + uint8_t manufacture; + uint8_t product_number_msb; + uint8_t product_number_lsb; + uint8_t product_revision; + }; +} isp_mem_signature_t; + + +/** + * Memory bootloader structure + * + * In the FLIP protocol, this structure is used to store medium + * and minor bootloader versions: + * - Example, Version 0x00 give 1.0.0 on batchisp log + * - Example, Version 0x03 give 1.0.3 on batchisp log + * - Example, Version 0x25 give 1.2.5 on batchisp log + * - id1 & id2 are not used and must always be 0. + */ +typedef struct { + uint8_t version; + uint8_t id1; + uint8_t id2; +} isp_mem_bootloader_t; + +COMPILER_PACK_RESET() + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif // _ISP_H_ diff --git a/Firmware/Atmel DFU Bootloader/common/services/isp/flip/xmega/cstartup.s90 b/Firmware/Atmel DFU Bootloader/common/services/isp/flip/xmega/cstartup.s90 new file mode 100644 index 0000000..d3b3196 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/isp/flip/xmega/cstartup.s90 @@ -0,0 +1,232 @@ +/** + * \file + * + * \brief AVR XMEGA boot process for bootloaders compiled with IAR. + * + * Copyright (C) 2011 - 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 +#include "conf_isp.h" + +#if (((__TID__ >> 8) & 0x7F) != 90) +#error This file should only be assembled by aa90 or aavr +#endif + +#define A90_PROC_OPTION ((__TID__ >> 4) & 0x0F) + +#ifndef Z0 +# define Z0 R30 +#endif + + +/* Length of pointer registers (X/Y/Z) */ +#if (A90_PROC_OPTION == 0) || (A90_PROC_OPTION == 2) +#define A90_POINTER_REG_SIZE 1 +#define A90_TINY_INDEX +#else /*!(A90_PROC_OPTION == 0) || (A90_PROC_OPTION == 2)*/ +#if (A90_PROC_OPTION == 1) || (A90_PROC_OPTION == 3) || (A90_PROC_OPTION ==5) +#define A90_POINTER_REG_SIZE 2 +#else /*!(A90_PROC_OPTION == 1) || (A90_PROC_OPTION == 3) || (A90_PROC_OPTION ==5)*/ +#if (A90_PROC_OPTION == 4) || (A90_PROC_OPTION == 6) +#define A90_POINTER_REG_SIZE 3 +#define A90_EXTENDED_DATA +#else /*!(A90_PROC_OPTION == 4) || (A90_PROC_OPTION == 6)*/ +#error Unknown processor option!! +#endif /*!(A90_PROC_OPTION == 4) || (A90_PROC_OPTION == 6)*/ +#endif /*!(A90_PROC_OPTION == 1) || (A90_PROC_OPTION == 3) || (A90_PROC_OPTION ==5)*/ +#endif /*!(A90_PROC_OPTION == 0) || (A90_PROC_OPTION == 2)*/ + + +;---------------------------------------------------------------------------- +; Set up the RESET segment with a reset vector +;---------------------------------------------------------------------------- + MODULE ?RESET + EXTERN ?C_STARTUP + PUBLIC __program_start + PUBLIC ?RESET + + ASEG BOOT_SECTION_START +__program_start: +?RESET: + RJMP ?C_STARTUP + + ENDMOD + +;---------------------------------------------------------------------------- +; Set up the INTVEC segment with a reset vector +;---------------------------------------------------------------------------- + MODULE ?VECT + COMMON INTVEC:CODE:ROOT(1) ; Align at an even address + EXTERN ?C_STARTUP + ENDMOD + +;---------------------------------------------------------------------------- +; Forward declarations of segments used in initialization +;---------------------------------------------------------------------------- + RSEG CSTACK:DATA:NOROOT(0) + RSEG RSTACK:DATA:NOROOT(0) + +;---------------------------------------------------------------------------- +; Perform C initialization +;---------------------------------------------------------------------------- + +// IAR forgets about include files after each module, so need to include again +#include + + MODULE ?C_STARTUP + EXTERN main + EXTERN exit + EXTERN _exit + + RSEG BOOT:CODE:NOROOT(1) + PUBLIC ?C_STARTUP + PUBLIC __RESTART + EXTERN ?RESET + +__RESTART: +?C_STARTUP: + +#if A90_POINTER_REG_SIZE > 2 + PUBLIC ?zero_reg_initialization +?zero_reg_initialization: + CLR R15 + OUT RAMPD,R15 +#endif + + +;---------------------------------------------------------------------------- +; Boot Process +;---------------------------------------------------------------------------- + +boot_process: + // Test Software reset + LDS R16,RST_STATUS + SBRC R16,RST_SRF_bp // Test Software Reset Flag + RJMP start_app + + // Test ISP pin + STS ISP_PORT_DIR, R15 + LDI R16,0x18 + STS ISP_PORT_PINCTRL, R16 + LDI R16,0xFF +tempo: + DEC R16 + TST R16 + BRNE tempo + LDS R16,ISP_PORT_IN + SBRS R16,ISP_PORT_PIN // test ISP pin active + RJMP start_boot // pin activated + + // Test beginning of flash blank + LDI R30, 0 + LDI R31, 0 + ELPM R16, Z+ + ELPM R17, Z + CPI R16, 255 + BRNE start_app_jmp + CPI R17, 255 + BRNE start_app_jmp + + RJMP start_boot +start_app_jmp: + RJMP start_app + +;---------------------------------------------------------------------------- +; Call Bootloader +;---------------------------------------------------------------------------- + RSEG STARTBOOT:CODE:NOROOT(1), BOOT_SECTION_START+0x1FC + PUBLIC start_boot +start_boot: + RJMP ?SETUP_STACK + +;---------------------------------------------------------------------------- +; Set up the CSTACK and RSTACK pointers. +;---------------------------------------------------------------------------- + RSEG CODE:CODE:NOROOT(1) + EXTERN __segment_init + PUBLIC ?need_segment_init + +?SETUP_STACK: + ;; Return address stack (RSTACK) + LDI R16,LOW(SFE(RSTACK)-1) + OUT 0x3D,R16 +#if A90_POINTER_REG_SIZE > 1 + LDI R16,HIGH(SFE(RSTACK)-1) + OUT 0x3E,R16 +#endif + + ;; Data stack (CSTACK) + LDI R28,LOW(SFE(CSTACK)) +#if A90_POINTER_REG_SIZE > 1 + LDI R29,HIGH(SFE(CSTACK)) +#if A90_POINTER_REG_SIZE > 2 + LDI Z0,HWRD(SFB(CSTACK)) + OUT RAMPY,Z0 +#endif +#endif +?need_segment_init: + CALL __segment_init + CALL main + +;---------------------------------------------------------------------------- +; Call Application +;---------------------------------------------------------------------------- + EXTERN start_app_key + +start_app: + STS ISP_PORT_PINCTRL, R15 + LDS R16, start_app_key + LDS R17, (start_app_key + 1) + CPI R16, 0xAA + SBCI R17, 0x55 + BREQ clear_rst_flags +jump_0: + JMP 0 + +// It is a start application launched by a batchisp start command +// then clear reset flagS +clear_rst_flags: + STS start_app_key, R15 + STS (start_app_key + 1), R15 + LDI R16,RST_SRF_bm + STS RST_STATUS,R16 // Clear Software Reset Flag + RJMP jump_0 + END + +;---------------------------------------------------------------------------- diff --git a/Firmware/Atmel DFU Bootloader/common/services/isp/flip/xmega/isp.c b/Firmware/Atmel DFU Bootloader/common/services/isp/flip/xmega/isp.c new file mode 100644 index 0000000..8d1883b --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/isp/flip/xmega/isp.c @@ -0,0 +1,281 @@ +/** + * \file + * + * \brief In system programming to control security, memories and fuse bits + * + * Copyright (c) 2011 - 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 "conf_isp.h" +#include "nvm.h" +#include "isp.h" +#include "string.h" + + +#ifdef __GNUC__ + uint16_t start_app_key __attribute__ ((section (".noinit"))); +#else + __no_init uint16_t start_app_key @"SRAM_NO_INIT"; +#endif + + +/** + * \ingroup isp + * \defgroup isp_implementation In System Programming XMEGA implementation + * This implementation links the XMEGA NVM functions to the common isp API. + * Also, it manage : + * - the flash access security + * - the JTAG ID information storage + * - the bootloader version storage + * - the start appli operation through software reset + * + * @{ + */ + +/** + * \name Memory APIs + */ +//@{ + +/** + * \name Specific memories + */ +//@{ + +//! Memory signature that stores information about the device +static isp_mem_signature_t mem_signature; + +//! Memory bootloader that stores the bootloader version +static isp_mem_bootloader_t mem_bootloader = { + .version = BOOTLOADER_VERSION, + .id1 = 0, + .id2 = 0, +}; +//@} + +/** + * \brief Copy a flash memory section to a RAM buffer + * + * \param dst Pointer to data destination. + * \param src Pointer to source flash. + * \param nbytes Number of bytes to transfer. + */ +static void mem_flash_read(void *dst, isp_addr_t src, uint16_t nbytes) +{ + nvm_flash_read_buffer(src, dst, nbytes); +} + +/** + * \brief Copy a RAM buffer to a flash memory section + * + * \param dst Pointer to flash destination. + * \param src Pointer to source data. + * \param nbytes Number of bytes to transfer. + */ +static void mem_flash_write(isp_addr_t dst, const void *src, uint16_t nbytes) +{ + nvm_flash_erase_and_write_buffer(dst, src, nbytes, true); +} + +/** + * \brief Copy a eeprom memory section to a RAM buffer + * + * \param dst Pointer to data destination. + * \param src Pointer to source flash. + * \param nbytes Number of bytes to transfer. + */ +static void mem_eeprom_read(void *dst, isp_addr_t src, uint16_t nbytes) +{ + nvm_eeprom_read_buffer( src, dst, nbytes ); +} + +/** + * \brief Copy a RAM buffer to a eeprom memory section + * + * \param dst Pointer to flash destination. + * \param src Pointer to source data. + * \param nbytes Number of bytes to transfer. + */ +static void mem_eeprom_write(isp_addr_t dst, const void *src, uint16_t nbytes) +{ +#if (FLASH_SIZE==0x10000) + // Optimize CODE space (150B), but decrease the speed + // 24s to program 2KB instead of 1s + while (nbytes--) { + nvm_eeprom_write_byte(dst++, *(uint8_t*)src); + src = (uint8_t*)src + 1; + } +#else + nvm_eeprom_erase_and_write_buffer(dst, src, nbytes); +#endif +} + + +/** + * \brief Copy a bootloader version memory section to a RAM buffer + * + * \param dst Pointer to data destination. + * \param src Pointer to source memory. + * \param nbytes Number of bytes to transfer. + */ +static void mem_bootloader_read(void *dst, isp_addr_t src, uint16_t nbytes) +{ + memcpy(dst, (uint8_t*)&mem_bootloader + src, nbytes); +} + +/** + * \brief Copy a signature memory section to a RAM buffer + * + * \param dst Pointer to data destination. + * \param src Pointer to source memory. + * \param nbytes Number of bytes to transfer. + */ +static void mem_signature_read(void *dst, isp_addr_t src, uint16_t nbytes) +{ + memcpy(dst, (uint8_t*)&mem_signature + src, nbytes); +} + +//! Interface for memory flash +const isp_mem_t isp_flash = { + .size = FLASH_SIZE, + .fnct_read = mem_flash_read, + .fnct_write = mem_flash_write, +}; + +//! Interface for memory eeprom +const isp_mem_t isp_eeprom = { + .size = EEPROM_SIZE, + .fnct_read = mem_eeprom_read, + .fnct_write = mem_eeprom_write, +}; + +//! Interface for memory bootloader version +const isp_mem_t isp_bootloader = { + .size = sizeof(mem_bootloader), + .fnct_read = mem_bootloader_read, + .fnct_write = NULL, +}; + +//! Interface for memory signature +const isp_mem_t isp_signature = { + .size = sizeof(mem_signature), + .fnct_read = mem_signature_read, + .fnct_write = NULL, +}; + +//! Interface for memory no available +const isp_mem_t isp_no_available = { + .size = 0, + .fnct_read = NULL, + .fnct_write = NULL, +}; + +//! \name Memories list declaration +const isp_mems_t isp_memories = { + .list = { + .flash = &isp_flash, + .eeprom = &isp_eeprom, + .security = &isp_no_available, + .conf = &isp_no_available, + .bootloader = &isp_bootloader, + .signature = &isp_signature, + .user = &isp_no_available, + .int_ram = &isp_no_available, + .ext_mem_cs0 = &isp_no_available, + .ext_mem_cs1 = &isp_no_available, + .ext_mem_cs2 = &isp_no_available, + .ext_mem_cs3 = &isp_no_available, + .ext_mem_cs4 = &isp_no_available, + .ext_mem_cs5 = &isp_no_available, + .ext_mem_cs6 = &isp_no_available, + .ext_mem_cs7 = &isp_no_available, + .ext_mem_df = &isp_no_available, + } +}; + +//@} + + +/** + * \name Miscellaneous functions of the In System Programming module + */ +//@{ + +void isp_init(void) +{ + mem_signature.manufacture = MCU.DEVID0; + mem_signature.product_number_msb = MCU.DEVID1; + mem_signature.product_number_lsb = MCU.DEVID2; + mem_signature.product_revision = MCU.REVID; +} + + +bool isp_is_security(void) +{ + return !(NVM.LOCKBITS&NVM_LOCKBITS_LB1_bm); +} + + +bool isp_erase_chip(void) +{ + nvm_flash_erase_app(); + nvm_eeprom_erase_all(); + return true; +} + + +void isp_start_appli(void) +{ + cpu_irq_disable(); + // generate soft reset for Xmega + start_app_key=0x55AA; + ccp_write_io((uint8_t *)&RST.CTRL, RST.CTRL | RST_SWRST_bm); + while (1); +} + + +void isp_force_boot_isp(bool force) +{ + // No available on Xmega +} + +//@} + + +//@} + diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/asf.h b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/asf.h new file mode 100644 index 0000000..eee6a9b --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/asf.h @@ -0,0 +1,82 @@ +/** + * \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 +#include + +// From module: Generic board support +#include + +// From module: Interrupt management - XMEGA implementation +#include + +// From module: NVM - Non Volatile Memory +#include + +// From module: Part identification macros +#include + +// From module: System Clock Control - XMEGA A1U/A3U/A3BU/A4U implementation +#include + +// From module: USB Device Stack Core optimized for DFU interface +#include +#include + +// From module: XMEGA compiler driver +#include +#include + +#endif // ASF_H diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/atxmega32a4u_boot.xcl b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/atxmega32a4u_boot.xcl new file mode 100644 index 0000000..640990c --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/atxmega32a4u_boot.xcl @@ -0,0 +1,102 @@ +/** + * \file + * + * \brief Linker script for ATxmega32A4U USB DFU FLIP bootloader + * + * Copyright (c) 2011 - 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 + * + */ + +// Set up XLINK +-ca90 +-w29 + +// Memory size definitions for convenience +// The '_..X_' prefix is used by C-SPY as an indication that the label should +// not be displayed in the dissassembly window. +-D_..X_FLASH_BASE=8002 +-D_..X_CODE_END=8FFF +-D_..X_INTVEC_END=81FB + + + +////////////////////////////////////////////////////////////////////////////// +// Code (flash) segments +-Z(CODE)INTVEC=81F4-81FF +-P(CODE)BOOT=_..X_FLASH_BASE-_..X_CODE_END +-P(CODE)CODE=_..X_FLASH_BASE-_..X_CODE_END +-P(CODE)FARCODE=_..X_FLASH_BASE-_..X_CODE_END +-Z(CODE)INITTAB=81FC-_..X_CODE_END +-Z(CODE)NEAR_ID=81FC-_..X_CODE_END + + +-D_..X_SRAM_BASE=2000 +-D_..X_SRAM_TINY_END=FF +-D_..X_SRAM_NEAR_END=FFFF +-D_..X_SRAM_FAR_END=FFFFFF +-D_..X_SRAM_HUGE_END=FFFFFF + +/* + * Modify the lines below to alter the size of the RSTACK, CSTACK and HEAP + * segments. These need to be fine tuned to suit your specific application. + */ +-D_..X_CSTACK_SIZE=70 /* 112 bytes for auto variables and register save. */ +-D_..X_RSTACK_SIZE=70 /* 112 bytes for return addresses, equivalent to */ + /* 56 levels of calls, including interrupts. */ +-D_..X_NEAR_HEAP_SIZE=1000 /* 4096 bytes of heap. */ +-D_..X_HEAP_SIZE=1000 /* 4096 bytes of heap. */ +-D_..X_FAR_HEAP_SIZE=1000 /* 4096 bytes of heap. */ +-D_..X_HUGE_HEAP_SIZE=1000 /* 4096 bytes of heap. */ +////////////////////////////////////////////////////////////////////////////// +// Data (SRAM, external ROM or external NV RAM) memory +-Z(DATA)SRAM_NO_INIT=2000-2001 +-Z(DATA)TINY_I,TINY_Z,TINY_N=_..X_SRAM_BASE-_..X_SRAM_NEAR_END +-Z(DATA)RSTACK+_..X_RSTACK_SIZE=_..X_SRAM_BASE-_..X_SRAM_NEAR_END +-Z(DATA)NEAR_I,NEAR_Z,NEAR_N,NEAR_C=_..X_SRAM_BASE-_..X_SRAM_NEAR_END +-Z(DATA)NEAR_HEAP+_..X_NEAR_HEAP_SIZE=_..X_SRAM_BASE-_..X_SRAM_NEAR_END +//-Z(DATA)FAR_I=[10000-_..X_SRAM_FAR_END]/10000 +-Z(DATA)CSTACK+_..X_CSTACK_SIZE=[_..X_SRAM_BASE-_..X_SRAM_FAR_END]/10000 +-Z(DATA)HEAP+_..X_HEAP_SIZE=[_..X_SRAM_BASE-_..X_SRAM_FAR_END]/10000 +-Z(DATA)IOSTREAM_N#[_..X_SRAM_BASE-_..X_SRAM_FAR_END]/10000 +-Z(DATA)FAR_Z,FAR_N,FAR_C=[_..X_SRAM_BASE-_..X_SRAM_FAR_END]/10000 +-Z(DATA)FAR_HEAP+_..X_FAR_HEAP_SIZE=_..X_SRAM_BASE-_..X_SRAM_FAR_END +-Z(DATA)HUGE_I,HUGE_Z,HUGE_N,HUGE_C=_..X_SRAM_BASE-_..X_SRAM_HUGE_END +-Z(DATA)HUGE_HEAP+_..X_HUGE_HEAP_SIZE=_..X_SRAM_BASE-_..X_SRAM_HUGE_END + + + + diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewd b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewd new file mode 100644 index 0000000..e97d912 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewd @@ -0,0 +1,1847 @@ + + 2 + + Debug + + AVR + + 1 + + C-SPY + 5 + + 14 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + AVRONE + 3 + + 3 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CCRAVR + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + + ICE200AVR + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + JTAGICEAVR + 3 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JTAGICEMKIIAVR + 4 + + 6 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DRAGONAVR + 2 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SIMAVR + 2 + + 1 + 1 + 1 + + + + + + + THIRDPARTYAVR + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + Release + + AVR + + 0 + + C-SPY + 5 + + 14 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + AVRONE + 3 + + 3 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CCRAVR + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + ICE200AVR + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + JTAGICEAVR + 3 + + 2 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JTAGICEMKIIAVR + 4 + + 6 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DRAGONAVR + 2 + + 2 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SIMAVR + 2 + + 1 + 1 + 0 + + + + + + + THIRDPARTYAVR + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewp b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewp new file mode 100644 index 0000000..4d0640e --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewp @@ -0,0 +1,2156 @@ + + 2 + + Debug + + AVR + + 1 + + General + 11 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCAVR + 6 + + 17 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AAVR + 5 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 2 + + 13 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 2 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Release + + AVR + + 0 + + General + 11 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCAVR + 6 + + 17 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AAVR + 5 + + 11 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 2 + + 13 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 2 + + 0 + 1 + 0 + + + + + + + BILINK + 0 + + + + + common + + services + + usb + + class + + dfu_flip + + device + + $PROJ_DIR$\..\..\..\..\udi_dfu_atmel.c + + + bootloader + + xmega + + $PROJ_DIR$\..\..\sysclk_opt.c + + + $PROJ_DIR$\..\..\main.c + + + + + $PROJ_DIR$\..\..\..\..\udi_dfu_atmel_desc.c + + + + + + udc + + $PROJ_DIR$\..\..\..\..\..\..\..\udc\udc_dfu_small.c + + + + + clock + + xmega + + $PROJ_DIR$\..\..\..\..\..\..\..\..\clock\xmega\sysclk.c + + + + + isp + + flip + + xmega + + $PROJ_DIR$\..\..\..\..\..\..\..\..\isp\flip\xmega\isp.c + + + $PROJ_DIR$\..\..\..\..\..\..\..\..\isp\flip\xmega\cstartup.s90 + + + + + + + + xmega + + drivers + + nvm + + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\nvm\nvm.c + + + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\nvm\nvm_asm.s + + + + usb + + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\usb\usb_device.c + + + + cpu + + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\cpu\ccp.s + + + + + + Release + Debug + + diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.eww b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.eww new file mode 100644 index 0000000..d1e75ec --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.eww @@ -0,0 +1,6 @@ + + + + $WS_DIR$\xmega_small.ewp + + diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_board.h b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_board.h new file mode 100644 index 0000000..6067f22 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_board.h @@ -0,0 +1,47 @@ +/** + * \file + * + * \brief Board 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_BOARD_H_INCLUDED +#define CONF_BOARD_H_INCLUDED + +#endif /* CONF_BOARD_H_INCLUDED */ diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_clock.h b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_clock.h new file mode 100644 index 0000000..0e79951 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_clock.h @@ -0,0 +1,61 @@ +/** + * \file + * + * \brief Chip-specific system clock manager configuration + * + * Copyright (c) 2011-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 CONF_CLOCK_H_INCLUDED +#define CONF_CLOCK_H_INCLUDED + +//! Configuration using On-Chip RC oscillator at 48MHz +//! The RC oscillator is calibrated via USB Start Of Frame +//! Clk USB = 48MHz (used by USB) +//! Clk sys = 48MHz +//! Clk cpu/per = 24MHz +#define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC +#define CONFIG_OSC_RC32_CAL 48000000UL + +#define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + +#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC32MHZ +#define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_2 +#define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 + + +#endif /* CONF_CLOCK_H_INCLUDED */ diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_isp.h b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_isp.h new file mode 100644 index 0000000..dafa006 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_isp.h @@ -0,0 +1,100 @@ +/** + * \file + * + * \brief ISP configuration file. + * + * Copyright (c) 2011-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 _CONF_ISP_H_ +#define _CONF_ISP_H_ + +#include "parts.h" + +#if !defined(__ASSEMBLER__) && !defined(__IAR_SYSTEMS_ASM__) +// This define may only be included from C files + +#include "compiler.h" +#include "nvm.h" + + +// Bootloader Versions +// Example: Version 0x00 give 1.0.0 on batchisp log +// Example: Version 0x03 give 1.0.3 on batchisp log +// Example: Version 0x25 give 1.2.5 on batchisp log +# define BOOTLOADER_VERSION 0x04 + +# if (FLASH_SIZE<=0x10000) // FLASH <= 64KB +// If all memories (flash,eeprom,...) do not exceed 64KB. +// then the ISP interface can be optimized to save CODE. +# define ISP_SMALL_MEMORY_SIZE +# endif + +#endif + +// Definition of hardware condition to enter in ISP mode +#if XMEGA_A1U +# define ISP_PORT_DIR PORTF_DIR +# define ISP_PORT_PINCTRL PORTF_PIN5CTRL +# define ISP_PORT_IN PORTF_IN +# define ISP_PORT_PIN 0 +#elif (XMEGA_A3U || XMEGA_A3BU || XMEGA_C3) +# define ISP_PORT_DIR PORTE_DIR +# define ISP_PORT_PINCTRL PORTE_PIN5CTRL +# define ISP_PORT_IN PORTE_IN +# define ISP_PORT_PIN 5 +#elif (XMEGA_A4U || XMEGA_C4) +// Changed default XMEGA_A4U to fit RevE rebooted. +//# define ISP_PORT_DIR PORTC_DIR +//# define ISP_PORT_PINCTRL PORTC_PIN3CTRL +//# define ISP_PORT_IN PORTC_IN +//# define ISP_PORT_PIN 3 +# define ISP_PORT_DIR PORTA_DIR +# define ISP_PORT_PINCTRL PORTA_PIN6CTRL +# define ISP_PORT_IN PORTA_IN +# define ISP_PORT_PIN 6 +#elif XMEGA_B +# define ISP_PORT_DIR PORTC_DIR +# define ISP_PORT_PINCTRL PORTC_PIN6CTRL +# define ISP_PORT_IN PORTC_IN +# define ISP_PORT_PIN 6 +#else +# error Unknow AVR Xmega part +#endif + +#endif // _CONF_ISP_H_ diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_usb.h b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_usb.h new file mode 100644 index 0000000..c9a19eb --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_usb.h @@ -0,0 +1,218 @@ +/** + * \file + * + * \brief USB configuration file + * + * Copyright (c) 2011-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 _CONF_USB_H_ +#define _CONF_USB_H_ + +#include "compiler.h" +#include "nvm.h" + +/* Redefine USB interrupt vectors base address to safe code space */ +# if defined(__GNUC__) +# error GCC no supported when interrupt vectors space is optimized +/* +# undef USB_BUSEVENT_vect +# undef USB_TRNCOMPL_vect +# undef USB_BUSEVENT_vect_num +# undef USB_TRNCOMPL_vect_num +# define USB_BUSEVENT_vect_num 1 +# define USB_BUSEVENT_vect _VECTOR(1) +# define USB_TRNCOMPL_vect_num 2 +# define USB_TRNCOMPL_vect _VECTOR(2) +*/ +# elif defined(__ICCAVR__) +# undef USB_BUSEVENT_vect +# undef USB_TRNCOMPL_vect +# define USB_BUSEVENT_vect 0x0 +# define USB_TRNCOMPL_vect 0x4 +# endif + +// A reduce clock implementation is used to fit on bootloader 4KB +#if (FLASH_SIZE<=0x10000) +// Redirection of common services clock interface +# define sysclk_init sysclk_init_opt +# define sysclk_enable_usb sysclk_enable_usb_opt +# define sysclk_disable_usb sysclk_disable_usb_opt + void sysclk_init_opt(void); + void sysclk_enable_usb_opt(uint8_t freq); + void sysclk_disable_usb_opt(void); +#endif + +/** + * USB Device Configuration + * @{ + */ + +//! Device definition (mandatory) +#define USB_DEVICE_VENDOR_ID USB_VID_ATMEL +#if AVR8_PART_IS_DEFINED(ATxmega16A4U) +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_DFU_ATXMEGA16A4U +//#define USB_DEVICE_PRODUCT_NAME "DFU ATXMEGA16A4U" // Removed to save CODE +#elif AVR8_PART_IS_DEFINED(ATxmega32A4U) +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_DFU_ATXMEGA32A4U +//#define USB_DEVICE_PRODUCT_NAME "DFU ATXMEGA32A4U" // Removed to save CODE +#elif AVR8_PART_IS_DEFINED(ATxmega64A4U) +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_DFU_ATXMEGA64A4U +#define USB_DEVICE_PRODUCT_NAME "DFU ATXMEGA64A4U" +#elif AVR8_PART_IS_DEFINED(ATxmega128A4U) +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_DFU_ATXMEGA128A4U +#define USB_DEVICE_PRODUCT_NAME "DFU ATXMEGA128A4U" +#elif AVR8_PART_IS_DEFINED(ATxmega64A3U) +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_DFU_ATXMEGA64A3U +#define USB_DEVICE_PRODUCT_NAME "DFU ATXMEGA64A3U" +#elif AVR8_PART_IS_DEFINED(ATxmega128A3U) +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_DFU_ATXMEGA128A3U +#define USB_DEVICE_PRODUCT_NAME "DFU ATXMEGA128A3U" +#elif AVR8_PART_IS_DEFINED(ATxmega192A3U) +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_DFU_ATXMEGA192A3U +#define USB_DEVICE_PRODUCT_NAME "DFU ATXMEGA128A3U" +#elif AVR8_PART_IS_DEFINED(ATxmega256A3U) +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_DFU_ATXMEGA256A3U +#define USB_DEVICE_PRODUCT_NAME "DFU ATXMEGA256A3U" +#elif AVR8_PART_IS_DEFINED(ATxmega256A3BU) +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_DFU_ATXMEGA256A3BU +#define USB_DEVICE_PRODUCT_NAME "DFU ATXMEGA256A3BU" +#elif AVR8_PART_IS_DEFINED(ATxmega128A1U) +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_DFU_ATXMEGA128A1U +#define USB_DEVICE_PRODUCT_NAME "DFU ATXMEGA128A1U" +#elif AVR8_PART_IS_DEFINED(ATxmega64A1U) +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_DFU_ATXMEGA64A1U +#define USB_DEVICE_PRODUCT_NAME "DFU ATXMEGA64A1U" +#elif AVR8_PART_IS_DEFINED(ATxmega128B1) +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_DFU_ATXMEGA128B1 +#define USB_DEVICE_PRODUCT_NAME "DFU ATXMEGA128B1" +#elif AVR8_PART_IS_DEFINED(ATxmega64B1) +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_DFU_ATXMEGA64B1 +#define USB_DEVICE_PRODUCT_NAME "DFU ATXMEGA64B1" +#elif AVR8_PART_IS_DEFINED(ATxmega128B3) +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_DFU_ATXMEGA128B3 +#define USB_DEVICE_PRODUCT_NAME "DFU ATXMEGA128B3" +#elif AVR8_PART_IS_DEFINED(ATxmega64B3) +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_DFU_ATXMEGA64B3 +#define USB_DEVICE_PRODUCT_NAME "DFU ATXMEGA64B3" +#elif AVR8_PART_IS_DEFINED(ATxmega384C3) +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_DFU_ATXMEGA384C3 +#define USB_DEVICE_PRODUCT_NAME "DFU ATXMEGA384C3" +#elif AVR8_PART_IS_DEFINED(ATxmega256C3) +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_DFU_ATXMEGA256C3 +#define USB_DEVICE_PRODUCT_NAME "DFU ATXMEGA256C3" +#elif AVR8_PART_IS_DEFINED(ATxmega128C3) +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_DFU_ATXMEGA128C3 +#define USB_DEVICE_PRODUCT_NAME "DFU ATXMEGA128C3" +#elif AVR8_PART_IS_DEFINED(ATxmega64C3) +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_DFU_ATXMEGA64C3 +#define USB_DEVICE_PRODUCT_NAME "DFU ATXMEGA64C3" +#elif AVR8_PART_IS_DEFINED(ATxmega32C4) +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_DFU_ATXMEGA32C4 +//#define USB_DEVICE_PRODUCT_NAME "DFU ATXMEGA32C4" // Removed to save CODE +#elif AVR8_PART_IS_DEFINED(ATxmega16C4) +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_DFU_ATXMEGA16C4 +//#define USB_DEVICE_PRODUCT_NAME "DFU ATXMEGA16C4" // Removed to save CODE +#else +#error Unknow DFU PID for this AVR part +#endif + +#define USB_DEVICE_MAJOR_VERSION (BOOTLOADER_VERSION>>4) +#define USB_DEVICE_MINOR_VERSION (BOOTLOADER_VERSION&0x0F) +#define USB_DEVICE_POWER 100 // Consumption on Vbus line (mA) +#if (FLASH_SIZE>0x10000) // Optimize CODE space (Boot = 4KB) +#define USB_DEVICE_MANUFACTURE_NAME "ATMEL" +#endif +#define USB_DEVICE_ATTR USB_CONFIG_ATTR_SELF_POWERED + +/** + * Device speeds support + * Only Full speed is authorized on DFU ATMEL + * Because FLIP supports only full speed + * Also: + * - low speed is too slow (endpoint 8 Bytes) + * - high speed does not increase flash program speed + * - high speed is not supported on custom board with bad USB layout + * @{ + */ +// No speed change possible +//@} + +/** + * USB Device Callbacks definitions (Optional) + * @{ + */ +#define UDC_VBUS_EVENT(b_vbus_high) // NO VBUS EVENT on XMEGA +//@} + +//@} + + +/** + * USB Interface Configuration + * @{ + */ +/** + * Configuration of DFU interface + * @{ + */ +//! Interface callback definition +#define UDI_DFU_ENABLE_EXT() true +#define UDI_DFU_DISABLE_EXT() + +//! FLIP protocol version to use +#define FLIP_PROTOCOL_VERSION FLIP_PROTOCOL_VERSION_2 +#if (FLASH_SIZE<0x8000) // Optimize RAM space (RAM = 2KB) +# define UDI_DFU_SMALL_RAM // Reduce RAM (1KB) but increase CODE (72B) +#endif +//@} +//@} + + +/** + * USB Device Driver Configuration + * @{ + */ +#define UDD_NO_SLEEP_MGR +//@} + +//! The includes of classes and other headers must be done at the end of this file to avoid compile error +#include "udi_dfu_atmel_conf.h" +#include "conf_isp.h" // Need to put bootloader version at USB device version + +#endif // _CONF_USB_H_ diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/main.c b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/main.c new file mode 100644 index 0000000..972e42d --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/main.c @@ -0,0 +1,80 @@ +/** + * \file + * + * \brief Main functions + * + * Copyright (c) 2011 - 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 +#include "conf_usb.h" + +/*! \brief Main function. Execution starts here. + */ +int main(void) +{ + // Map interrupt vectors table in bootloader section + ccp_write_io((uint8_t*)&PMIC.CTRL, PMIC_IVSEL_bm | PMIC_LOLVLEN_bm + | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm); + + sysclk_init(); + cpu_irq_enable(); + + // Start USB stack to authorize VBus monitoring + udc_start(); + + udc_attach(); + while (true) { + } +} + + +/** + * \mainpage ASF USB Device DFU + * + * \section intro Introduction + * This application is the official Atmel USB DFU bootloader for XMEGA. + * + * A USB DFU bootloader guide is proposed for all AVR XMEGA parts with USB interface: + * + * \section files Application Files + * The specific files of application are: + * - main.c: the main file to start clock and USB DFU Device. + * - specific linker script + * - specific optimized codes to fit with boot section size + */ diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/main.h b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/main.h new file mode 100644 index 0000000..c238207 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/main.h @@ -0,0 +1,47 @@ +/** + * \file + * + * \brief Main functions + * + * 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 _MAIN_H_ +#define _MAIN_H_ + +#endif // _MAIN_H_ diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/sysclk_opt.c b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/sysclk_opt.c new file mode 100644 index 0000000..90467b7 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/sysclk_opt.c @@ -0,0 +1,98 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (c) 2011-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 + +#include +#include +#include +#if (CONFIG_OSC_RC32_CAL==48000000UL) +#include +#endif + +void sysclk_init_opt(void) +{ + sysclk_set_prescalers(CONFIG_SYSCLK_PSADIV,CONFIG_SYSCLK_PSBCDIV); + /* Loads 48MHz internal RC calibration value */ + DFLLRC32M.CALA=nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSCA)); + DFLLRC32M.CALB=nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSC)); + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); + ccp_write_io((uint8_t *)&CLK.CTRL, CONFIG_SYSCLK_SOURCE); + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_gm); + // Calibrate 32MRC at 48MHz using USB SOF + // 48MHz/1kHz=0xBB80 + DFLLRC32M.COMP1=0x80; + DFLLRC32M.COMP2=0xBB; + OSC.DFLLCTRL |= OSC_RC32MCREF_USBSOF_gc; + DFLLRC32M.CTRL |= DFLL_ENABLE_bm; +} + + +/** + * \brief Enable clock for the USB module + * + * \pre CONFIG_USBCLK_SOURCE must be defined. + * + * \param freq The required USB clock frequency in MHz: + * \arg \c 6 for 6 MHz + * \arg \c 48 for 48 MHz + */ +void sysclk_enable_usb_opt(uint8_t freq) +{ + Assert(freq == 48); + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_USB); + ccp_write_io((uint8_t *)&CLK.USBCTRL, 0 + | CLK_USBSRC_RC32M_gc + | CLK_USBSEN_bm); +} + +/** + * \brief Disable clock for the USB module + */ +void sysclk_disable_usb_opt(void) +{ + ccp_write_io((uint8_t *)&CLK.USBCTRL, 0); +} diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel.c b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel.c new file mode 100644 index 0000000..a711dcd --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel.c @@ -0,0 +1,976 @@ +/** + * \file + * + * \brief USB Device Atmel Firmware Upgrade (DFU) interface definitions. + * + * Copyright (c) 2011-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 "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_dfu.h" +#include "udd.h" +#include "udc.h" +#include "udi_dfu_atmel.h" +#include "conf_isp.h" +#include "isp.h" +#include "flip_protocol.h" +#include "string.h" + + +#ifndef FLIP_PROTOCOL_VERSION +# error FLIP_PROTOCOL_VERSION must be define in conf_usb.h +#endif +#if ((FLIP_PROTOCOL_VERSION != FLIP_PROTOCOL_VERSION_2) \ + && (FLIP_PROTOCOL_VERSION != FLIP_PROTOCOL_VERSION_1)) +# error Bootloader protocol not supported (FLIP_PROTOCOL_VERSION) +#endif + +/** + * \ingroup udi_dfu_atmel_group + * \defgroup udi_dfu_atmel_group_udc Interface with USB Device Core (UDC) + * + * Structures and functions required by UDC. + * + * @{ + */ +bool udi_dfu_atmel_enable(void); +void udi_dfu_atmel_disable(void); +bool udi_dfu_atmel_setup(void); +uint8_t udi_dfu_atmel_getsetting(void); + +//! Global structure which contains standard UDI interface for UDC +UDC_DESC_STORAGE udi_api_t udi_api_dfu_atmel = { + .enable = udi_dfu_atmel_enable, + .disable = udi_dfu_atmel_disable, + .setup = udi_dfu_atmel_setup, + .getsetting = udi_dfu_atmel_getsetting, + .sof_notify = NULL, +}; +//@} + + +/** + * \ingroup udi_dfu_atmel_group + * \defgroup udi_dfu_atmel_group_internal Implementation of UDI DFU Atmel Class + * + * Class internal implementation + * @{ + */ + +/** + * \name Internal routines to manage DFU requests + */ +//@{ + +//! \brief Resets DFU status and usb setup process callbacks +static void udi_dfu_atmel_reset_protocol(void); + +//! \brief Decodes the Atmel DFU Command +//! Called by over_under_run callback when the first data packet +//! from a DNLOAD DFU request is received +//! +//! Note: An Atmel DFU commands can be stalled in following cases: +//! memory security, bad address or blank check fail +//! +static bool udi_dfu_flip_msg_decode(void); + + +#if (FLIP_PROTOCOL_VERSION == FLIP_PROTOCOL_VERSION_2) +/** + * \name Manages Atmel DFU command from protocol version 2 + */ +//@{ +//! \brief Decodes and prepares program memory command +//! +//! \return \c 1 if command was accepted, otherwise \c 0. +//! +static bool udi_dfu_atmel_program(void); + +//! \brief Decodes and prepares read memory command +//! +//! \return \c 1 if command was accepted, otherwise \c 0. +//! +static bool udi_dfu_atmel_read(void); + +//! \brief Decodes and process blank check memory command +//! +//! \return \c 1 if command was accepted, otherwise \c 0. +//! +static bool udi_dfu_atmel_blankcheck(void); + +//! \brief Decodes and process erase chip command +//! +//! \return \c 1 if command was accepted, otherwise \c 0. +//! +static bool udi_dfu_atmel_erase_chip(void); + +//! \brief Decodes and prepares CPU reset command +static void udi_dfu_atmel_start(void); + +//! \brief Decodes and process memory select command +//! +//! \return \c 1 if command was accepted, otherwise \c 0. +//! +static bool udi_dfu_atmel_select_memory(void); +//@} + +#else + +/** + * \name Manages Atmel DFU command from protocol version 1 + */ +//@{ + +//! \brief Decodes and prepares program memory command +//! +//! \param mem memory id to program +//! +//! \return \c 1 if command was accepted, otherwise \c 0. +//! +static bool udi_dfu_atmel_progstart(uint8_t mem); + +//! \brief Decodes and prepares read or check memory command +//! +//! \param mem memory id to program or check +//! \param b_check true if command check must be process +//! +//! \return \c 1 if command was accepted, otherwise \c 0. +//! +static bool udi_dfu_atmel_read(uint8_t mem, bool b_check); + +//! \brief Decodes and prepares byte read command on specific memory +//! +//! \param mem memory id to program or check +//! \param addr address in memory to read +//! +//! \return \c 1 if command was accepted, otherwise \c 0. +//! +static void udi_dfu_atmel_read_id(uint8_t mem, uint8_t addr); + +//! \brief Decodes and process erase chip command +//! +//! \return \c 1 if command was accepted, otherwise \c 0. +//! +static bool udi_dfu_atmel_chip_erase(void); + +//! \brief Decodes and prepares CPU reset command +//! +static void udi_dfu_atmel_start_app(void); + +//! \brief Decodes change high address command +//! +//! \return \c 1 if command was accepted, otherwise \c 0. +//! +#ifndef ISP_SMALL_MEMORY_SIZE +static bool udi_dfu_flip_msg_decode_changeaddr(void); +#endif + +//@} + +#endif + +//! \brief Selects the memory +//! +//! \param mem_num memory id to select +//! +static void udi_dfu_atmel_sel_mem( uint8_t mem_num ); + +//! \brief Change DFU status to notify that the memory is protected +//! +//! \return \c 1 if command was accepted, otherwise \c 0. +//! +static bool udi_dfu_atmel_mem_protected(void); + +//! \brief Gets a memory address in a Atmel DFU command +//! +//! \param arg pointer to read address +//! +//! \return \c 1 if command was accepted, otherwise \c 0. +//! +static bool udi_dfu_atmel_mem_getaddr(uint8_t * arg); + +//! \brief Reads memory and transfer data to USB interface +//! +//! \return \c 1 if command was accepted, otherwise \c 0. +//! +static bool udi_dfu_atmel_mem_read(void); + +//! \brief Process a blank check on memory +static void udi_dfu_atmel_mem_check(void); + +//! \brief Send address which has failed during check memory +//! +//! \return \c 1 if command was accepted, otherwise \c 0. +//! +static bool udi_dfu_atmel_mem_send_last_add(void); + +//! \brief Writes memory with data from USB interface +//! +//! \return \c 1 if command was accepted, otherwise \c 0. +//! +static bool udi_dfu_atmel_mem_write(void); + +//@} + +//! Macro to simplify and to optimize command decode process +#define CAT_CMD(val1,val2) (((uint16_t)val1<<8)|(val2<<0)) + + +/** + * \name Internal variables to manage DFU requests + */ +//@{ + +//! Status of DFU process +static dfu_status_t udi_dfu_atmel_status; +#if (FLIP_PROTOCOL_VERSION == FLIP_PROTOCOL_VERSION_2) +# ifdef UDI_DFU_ATMEL_PROTOCOL_2_SPLIT_ERASE_CHIP +//! Flag to signal that a chip erase process is running +static bool udi_dfu_atmel_erase_running; +# endif +#endif + +//! Structure to store the command fields +static union{ +#if (FLIP_PROTOCOL_VERSION == FLIP_PROTOCOL_VERSION_2) + flip_msg_v2_t msg; +#else // V1 + flip_msg_v1_t msg; +#endif + uint8_t payload[USB_DEVICE_EP_CTRL_SIZE]; + }udi_dfu_flip_msg; + +#if (FLIP_PROTOCOL_VERSION == FLIP_PROTOCOL_VERSION_2) +# ifdef UDI_DFU_SMALL_RAM +# define DFU_ATMEL_BUF_TRANS_SIZE (FLIP_V2_BUF_TRANS_SIZE/2) +# else +# define DFU_ATMEL_BUF_TRANS_SIZE FLIP_V2_BUF_TRANS_SIZE +# endif +#else // V1 +# define DFU_ATMEL_BUF_TRANS_SIZE FLIP_V1_BUF_TRANS_SIZE +#endif + + +//! Buffer to receive or send data +COMPILER_WORD_ALIGNED + static uint8_t + udi_dfu_atmel_buf_trans[DFU_ATMEL_BUF_TRANS_SIZE]; + +//! Callback to use when an upload request is received +static bool(*udi_dfu_atmel_upload_callback) (void); + +//! Notify a reset request to start +static bool udi_dfu_atmel_reset; + +//! Store the current security level +static bool udi_dfu_atmel_security; + +/** + * \name To manage memories + */ +//@{ +#if (FLIP_PROTOCOL_VERSION == FLIP_PROTOCOL_VERSION_2) +//! Flag to signal that memory is write protected +static bool udi_dfu_atmel_mem_b_protected; +#endif +//! Memory address to read, write or check blank +static isp_addr_t udi_dfu_atmel_mem_add; +//! Number of data to process during read, write or check blank +static isp_addr_t udi_dfu_atmel_mem_nb_data; +//! Memory ID selected to read, write or check blank +static isp_mem_t udi_dfu_atmel_mem_sel; +//@} + +//@} + + +bool udi_dfu_atmel_enable(void) +{ + udi_dfu_atmel_reset = false; + udi_dfu_atmel_reset_protocol(); + // Load chip information + isp_init(); + udi_dfu_atmel_security = isp_is_security(); + return UDI_DFU_ENABLE_EXT(); +} + + +void udi_dfu_atmel_disable(void) +{ + UDI_DFU_DISABLE_EXT(); +} + + +bool udi_dfu_atmel_setup(void) +{ + //** Interface requests + if (Udd_setup_type() != USB_REQ_TYPE_CLASS) { + return false; // Only class request decoded + } + + if (Udd_setup_is_in()) { + // Requests Class Interface Get + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_DFU_GETSTATUS: +#if (FLIP_PROTOCOL_VERSION == FLIP_PROTOCOL_VERSION_2) +# ifdef UDI_DFU_ATMEL_PROTOCOL_2_SPLIT_ERASE_CHIP + if (udi_dfu_atmel_erase_running) { + udi_dfu_atmel_erase_chip(); + } +# endif +#endif + Assert(udd_g_ctrlreq.req.wValue==0); + Assert(sizeof(udi_dfu_atmel_status)==udd_g_ctrlreq.req.wLength); + udd_set_setup_payload( + (uint8_t *) & udi_dfu_atmel_status, + sizeof(udi_dfu_atmel_status)); + return true; + + // Used to send data to the host + // when the previous Atmel command (DNLOAD) request data + case USB_REQ_DFU_UPLOAD: +#if (FLIP_PROTOCOL_VERSION == FLIP_PROTOCOL_VERSION_2) +# ifdef UDI_DFU_ATMEL_PROTOCOL_2_SPLIT_ERASE_CHIP + Assert( !udi_dfu_atmel_erase_running ); +# endif +#endif + Assert(DFU_STATE_DFUERROR != udi_dfu_atmel_status.bState); + if (NULL != udi_dfu_atmel_upload_callback) { + return udi_dfu_atmel_upload_callback(); + } + } + } + +#if (FLIP_PROTOCOL_VERSION == FLIP_PROTOCOL_VERSION_2) +# ifdef UDI_DFU_ATMEL_PROTOCOL_2_SPLIT_ERASE_CHIP + Assert( !udi_dfu_atmel_erase_running ); +# endif +#endif + + if (Udd_setup_is_out()) { + // Requests Class Interface Set + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_DFU_CLRSTATUS: + Assert(udd_g_ctrlreq.req.wValue==0); + Assert(udd_g_ctrlreq.req.wLength==0); + udi_dfu_atmel_reset_protocol(); + return true; + + // DNLOAD request including Atmel command fields + // and data for write operation. + // For read operation, the data are sent in the next UPLOAD request + case USB_REQ_DFU_DNLOAD: + // Check if a reset has been requested + if (udi_dfu_atmel_reset) { + // Remove force ISP before a reset CPU to start Application + isp_force_boot_isp(false); + // Then this DNLOAD DFU request must be empty (0==wLength) + // and valid the reset application command. + // Valid SETUP request and reset application via request callback. + udd_g_ctrlreq.callback = isp_start_appli; + return true; + } + + Assert(DFU_STATE_DFUERROR != udi_dfu_atmel_status.bState); + Assert(udd_g_ctrlreq.req.wLength!=0); + + // The first packet contains the command + // after this packet the over_under_run callback can be called + // if the Host want to send more data to device + udd_set_setup_payload( + (uint8_t *) & udi_dfu_flip_msg.payload, + sizeof(udi_dfu_flip_msg)), + // Called when the first packet is received + // before continuing DATA phase or start ZLP phase + udd_g_ctrlreq.over_under_run = udi_dfu_flip_msg_decode; + // Note udd_g_ctrlreq.callback is updated + // by udi_dfu_flip_msg_decode() before ZLP phase + return true; + } + } + // Unknown request + udi_dfu_atmel_status.bStatus = DFU_STATUS_ERRSTALLEDPK; + udi_dfu_atmel_status.bState = DFU_STATE_DFUERROR; + return false; +} + + +uint8_t udi_dfu_atmel_getsetting(void) +{ + return 0; +} + + +static void udi_dfu_atmel_reset_protocol(void) +{ + // Reset DFU status + udi_dfu_atmel_status.bStatus = DFU_STATUS_OK; + udi_dfu_atmel_status.bState = DFU_STATE_DFUIDLE; + // These fields are not used and always set to zero: + // bwPollTimeout[3] + // iString + + // Reset all callbacks + udd_g_ctrlreq.over_under_run = NULL; + udd_g_ctrlreq.callback = NULL; +} + + +#if (FLIP_PROTOCOL_VERSION == FLIP_PROTOCOL_VERSION_2) + +static bool udi_dfu_flip_msg_decode(void) +{ + // By default no callback initialized + // By default request states are success and finish + udi_dfu_atmel_reset_protocol(); + udi_dfu_atmel_upload_callback = NULL; + + // To restart ISP in case of USB cable is unplugged during program load + isp_force_boot_isp(true); + + // Decode Atmel command ID + if (CAT_CMD( udi_dfu_flip_msg.msg.group, udi_dfu_flip_msg.msg.cmd_id) == + CAT_CMD( FLIP_V2_CMD_GRP_DNLOAD, FLIP_V2_CMD_PROGRAM_START)) { + return udi_dfu_atmel_program(); + } + if (CAT_CMD( udi_dfu_flip_msg.msg.group, udi_dfu_flip_msg.msg.cmd_id) == + CAT_CMD( FLIP_V2_CMD_GRP_UPLOAD, FLIP_V2_CMD_READ_MEMORY)) { + return udi_dfu_atmel_read(); + } + if (CAT_CMD( udi_dfu_flip_msg.msg.group, udi_dfu_flip_msg.msg.cmd_id) == + CAT_CMD( FLIP_V2_CMD_GRP_UPLOAD, FLIP_V2_CMD_BLANK_CHECK)) { + return udi_dfu_atmel_blankcheck(); + } + if (CAT_CMD( udi_dfu_flip_msg.msg.group, udi_dfu_flip_msg.msg.cmd_id) == + CAT_CMD( FLIP_V2_CMD_GRP_EXEC, FLIP_V2_CMD_ERASE)) { + return udi_dfu_atmel_erase_chip(); + } + if (CAT_CMD( udi_dfu_flip_msg.msg.group, udi_dfu_flip_msg.msg.cmd_id) == + CAT_CMD( FLIP_V2_CMD_GRP_EXEC, FLIP_V2_CMD_START_APPLI)) { + udi_dfu_atmel_start(); + return true; + } + if (CAT_CMD( udi_dfu_flip_msg.msg.group, udi_dfu_flip_msg.msg.cmd_id) == + CAT_CMD( FLIP_V2_CMD_GRP_SELECT, FLIP_V2_CMD_SELECT_MEMORY)) { + return udi_dfu_atmel_select_memory(); + } + return false; // Unknown command +} + +static bool udi_dfu_atmel_program(void) +{ + // Check list before start memory programming + if (udi_dfu_atmel_security && udi_dfu_atmel_mem_b_protected) { + // Security enabled + return udi_dfu_atmel_mem_protected(); + } + if (!udi_dfu_atmel_mem_sel.fnct_write) { + udi_dfu_atmel_status.bStatus = DFU_STATUS_ERRWRITE; + udi_dfu_atmel_status.bState = DFU_STATE_DFUERROR; + return false; // Write memory not available + } + if (!udi_dfu_atmel_mem_getaddr(&udi_dfu_flip_msg.msg.arg[0])) + return false; // Bad Range + + // Init buffer to fill during next DATA phase of request + udd_set_setup_payload( + udi_dfu_atmel_buf_trans, + DFU_ATMEL_BUF_TRANS_SIZE); + // Init callback called after buffer filled + udd_g_ctrlreq.over_under_run = udi_dfu_atmel_mem_write; + return true; +} + +static bool udi_dfu_atmel_read(void) +{ + // Check before decoding the command + if (!udi_dfu_atmel_mem_getaddr(&udi_dfu_flip_msg.msg.arg[0])) + return false; // Range bad + + if (!udi_dfu_atmel_mem_sel.fnct_read) { + udi_dfu_atmel_status.bStatus = DFU_STATUS_ERRWRITE; + udi_dfu_atmel_status.bState = DFU_STATE_DFUERROR; + return false; // Read memory not available + } + + if (udi_dfu_atmel_security && udi_dfu_atmel_mem_b_protected) { + // Memory security then remove read callback by protected callback + udi_dfu_atmel_upload_callback = udi_dfu_atmel_mem_protected; + }else{ + udi_dfu_atmel_upload_callback = udi_dfu_atmel_mem_read; + } + return true; +} + +static bool udi_dfu_atmel_blankcheck(void) +{ + // Check before decoding the command + if (!udi_dfu_atmel_mem_getaddr(&udi_dfu_flip_msg.msg.arg[0])) + return false; // Range bad + + if (!udi_dfu_atmel_mem_sel.fnct_read) { + udi_dfu_atmel_status.bStatus = DFU_STATUS_ERRWRITE; + udi_dfu_atmel_status.bState = DFU_STATE_DFUERROR; + return false; // Read memory not available + } + udi_dfu_atmel_mem_check(); + return true; +} + +static bool udi_dfu_atmel_erase_chip(void) +{ + Assert(udi_dfu_flip_msg.msg.arg[0]==FLIP_V2_CMD_ERASE_ARG_CHIP); + +#ifdef UDI_DFU_ATMEL_PROTOCOL_2_SPLIT_ERASE_CHIP + if (isp_erase_chip_split()) { + // Erase finish + udi_dfu_atmel_security = false; + udi_dfu_atmel_erase_running = false; + udi_dfu_atmel_status.bStatus = DFU_STATUS_OK; + udi_dfu_atmel_status.bState = DFU_STATE_DFUIDLE; + }else{ + // Erase on-going + udi_dfu_atmel_erase_running = true; + udi_dfu_atmel_status.bStatus = DFU_STATUS_ERRNOTDONE; + udi_dfu_atmel_status.bState = DFU_STATE_DFUDNBUSY; + } +#else + if (!isp_erase_chip()) { + return false; + } + // Erase finish + udi_dfu_atmel_security = false; +#endif + return true; +} + +static void udi_dfu_atmel_start(void) +{ + // Start application reset after next DNLOAD request + Assert( (udi_dfu_flip_msg.msg.arg[0] == FLIP_V2_CMD_START_APPLI_ARG_RESET) + || (udi_dfu_flip_msg.msg.arg[0] == FLIP_V2_CMD_START_APPLI_ARG_NO_RESET)); + udi_dfu_atmel_reset = true; +} + +static bool udi_dfu_atmel_select_memory(void) +{ + switch (udi_dfu_flip_msg.msg.arg[0]) { + case FLIP_V2_CMD_SELECT_MEMORY_ARG_UNIT: + if (ISP_MEM_COUNT <= udi_dfu_flip_msg.msg.arg[1]) { + udi_dfu_atmel_status.bStatus = DFU_STATUS_ERRADDRESS; + udi_dfu_atmel_status.bState = DFU_STATE_DFUERROR; + return false; // Memory id error + } + udi_dfu_atmel_sel_mem(udi_dfu_flip_msg.msg.arg[1]); + udi_dfu_atmel_mem_add = 0; + break; + +#ifndef ISP_SMALL_MEMORY_SIZE + case FLIP_V2_CMD_SELECT_MEMORY_ARG_PAGE: + { + uint32_t tmp = 0; + MSB0W(tmp) = udi_dfu_flip_msg.msg.arg[1]; + MSB1W(tmp) = udi_dfu_flip_msg.msg.arg[2]; + if (tmp >= udi_dfu_atmel_mem_sel.size) { + udi_dfu_atmel_status.bStatus = DFU_STATUS_ERRADDRESS; + udi_dfu_atmel_status.bState = DFU_STATE_DFUERROR; + return false; // Address error + } + udi_dfu_atmel_mem_add = tmp; + } + break; +#endif + + default: + Assert(false); // Bad command + break; + } + + return true; +} + + +#else // V1 + +static bool udi_dfu_flip_msg_decode(void) +{ + // By default no callback initialized + // By default request states are success and finish + udi_dfu_atmel_reset_protocol(); + udi_dfu_atmel_upload_callback = NULL; + + // Decode Atmel command ID + switch (CAT_CMD(udi_dfu_flip_msg.msg.cmd_id, + udi_dfu_flip_msg.msg.arg[0])) { + +#ifndef ISP_SMALL_MEMORY_SIZE + // Command to change high address + case CAT_CMD(FLIP_V1_CMD_CHANGE_BASE_ADDR, + FLIP_V1_CMD_CHANGE_BASE_ADDR_ARG0): + return udi_dfu_flip_msg_decode_changeaddr(); +#endif + + // Commands to program a memory + case CAT_CMD(FLIP_V1_CMD_PROG_START, + FLIP_V1_CMD_PROG_START_ARG_FLASH): + return udi_dfu_atmel_progstart(ISP_MEM_FLASH); + case CAT_CMD(FLIP_V1_CMD_PROG_START, + FLIP_V1_CMD_PROG_START_ARG_EEPROM): + return udi_dfu_atmel_progstart(ISP_MEM_EEPROM); + case CAT_CMD(FLIP_V1_CMD_PROG_START, + FLIP_V1_CMD_PROG_START_ARG_CUSTOM): + return udi_dfu_atmel_progstart(ISP_MEM_CUSTOM); + + // Commands to read a memory + case CAT_CMD(FLIP_V1_CMD_READ, + FLIP_V1_CMD_READ_ARG_FLASH): + return udi_dfu_atmel_read(ISP_MEM_FLASH,false); + case CAT_CMD(FLIP_V1_CMD_READ, + FLIP_V1_CMD_READ_ARG_EEPROM): + return udi_dfu_atmel_read(ISP_MEM_EEPROM,false); + case CAT_CMD(FLIP_V1_CMD_READ, + FLIP_V1_CMD_READ_ARG_CUSTOM): + return udi_dfu_atmel_read(ISP_MEM_CUSTOM,false); + + // Commands to blank check a memory + case CAT_CMD(FLIP_V1_CMD_READ, + FLIP_V1_CMD_READ_ARG_FLASHCHECK): + return udi_dfu_atmel_read(ISP_MEM_FLASH,true); + } + + switch (CAT_CMD(udi_dfu_flip_msg.msg.cmd_id, + udi_dfu_flip_msg.msg.arg[0])) { + + // Commands to erase chip + case CAT_CMD(FLIP_V1_CMD_WRITE, + FLIP_V1_CMD_WRITE_ARG_ERASE): + return udi_dfu_atmel_chip_erase(); + + // Commands to start application + case CAT_CMD(FLIP_V1_CMD_WRITE, + FLIP_V1_CMD_WRITE_ARG_RST): + udi_dfu_atmel_start_app(); + return true; + + // Commands to read Bootloader version + case CAT_CMD(FLIP_V1_CMD_READ_ID, + FLIP_V1_CMD_READ_ID_ARG_BOOTLOADER): + udi_dfu_atmel_read_id(ISP_MEM_BOOTLOADER, + udi_dfu_flip_msg.msg.arg[1]); + return true; + + // Commands to read Chip identification + case CAT_CMD(FLIP_V1_CMD_READ_ID, + FLIP_V1_CMD_READ_ID_ARG_SIGNATURE): + switch (udi_dfu_flip_msg.msg.arg[1]) { + case FLIP_V1_CMD_READ_ID_SIGNATURE_ARG_MANUF: + udi_dfu_atmel_read_id(ISP_MEM_SIGNATURE,0); + break; + case FLIP_V1_CMD_READ_ID_SIGNATURE_ARG_FAMILY: + udi_dfu_atmel_read_id(ISP_MEM_SIGNATURE,1); + break; + case FLIP_V1_CMD_READ_ID_SIGNATURE_ARG_PRODUCT: + udi_dfu_atmel_read_id(ISP_MEM_SIGNATURE,2); + break; + case FLIP_V1_CMD_READ_ID_SIGNATURE_ARG_REVISION: + udi_dfu_atmel_read_id(ISP_MEM_SIGNATURE,3); + break; + } + return true; + } + + return false; // Unknown command +} + +static bool udi_dfu_atmel_progstart(uint8_t mem) +{ + udi_dfu_atmel_sel_mem(mem); + + if (udi_dfu_atmel_security) { + return udi_dfu_atmel_mem_protected(); + } + + if (!udi_dfu_atmel_mem_getaddr(&udi_dfu_flip_msg.msg.arg[1])) { + return false; // Bad Range + } + + // Init buffer to fill during next DATA phase of request + udd_set_setup_payload( + udi_dfu_atmel_buf_trans, + DFU_ATMEL_BUF_TRANS_SIZE); + // Init callback called after buffer filled + udd_g_ctrlreq.over_under_run = udi_dfu_atmel_mem_write; + return true; +} + +static bool udi_dfu_atmel_read(uint8_t mem, bool b_check) +{ + udi_dfu_atmel_sel_mem( mem ); + + if (!udi_dfu_atmel_mem_getaddr(&udi_dfu_flip_msg.msg.arg[1])) + return false; // Bad Range + + if ((!udi_dfu_atmel_mem_sel.fnct_read) || udi_dfu_atmel_security) { + // Read memory not available OR memory protected + // then accept request but stall next UPLOAD DFU request + udi_dfu_atmel_upload_callback = udi_dfu_atmel_mem_protected; + return true; + } + + if (b_check) { + // It is not a read operation then it is a blanc check, thus do it now + udi_dfu_atmel_mem_check(); + }else{ + udi_dfu_atmel_upload_callback = udi_dfu_atmel_mem_read; + } + return true; +} + + +static bool udi_dfu_atmel_chip_erase(void) +{ + Assert(udi_dfu_flip_msg.msg.arg[1]==FLIP_V1_CMD_WRITE_ARG_ERASE_CHIP); + if (!isp_erase_chip()) { + return false; + } + udi_dfu_atmel_security = false; + return true; +} + + +static void udi_dfu_atmel_start_app(void) +{ + // Start application reset after next DNLOAD request + Assert( (udi_dfu_flip_msg.msg.arg[1] == FLIP_V1_CMD_WRITE_ARG_RST_HW) + || (udi_dfu_flip_msg.msg.arg[1] == FLIP_V1_CMD_WRITE_ARG_RST_SF)); + udi_dfu_atmel_reset = true; +} + +static void udi_dfu_atmel_read_id(uint8_t mem, uint8_t addr) +{ + udi_dfu_atmel_sel_mem( mem ); + udi_dfu_atmel_mem_add = addr; + udi_dfu_atmel_mem_nb_data = 1; + udi_dfu_atmel_upload_callback = udi_dfu_atmel_mem_read; +} + +#ifndef ISP_SMALL_MEMORY_SIZE +static bool udi_dfu_flip_msg_decode_changeaddr(void) +{ + udi_dfu_atmel_mem_add = ((uint32_t)udi_dfu_flip_msg.msg.arg[2])<<16; + return true; +} +#endif + +#endif // Protocol V1 or V2 + + +static void udi_dfu_atmel_sel_mem( uint8_t mem_num ) +{ +#if (FLIP_PROTOCOL_VERSION == FLIP_PROTOCOL_VERSION_2) + if((mem_num!=ISP_MEM_CONFIGURATION) + &&(mem_num!=ISP_MEM_SECURITY) + &&(mem_num!=ISP_MEM_BOOTLOADER) + &&(mem_num!=ISP_MEM_SIGNATURE)) { + udi_dfu_atmel_mem_b_protected = true; + }else{ + udi_dfu_atmel_mem_b_protected = false; + } +#endif + udi_dfu_atmel_mem_sel = *isp_memories.mem[mem_num]; +} + +static bool udi_dfu_atmel_mem_protected(void) +{ + udi_dfu_atmel_status.bStatus = DFU_STATUS_ERRWRITE; + udi_dfu_atmel_status.bState = DFU_STATE_DFUIDLE; + return false; +} + + +static bool udi_dfu_atmel_mem_getaddr(uint8_t * arg) +{ + isp_addr_t addr_end; + + // Get address for request argument + udi_dfu_atmel_mem_add = + (udi_dfu_atmel_mem_add&0xFFFF0000) + ((uint16_t)arg[0]<<8) + (arg[1]<<0); + addr_end = + (udi_dfu_atmel_mem_add&0xFFFF0000) + ((uint16_t)arg[2]<<8) + (arg[3]<<0); + + Assert(addr_end >= udi_dfu_atmel_mem_add); + + // Check address + if (addr_end >= udi_dfu_atmel_mem_sel.size) { + udi_dfu_atmel_status.bStatus = DFU_STATUS_ERRADDRESS; + udi_dfu_atmel_status.bState = DFU_STATE_DFUERROR; + return false; + } + + // Compute the number of data to transfer + udi_dfu_atmel_mem_nb_data = addr_end - udi_dfu_atmel_mem_add + 1; + return true; +} + + +static bool udi_dfu_atmel_mem_read(void) +{ + Assert(udi_dfu_atmel_mem_nb_data <= DFU_ATMEL_BUF_TRANS_SIZE); + udi_dfu_atmel_mem_sel.fnct_read(udi_dfu_atmel_buf_trans, + udi_dfu_atmel_mem_add, udi_dfu_atmel_mem_nb_data); + + // Init buffer to transfer + udd_set_setup_payload( udi_dfu_atmel_buf_trans, udi_dfu_atmel_mem_nb_data); + return true; +} + + +static void udi_dfu_atmel_mem_check(void) +{ + uint8_t *ptr_buf; + uint16_t packet_size; + + // Patch for part with 64KB of flash + // The (uint16_t)udi_dfu_atmel_mem_nb_data is 0 for 64KB + // This avoid to use a uint32_t and increase code. + if (!udi_dfu_atmel_mem_nb_data) { + udi_dfu_atmel_mem_nb_data = (64*1024L)-DFU_ATMEL_BUF_TRANS_SIZE; + packet_size = DFU_ATMEL_BUF_TRANS_SIZE; + goto udi_dfu_atmel_mem_check_patch; + } + + while (udi_dfu_atmel_mem_nb_data) { + // Compute buffer to read + packet_size = min(udi_dfu_atmel_mem_nb_data, + DFU_ATMEL_BUF_TRANS_SIZE); + udi_dfu_atmel_mem_nb_data -= packet_size; + +udi_dfu_atmel_mem_check_patch: + // Fill buffer from memory + udi_dfu_atmel_mem_sel.fnct_read(udi_dfu_atmel_buf_trans, + udi_dfu_atmel_mem_add, packet_size); + + // Check buffer content + ptr_buf = udi_dfu_atmel_buf_trans; + while (packet_size--) { + if (*ptr_buf++ != 0xFF) { + // Error, don't stall request but: + // Update DFU status + udi_dfu_atmel_status.bStatus = DFU_STATUS_ERRCHECK_ERASED; + // Send last address checked in next Upload command + udi_dfu_atmel_upload_callback = udi_dfu_atmel_mem_send_last_add; + return; + } + udi_dfu_atmel_mem_add++; + } + } +} + + +static bool udi_dfu_atmel_mem_send_last_add(void) +{ + // Send last checked address + udi_dfu_atmel_buf_trans[0] = (uint8_t)(udi_dfu_atmel_mem_add>>8); + udi_dfu_atmel_buf_trans[1] = (uint8_t)udi_dfu_atmel_mem_add; + // Init buffer to transfer + udd_set_setup_payload( udi_dfu_atmel_buf_trans, 2); + return true; +} + + +#ifdef UDI_DFU_SMALL_RAM +static bool udi_dfu_atmel_mem_write(void) +{ + uint8_t padding_prefix; + uint16_t nb_trans_max; + + // In order to be in accordance with the memory write entity (page size), + // X non-significant bytes may be added before the first byte to program. + // The X number is calculated to align the beginning of the firmware + // with the memory write entity. + padding_prefix = Get_align(udi_dfu_atmel_mem_add, + USB_DEVICE_EP_CTRL_SIZE); + nb_trans_max = DFU_ATMEL_BUF_TRANS_SIZE-padding_prefix; + + // Program data in memory + udi_dfu_atmel_mem_sel.fnct_write( + udi_dfu_atmel_mem_add, + udi_dfu_atmel_buf_trans + padding_prefix, + min(udi_dfu_atmel_mem_nb_data, nb_trans_max)); + + if (udi_dfu_atmel_mem_nb_data <= nb_trans_max) { + // Init callback called after buffer filled + udd_g_ctrlreq.over_under_run = NULL; + return true; + } + + // Init buffer to fill during next DATA phase of request + udi_dfu_atmel_mem_add += nb_trans_max; + udi_dfu_atmel_mem_nb_data -= nb_trans_max; + udd_set_setup_payload(udi_dfu_atmel_buf_trans, DFU_ATMEL_BUF_TRANS_SIZE); + return true; +} +#else +static bool udi_dfu_atmel_mem_write(void) +{ + uint8_t padding_prefix; + + Assert(udi_dfu_atmel_mem_nb_data <= DFU_ATMEL_BUF_TRANS_SIZE); + Assert(udi_dfu_atmel_mem_nb_data == udd_g_ctrlreq.payload_size); + + // In order to be in accordance with the memory write entity (page size), + // X non-significant bytes may be added before the first byte to program. + // The X number is calculated to align the beginning of the firmware + // with the memory write entity. + padding_prefix = Get_align(udi_dfu_atmel_mem_add, + USB_DEVICE_EP_CTRL_SIZE); + + // Program data in memory + udi_dfu_atmel_mem_sel.fnct_write + (udi_dfu_atmel_mem_add, + udi_dfu_atmel_buf_trans + padding_prefix, + udi_dfu_atmel_mem_nb_data); + + // Init callback called after buffer filled + udd_g_ctrlreq.over_under_run = NULL; + return true; +} +#endif + +//@} diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel.h b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel.h new file mode 100644 index 0000000..764ffbb --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel.h @@ -0,0 +1,126 @@ +/** + * \file + * + * \brief USB Device Atmel Firmware Upgrade (Atmel DFU) interface definitions. + * + * Copyright (c) 2011-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 _UDI_DFU_ATMEL_H_ +#define _UDI_DFU_ATMEL_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_dfu.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup udi_dfu_atmel_group_udc + * @{ + */ +//! Global structure which contains standard UDI API for UDC +extern UDC_DESC_STORAGE udi_api_t udi_api_dfu_atmel; +//@} + +/** + * \ingroup udi_dfu_atmel_group + * \defgroup udi_dfu_atmel_group_desc USB interface descriptors + * + * The following structures provide predefined USB interface descriptors. + * It must be used to define the final USB descriptors. + */ +//@{ + +//! Interface descriptor structure for Atmel DFU +typedef struct { + usb_iface_desc_t iface; +} udi_dfu_atmel_desc_t; + +//! By default no string associated to this interface +#ifndef UDI_DFU_ATMEL_STRING_ID +#define UDI_DFU_ATMEL_STRING_ID 0 +#endif + +//! Content of DFU interface descriptor for Full Speed +#define UDI_DFU_ATMEL_DESC {\ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bInterfaceNumber = UDI_DFU_ATMEL_IFACE_NUMBER,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 0,\ + .iface.bInterfaceClass = CLASS_VENDOR_SPECIFIC,\ + .iface.bInterfaceSubClass = 0,\ + .iface.bInterfaceProtocol = 0,\ + .iface.iInterface = UDI_DFU_ATMEL_STRING_ID,\ + } +//@} + + +/** + * \ingroup udi_group + * \defgroup udi_dfu_atmel_group USB Device Interface (UDI) for Device Firmware Upgrade Atmel specific + * + * The DFU from Atmel is based on DFU specification, + * but does not implement same protocol. + * + * The USB Device Atmel DFU class implement both version: + * - The + * doc7618: USB DFU Bootloader Datasheet describes the + * FLIP USB DFU Protocol version 1 used by Mega devices. + * - The + * AVR32760: AVR32 UC3 USB DFU Bootloader Protocol and the + * + * AVR4023: FLIP USB DFU Protocol describes the + * FLIP USB DFU Protocol version 2 used by UC3 and Xmega devices. + * + * The interface between the DFU Atmel Class and device is done through the + * \ref isp service. + * @{ + */ +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDI_DFU_ATMEL_H_ diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel_conf.h b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel_conf.h new file mode 100644 index 0000000..b18f106 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel_conf.h @@ -0,0 +1,76 @@ +/** + * \file + * + * \brief Default Atmel DFU configuration for a USB Device + * with a single interface Atmel DFU + * + * Copyright (c) 2011-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 _UDI_DFU_ATMEL_CONF_H_ +#define _UDI_DFU_ATMEL_CONF_H_ + +#include "conf_usb.h" +#include "flip_protocol.h" + +/** + * \addtogroup udi_dfu_atmel_group_single_desc + * @{ + */ + +//! Control endpoint size +#if (FLIP_PROTOCOL_VERSION == FLIP_PROTOCOL_VERSION_2) +#define USB_DEVICE_EP_CTRL_SIZE 64 +#else +#define USB_DEVICE_EP_CTRL_SIZE 32 +#endif + +//! Interface number +#define UDI_DFU_ATMEL_IFACE_NUMBER 0 + +/** + * \name UDD Configuration + */ +//@{ +//! 0 endpoints used by DFU interface +#define USB_DEVICE_MAX_EP 0 +//@} + +//@} + +#endif // _UDI_DFU_ATMEL_CONF_H_ diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel_desc.c b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel_desc.c new file mode 100644 index 0000000..a432ccc --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel_desc.c @@ -0,0 +1,146 @@ +/** + * \file + * + * \brief Default descriptors for a USB Device with a single interface DFU Atmel + * + * Copyright (c) 2011-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 "conf_usb.h" +#include "udd.h" +#include "udi.h" +#include "udc_desc.h" +#include "udi_dfu_atmel.h" + +/** + * \defgroup udi_dfu_atmel_group_single_desc USB device descriptors for a single interface + * + * The following structures provide the USB device descriptors required for + * USB Device with a single interface DFU Atmel Class. + * + * It is ready to use and do not require more definition. + * @{ + */ + +//! Only one interface for this device +#define USB_DEVICE_NB_INTERFACE 1 + +//! USB Device Descriptor +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_desc_t udc_device_desc = { + .bLength = sizeof(usb_dev_desc_t), + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = LE16(USB_V2_0), + .bDeviceClass = NO_CLASS, + .bDeviceSubClass = NO_SUBCLASS, + .bDeviceProtocol = NO_PROTOCOL, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .idVendor = LE16(USB_DEVICE_VENDOR_ID), + .idProduct = LE16(USB_DEVICE_PRODUCT_ID), + .bcdDevice = LE16((USB_DEVICE_MAJOR_VERSION << 8) + | USB_DEVICE_MINOR_VERSION), +#ifdef USB_DEVICE_MANUFACTURE_NAME + .iManufacturer = 1, +#else + .iManufacturer = 0, // No manufacture string +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + .iProduct = 2, +#else + .iProduct = 0, // No product string +#endif +#ifdef USB_DEVICE_SERIAL_NAME + .iSerialNumber = 3, +#else + .iSerialNumber = 0, // No serial string +#endif + .bNumConfigurations = 1 +}; + + +//! Structure for USB Device Configuration Descriptor +COMPILER_PACK_SET(1) +typedef struct { + usb_conf_desc_t conf; + udi_dfu_atmel_desc_t udi_dfu_atmel; +} udc_desc_t; +COMPILER_PACK_RESET() + +//! USB Device Configuration Descriptor filled for FS +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE udc_desc_t udc_desc_fs = { + .conf.bLength = sizeof(usb_conf_desc_t), + .conf.bDescriptorType = USB_DT_CONFIGURATION, + .conf.wTotalLength = LE16(sizeof(udc_desc_t)), + .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, + .conf.bConfigurationValue = 1, + .conf.iConfiguration = 0, + .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, + .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), + .udi_dfu_atmel = UDI_DFU_ATMEL_DESC, +}; + +#ifdef USB_DEVICE_HS_SUPPORT +# error DFU Atmel for USB High Speed not implemented +#endif + + +/** + * \name UDC structures which contains all USB Device definitions + */ +//@{ + +//! Associate an UDI for each USB interface +UDC_DESC_STORAGE udi_api_t *udi_apis[USB_DEVICE_NB_INTERFACE] = { + &udi_api_dfu_atmel, +}; + +//! Add UDI with USB Descriptors FS +UDC_DESC_STORAGE udc_config_speed_t udc_config_lsfs[1] = {{ + .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_fs, + .udi_apis = udi_apis, +}}; + +//! Add all information about USB Device in global structure for UDC +UDC_DESC_STORAGE udc_config_t udc_config = { + .confdev_lsfs = &udc_device_desc, + .conf_lsfs = udc_config_lsfs, +}; + +//@} +//@} diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/usb_protocol_dfu.h b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/usb_protocol_dfu.h new file mode 100644 index 0000000..e4d9a54 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/usb_protocol_dfu.h @@ -0,0 +1,192 @@ +/** + * \file + * + * \brief USB Device Firmware Upgrade (DFU) protocol definitions. + * + * Copyright (c) 2011-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 _USB_PROTOCOL_DFU_H_ +#define _USB_PROTOCOL_DFU_H_ + + +/** + * \ingroup usb_protocol_group + * \defgroup usb_dfu_protocol USB Device Firmware Upgrade (DFU) + * protocol definitions + * + * @{ + */ + +/** + * \name Class value + */ +//@{ +#define DFU_CLASS 0xFE +//@} + +/** + * \name SubClass value + */ +//@{ +#define DFU_SUBCLASS 0x01 +//@} + +/** + * \name protocol value + */ +//@{ +#define DFU_PROTOCOL 0x01 +//@} + + +/** + * \brief DFU USB requests (bRequest) + */ +enum usb_reqid_dfu { + USB_REQ_DFU_DETACH = 0x00, + USB_REQ_DFU_DNLOAD = 0x01, + USB_REQ_DFU_UPLOAD = 0x02, + USB_REQ_DFU_GETSTATUS = 0x03, + USB_REQ_DFU_CLRSTATUS = 0x04, + USB_REQ_DFU_GETSTATE = 0x05, + USB_REQ_DFU_ABORT = 0x06, +}; + +/** + * \brief DFU USB descriptor types + */ +enum usb_descriptor_type_dfu { + USB_DT_DFU_FUNCTIONAL = 0x21, +}; + + +//! \name USB DFU Status IDs +//@{ +#define DFU_STATUS_OK 0x00 +#define DFU_STATUS_ERRTARGET 0x01 +#define DFU_STATUS_ERRFILE 0x02 +#define DFU_STATUS_ERRWRITE 0x03 +#define DFU_STATUS_ERRERASE 0x04 +#define DFU_STATUS_ERRCHECK_ERASED 0x05 +#define DFU_STATUS_ERRPROG 0x06 +#define DFU_STATUS_ERRVERIFY 0x07 +#define DFU_STATUS_ERRADDRESS 0x08 +#define DFU_STATUS_ERRNOTDONE 0x09 +#define DFU_STATUS_ERRFIRMWARE 0x0A +#define DFU_STATUS_ERRVENDOR 0x0B +#define DFU_STATUS_ERRUSBR 0x0C +#define DFU_STATUS_ERRPOR 0x0D +#define DFU_STATUS_ERRUNKNOWN 0x0E +#define DFU_STATUS_ERRSTALLEDPK 0x0F +//@} + +//! \name USB DFU State IDs +//@{ +#define DFU_STATE_APPIDLE 0x00 +#define DFU_STATE_APPDETACH 0x01 +#define DFU_STATE_DFUIDLE 0x02 +#define DFU_STATE_DFUDNLOAD_SUNC 0x03 +#define DFU_STATE_DFUDNBUSY 0x04 +#define DFU_STATE_DFUDNLOAD_IDLE 0x05 +#define DFU_STATE_DFUMANIFEST_SYNC 0x06 +#define DFU_STATE_DFUMANIFEST 0x07 +#define DFU_STATE_DFUMANIFEST_WAIT_RESET 0x08 +#define DFU_STATE_DFUUPLOAD_IDLE 0x09 +#define DFU_STATE_DFUERROR 0x0A +//@} + + +/** + * \brief DFU Functional attributes + */ +enum usb_dfu_functional_attributes { + USB_DFU_FONC_CAN_DNLOAD = (1 << 0), + USB_DFU_FONC_CAN_UPLOAD = (1 << 1), + USB_DFU_FONC_MANIFEST_TOLERANT = (1 << 2), + USB_DFU_FONC_WILL_DETACH = (1 << 3), +}; + +//! Value for fields bcdDFU(Version) +#define USB_DFU_V1_0 0x0100 //!< USB DFU Specification version 1.0 + +COMPILER_PACK_SET(1) + +/** + * \brief DFU Descriptor + */ +typedef struct { + uint8_t bLength; //!< Size of this descriptor in bytes + uint8_t bDescriptorType;//!< DFU functional descriptor type + uint8_t bmAttributes; //!< DFU attributes + le16_t wDetachTimeOut; //!< Detach timeout + le16_t wTransferSize; //!< Maximum number of bytes that the device can accept + le16_t bcdDFUVersion; //!< DFU specification release +} usb_dfu_functional_desc_t; + +/** + * \brief DFU Status + */ +typedef struct { + uint8_t bStatus; + uint8_t bwPollTimeout[3]; + uint8_t bState; + uint8_t iString; +} dfu_status_t; + +/** + * \brief DFU File Suffix + */ +typedef struct { + le32_t dwCRC; //!< Number The CRC of the entire file, excluding dwCRC. + uint8_t bLength; //!< The length of this DFU suffix including dwCRC. + uint8_t ucDfuSignature[3]; //!< The unique DFU signature field. + le16_t bcdDFU; //!< DFU specification number. + le16_t idVendor; //!< The vendor ID associated with this file. + //!< Either FFFFh or must match device's vendor ID. + le16_t idProduct; //!< The product ID associated with this file. + //!< Either FFFFh or must match device's product ID. + le16_t bcdDevice; //!< The release number of the device + //!< Either FFFFh or a BCD firmware release or version number. +} dfu_file_suffix_t; + +COMPILER_PACK_RESET() + +//@} + +#endif // _USB_PROTOCOL_DFU_H_ diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/udc/udc.h b/Firmware/Atmel DFU Bootloader/common/services/usb/udc/udc.h new file mode 100644 index 0000000..be60ce9 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/udc/udc.h @@ -0,0 +1,726 @@ +/** + * \file + * + * \brief Interface of the USB Device Controller (UDC) + * + * 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 _UDC_H_ +#define _UDC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udc_desc.h" +#include "udd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udc_group USB Device Controller (UDC) + * + * The UDC provides a high-level abstraction of the usb device. + * You can use these functions to control the main device state + * (start/attach/wakeup). + * + * \section USB_DEVICE_CONF USB Device Custom configuration + * The following USB Device configuration must be included in the conf_usb.h + * file of the application. + * + * USB_DEVICE_VENDOR_ID (Word)
+ * Vendor ID provided by USB org (ATMEL 0x03EB). + * + * USB_DEVICE_PRODUCT_ID (Word)
+ * Product ID (Referenced in usb_atmel.h). + * + * USB_DEVICE_MAJOR_VERSION (Byte)
+ * Major version of the device + * + * USB_DEVICE_MINOR_VERSION (Byte)
+ * Minor version of the device + * + * USB_DEVICE_MANUFACTURE_NAME (string)
+ * ASCII name for the manufacture + * + * USB_DEVICE_PRODUCT_NAME (string)
+ * ASCII name for the product + * + * USB_DEVICE_SERIAL_NAME (string)
+ * ASCII name to enable and set a serial number + * + * USB_DEVICE_POWER (Numeric)
+ * (unit mA) Maximum device power + * + * USB_DEVICE_ATTR (Byte)
+ * USB attributes available: + * - USB_CONFIG_ATTR_SELF_POWERED + * - USB_CONFIG_ATTR_REMOTE_WAKEUP + * Note: if remote wake enabled then defines remotewakeup callbacks, + * see Table 5-2. External API from UDC - Callback + * + * USB_DEVICE_LOW_SPEED (Only defined)
+ * Force the USB Device to run in low speed + * + * USB_DEVICE_HS_SUPPORT (Only defined)
+ * Authorize the USB Device to run in high speed + * + * USB_DEVICE_MAX_EP (Byte)
+ * Define the maximum endpoint number used by the USB Device.
+ * This one is already defined in UDI default configuration. + * Ex: + * - When endpoint control 0x00, endpoint 0x01 and + * endpoint 0x82 is used then USB_DEVICE_MAX_EP=2 + * - When only endpoint control 0x00 is used then USB_DEVICE_MAX_EP=0 + * - When endpoint 0x01 and endpoint 0x81 is used then USB_DEVICE_MAX_EP=1
+ * (configuration not possible on USBB interface) + * @{ + */ + +/** + * \brief Authorizes the VBUS event + * + * \return true, if the VBUS monitoring is possible. + * + * \section udc_vbus_monitoring VBus monitoring used cases + * + * The VBus monitoring is used only for USB SELF Power application. + * + * - No custom implementation \n + * // Authorize VBUS monitoring \n + * if (!udc_include_vbus_monitoring()) { \n + * // VBUS monitoring is not available on this product \n + * // thereby VBUS has to be considered as present \n + * // Attach USB Device \n + * udc_attach(); \n + * } \n + * + * - Add custom VBUS monitoring \n + * // Authorize VBUS monitoring \n + * if (!udc_include_vbus_monitoring()) { \n + * // Implement custom VBUS monitoring via GPIO or other \n + * } \n + * Event_VBUS_present() // VBUS interrupt or GPIO interrupt or other \n + * { \n + * // Attach USB Device \n + * udc_attach(); \n + * } \n + * + * - Case of battery charging \n + * Event VBUS present() // VBUS interrupt or GPIO interrupt or .. \n + * { \n + * // Authorize battery charging, but wait key press to start USB. \n + * } \n + * Event Key press() \n + * { \n + * // Stop batteries charging \n + * // Start USB \n + * udc_attach(); \n + * } \n + */ +static inline bool udc_include_vbus_monitoring(void) +{ + return udd_include_vbus_monitoring(); +} + +/*! \brief Start the USB Device stack + */ +void udc_start(void); + +/*! \brief Stop the USB Device stack + */ +void udc_stop(void); + +/** + * \brief Attach device to the bus when possible + * + * \warning If a VBus control is included in driver, + * then it will attach device when an acceptable Vbus + * level from the host is detected. + */ +static inline void udc_attach(void) +{ + udd_attach(); +} + + +/** + * \brief Detaches the device from the bus + * + * The driver must remove pull-up on USB line D- or D+. + */ +static inline void udc_detach(void) +{ + udd_detach(); +} + + +/*! \brief The USB driver sends a resume signal called \e "Upstream Resume" + * This is authorized only when the remote wakeup feature is enabled by host. + */ +static inline void udc_remotewakeup(void) +{ + udd_send_remotewakeup(); +} + + +/** + * \brief Returns a pointer on the current interface descriptor + * + * \return pointer on the current interface descriptor. + */ +usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void); + +//@} + +/** + * \ingroup usb_group + * \defgroup usb_device_group USB Stack Device + * + * This module includes USB Stack Device implementation. + * The stack is divided in three parts: + * - USB Device Controller (UDC) provides USB chapter 9 compliance + * - USB Device Interface (UDI) provides USB Class compliance + * - USB Device Driver (UDD) provides USB Driver for each Atmel MCU + + * Many USB Device applications can be implemented on Atmel MCU. + * Atmel provides many application notes for different applications: + * - AVR4900, provides general information about Device Stack + * - AVR4901, explains how to create a new class + * - AVR4902, explains how to create a composite device + * - AVR49xx, all device classes provided in ASF have an application note + * + * A basic USB knowledge is required to understand the USB Device + * Class application notes (HID,MS,CDC,PHDC,...). + * Then, to create an USB device with + * only one class provided by ASF, refer directly to the application note + * corresponding to this USB class. The USB Device application note for + * New Class and Composite is dedicated to advanced USB users. + * + * @{ + */ + +//! @} + +#ifdef __cplusplus +} +#endif + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_prereq USB Device Controller (UDC) - Prerequisites + * Common prerequisites for all USB devices. + * + * This module is based on USB device stack full interrupt driven, and supporting + * \ref sleepmgr_group sleepmgr and \ref clk_group clock services. + * + * The following procedure must be executed to setup the project correctly: + * - Specify the clock configuration: + * - XMEGA USB devices need 48MHz clock input.\n + * XMEGA USB devices need CPU frequency higher than 12MHz.\n + * You can use either an internal RC48MHz auto calibrated by Start of Frames + * or an external OSC. + * - UC3 and SAM devices without USB high speed support need 48MHz clock input.\n + * You must use a PLL and an external OSC. + * - UC3 and SAM devices with USB high speed support need 12MHz clock input.\n + * You must use an external OSC. + * - UC3 devices with USBC hardware need CPU frequency higher than 25MHz. + * - In conf_board.h, the define CONF_BOARD_USB_PORT must be added to enable USB lines. + * (Not mandatory for all boards) + * - Enable interrupts + * - Initialize the clock service + * + * The usage of \ref sleepmgr_group sleepmgr service is optional, but recommended to reduce power + * consumption: + * - Initialize the sleep manager service + * - Activate sleep mode when the application is in IDLE state + * + * \subpage udc_conf_clock. + * + * Add to the initialization code: + * \code + * sysclk_init(); + * irq_initialize_vectors(); + * cpu_irq_enable(); + * board_init(); + * sleepmgr_init(); // Optional + * \endcode + * Add to the main IDLE loop: + * \code + * sleepmgr_enter_sleep(); // Optional + * \endcode + * + */ + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_code USB Device Controller (UDC) - Example code + * Common example code for all USB devices. + * + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_VENDOR_ID 0x03EB + * #define USB_DEVICE_PRODUCT_ID 0xXXXX + * #define USB_DEVICE_MAJOR_VERSION 1 + * #define USB_DEVICE_MINOR_VERSION 0 + * #define USB_DEVICE_POWER 100 + * #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED + * + * #define UDC_VBUS_EVENT(b_vbus_high) my_vbus_action(b_vbus_high) + * extern void my_vbus_action(bool b_high); + * \endcode + * + * Add to application C-file: + * \code + * void usb_init(void) + * { + * udc_start(); + * } + * + * void my_vbus_action(bool b_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } + * \endcode + */ + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_flow USB Device Controller (UDC) - Workflow + * Common workflow for all USB devices. + * + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the main USB device configuration: + * - \code // Vendor ID provided by USB org (ATMEL 0x03EB) + * #define USB_DEVICE_VENDOR_ID 0x03EB // Type Word + * // Product ID (Atmel PID referenced in usb_atmel.h) + * #define USB_DEVICE_PRODUCT_ID 0xXXXX // Type Word + * // Major version of the device + * #define USB_DEVICE_MAJOR_VERSION 1 // Type Byte + * // Minor version of the device + * #define USB_DEVICE_MINOR_VERSION 0 // Type Byte + * // Maximum device power (mA) + * #define USB_DEVICE_POWER 100 // Type 9-bits + * // USB attributes to enable features + * #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED // Flags \endcode + * - \code #define UDC_VBUS_EVENT(b_vbus_high) my_vbus_action(b_vbus_high) + * extern void my_vbus_action(bool b_high); \endcode + * \note This callback is called when USB Device cable is plugged or unplugged. + * -# Call the USB device stack start function to enable stack: + * - \code udc_start(); \endcode + * \note In case of USB dual roles (Device and Host) managed through USB OTG connector + * (USB ID pin), the call of udc_start() must be removed and replaced by uhc_start(). + * SeRefer to "AVR4950 section 6.1 Dual roles" for further information about dual roles. + * -# Connect or disconnect USB device according to Vbus state: + * - \code void my_vbus_action(bool b_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } \endcode + */ + +/** + * \page udc_conf_clock conf_clock.h examples with USB support + * + * Content of XMEGA conf_clock.h: + * \code + * // Configuration based on internal RC: + * // USB clock need of 48Mhz + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * // CPU clock need of clock > 12MHz to run with USB (Here 24MHz) + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC32MHZ + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_2 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 + * \endcode + * + * Content of conf_clock.h for AT32UC3A0, AT32UC3A1, AT32UC3B devices (USBB): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 + * #define CONFIG_PLL1_MUL 8 + * #define CONFIG_PLL1_DIV 2 + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * \endcode + * + * Content of conf_clock.h for AT32UC3A3, AT32UC3A4 devices (USBB with high speed support): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_OSC0 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * \endcode + * + * Content of conf_clock.h for AT32UC3C, ATUCXXD, ATUCXXL3U, ATUCXXL4U devices (USBC): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 + * #define CONFIG_PLL1_MUL 8 + * #define CONFIG_PLL1_DIV 2 + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * // CPU clock need of clock > 25MHz to run with USBC + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL1 + * \endcode + * + * Content of conf_clock.h for SAM3S, SAM3SD, SAM4S devices (UPD: USB Peripheral Device): + * \code + * // PLL1 (B) Options (Fpll = (Fclk * PLL_mul) / PLL_div) + * #define CONFIG_PLL1_SOURCE PLL_SRC_MAINCK_XTAL + * #define CONFIG_PLL1_MUL 16 + * #define CONFIG_PLL1_DIV 2 + * // USB Clock Source Options (Fusb = FpllX / USB_div) + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 2 + * \endcode + * + * Content of conf_clock.h for SAM3U device (UPDHS: USB Peripheral Device High Speed): + * \code + * // USB Clock Source fixed at UPLL. + * \endcode + * + * Content of conf_clock.h for SAM3X, SAM3A devices (UOTGHS: USB OTG High Speed): + * \code + * // USB Clock Source fixed at UPLL. + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_UPLL + * #define CONFIG_USBCLK_DIV 1 + * \endcode + */ + +/** + * \page udc_use_case_1 Change USB speed + * + * In this use case, the USB device is used with different USB speeds. + * + * \section udc_use_case_1_setup Setup steps + * + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_1_usage Usage steps + * + * \subsection udc_use_case_1_usage_code Example code + * Content of conf_usb.h: + * \code + * #if // Low speed + * #define USB_DEVICE_LOW_SPEED + * // #define USB_DEVICE_HS_SUPPORT + * + * #elif // Full speed + * // #define USB_DEVICE_LOW_SPEED + * // #define USB_DEVICE_HS_SUPPORT + * + * #elif // High speed + * // #define USB_DEVICE_LOW_SPEED + * #define USB_DEVICE_HS_SUPPORT + * + * #endif + * \endcode + * + * \subsection udc_use_case_1_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB device low speed (1.5Mbit/s): + * - \code #define USB_DEVICE_LOW_SPEED + * //#define USB_DEVICE_HS_SUPPORT \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB device full speed (12Mbit/s): + * - \code //#define USB_DEVICE_LOW_SPEED + * //#define USB_DEVICE_HS_SUPPORT \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB device high speed (480Mbit/s): + * - \code //#define USB_DEVICE_LOW_SPEED + * #define USB_DEVICE_HS_SUPPORT \endcode + */ + +/** + * \page udc_use_case_2 Use USB strings + * + * In this use case, the usual USB strings is added in the USB device. + * + * \section udc_use_case_2_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_2_usage Usage steps + * + * \subsection udc_use_case_2_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" + * #define USB_DEVICE_PRODUCT_NAME "Product name" + * #define USB_DEVICE_SERIAL_NAME "12...EF" + * \endcode + * + * \subsection udc_use_case_2_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable different USB strings: + * - \code // Static ASCII name for the manufacture + * #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" \endcode + * - \code // Static ASCII name for the product + * #define USB_DEVICE_PRODUCT_NAME "Product name" \endcode + * - \code // Static ASCII name to enable and set a serial number + * #define USB_DEVICE_SERIAL_NAME "12...EF" \endcode + */ + +/** + * \page udc_use_case_3 Use USB remote wakeup feature + * + * In this use case, the USB remote wakeup feature is enabled. + * + * \section udc_use_case_3_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_3_usage Usage steps + * + * \subsection udc_use_case_3_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR \ + * (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) + * #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() + * extern void my_callback_remotewakeup_enable(void); + * #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() + * extern void my_callback_remotewakeup_disable(void); + * \endcode + * + * Add to application C-file: + * \code + * void my_callback_remotewakeup_enable(void) + * { + * // Enable application wakeup events (e.g. enable GPIO interrupt) + * } + * void my_callback_remotewakeup_disable(void) + * { + * // Disable application wakeup events (e.g. disable GPIO interrupt) + * } + * + * void my_interrupt_event(void) + * { + * udc_remotewakeup(); + * } + * \endcode + * + * \subsection udc_use_case_3_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable remote wakeup feature: + * - \code // Authorizes the remote wakeup feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) \endcode + * - \code // Define callback called when the host enables the remotewakeup feature + * #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() + * extern void my_callback_remotewakeup_enable(void); \endcode + * - \code // Define callback called when the host disables the remotewakeup feature + * #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() + * extern void my_callback_remotewakeup_disable(void); \endcode + * -# Send a remote wakeup (USB upstream): + * - \code udc_remotewakeup(); \endcode + */ + +/** + * \page udc_use_case_4 Self power application recommendations + * + * In this use case, the USB device self power feature is enabled. + * To be USB compliance, the SELF power application requires to manage Vbus event, + * because the USB device D+/- pull-up must be disabled if the USB cable is unplugged + * (unplug = Vbus not present, pull-up disable = \ref udd_detach()). + * This use case requires that Atmel products includes a Vbus monitoring, else + * see \ref udc_include_vbus_monitoring function documentation for more example. + * + * \section udc_use_case_4_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_4_usage Usage steps + * + * \subsection udc_use_case_4_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_SELF_POWERED) + * #define UDC_VBUS_EVENT(b_vbus_high) user_callback_vbus_action(b_vbus_high) + * extern void user_callback_vbus_action(bool b_vbus_high); + * \endcode + * + * Add to application C-file: + * \code + * void user_callback_vbus_action(bool b_vbus_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } + * \endcode + * + * \subsection udc_use_case_4_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for USB device SELF power device: + * - \code // Authorizes the SELF power feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_SELF_POWERED) \endcode + * - \code // Define callback called when the Vbus level change + * #define UDC_VBUS_EVENT(b_vbus_high) user_callback_vbus_action(b_vbus_high) + * extern void user_callback_vbus_action(bool b_vbus_high); \endcode + * -# Signal the USB device presence on USB line + * - \code udc_attach(); \endcode + * -# Remove signal of the USB device presence on USB line + * - \code udc_detach(); \endcode + */ + +/** + * \page udc_use_case_5 Bus power application recommendations + * + * In this use case, the USB device BUS power feature is enabled. + * This feature requires a correct power consumption management. + * + * \section udc_use_case_5_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_5_usage Usage steps + * + * \subsection udc_use_case_5_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) + * #define UDC_SUSPEND_EVENT() user_callback_suspend_action() + * extern void user_callback_suspend_action(void) + * #define UDC_RESUME_EVENT() user_callback_resume_action() + * extern void user_callback_resume_action(void) + * \endcode + * + * Add to application C-file: + * \code + * void user_callback_suspend_action(void) + * { + * // Disable hardware component to reduce power consumption + * } + * void user_callback_resume_action(void) + * { + * // Re-enable hardware component + * } + * \endcode + * + * \subsection udc_use_case_5_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters: + * - \code // Authorizes the BUS power feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) \endcode + * - \code // Define callback called when the host suspend the USB line + * #define UDC_SUSPEND_EVENT() user_callback_suspend_action() + * extern void user_callback_suspend_action(void); \endcode + * - \code // Define callback called when the host or device resume the USB line + * #define UDC_RESUME_EVENT() user_callback_resume_action() + * extern void user_callback_resume_action(void); \endcode + * -# Reduce power consumption in suspend mode (max. 2.5mA on Vbus): + * - \code void user_callback_suspend_action(void) + * { + * turn_off_components(); + * } \endcode + */ + +/** + * \page udc_use_case_6 USB dynamic serial number + * + * In this use case, the USB serial strings is dynamic. + * For a static serial string refer to \ref udc_use_case_2. + * + * \section udc_use_case_6_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_6_usage Usage steps + * + * \subsection udc_use_case_6_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_SERIAL_NAME + * #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number + * #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 + * extern uint8_t serial_number[]; + * \endcode + * + * Add to application C-file: + * \code + * uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; + * + * void init_build_usb_serial_number(void) + * { + * serial_number[0] = 'A'; + * serial_number[1] = 'B'; + * ... + * serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; + * } \endcode + * + * \subsection udc_use_case_6_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable a USB serial number strings dynamically: + * - \code #define USB_DEVICE_SERIAL_NAME // Define this empty + * #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number // Give serial array pointer + * #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 // Give size of serial array + * extern uint8_t serial_number[]; // Declare external serial array \endcode + * -# Before start USB stack, initialize the serial array + * - \code + * uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; + * + * void init_build_usb_serial_number(void) + * { + * serial_number[0] = 'A'; + * serial_number[1] = 'B'; + * ... + * serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; + * } \endcode + */ + + + +#endif // _UDC_H_ diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/udc/udc_desc.h b/Firmware/Atmel DFU Bootloader/common/services/usb/udc/udc_desc.h new file mode 100644 index 0000000..20378f0 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/udc/udc_desc.h @@ -0,0 +1,131 @@ +/** + * \file + * + * \brief Common API for USB Device Interface + * + * 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 _UDC_DESC_H_ +#define _UDC_DESC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup udc_group + * \defgroup udc_desc_group USB Device Descriptor + * + * @{ + */ + +/** + * \brief Defines the memory's location of USB descriptors + * + * By default the Descriptor is stored in RAM + * (UDC_DESC_STORAGE is defined empty). + * + * If you have need to free RAM space, + * it is possible to put descriptor in flash in following case: + * - USB driver authorize flash transfer (USBB on UC3 and USB on Mega) + * - USB Device is not high speed (UDC no need to change USB descriptors) + * + * For UC3 application used "const". + * + * For Mega application used "code". + */ +#define UDC_DESC_STORAGE + // Descriptor storage in internal RAM +#if (defined UDC_DATA_USE_HRAM_SUPPORT) +# if defined(__GNUC__) +# define UDC_DATA(x) COMPILER_WORD_ALIGNED __attribute__((__section__(".data_hram0"))) +# define UDC_BSS(x) COMPILER_ALIGNED(x) __attribute__((__section__(".bss_hram0"))) +# elif defined(__ICCAVR32__) +# define UDC_DATA(x) COMPILER_ALIGNED(x) __data32 +# define UDC_BSS(x) COMPILER_ALIGNED(x) __data32 +# endif +#else +# define UDC_DATA(x) COMPILER_ALIGNED(x) +# define UDC_BSS(x) COMPILER_ALIGNED(x) +#endif + + + +/** + * \brief Configuration descriptor and UDI link for one USB speed + */ +typedef struct { + //! USB configuration descriptor + usb_conf_desc_t UDC_DESC_STORAGE *desc; + //! Array of UDI API pointer + udi_api_t UDC_DESC_STORAGE *UDC_DESC_STORAGE * udi_apis; +} udc_config_speed_t; + + +/** + * \brief All information about the USB Device + */ +typedef struct { + //! USB device descriptor for low or full speed + usb_dev_desc_t UDC_DESC_STORAGE *confdev_lsfs; + //! USB configuration descriptor and UDI API pointers for low or full speed + udc_config_speed_t UDC_DESC_STORAGE *conf_lsfs; +#ifdef USB_DEVICE_HS_SUPPORT + //! USB device descriptor for high speed + usb_dev_desc_t UDC_DESC_STORAGE *confdev_hs; + //! USB device qualifier, only use in high speed mode + usb_dev_qual_desc_t UDC_DESC_STORAGE *qualifier; + //! USB configuration descriptor and UDI API pointers for high speed + udc_config_speed_t UDC_DESC_STORAGE *conf_hs; +#endif +} udc_config_t; + +//! Global variables of USB Device Descriptor and UDI links +extern UDC_DESC_STORAGE udc_config_t udc_config; + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDC_DESC_H_ diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/udc/udc_dfu_small.c b/Firmware/Atmel DFU Bootloader/common/services/usb/udc/udc_dfu_small.c new file mode 100644 index 0000000..7dbe5d2 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/udc/udc_dfu_small.c @@ -0,0 +1,488 @@ +/** + * \file + * + * \brief USB Device Controller (UDC) optimized for DFU FLIP Device + * + * Copyright (c) 2011 - 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 "conf_usb.h" +#include "usb_protocol.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi.h" +#include "udc.h" +#include "udi_dfu_atmel.h" + +extern bool udi_dfu_atmel_enable(void); +extern void udi_dfu_atmel_disable(void); +extern bool udi_dfu_atmel_setup(void); + +/** + * \addtogroup udc_group + * @{ + */ + +//! \name Internal variables to manage the USB device +//! @{ + +//! Device status state (see enum usb_device_status in usb_protocol.h) +static le16_t udc_device_status; +//! Device Configuration number selected by the USB host +static uint8_t udc_num_configuration = 0; +//! Pointer on the selected speed device configuration +//static udc_config_speed_t UDC_DESC_STORAGE *udc_ptr_conf; +//! Pointer on interface descriptor used by SETUP request. +//static usb_iface_desc_t UDC_DESC_STORAGE *udc_ptr_iface; +extern UDC_DESC_STORAGE usb_dev_desc_t udc_device_desc; +//! Structure for USB Device Configuration Descriptor +COMPILER_PACK_SET(1) +typedef struct { + usb_conf_desc_t conf; + udi_dfu_atmel_desc_t udi_dfu_atmel; +} udc_desc_t; +COMPILER_PACK_RESET() +extern UDC_DESC_STORAGE udc_desc_t udc_desc_fs; + +//! @} + + +//! \name Internal structure to store the USB device main strings +//! @{ + +/** + * \brief USB device manufacture name storage + * String is allocated only if USB_DEVICE_MANUFACTURE_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_MANUFACTURE_NAME +static uint8_t udc_string_manufacturer_name[] = USB_DEVICE_MANUFACTURE_NAME; +#define USB_DEVICE_MANUFACTURE_NAME_SIZE (sizeof(udc_string_manufacturer_name)-1) +#else +#define USB_DEVICE_MANUFACTURE_NAME_SIZE 0 +#endif + + +/** + * \brief USB device product name storage + * String is allocated only if USB_DEVICE_PRODUCT_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_PRODUCT_NAME +static uint8_t udc_string_product_name[] = USB_DEVICE_PRODUCT_NAME; +#define USB_DEVICE_PRODUCT_NAME_SIZE (sizeof(udc_string_product_name)-1) +#else +#define USB_DEVICE_PRODUCT_NAME_SIZE 0 +#endif + +/** + * \brief USB device serial number storage + * String is allocated only if USB_DEVICE_SERIAL_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_SERIAL_NAME +static uint8_t udc_string_serial_name[] = USB_DEVICE_SERIAL_NAME; +#define USB_DEVICE_SERIAL_NAME_SIZE (sizeof(udc_string_serial_name)-1) +#else +#define USB_DEVICE_SERIAL_NAME_SIZE 0 +#endif + +/** + * \brief USB device string descriptor + * Structure used to transfer ASCII strings to USB String descriptor structure. + */ +struct udc_string_desc_t { + usb_str_desc_t header; + le16_t string[Max(Max(USB_DEVICE_MANUFACTURE_NAME_SIZE, \ + USB_DEVICE_PRODUCT_NAME_SIZE), USB_DEVICE_SERIAL_NAME_SIZE)]; +}; +static UDC_DESC_STORAGE struct udc_string_desc_t udc_string_desc = { + .header.bDescriptorType = USB_DT_STRING +}; + +/** + * \brief Language ID of USB device (US ID by default) + */ +static UDC_DESC_STORAGE usb_str_lgid_desc_t udc_string_desc_languageid = { + .desc.bLength = sizeof(usb_str_lgid_desc_t), + .desc.bDescriptorType = USB_DT_STRING, + .string = {LE16(USB_LANGID_EN_US)} +}; + +//! @} + + + + +/** + * \brief Disables an usb device interface (UDI) + * This routine call the UDI corresponding to interface number + * + * \param iface_num Interface number to disable + * + * \return 1 if it is done or 0 if interface is not found + */ +static bool udc_iface_disable(void) +{ + // Disable interface + udi_dfu_atmel_disable(); + return true; +} + + +/** + * \brief Enables an usb device interface (UDI) + * This routine calls the UDI corresponding + * to the interface and setting number. + * + * \param iface_num Interface number to enable + * \param setting_num Setting number to enable + * + * \return 1 if it is done or 0 if interface is not found + */ +static bool udc_iface_enable(void) +{ + // Enable the interface + return udi_dfu_atmel_enable(); +} + +/*! \brief Start the USB Device stack + */ +void udc_start(void) +{ + udd_enable(); +} + +/*! \brief Stop the USB Device stack + */ +void udc_stop(void) +{ + udd_disable(); +} + +/** + * \brief Reset the current configuration of the USB device, + * This routines can be called by UDD when a RESET on the USB line occurs. + */ +void udc_reset(void) +{ + if (udc_num_configuration) { + udc_iface_disable(); + } + udc_num_configuration = 0; + udc_device_status = +#if (USB_DEVICE_ATTR & USB_CONFIG_ATTR_SELF_POWERED) + CPU_TO_LE16(USB_DEV_STATUS_SELF_POWERED); +#else + CPU_TO_LE16(USB_DEV_STATUS_BUS_POWERED); +#endif +} + +void udc_sof_notify(void) +{ +} + +/** + * \brief Standard device request to get device status + * + * \return true if success + */ +static bool udc_req_std_dev_get_status(void) +{ + udd_set_setup_payload( + (uint8_t *) &udc_device_status, + sizeof(udc_device_status)); + return true; +} + + +/** + * \brief Change the address of device + * Callback called at the end of request set address + */ +static void udc_valid_address(void) +{ + udd_set_address(udd_g_ctrlreq.req.wValue & 0x7F); +} + + +/** + * \brief Standard device request to set device address + * + * \return true if success + */ +static bool udc_req_std_dev_set_address(void) +{ + // The address must be changed at the end of setup request after the handshake + // then we use a callback to change address + udd_g_ctrlreq.callback = udc_valid_address; + return true; +} + + +/** + * \brief Standard device request to get device string descriptor + * + * \return true if success + */ +static bool udc_req_std_dev_get_str_desc(void) +{ + uint8_t i; + uint8_t *str; + uint8_t str_lgt=0; + + // Link payload pointer to the string corresponding at request + switch (udd_g_ctrlreq.req.wValue & 0xff) { + case 0: + udd_set_setup_payload( + (uint8_t *) & udc_string_desc_languageid, + sizeof(udc_string_desc_languageid)); + break; + +#ifdef USB_DEVICE_MANUFACTURE_NAME + case 1: + str_lgt = USB_DEVICE_MANUFACTURE_NAME_SIZE; + str = udc_string_manufacturer_name; + break; +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + case 2: + str_lgt = USB_DEVICE_PRODUCT_NAME_SIZE; + str = udc_string_product_name; + break; +#endif +#ifdef USB_DEVICE_SERIAL_NAME + case 3: + str_lgt = USB_DEVICE_SERIAL_NAME_SIZE; + str = udc_string_serial_name; + break; +#endif + default: + return false; + } + + if (str_lgt != 0) { + for(i = 0; i < str_lgt; i++) { + udc_string_desc.string[i] = cpu_to_le16((le16_t)str[i]); + } + + udc_string_desc.header.bLength = 2 + (str_lgt) * 2; + udd_set_setup_payload( + (uint8_t *) &udc_string_desc, + udc_string_desc.header.bLength); + } + return true; +} + + +/** + * \brief Standard device request to get descriptors about USB device + * + * \return true if success + */ +static bool udc_req_std_dev_get_descriptor(void) +{ + // Check descriptor ID + switch ((uint8_t) (udd_g_ctrlreq.req.wValue >> 8)) { + case USB_DT_DEVICE: + // Device descriptor requested + udd_set_setup_payload( + (uint8_t*)&udc_device_desc, + udc_device_desc.bLength); + break; + + case USB_DT_CONFIGURATION: + // Configuration descriptor requested + // FS descriptor + udd_set_setup_payload( + (uint8_t*)&udc_desc_fs, + le16_to_cpu(udc_desc_fs.conf.wTotalLength)); + break; + + case USB_DT_STRING: + // String descriptor requested + if (!udc_req_std_dev_get_str_desc()) { + return false; + } + break; + + default: + // Unknown descriptor requested + return false; + } + // if the descriptor is larger than length requested, then reduce it + if (udd_g_ctrlreq.req.wLength < udd_g_ctrlreq.payload_size) { + udd_g_ctrlreq.payload_size = udd_g_ctrlreq.req.wLength; + } + return true; +} + + +/** + * \brief Standard device request to get configuration number + * + * \return true if success + */ +static bool udc_req_std_dev_get_configuration(void) +{ + udd_set_setup_payload( + &udc_num_configuration, 1); + return true; +} + + +/** + * \brief Standard device request to enable a configuration + * + * \return true if success + */ +static bool udc_req_std_dev_set_configuration(void) +{ + // Reset current configuration + udc_reset(); + + // Enable new configuration + udc_num_configuration = udd_g_ctrlreq.req.wValue & 0xFF; + if (udc_num_configuration == 0) { + return true; // Default empty configuration requested + } + // Pointer of the configuration descriptor always good + // Enable all interfaces of the selected configuration + if (!udc_iface_enable()) { + return false; + } + return true; +} + + +/** + * \brief Main routine to manage the standard USB SETUP request + * + * \return true if the request is supported + */ +static bool udc_reqstd(void) +{ + if (USB_REQ_RECIP_DEVICE != Udd_setup_recipient()) { + return false; + } + + if (Udd_setup_is_in()) { + // Standard Get Device request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_STATUS: + return udc_req_std_dev_get_status(); + case USB_REQ_GET_DESCRIPTOR: + return udc_req_std_dev_get_descriptor(); + case USB_REQ_GET_CONFIGURATION: + return udc_req_std_dev_get_configuration(); + } + } else { + // Standard Set Device request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_SET_ADDRESS: + return udc_req_std_dev_set_address(); + case USB_REQ_SET_CONFIGURATION: + return udc_req_std_dev_set_configuration(); + } + } + return false; +} + + +/** + * \brief Send the SETUP interface request to UDI + * + * \return true if the request is supported + */ +static bool udc_req_iface(void) +{ + // Send the SETUP request to the UDI corresponding to the interface number + return udi_dfu_atmel_setup(); +} + + +/** + * \brief Main routine to manage the USB SETUP request. + * + * This function parses a USB SETUP request and submits an appropriate + * response back to the host or, in the case of SETUP OUT requests + * with data, sets up a buffer for receiving the data payload. + * + * The main standard requests defined by the USB 2.0 standard are handled + * internally. The interface requests are sent to UDI, and the specific request + * sent to a specific application callback. + * + * \return true if the request is supported, else the request is stalled by UDD + */ +bool udc_process_setup(void) +{ + // By default no data (receive/send) and no callbacks registered + udd_g_ctrlreq.payload_size = 0; + udd_g_ctrlreq.callback = NULL; + udd_g_ctrlreq.over_under_run = NULL; + + if (Udd_setup_is_in()) { + if (udd_g_ctrlreq.req.wLength == 0) { + return false; // Error from USB host + } + } + + // If standard request then try to decode it in UDC + if (Udd_setup_type() == USB_REQ_TYPE_STANDARD) { + if (udc_reqstd()) { + return true; + } + } + + // If interface request then try to decode it in UDI + if (Udd_setup_recipient() == USB_REQ_RECIP_INTERFACE) { + if (udc_req_iface()) { + return true; + } + } + + // Here SETUP request unknown by UDC and UDIs +#ifdef USB_DEVICE_SPECIFIC_REQUEST + // Try to decode it in specific callback + return USB_DEVICE_SPECIFIC_REQUEST(); // Ex: Vendor request,... +#else + return false; +#endif +} + +//! @} diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/udc/udd.h b/Firmware/Atmel DFU Bootloader/common/services/usb/udc/udd.h new file mode 100644 index 0000000..29eb07e --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/udc/udd.h @@ -0,0 +1,392 @@ +/** + * \file + * + * \brief Common API for USB Device Drivers (UDD) + * + * 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 _UDD_H_ +#define _UDD_H_ + +#include "usb_protocol.h" +#include "udc_desc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udd_group USB Device Driver (UDD) + * + * The UDD driver provides a low-level abstraction of the device + * controller hardware. Most events coming from the hardware such as + * interrupts, which may cause the UDD to call into the UDC and UDI. + * + * @{ + */ + +//! \brief Endpoint identifier +typedef uint8_t udd_ep_id_t; + +//! \brief Endpoint transfer status +//! Returned in parameters of callback register via udd_ep_run routine. +typedef enum { + UDD_EP_TRANSFER_OK = 0, + UDD_EP_TRANSFER_ABORT = 1, +} udd_ep_status_t; + +/** + * \brief Global variable to give and record information of the setup request management + * + * This global variable allows to decode and response a setup request. + * It can be updated by udc_process_setup() from UDC or *setup() from UDIs. + */ +typedef struct { + //! Data received in USB SETUP packet + //! Note: The swap of "req.wValues" from uin16_t to le16_t is done by UDD. + usb_setup_req_t req; + + //! Point to buffer to send or fill with data following SETUP packet + uint8_t *payload; + + //! Size of buffer to send or fill, and content the number of byte transfered + uint16_t payload_size; + + //! Callback called after reception of ZLP from setup request + void (*callback) (void); + + //! Callback called when the buffer given (.payload) is full or empty. + //! This one return false to abort data transfer, or true with a new buffer in .payload. + bool(*over_under_run) (void); +} udd_ctrl_request_t; +extern udd_ctrl_request_t udd_g_ctrlreq; + +//! Return true if the setup request \a udd_g_ctrlreq indicates IN data transfer +#define Udd_setup_is_in() \ + (USB_REQ_DIR_IN == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) + +//! Return true if the setup request \a udd_g_ctrlreq indicates OUT data transfer +#define Udd_setup_is_out() \ + (USB_REQ_DIR_OUT == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) + +//! Return the type of the SETUP request \a udd_g_ctrlreq. \see usb_reqtype. +#define Udd_setup_type() \ + (udd_g_ctrlreq.req.bmRequestType & USB_REQ_TYPE_MASK) + +//! Return the recipient of the SETUP request \a udd_g_ctrlreq. \see usb_recipient +#define Udd_setup_recipient() \ + (udd_g_ctrlreq.req.bmRequestType & USB_REQ_RECIP_MASK) + +/** + * \brief End of halt callback function type. + * Registered by routine udd_ep_wait_stall_clear() + * Callback called when endpoint stall is cleared. + */ +typedef void (*udd_callback_halt_cleared_t) (void); + +/** + * \brief End of transfer callback function type. + * Registered by routine udd_ep_run() + * Callback called by USB interrupt after data transfer or abort (reset,...). + * + * \param status UDD_EP_TRANSFER_OK, if transfer is complete + * \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted + * \param n number of data transfered + */ +typedef void (*udd_callback_trans_t) (udd_ep_status_t status, + iram_size_t nb_transfered, udd_ep_id_t ep); + +/** + * \brief Authorizes the VBUS event + * + * \return true, if the VBUS monitoring is possible. + */ +bool udd_include_vbus_monitoring(void); + +/** + * \brief Enables the USB Device mode + */ +void udd_enable(void); + +/** + * \brief Disables the USB Device mode + */ +void udd_disable(void); + +/** + * \brief Attach device to the bus when possible + * + * \warning If a VBus control is included in driver, + * then it will attach device when an acceptable Vbus + * level from the host is detected. + */ +void udd_attach(void); + +/** + * \brief Detaches the device from the bus + * + * The driver must remove pull-up on USB line D- or D+. + */ +void udd_detach(void); + +/** + * \brief Test whether the USB Device Controller is running at high + * speed or not. + * + * \return \c true if the Device is running at high speed mode, otherwise \c false. + */ +bool udd_is_high_speed(void); + +/** + * \brief Changes the USB address of device + * + * \param address New USB address + */ +void udd_set_address(uint8_t address); + +/** + * \brief Returns the USB address of device + * + * \return USB address + */ +uint8_t udd_getaddress(void); + +/** + * \brief Returns the current start of frame number + * + * \return current start of frame number. + */ +uint16_t udd_get_frame_number(void); + +/** + * \brief Returns the current micro start of frame number + * + * \return current micro start of frame number required in high speed mode. + */ +uint16_t udd_get_micro_frame_number(void); + +/*! \brief The USB driver sends a resume signal called Upstream Resume + */ +void udd_send_remotewakeup(void); + +/** + * \brief Load setup payload + * + * \param payload Pointer on payload + * \param payload_size Size of payload + */ +void udd_set_setup_payload( uint8_t *payload, uint16_t payload_size ); + + +/** + * \name Endpoint Management + * + * The following functions allow drivers to create and remove + * endpoints, as well as set, clear and query their "halted" and + * "wedged" states. + */ +//@{ + +#if (USB_DEVICE_MAX_EP != 0) + +/** + * \brief Configures and enables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + * \param bmAttributes Attributes of endpoint declared in the descriptor. + * \param MaxEndpointSize Endpoint maximum size + * + * \return \c 1 if the endpoint is enabled, otherwise \c 0. + */ +bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, + uint16_t MaxEndpointSize); + +/** + * \brief Disables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + */ +void udd_ep_free(udd_ep_id_t ep); + +/** + * \brief Check if the endpoint \a ep is halted. + * + * \param ep The ID of the endpoint to check. + * + * \return \c 1 if \a ep is halted, otherwise \c 0. + */ +bool udd_ep_is_halted(udd_ep_id_t ep); + +/** + * \brief Set the halted state of the endpoint \a ep + * + * After calling this function, any transaction on \a ep will result + * in a STALL handshake being sent. Any pending transactions will be + * performed first, however. + * + * \param ep The ID of the endpoint to be halted + * + * \return \c 1 if \a ep is halted, otherwise \c 0. + */ +bool udd_ep_set_halt(udd_ep_id_t ep); + +/** + * \brief Clear the halted state of the endpoint \a ep + * + * After calling this function, any transaction on \a ep will + * be handled normally, i.e. a STALL handshake will not be sent, and + * the data toggle sequence will start at DATA0. + * + * \param ep The ID of the endpoint to be un-halted + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udd_ep_clear_halt(udd_ep_id_t ep); + +/** + * \brief Registers a callback to call when endpoint halt is cleared + * + * \param ep The ID of the endpoint to use + * \param callback NULL or function to call when endpoint halt is cleared + * + * \warning if the endpoint is not halted then the \a callback is called immediately. + * + * \return \c 1 if the register is accepted, otherwise \c 0. + */ +bool udd_ep_wait_stall_clear(udd_ep_id_t ep, + udd_callback_halt_cleared_t callback); + +/** + * \brief Allows to receive or send data on an endpoint + * + * The driver uses a specific DMA USB to transfer data + * from internal RAM to endpoint, if this one is available. + * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. + * The \a callback returns the transfer status and eventually the number of byte transfered. + * Note: The control endpoint is not authorized. + * + * \param ep The ID of the endpoint to use + * \param b_shortpacket Enabled automatic short packet + * \param buf Buffer on Internal RAM to send or fill. + * It must be align, then use COMPILER_WORD_ALIGNED. + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + * + * \warning About \a b_shortpacket, for IN endpoint it means that a short packet + * (or a Zero Length Packet) will be sent to the USB line to properly close the usb + * transfer at the end of the data transfer. + * For Bulk and Interrupt OUT endpoint, it will automatically stop the transfer + * at the end of the data transfer (received short packet). + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udd_ep_run(udd_ep_id_t ep, bool b_shortpacket, + uint8_t * buf, iram_size_t buf_size, + udd_callback_trans_t callback); +/** + * \brief Aborts transfer on going on endpoint + * + * If a transfer is on going, then it is stopped and + * the callback registered is called to signal the end of transfer. + * Note: The control endpoint is not authorized. + * + * \param ep Endpoint to abort + */ +void udd_ep_abort(udd_ep_id_t ep); + +#endif + +//@} + + +/** + * \name High speed test mode management + * + * The following functions allow the device to jump to a specific test mode required in high speed mode. + */ +//@{ +void udd_test_mode_j(void); +void udd_test_mode_k(void); +void udd_test_mode_se0_nak(void); +void udd_test_mode_packet(void); +//@} + + +/** + * \name UDC callbacks to provide for UDD + * + * The following callbacks are used by UDD. + */ +//@{ + +/** + * \brief Decodes and manages a setup request + * + * The driver call it when a SETUP packet is received. + * The \c udd_g_ctrlreq contains the data of SETUP packet. + * If this callback accepts the setup request then it must + * return \c 1 and eventually update \c udd_g_ctrlreq to send or receive data. + * + * \return \c 1 if the request is accepted, otherwise \c 0. + */ +extern bool udc_process_setup(void); + +/** + * \brief Reset the UDC + * + * The UDC must reset all configuration. + */ +extern void udc_reset(void); + +/** + * \brief To signal that a SOF is occurred + * + * The UDC must send the signal to all UDIs enabled + */ +extern void udc_sof_notify(void); + +//@} + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDD_H_ diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/udc/udi.h b/Firmware/Atmel DFU Bootloader/common/services/usb/udc/udi.h new file mode 100644 index 0000000..2c16444 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/udc/udi.h @@ -0,0 +1,130 @@ +/** + * \file + * + * \brief Common API for USB Device Interface + * + * 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 _UDI_H_ +#define _UDI_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udi_group USB Device Interface (UDI) + * The UDI provides a common API for all classes, + * and this is used by UDC for the main control of USB Device interface. + * @{ + */ + +/** + * \brief UDI API. + * + * The callbacks within this structure are called only by + * USB Device Controller (UDC) + * + * The udc_get_interface_desc() can be use by UDI to know the interface descriptor + * selected by UDC. + */ +typedef struct { + /** + * \brief Enable the interface. + * + * This function is called when the host selects a configuration + * to which this interface belongs through a Set Configuration + * request, and when the host selects an alternate setting of + * this interface through a Set Interface request. + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ + bool(*enable) (void); + + /** + * \brief Disable the interface. + * + * This function is called when this interface is currently + * active, and + * - the host selects any configuration through a Set + * Configuration request, or + * - the host issues a USB reset, or + * - the device is detached from the host (i.e. Vbus is no + * longer present) + */ + void (*disable) (void); + + /** + * \brief Handle a control request directed at an interface. + * + * This function is called when this interface is currently + * active and the host sends a SETUP request + * with this interface as the recipient. + * + * Use udd_g_ctrlreq to decode and response to SETUP request. + * + * \return \c 1 if this interface supports the SETUP request, otherwise \c 0. + */ + bool(*setup) (void); + + /** + * \brief Returns the current setting of the selected interface. + * + * This function is called when UDC when know alternate setting of selected interface. + * + * \return alternate setting of selected interface + */ + uint8_t(*getsetting) (void); + + /** + * \brief To signal that a SOF is occurred + */ + void(*sof_notify) (void); +} udi_api_t; + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDI_H_ diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/usb_atmel.h b/Firmware/Atmel DFU Bootloader/common/services/usb/usb_atmel.h new file mode 100644 index 0000000..d9c1c33 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/usb_atmel.h @@ -0,0 +1,185 @@ +/** + * \file + * + * \brief All USB VIDs and PIDs from Atmel USB applications + * + * 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 _USB_ATMEL_H_ +#define _USB_ATMEL_H_ + +/** + * \defgroup usb_group USB Stack + * + * This stack includes the USB Device Stack, USB Host Stack and common + * definitions. + * @{ + */ + +//! @} + +/** + * \ingroup usb_group + * \defgroup usb_atmel_ids_group Atmel USB Identifiers + * + * This module defines Atmel PID and VIDs constants. + * + * @{ + */ + +//! \name Vendor Identifier assigned by USB org to ATMEL +#define USB_VID_ATMEL 0x03EB + + +//! \name Product Identifier assigned by ATMEL to AVR applications +//! @{ + +//! \name The range from 2000h to 20FFh is reserved to the old PID for C51, MEGA, and others. +//! @{ +#define USB_PID_ATMEL_MEGA_HIDGENERIC 0x2013 +#define USB_PID_ATMEL_MEGA_HIDKEYBOARD 0x2017 +#define USB_PID_ATMEL_MEGA_CDC 0x2018 +#define USB_PID_ATMEL_MEGA_AUDIO_IN 0x2019 +#define USB_PID_ATMEL_MEGA_MS 0x201A +#define USB_PID_ATMEL_MEGA_AUDIO_IN_OUT 0x201B +#define USB_PID_ATMEL_MEGA_HIDMOUSE 0x201C +#define USB_PID_ATMEL_MEGA_HIDMOUSE_CERTIF_U4 0x201D +#define USB_PID_ATMEL_MEGA_CDC_MULTI 0x201E +#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_USBKEY 0x2022 +#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_STK525 0x2023 +#define USB_PID_ATMEL_MEGA_MS_2 0x2029 +#define USB_PID_ATMEL_MEGA_MS_HIDMS 0x202A +#define USB_PID_ATMEL_MEGA_MS_3 0x2032 +#define USB_PID_ATMEL_MEGA_LIBUSB 0x2050 +//! @} + +//! \name The range 2100h to 21FFh is reserved to PIDs for AVR Tools. +//! @{ +#define USB_PID_ATMEL_XPLAINED 0x2122 +//! @} + +//! \name The range 2300h to 23FFh is reserved to PIDs for demo from ASF1.7=> +//! @{ +#define USB_PID_ATMEL_UC3_ENUM 0x2300 +#define USB_PID_ATMEL_UC3_MS 0x2301 +#define USB_PID_ATMEL_UC3_MS_SDRAM_LOADER 0x2302 +#define USB_PID_ATMEL_UC3_EVK1100_CTRLPANEL 0x2303 +#define USB_PID_ATMEL_UC3_HID 0x2304 +#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID 0x2305 +#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID_MS 0x2306 +#define USB_PID_ATMEL_UC3_CDC 0x2307 +#define USB_PID_ATMEL_UC3_AUDIO_MICRO 0x2308 +#define USB_PID_ATMEL_UC3_CDC_DEBUG 0x2310 // Virtual Com (debug interface) on EVK11xx +#define USB_PID_ATMEL_UC3_AUDIO_SPEAKER_MICRO 0x2311 +#define USB_PID_ATMEL_UC3_CDC_MSC 0x2312 +//! @} + +//! \name The range 2400h to 24FFh is reserved to PIDs for ASF applications +//! @{ +#define USB_PID_ATMEL_ASF_HIDMOUSE 0x2400 +#define USB_PID_ATMEL_ASF_HIDKEYBOARD 0x2401 +#define USB_PID_ATMEL_ASF_HIDGENERIC 0x2402 +#define USB_PID_ATMEL_ASF_MSC 0x2403 +#define USB_PID_ATMEL_ASF_CDC 0x2404 +#define USB_PID_ATMEL_ASF_PHDC 0x2405 +#define USB_PID_ATMEL_ASF_MSC_HIDMOUSE 0x2420 +#define USB_PID_ATMEL_ASF_MSC_HIDS_CDC 0x2421 +#define USB_PID_ATMEL_ASF_MSC_HIDKEYBOARD 0x2422 +#define USB_PID_ATMEL_ASF_VENDOR_CLASS 0x2423 +#define USB_PID_ATMEL_ASF_MSC_CDC 0x2424 +#define USB_PID_ATMEL_ASF_TWO_CDC 0x2425 +#define USB_PID_ATMEL_ASF_SEVEN_CDC 0x2426 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_POWERONLY 0x2430 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_TERMINAL 0x2431 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_TOUCH 0x2432 +#define USB_PID_ATMEL_ASF_AUDIO_SPEAKER 0x2433 +#define USB_PID_ATMEL_ASF_XMEGA_B1_XPLAINED 0x2434 +//! @} + +//! \name The range 2F00h to 2FFFh is reserved to official PIDs for AVR bootloaders +//! Note, !!!! don't use this range for demos or examples !!!! +//! @{ +#define USB_PID_ATMEL_DFU_ATXMEGA64C3 0x2FD6 +#define USB_PID_ATMEL_DFU_ATXMEGA128C3 0x2FD7 +#define USB_PID_ATMEL_DFU_ATXMEGA16C4 0x2FD8 +#define USB_PID_ATMEL_DFU_ATXMEGA32C4 0x2FD9 +#define USB_PID_ATMEL_DFU_ATXMEGA256C3 0x2FDA +#define USB_PID_ATMEL_DFU_ATXMEGA384C3 0x2FDB +#define USB_PID_ATMEL_DFU_ATUCL3_L4 0x2FDC +#define USB_PID_ATMEL_DFU_ATXMEGA64A4U 0x2FDD +#define USB_PID_ATMEL_DFU_ATXMEGA128A4U 0x2FDE + +#define USB_PID_ATMEL_DFU_ATXMEGA64B3 0x2FDF +#define USB_PID_ATMEL_DFU_ATXMEGA128B3 0x2FE0 +#define USB_PID_ATMEL_DFU_ATXMEGA64B1 0x2FE1 +#define USB_PID_ATMEL_DFU_ATXMEGA256A3BU 0x2FE2 +#define USB_PID_ATMEL_DFU_ATXMEGA16A4U 0x2FE3 +#define USB_PID_ATMEL_DFU_ATXMEGA32A4U 0x2FE4 +#define USB_PID_ATMEL_DFU_ATXMEGA64A3U 0x2FE5 +#define USB_PID_ATMEL_DFU_ATXMEGA128A3U 0x2FE6 +#define USB_PID_ATMEL_DFU_ATXMEGA192A3U 0x2FE7 +#define USB_PID_ATMEL_DFU_ATXMEGA64A1U 0x2FE8 +#define USB_PID_ATMEL_DFU_ATUC3D 0x2FE9 +#define USB_PID_ATMEL_DFU_ATXMEGA128B1 0x2FEA +#define USB_PID_ATMEL_DFU_AT32UC3C 0x2FEB +#define USB_PID_ATMEL_DFU_ATXMEGA256A3U 0x2FEC +#define USB_PID_ATMEL_DFU_ATXMEGA128A1U 0x2FED +#define USB_PID_ATMEL_DFU_ATMEGA8U2 0x2FEE +#define USB_PID_ATMEL_DFU_ATMEGA16U2 0x2FEF +#define USB_PID_ATMEL_DFU_ATMEGA32U2 0x2FF0 +#define USB_PID_ATMEL_DFU_AT32UC3A3 0x2FF1 +#define USB_PID_ATMEL_DFU_ATMEGA32U6 0x2FF2 +#define USB_PID_ATMEL_DFU_ATMEGA16U4 0x2FF3 +#define USB_PID_ATMEL_DFU_ATMEGA32U4 0x2FF4 +#define USB_PID_ATMEL_DFU_AT32AP7200 0x2FF5 +#define USB_PID_ATMEL_DFU_AT32UC3B 0x2FF6 +#define USB_PID_ATMEL_DFU_AT90USB82 0x2FF7 +#define USB_PID_ATMEL_DFU_AT32UC3A 0x2FF8 +#define USB_PID_ATMEL_DFU_AT90USB64 0x2FF9 +#define USB_PID_ATMEL_DFU_AT90USB162 0x2FFA +#define USB_PID_ATMEL_DFU_AT90USB128 0x2FFB +// 2FFCh to 2FFFh used by C51 family products +//! @} + +//! @} + +//! @} + + +#endif // _USB_ATMEL_H_ diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/usb_protocol.h b/Firmware/Atmel DFU Bootloader/common/services/usb/usb_protocol.h new file mode 100644 index 0000000..443de6b --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/services/usb/usb_protocol.h @@ -0,0 +1,410 @@ +/** + * \file + * + * \brief USB protocol definitions. + * + * This file contains the USB definitions and data structures provided by the + * USB 2.0 specification. + * + * 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 _USB_PROTOCOL_H_ +#define _USB_PROTOCOL_H_ + +#include "usb_atmel.h" + +/** + * \ingroup usb_group + * \defgroup usb_protocol_group USB Protocol Definitions + * + * This module defines constants and data structures provided by the USB + * 2.0 specification. + * + * @{ + */ + +//! Value for field bcdUSB +#define USB_V2_0 0x0200 //!< USB Specification version 2.00 + +/*! \name Generic definitions (Class, subclass and protocol) + */ +//! @{ +#define NO_CLASS 0x00 +#define CLASS_VENDOR_SPECIFIC 0xFF +#define NO_SUBCLASS 0x00 +#define NO_PROTOCOL 0x00 +//! @} + +//! \name IAD (Interface Association Descriptor) constants +//! @{ +#define CLASS_IAD 0xEF +#define SUB_CLASS_IAD 0x02 +#define PROTOCOL_IAD 0x01 +//! @} + +/** + * \brief USB request data transfer direction (bmRequestType) + */ +#define USB_REQ_DIR_OUT (0<<7) //!< Host to device +#define USB_REQ_DIR_IN (1<<7) //!< Device to host +#define USB_REQ_DIR_MASK (1<<7) //!< Mask + +/** + * \brief USB request types (bmRequestType) + */ +#define USB_REQ_TYPE_STANDARD (0<<5) //!< Standard request +#define USB_REQ_TYPE_CLASS (1<<5) //!< Class-specific request +#define USB_REQ_TYPE_VENDOR (2<<5) //!< Vendor-specific request +#define USB_REQ_TYPE_MASK (3<<5) //!< Mask + +/** + * \brief USB recipient codes (bmRequestType) + */ +#define USB_REQ_RECIP_DEVICE (0<<0) //!< Recipient device +#define USB_REQ_RECIP_INTERFACE (1<<0) //!< Recipient interface +#define USB_REQ_RECIP_ENDPOINT (2<<0) //!< Recipient endpoint +#define USB_REQ_RECIP_OTHER (3<<0) //!< Recipient other +#define USB_REQ_RECIP_MASK (0x1F) //!< Mask + +/** + * \brief Standard USB requests (bRequest) + */ +enum usb_reqid { + USB_REQ_GET_STATUS = 0, + USB_REQ_CLEAR_FEATURE = 1, + USB_REQ_SET_FEATURE = 3, + USB_REQ_SET_ADDRESS = 5, + USB_REQ_GET_DESCRIPTOR = 6, + USB_REQ_SET_DESCRIPTOR = 7, + USB_REQ_GET_CONFIGURATION = 8, + USB_REQ_SET_CONFIGURATION = 9, + USB_REQ_GET_INTERFACE = 10, + USB_REQ_SET_INTERFACE = 11, + USB_REQ_SYNCH_FRAME = 12, +}; + +/** + * \brief Standard USB device status flags + * + */ +enum usb_device_status { + USB_DEV_STATUS_BUS_POWERED = 0, + USB_DEV_STATUS_SELF_POWERED = 1, + USB_DEV_STATUS_REMOTEWAKEUP = 2 +}; + +/** + * \brief Standard USB Interface status flags + * + */ +enum usb_interface_status { + USB_IFACE_STATUS_RESERVED = 0 +}; + +/** + * \brief Standard USB endpoint status flags + * + */ +enum usb_endpoint_status { + USB_EP_STATUS_HALTED = 1, +}; + +/** + * \brief Standard USB device feature flags + * + * \note valid for SetFeature request. + */ +enum usb_device_feature { + USB_DEV_FEATURE_REMOTE_WAKEUP = 1, //!< Remote wakeup enabled + USB_DEV_FEATURE_TEST_MODE = 2, //!< USB test mode + USB_DEV_FEATURE_OTG_B_HNP_ENABLE = 3, + USB_DEV_FEATURE_OTG_A_HNP_SUPPORT = 4, + USB_DEV_FEATURE_OTG_A_ALT_HNP_SUPPORT = 5 +}; + +/** + * \brief Test Mode possible on HS USB device + * + * \note valid for USB_DEV_FEATURE_TEST_MODE request. + */ +enum usb_device_hs_test_mode { + USB_DEV_TEST_MODE_J = 1, + USB_DEV_TEST_MODE_K = 2, + USB_DEV_TEST_MODE_SE0_NAK = 3, + USB_DEV_TEST_MODE_PACKET = 4, + USB_DEV_TEST_MODE_FORCE_ENABLE = 5, +}; + +/** + * \brief Standard USB endpoint feature/status flags + */ +enum usb_endpoint_feature { + USB_EP_FEATURE_HALT = 0, +}; + +/** + * \brief Standard USB Test Mode Selectors + */ +enum usb_test_mode_selector { + USB_TEST_J = 0x01, + USB_TEST_K = 0x02, + USB_TEST_SE0_NAK = 0x03, + USB_TEST_PACKET = 0x04, + USB_TEST_FORCE_ENABLE = 0x05, +}; + +/** + * \brief Standard USB descriptor types + */ +enum usb_descriptor_type { + USB_DT_DEVICE = 1, + USB_DT_CONFIGURATION = 2, + USB_DT_STRING = 3, + USB_DT_INTERFACE = 4, + USB_DT_ENDPOINT = 5, + USB_DT_DEVICE_QUALIFIER = 6, + USB_DT_OTHER_SPEED_CONFIGURATION = 7, + USB_DT_INTERFACE_POWER = 8, + USB_DT_OTG = 9, + USB_DT_IAD = 0x0B, +}; + +/** + * \brief Standard USB endpoint transfer types + */ +enum usb_ep_type { + USB_EP_TYPE_CONTROL = 0x00, + USB_EP_TYPE_ISOCHRONOUS = 0x01, + USB_EP_TYPE_BULK = 0x02, + USB_EP_TYPE_INTERRUPT = 0x03, + USB_EP_TYPE_MASK = 0x03, +}; + +/** + * \brief Standard USB language IDs for string descriptors + */ +enum usb_langid { + USB_LANGID_EN_US = 0x0409, //!< English (United States) +}; + +/** + * \brief Mask selecting the index part of an endpoint address + */ +#define USB_EP_ADDR_MASK 0x0f + +//! \brief USB address identifier +typedef uint8_t usb_add_t; + +/** + * \brief Endpoint transfer direction is IN + */ +#define USB_EP_DIR_IN 0x80 + +/** + * \brief Endpoint transfer direction is OUT + */ +#define USB_EP_DIR_OUT 0x00 + +//! \brief Endpoint identifier +typedef uint8_t usb_ep_t; + +/** + * \brief Maximum length in bytes of a USB descriptor + * + * The maximum length of a USB descriptor is limited by the 8-bit + * bLength field. + */ +#define USB_MAX_DESC_LEN 255 + +/* + * 2-byte alignment requested for all USB structures. + */ +COMPILER_PACK_SET(1) + +/** + * \brief A USB Device SETUP request + * + * The data payload of SETUP packets always follows this structure. + */ +typedef struct { + uint8_t bmRequestType; + uint8_t bRequest; + le16_t wValue; + le16_t wIndex; + le16_t wLength; +} usb_setup_req_t; + +/** + * \brief Standard USB device descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + le16_t idVendor; + le16_t idProduct; + le16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} usb_dev_desc_t; + +/** + * \brief Standard USB device qualifier descriptor structure + * + * This descriptor contains information about the device when running at + * the "other" speed (i.e. if the device is currently operating at high + * speed, this descriptor can be used to determine what would change if + * the device was operating at full speed.) + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint8_t bNumConfigurations; + uint8_t bReserved; +} usb_dev_qual_desc_t; + + +/** + * \brief Standard USB Interface Association Descriptor structure + */ +typedef struct { + uint8_t bLength; //!< size of this descriptor in bytes + uint8_t bDescriptorType; //!< INTERFACE descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass;//!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol;//!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} usb_association_desc_t; + + +/** + * \brief Standard USB configuration descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +} usb_conf_desc_t; + + +#define USB_CONFIG_ATTR_MUST_SET (1 << 7) //!< Must always be set +#define USB_CONFIG_ATTR_BUS_POWERED (0 << 6) //!< Bus-powered +#define USB_CONFIG_ATTR_SELF_POWERED (1 << 6) //!< Self-powered +#define USB_CONFIG_ATTR_REMOTE_WAKEUP (1 << 5) //!< remote wakeup supported + +#define USB_CONFIG_MAX_POWER(ma) (((ma) + 1) / 2) //!< Max power in mA + +/** + * \brief Standard USB association descriptor structure + */ +typedef struct { + uint8_t bLength; //!< Size of this descriptor in bytes + uint8_t bDescriptorType; //!< Interface descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass; //!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol; //!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} usb_iad_desc_t; + +/** + * \brief Standard USB interface descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} usb_iface_desc_t; + +/** + * \brief Standard USB endpoint descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + le16_t wMaxPacketSize; + uint8_t bInterval; +} usb_ep_desc_t; + + +/** + * \brief A standard USB string descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; +} usb_str_desc_t; + +typedef struct { + usb_str_desc_t desc; + le16_t string[1]; +} usb_str_lgid_desc_t; + +COMPILER_PACK_RESET() + +//! @} + +#endif /* _USB_PROTOCOL_H_ */ diff --git a/Firmware/Atmel DFU Bootloader/common/utils/interrupt.h b/Firmware/Atmel DFU Bootloader/common/utils/interrupt.h new file mode 100644 index 0000000..468656e --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/utils/interrupt.h @@ -0,0 +1,139 @@ +/** + * \file + * + * \brief Global interrupt management for 8- and 32-bit AVR + * + * 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 UTILS_INTERRUPT_H +#define UTILS_INTERRUPT_H + +#include + +#if XMEGA || MEGA +# include "interrupt/interrupt_avr8.h" +#elif UC3 +# include "interrupt/interrupt_avr32.h" +#elif SAM3S || SAM3N || SAM3XA || SAM3U || SAM4S +# 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 compatibilty accross 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/Firmware/Atmel DFU Bootloader/common/utils/interrupt/interrupt_avr8.h b/Firmware/Atmel DFU Bootloader/common/utils/interrupt/interrupt_avr8.h new file mode 100644 index 0000000..591e273 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/utils/interrupt/interrupt_avr8.h @@ -0,0 +1,138 @@ +/** + * \file + * + * \brief Global interrupt management for 8-bit AVR + * + * 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_INTERRUPT_INTERRUPT_H +#define UTILS_INTERRUPT_INTERRUPT_H + +#include +#include + +/** + * \weakgroup interrupt_group + * + * @{ + */ + +/** + * \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 +#elif defined(__ICCAVR__) +# define __ISR(x) _Pragma(#x) +# define ISR(vect) __ISR(vector=vect) __interrupt void handler_##vect(void) +#endif + +#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; +#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 + 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/Firmware/Atmel DFU Bootloader/common/utils/parts.h b/Firmware/Atmel DFU Bootloader/common/utils/parts.h new file mode 100644 index 0000000..fe3446c --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/common/utils/parts.h @@ -0,0 +1,644 @@ +/** + * \file + * + * \brief Atmel part identification macros + * + * 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 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(ATxmega128C3) || \ + AVR8_PART_IS_DEFINED(ATxmega64C3) \ + ) + +#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(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 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 product line */ +#define XMEGA (XMEGA_A || XMEGA_AU || XMEGA_B || XMEGA_C || XMEGA_D) + +/** @} */ + +/** + * \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(ATmega324) || \ + 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) \ + ) + +/** 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) \ + ) + +/** Unspecified group */ +#define MEGA_UNSPECIFIED ( \ + 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) || \ + AVR8_PART_IS_DEFINED(ATmega169P) || \ + AVR8_PART_IS_DEFINED(ATmega169PA) || \ + AVR8_PART_IS_DEFINED(ATmega329P) || \ + AVR8_PART_IS_DEFINED(ATmega329PA) \ + ) +/** @} */ + +/** megaAVR product line */ +#define MEGA (MEGA_XX0_1 || MEGA_XX4 || MEGA_XX8 || MEGA_XX || MEGA_UNSPECIFIED) + +/** @} */ + +/** + * \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 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 SAM4S8 ( \ + SAM_PART_IS_DEFINED(SAM4S8B) || \ + SAM_PART_IS_DEFINED(SAM4S8C) \ + ) + +#define SAM4S16 ( \ + SAM_PART_IS_DEFINED(SAM4S16B) || \ + SAM_PART_IS_DEFINED(SAM4S16C) \ + ) +/** @} */ + +/** + * \name SAM families + * @{ + */ +/** SAM3S Family */ +#define SAM3S (SAM3S1 || SAM3S2 || SAM3S4 || SAM3S8 || SAM3SD8) + +/** SAM3U Family */ +#define SAM3U (SAM3U1 || SAM3U2 || SAM3U4) + +/** SAM3N Family */ +#define SAM3N (SAM3N1 || SAM3N2 || SAM3N4) + +/** SAM3XA Family */ +#define SAM3XA (SAM3X4 || SAM3X8 || SAM3A4 || SAM3A8) + +/** SAM4S Family */ +#define SAM4S (SAM4S8 || SAM4S16) +/** @} */ + +/** SAM product line */ +#define SAM (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S) + +/** @} */ + +/** @} */ + +#endif /* ATMEL_PARTS_H */ diff --git a/Firmware/Atmel DFU Bootloader/xmega/boards/dummy/dummy_board.h b/Firmware/Atmel DFU Bootloader/xmega/boards/dummy/dummy_board.h new file mode 100644 index 0000000..fae9cd4 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/xmega/boards/dummy/dummy_board.h @@ -0,0 +1,53 @@ +/***************************************************************************** + * + * \file + * + * \brief Dummy board header file. + * + * This file contains empty definitions to support board-independant applications (e.g. bootloader) + * + * To use this board, define BOARD=DUMMY_BOARD. + * + * 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 _DUMMY_BOARD_H_ +#define _DUMMY_BOARD_H_ + +#endif // _DUMMY_BOARD_H_ diff --git a/Firmware/Atmel DFU Bootloader/xmega/drivers/cpu/ccp.h b/Firmware/Atmel DFU Bootloader/xmega/drivers/cpu/ccp.h new file mode 100644 index 0000000..45bb10c --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/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 + +/** + * \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/Firmware/Atmel DFU Bootloader/xmega/drivers/cpu/ccp.s b/Firmware/Atmel DFU Bootloader/xmega/drivers/cpu/ccp.s new file mode 100644 index 0000000..3f7e279 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/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 + +//! 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/Firmware/Atmel DFU Bootloader/xmega/drivers/cpu/xmega_reset_cause.h b/Firmware/Atmel DFU Bootloader/xmega/drivers/cpu/xmega_reset_cause.h new file mode 100644 index 0000000..ed10d3b --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/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/Firmware/Atmel DFU Bootloader/xmega/drivers/nvm/nvm.c b/Firmware/Atmel DFU Bootloader/xmega/drivers/nvm/nvm.c new file mode 100644 index 0000000..9305d11 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/xmega/drivers/nvm/nvm.c @@ -0,0 +1,757 @@ +/** + * \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 + +/** + * \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 IO mapping. + * + * This function reads one byte from EEPROM using IO-mapped access. + * If memory mapped EEPROM is enabled, this function will not work. + * + * \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) +{ + Assert(addr <= EEPROM_SIZE); + + /* Wait until NVM is ready */ + nvm_wait_until_ready(); + + /* Set address to read from */ + NVM.ADDR2 = 0x00; + NVM.ADDR1 = (addr >> 8) & 0xFF; + NVM.ADDR0 = addr & 0xFF; + + /* Issue EEPROM Read command */ + nvm_issue_command(NVM_CMD_READ_EEPROM_gc); + + return NVM.DATA0; +} + +/** + * \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. + * If memory mapped EEPROM is enabled, this function will not work. + * 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; + + /* 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.CMD = NVM_CMD_LOAD_EEPROM_BUFFER_gc; + + Assert(address <= EEPROM_SIZE); + + // Set address to write to + NVM.ADDR2 = 0x00; + NVM.ADDR1 = (address >> 8) & 0xFF; + NVM.ADDR0 = address & 0xFF; + + // Load data to write, which triggers the loading of EEPROM page buffer + NVM.DATA0 = value; + + /* 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) +{ + uint8_t old_cmd; + old_cmd = NVM.CMD; + + // Wait until NVM is ready + nvm_wait_until_ready(); + + NVM.CMD = NVM_CMD_LOAD_EEPROM_BUFFER_gc; + + // Set address + NVM.ADDR2 = 0x00; + NVM.ADDR1 = 0x00; + NVM.ADDR0 = byte_addr & 0xFF; + + // Set data, which triggers loading of EEPROM page buffer + NVM.DATA0 = value; + + NVM.CMD = old_cmd; +} + + +/** + * \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) +{ + uint8_t old_cmd; + old_cmd = NVM.CMD; + + // Wait until NVM is ready + nvm_wait_until_ready(); + + NVM.CMD = NVM_CMD_LOAD_EEPROM_BUFFER_gc; + + /* Set address to zero, as only the lower bits matters. ADDR0 is + * maintained inside the loop below. + */ + NVM.ADDR2 = 0x00; + NVM.ADDR1 = 0x00; + + // Load multiple bytes into page buffer + uint8_t i; + for (i = 0; i < EEPROM_PAGE_SIZE; ++i) { + NVM.ADDR0 = i; + NVM.DATA0 = *values; + ++values; + } + NVM.CMD = old_cmd; +} + +/** + * \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) +{ + uint8_t old_cmd; + old_cmd = NVM.CMD; + + nvm_eeprom_flush_buffer(); + // Wait until NVM is ready + nvm_wait_until_ready(); + + NVM.CMD = NVM_CMD_LOAD_EEPROM_BUFFER_gc; + + /* Set address to zero, as only the lower bits matters. ADDR0 is + * maintained inside the loop below. + */ + NVM.ADDR2 = 0x00; + NVM.ADDR1 = 0x00; + + // Load multiple bytes into page buffer + uint8_t i; + for (i = 0; i < EEPROM_PAGE_SIZE; ++i) { + NVM.ADDR0 = i; + NVM.DATA0 = value; + } + NVM.CMD = old_cmd; +} + +/** + * \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_pos0x10000) + 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 +#include + +#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 +# 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) +{ + NVM_CTRLB = NVM_CTRLB | NVM_EEMAPEN_bm; +} + + +/*! \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) +{ + NVM_CTRLB = NVM_CTRLB & ~NVM_EEMAPEN_bm; +} + + +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 + +// 16K devices +# if 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) + +// 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) + +// 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(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/Firmware/Atmel DFU Bootloader/xmega/drivers/nvm/nvm_asm.s b/Firmware/Atmel DFU Bootloader/xmega/drivers/nvm/nvm_asm.s new file mode 100644 index 0000000..700cd07 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/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 + +#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 +#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 +#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/Firmware/Atmel DFU Bootloader/xmega/drivers/usb/usb_device.c b/Firmware/Atmel DFU Bootloader/xmega/drivers/usb/usb_device.c new file mode 100644 index 0000000..0c3cb39 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/xmega/drivers/usb/usb_device.c @@ -0,0 +1,1448 @@ +/** + * \file + * + * \brief USB Device driver + * Compliance with common driver UDD + * + * Copyright (c) 2011 - 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 "conf_usb.h" + +// Read Modify Write opcode is implemented after IAR AVR 5.51 +#ifdef __ICCAVR__ +# if (__VER__ <= 551 || (__VER__ <= 611 && XMEGA_A1U) ) +# undef USB_WORKAROUND_DO_NOT_USE_RMW +# define USB_WORKAROUND_DO_NOT_USE_RMW +# endif +#endif + +#include "sysclk.h" +#include "udd.h" +#include "usb_device.h" +#include + +#ifndef UDD_NO_SLEEP_MGR +#include "sleepmgr.h" +#endif + +#ifndef UDD_USB_INT_LEVEL +// By default USB interrupt have low priority +# define UDD_USB_INT_LEVEL USB_INTLVL_LO_gc +#endif + + + +#ifdef USB_DEVICE_HS_SUPPORT +#error This product does not support high speed mode, please remove define USB_DEVICE_HS_SUPPORT in conf_usb.h +#endif + +//////////////////////////////////////////////////// +// USBB Device low-level driver (UDD) +//////////////////////////////////////////////////// +/** + * \ingroup udd_group + * \defgroup udd_xmega_usb_group Xmega USB Device Driver + * + * \section USBB_CONF USBB Custom configuration + * The following USBB driver configuration must be included in the conf_usb.h + * file of the application. + * + * UDD_USB_INT_LEVEL
+ * Option to change the interrupt priority (USB_INTLVL_x_gc) + * by default USB_INTLVL_LO_gc (recommended). + * + * \section Callbacks management + * The USB driver is fully managed by interrupt and does not request periodic + * task. Thereby, the USB events use callbacks to transfer the information. + * The callbacks are declared in static during compilation or in variable during + * code execution. + * + * Static declarations defined in conf_usb.h: + * - UDC_VBUS_EVENT(bool b_present)
+ * To signal Vbus level change + * - UDC_SUSPEND_EVENT()
+ * Called when USB bus enter in suspend mode + * - UDC_RESUME_EVENT()
+ * Called when USB bus is wakeup + * - UDC_SOF_EVENT()
+ * Called for each received SOF, Note: Each 1ms in HS/FS mode only. + * + * Dynamic callbacks, called "endpoint job" , are registered + * in udd_ep_job_t structure via the following functions: + * - udd_ep_run()
+ * To call it when a transfer is finish + * - udd_ep_wait_stall_clear()
+ * To call it when a endpoint halt is disabled + * + * \section Power mode management + * The Sleep modes authorized : + * - in USB IDLE state, the USB needs of USB clock and authorizes up to IDLE mode + * - in USB SUSPEND state, the USB no needs USB clock but requests a minimum + * clock restart timing. Thus, it authorizes up to POWER_DOWN or STANDBY mode. + * + * The USB_SLEEP_MODE_USB_IDLE equals SLEEPMGR_IDLE. + * + * The USB_SLEEP_MODE_USB_SUSPEND depends on USB clock startup timing: + * | Clock Startup | Sleep mode authorized | + * | >10ms | SLEEPMGR_STDBY | + * | <=10ms | SLEEPMGR_PDOWN | + * + * @{ + */ + + +// Check USB Device configuration +#ifndef USB_DEVICE_EP_CTRL_SIZE +# error USB_DEVICE_EP_CTRL_SIZE not defined +#endif +#ifndef USB_DEVICE_MAX_EP +# error USB_DEVICE_MAX_EP not defined +#endif + + +/** + * \name Power management routine. + */ +//@{ + + +#ifndef UDD_NO_SLEEP_MGR + +//! Definition of sleep levels +#if ((defined USB_DEVICE_HS_SUPPORT) && (USBCLK_STARTUP_TIMEOUT>3000)) \ + || ((!defined USB_DEVICE_HS_SUPPORT) && (USBCLK_STARTUP_TIMEOUT>10000)) +# define USBC_SLEEP_MODE_USB_SUSPEND SLEEPMGR_IDLE +#else +# define USBC_SLEEP_MODE_USB_SUSPEND SLEEPMGR_PDOWN +#endif +#define USBC_SLEEP_MODE_USB_IDLE SLEEPMGR_IDLE + +//! State of USB line +static bool udd_b_idle; + + +/*! \brief Authorize or not the CPU powerdown mode + * + * \param b_enable true to authorize powerdown mode + */ +static void udd_sleep_mode(bool b_idle) +{ + if (!b_idle && udd_b_idle) { + sleepmgr_unlock_mode(USBC_SLEEP_MODE_USB_IDLE); + } + if (b_idle && !udd_b_idle) { + sleepmgr_lock_mode(USBC_SLEEP_MODE_USB_IDLE); + } + udd_b_idle = b_idle; +} +#else + +static void udd_sleep_mode(bool b_idle) { +} +#endif // UDD_NO_SLEEP_MGR + +//@} + +/** + * \brief USB SRAM data about fifo, endpoint descriptor table and frame number + * + * The content of the USB SRAM can be: + * - modified by USB hardware by interface to signal endpoint status. + * Thereby, it is read by software. + * - modified by USB software to control endpoint. + * Thereby, it is read by hardware. + * This data section is volatile and the specific opcode read/modify/write must be used. + * + * @{ + */ +struct udd_sram_data { +#if XMEGA_A1U +# if (0!=((USB_DEVICE_MAX_EP+1)%4)) + uint8_t padding_align[16 - ((USB_DEVICE_MAX_EP + 1) * + sizeof(uint32_t)) % 16]; +# endif +#endif + uint32_t fifo[USB_DEVICE_MAX_EP + 1]; + USB_EP_t ep_ctrl[2 * (USB_DEVICE_MAX_EP + 1)]; + uint16_t frame_number; +}; +#if XMEGA_A1U +COMPILER_ALIGNED(16) +#else +COMPILER_ALIGNED(4) //! Caution seems GCC does not handle 2 alignment properly +#endif +static volatile struct udd_sram_data udd_sram; +#define UDD_EP_t USB_EP_t volatile + +// @} + +/** + * \name initialization of endpoint + */ +//@{ +/** + * \brief Configures and enables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + * \param bmAttributes Attribute of endpoint declared in descriptor. + * \param MaxEndpointSize Endpoint size maximum + */ +static void udd_ep_init(udd_ep_id_t ep, uint8_t bmAttributes, + uint16_t MaxEndpointSize); + +/** + * \brief Returns a pointer on endpoint control SRAM corresponding at endpoint number + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + * + * \return endpoint descriptor index + */ +static UDD_EP_t *udd_ep_get_ctrl(udd_ep_id_t ep); +//@} + + +/** + * \name Control endpoint low level management routine. + * + * This function performs control endpoint management. + * It handle the SETUP/DATA/HANDSHAKE phases of a control transaction. + */ +//@{ + +//! Global variable to give and record information about setup request management +udd_ctrl_request_t udd_g_ctrlreq; + +//! Bit definitions about endpoint control state machine for udd_ep_control_state +typedef enum { + UDD_EPCTRL_SETUP = 0, //!< Wait a SETUP packet + UDD_EPCTRL_DATA_OUT = 1, //!< Wait a OUT data packet + UDD_EPCTRL_DATA_IN = 2, //!< Wait a IN data packet + UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP = 3, //!< Wait a IN ZLP packet + UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP = 4, //!< Wait a OUT ZLP packet + UDD_EPCTRL_STALL_REQ = 5, //!< STALL enabled on IN & OUT packet +} udd_ctrl_ep_state_t; + +//! State of the endpoint control management +static udd_ctrl_ep_state_t udd_ep_control_state; +//! Total number of data received/sent during data packet phase with previous payload buffers +static uint16_t udd_ctrl_prev_payload_nb_trans; +//! Number of data received/sent to/from udd_g_ctrlreq.payload buffer +static uint16_t udd_ctrl_payload_nb_trans; + +/** + * \brief Buffer to store the data received on control endpoint (SETUP/OUT endpoint 0) + * + * Used to avoid a RAM buffer overflow in case of the payload buffer + * is smaller than control endpoint size + */ +static uint8_t udd_ctrl_buffer[USB_DEVICE_EP_CTRL_SIZE]; + +/** + * \brief Reset control endpoint management + * + * Called after a USB line reset or at the end of SETUP request (after ZLP) + */ +static void udd_ctrl_init(void); + +//! \brief Managed reception of SETUP packet on control endpoint +static void udd_ctrl_setup_received(void); + +//! \brief Managed reception of IN packet on control endpoint +static void udd_ctrl_in_sent(void); + +//! \brief Managed reception of OUT packet on control endpoint +static void udd_ctrl_out_received(void); + +//! \brief Managed underflow event of IN packet on control endpoint +//! It is used to detect a DATA phase stopped by the host via a ZLP request. +//! This is mandatory for chapter 8 compliance +static void udd_ctrl_underflow(void); + +//! \brief Managed overflow event of OUT packet on control endpoint +//! It is used to detect a DATA phase stopped by the host via a ZLP request. +//! This is mandatory for chapter 8 compliance +static void udd_ctrl_overflow(void); + +//! \brief Managed stall event of IN/OUT packet on control endpoint +static void udd_ctrl_stall_data(void); + +//! \brief Send a ZLP IN on control endpoint +static void udd_ctrl_send_zlp_in(void); + +//! \brief Send a ZLP OUT on control endpoint +static void udd_ctrl_send_zlp_out(void); + +//! \brief Call callback associated to setup request +static void udd_ctrl_endofrequest(void); + +/** + * \brief Sub interrupt routine to manage error on control endpoint + * + * \return \c 1 if an error about control endpoint is occurred, otherwise \c 0. + */ +static bool udd_ctrl_interrupt_error(void); + +/** + * \brief Sub interrupt routine to manage a SETUP transfer complete on control endpoint + * + * \return \c 1 if an SETUP transfer complete about control endpoint is occurred, + * otherwise \c 0. + */ +static bool udd_ctrl_interrupt_tc_setup(void); + +//@} + + +/** + * \name Management of bulk/interrupt/isochronous endpoints + * + * The UDD manages the data transfer on endpoints: + * - Start data transfer on endpoint with USB Device DMA + * - Send a ZLP packet if requested + * - Call callback registered to signal end of transfer + * The transfer abort and stall feature are supported. + */ +//@{ +#if (0!=USB_DEVICE_MAX_EP) + +//! Structure definition about job registered on an endpoint +typedef struct { + //! A job is registered on this endpoint + uint8_t busy:1; + //! A short packet is requested for this job on endpoint IN + uint8_t b_shortpacket:1; + //! The cache buffer is currently used on endpoint OUT + uint8_t b_use_out_cache_buffer:1; + //! Buffer located in internal RAM to send or fill during job + uint8_t *buf; + //! Size of buffer to send or fill + iram_size_t buf_size; + //! Total number of data transfered on endpoint + iram_size_t nb_trans; + union { + //! Callback to call at the end of transfer + udd_callback_trans_t call_trans; + //! Callback to call when the endpoint halt is cleared + udd_callback_halt_cleared_t call_nohalt; + }; +} udd_ep_job_t; + +//! Array to register a job on bulk/interrupt/isochronous endpoint +static udd_ep_job_t udd_ep_job[USB_DEVICE_MAX_EP * 2]; + +/** + * \brief Buffer to store the data received on bulk/interrupt endpoints + * + * Used to avoid a RAM buffer overflow in case of the user buffer + * is smaller than endpoint size + * + * \warning The isochronous endpoint is not protected by this system + * and the user must always use a buffer corresponding at endpoint size + */ +#ifdef USB_DEVICE_LOW_SPEED +static uint8_t udd_ep_out_cache_buffer[USB_DEVICE_MAX_EP][8]; +#else +static uint8_t udd_ep_out_cache_buffer[USB_DEVICE_MAX_EP][64]; +#endif + + +/** + * \brief Checks endpoint number + * + * \param ep endpoint number + */ +bool udd_ep_is_valid(udd_ep_id_t ep); + +/** + * \brief Manages transfer complete on bulk/interrupt/isochronous endpoints + * + * \param ep endpoint number to manage + */ +static void udd_ep_trans_complet(udd_ep_id_t ep); + +/** + * \brief Returns the size of endpoint + * + * \return the size of current selected endpoint + */ +static uint16_t udd_ep_get_size(UDD_EP_t * ep_ctrl); + +/** + * \brief Returns a pointer on endpoint job corresponding at endpoint number + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + */ +static udd_ep_job_t *udd_ep_get_job(udd_ep_id_t ep); + +#endif // (0!=USB_DEVICE_MAX_EP) +//@} + + +void udd_enable(void) +{ + uint8_t i; + irqflags_t flags; + + // Sanity check Silicon revision +#if AVR8_PART_IS_DEFINED(ATxmega128A1U) + // The part ATxmega128A1U Rev. J is not supported, please use new silicon revision. + Assert(!(MCU_REVID < 0x0A)); +#endif + +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC +# if CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC == OSC_ID_USBSOF + // RC oscillator calibration via USB Start Of Frame is not available + // in low speed mode. + // Thus, the calibration is disabled + // when USB interface start in low speed mode + DFLLRC32M.CTRL = 0; +# endif +#endif + +#ifdef USB_DEVICE_LOW_SPEED + // The USB hardware need of 6MHz in low speed mode + sysclk_enable_usb(6); + udd_set_low_speed(); +#else + // The USB hardware need of 48MHz in full speed mode + sysclk_enable_usb(48); + udd_set_full_speed(); +#endif + +// The XMEGA_A1U does not support the RC calibration through Keepalive (Low speed). +#if (!defined USB_DEVICE_LOW_SPEED) || (!XMEGA_A1U) +# ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC +# if CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC == OSC_ID_USBSOF + // The SOF calibration can be enabled + DFLLRC32M.CTRL = DFLL_ENABLE_bm; +# endif +# endif +#endif + + flags = cpu_irq_save(); + + // Reset endpoints table + for (i = 0; i < ((USB_DEVICE_MAX_EP + 1) * 2); i++) { + udd_sram.ep_ctrl[i].CTRL = 0; + } +#if (0!=USB_DEVICE_MAX_EP) + // Reset internal variables + for (i = 0; i < (USB_DEVICE_MAX_EP * 2); i++) { + udd_ep_job[i].busy = false; + } +#endif + + //** Enable USB hardware + usb_pad_init(); + udd_set_nb_max_ep(USB_DEVICE_MAX_EP); + udd_enable_interface(); + udd_enable_store_frame_number(); + udd_set_ep_table_addr(udd_sram.ep_ctrl); + // Enable TC fifo management + udd_enable_fifo(); + udd_reset_fifo(); + // Enable Interrupt USB Device + udd_enable_interrupt(UDD_USB_INT_LEVEL); + +#ifndef UDD_NO_SLEEP_MGR + // Initialize the sleep mode authorized for the USB suspend mode + udd_b_idle = false; + sleepmgr_lock_mode(USBC_SLEEP_MODE_USB_SUSPEND); +#endif + + cpu_irq_restore(flags); +} + + +void udd_disable(void) +{ + irqflags_t flags; + flags = cpu_irq_save(); + udd_detach_device(); + // Disable interface + USB_CTRLA = 0; + USB_CTRLB = 0; + sysclk_disable_usb(); + udd_sleep_mode(false); +#ifndef UDD_NO_SLEEP_MGR + sleepmgr_unlock_mode(USBC_SLEEP_MODE_USB_SUSPEND); +#endif + cpu_irq_restore(flags); +} + +bool udd_include_vbus_monitoring(void) +{ + return false; // No Vbus monitoring +} + +void udd_attach(void) +{ + irqflags_t flags; + flags = cpu_irq_save(); + + // At startup the USB bus state is unknown, + // therefore the state is considered IDLE to not miss any USB event + udd_sleep_mode(true); + + udd_ack_suspend_event(); + udd_ack_resume_event(); + udd_attach_device(); + // Enable main USB interrupts + udd_enable_tc_interrupt(); + udd_enable_busevt_interrupt(); + udd_enable_setup_interrupt(); + udd_enable_start_of_frame_interrupt(); + + cpu_irq_restore(flags); +} + +void udd_detach(void) +{ + // Detach device from the bus + udd_detach_device(); +} + +bool udd_is_high_speed(void) +{ + return false; +} + +void udd_set_address(uint8_t address) +{ + udd_set_device_address(address); +} + +uint8_t udd_getaddress(void) +{ + return udd_get_device_address(); +} + +uint16_t udd_get_frame_number(void) +{ + return udd_sram.frame_number; +} + +uint16_t udd_get_micro_frame_number(void) +{ + return 0; +} + +void udd_send_remotewakeup(void) +{ +#ifndef UDD_NO_SLEEP_MGR + if (!udd_b_idle) +#endif + { + udd_sleep_mode(true); // Enter in IDLE mode + udd_send_remote_wake_up(); + } +} + +void udd_set_setup_payload( uint8_t *payload, uint16_t payload_size ) +{ + udd_g_ctrlreq.payload = payload; + udd_g_ctrlreq.payload_size = payload_size; +} + +#if (0!=USB_DEVICE_MAX_EP) +bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, + uint16_t MaxEndpointSize) +{ + UDD_EP_t *ep_ctrl; + Assert(udd_ep_is_valid(ep)); + + ep_ctrl = udd_ep_get_ctrl(ep); + if (udd_endpoint_is_enable(ep_ctrl)) { + return false; // Already allocated + } + udd_ep_init(ep, bmAttributes, MaxEndpointSize); + + // Do not use multipacket mode with isochronous 1023 bytes endpoint + if (udd_endpoint_get_type(ep_ctrl)==USB_EP_TYPE_ISOCHRONOUS_gc + && (udd_endpoint_get_size_field(ep_ctrl) + ==USB_EP_BUFSIZE_1023_gc)) { + return true; + } + + udd_endpoint_set_multipacket(ep_ctrl); + return true; +} + +void udd_ep_free(udd_ep_id_t ep) +{ + UDD_EP_t *ep_ctrl; + Assert(udd_ep_is_valid(ep)); + + udd_ep_abort(ep); + ep_ctrl = udd_ep_get_ctrl(ep); + udd_endpoint_disable(ep_ctrl); +} + +bool udd_ep_is_halted(udd_ep_id_t ep) +{ + UDD_EP_t *ep_ctrl; + Assert(udd_ep_is_valid(ep)); + + ep_ctrl = udd_ep_get_ctrl(ep); + return (udd_endpoint_is_stall(ep_ctrl)); +} + +bool udd_ep_set_halt(udd_ep_id_t ep) +{ + UDD_EP_t *ep_ctrl; + Assert(udd_ep_is_valid(ep)); + + ep_ctrl = udd_ep_get_ctrl(ep); + udd_endpoint_enable_stall(ep_ctrl); + udd_endpoint_clear_dtgl(ep_ctrl); + + udd_ep_abort(ep); + return true; +} + +bool udd_ep_clear_halt(udd_ep_id_t ep) +{ + udd_ep_job_t *ptr_job; + UDD_EP_t *ep_ctrl; + Assert(udd_ep_is_valid(ep)); + + ep_ctrl = udd_ep_get_ctrl(ep); + if (!udd_endpoint_is_stall(ep_ctrl)) { + return true; // No stall on going + } + udd_endpoint_disable_stall(ep_ctrl); + + // If a job is register on clear halt action + // then execute callback + ptr_job = udd_ep_get_job(ep); + if (ptr_job->busy == true) { + ptr_job->busy = false; + ptr_job->call_nohalt(); + } + return true; +} + +bool udd_ep_run(udd_ep_id_t ep, bool b_shortpacket, uint8_t * buf, + iram_size_t buf_size, udd_callback_trans_t callback) +{ + udd_ep_job_t *ptr_job; + irqflags_t flags; + UDD_EP_t *ep_ctrl; + + Assert(udd_ep_is_valid(ep)); + + // Get control & job about this endpoint + ptr_job = udd_ep_get_job(ep); + ep_ctrl = udd_ep_get_ctrl(ep); + + if (!udd_endpoint_is_enable(ep_ctrl)) { + return false; // Endpoint not allocated + } + if (udd_endpoint_get_type(ep_ctrl)!=USB_EP_TYPE_ISOCHRONOUS_gc + && udd_endpoint_is_stall(ep_ctrl)) { + return false; // Endpoint is halted + } + flags = cpu_irq_save(); + if (ptr_job->busy == true) { + cpu_irq_restore(flags); + return false; // Job already on going + } + ptr_job->busy = true; + cpu_irq_restore(flags); + + + // Update Job information + ptr_job->buf = buf; + ptr_job->buf_size = buf_size; + ptr_job->nb_trans = 0; + ptr_job->call_trans = callback; + // Need to enable shortpacket to send a ZLP (buf_size==0) + ptr_job->b_shortpacket = b_shortpacket || (buf_size==0); + ptr_job->b_use_out_cache_buffer = false; + + // Initialize value to simulate a empty transfer + if (USB_EP_DIR_IN == (ep & USB_EP_DIR_IN)) { + udd_endpoint_in_reset_nb_sent(ep_ctrl); + } + else + { + if ((USB_EP_TYPE_ISOCHRONOUS_gc == udd_endpoint_get_type(ep_ctrl)) + && (0 != (buf_size % udd_ep_get_size(ep_ctrl)))) { + // The user must use a buffer size modulo endpoint size + ptr_job->busy = false; + return false; + } + udd_endpoint_out_reset_nb_received(ep_ctrl); + udd_endpoint_out_set_nbbyte(ep_ctrl, 0); + } + // Request next transfer + udd_ep_trans_complet(ep); + return true; +} + +void udd_ep_abort(udd_ep_id_t ep) +{ + UDD_EP_t *ep_ctrl; + udd_ep_job_t *ptr_job; + Assert(udd_ep_is_valid(ep)); + + ep_ctrl = udd_ep_get_ctrl(ep); + ptr_job = udd_ep_get_job(ep); + + // Stop transfer + udd_endpoint_set_NACK0(ep_ctrl); + if (ptr_job->busy == false) { + return; // No job on going + } + ptr_job->busy = false; + if (NULL != ptr_job->call_trans) { + ptr_job->call_trans(UDD_EP_TRANSFER_ABORT, + (ep & USB_EP_DIR_IN) ? + udd_endpoint_in_nb_sent(ep_ctrl) + : udd_endpoint_out_nb_receiv(ep_ctrl), + ep); + } +} + +bool udd_ep_wait_stall_clear(udd_ep_id_t ep, + udd_callback_halt_cleared_t callback) +{ + udd_ep_job_t *ptr_job; + UDD_EP_t *ep_ctrl; + Assert(udd_ep_is_valid(ep)); + + ep_ctrl = udd_ep_get_ctrl(ep); + ptr_job = udd_ep_get_job(ep); + + if (udd_endpoint_is_stall(ep_ctrl)) { + // Wait clear halt endpoint + if (ptr_job->busy == true) { + return false; // Job already on going + } + ptr_job->busy = true; + ptr_job->call_nohalt = callback; + } else { + // endpoint not halted then call directly callback + callback(); + } + return true; +} +#endif // (0!=USB_DEVICE_MAX_EP) + +//-------------------------------------------------------- +//--- INTERNAL ROUTINES TO MANAGED GLOBAL EVENTS + +/** + * \internal + * \brief Function called by USB bus event interrupt + * + * USB bus event interrupt includes : + * - USB line events SOF, reset, suspend, resume, wakeup + * - endpoint control errors underflow, overflow, stall + */ +ISR(USB_BUSEVENT_vect) +{ + if (udd_is_start_of_frame_event()) { + udd_ack_start_of_frame_event(); + udc_sof_notify(); +#ifdef UDC_SOF_EVENT + UDC_SOF_EVENT(); +#endif + goto udd_interrupt_bus_event_end; + } + + if (udd_ctrl_interrupt_error()) { + goto udd_interrupt_bus_event_end; + } + if (udd_is_reset_event()) { + udd_ack_reset_event(); +#if (0!=USB_DEVICE_MAX_EP) + // Abort all endpoint jobs on going + uint8_t i; + for (i = 1; i < USB_DEVICE_MAX_EP; i++) { + udd_ep_abort(i); + udd_ep_abort(i | USB_EP_DIR_IN); + } +#endif + udc_reset(); + + // Reset USB address to 0 + udd_set_device_address(0); + // Alloc and configure control endpoint + udd_ep_init(0, USB_EP_TYPE_CONTROL, USB_DEVICE_EP_CTRL_SIZE); + udd_ep_init(0 | USB_EP_DIR_IN, USB_EP_TYPE_CONTROL, + USB_DEVICE_EP_CTRL_SIZE); + udd_control_out_set_buf(&udd_ctrl_buffer); + // Reset endpoint control management + udd_ctrl_init(); + goto udd_interrupt_bus_event_end; + } + + if (udd_is_suspend_event()) { + udd_ack_suspend_event(); + udd_sleep_mode(false); // Enter in SUSPEND mode +#ifdef UDC_SUSPEND_EVENT + UDC_SUSPEND_EVENT(); +#endif + goto udd_interrupt_bus_event_end; + } + + if (udd_is_resume_event()) { + udd_ack_resume_event(); + udd_sleep_mode(true); // Enter in power reduction mode +#ifdef UDC_RESUME_EVENT + UDC_RESUME_EVENT(); +#endif + goto udd_interrupt_bus_event_end; + } + +udd_interrupt_bus_event_end: + return; +} + +/** + * \internal + * \brief Function called by USB transfer complete interrupt + * + * USB transfer complete interrupt includes events about endpoint transfer on all endpoints. + */ +ISR(USB_TRNCOMPL_vect) +{ +#if (0!=USB_DEVICE_MAX_EP) + uint8_t ep_index; + uint8_t i_fifo; + uint16_t ad; + uint16_t *p_ad; + int8_t rp; + UDD_EP_t *ep_ctrl; + udd_ep_id_t ep; +#endif + + if (!udd_is_tc_event()) { + // If no other transfer complete + // then check reception of SETUP packet on control endpoint + if (udd_ctrl_interrupt_tc_setup()) { + // Interrupt acked by control endpoint managed + goto udd_interrupt_tc_end; + } + Assert(false); + } + // Check IN/OUT transfer complete on all endpoints + udd_ack_tc_event(); + +#if (0!=USB_DEVICE_MAX_EP) + //** Decode TC FIFO + // Compute ep addr + rp = udd_get_fifo_rp(); + i_fifo = 2 * (1 + ~rp); + ad = ((uint16_t) udd_sram.ep_ctrl) - i_fifo; + p_ad = (uint16_t *) ad; + // Compute ep + ep_index = (((uint16_t) * p_ad - ((uint16_t) udd_sram.ep_ctrl)) >> 3); + ep = (ep_index / 2) + ((ep_index & 1) ? USB_EP_DIR_IN : 0); + Assert(USB_DEVICE_MAX_EP >= (ep & USB_EP_ADDR_MASK)); + + // Ack IT TC of endpoint + ep_ctrl = udd_ep_get_ctrl(ep); + if (!udd_endpoint_transfer_complete(ep_ctrl)) { + return; // Error, TC is generated by Multipacket transfer + } + udd_endpoint_ack_transfer_complete(ep_ctrl); + + // Check status on control endpoint + if (ep == 0) { + udd_ctrl_out_received(); + goto udd_interrupt_tc_end; // Interrupt acked by control endpoint managed + } + if (ep == (0 | USB_EP_DIR_IN)) { + udd_ctrl_in_sent(); + goto udd_interrupt_tc_end; // Interrupt acked by control endpoint managed + } + Assert(udd_ep_is_valid(ep)); + // Manage end of transfer on endpoint bulk/interrupt/isochronous + udd_ep_trans_complet(ep); + +#else + + udd_get_fifo_rp(); + if (udd_endpoint_transfer_complete(udd_ep_get_ctrl(0))) { + udd_endpoint_ack_transfer_complete(udd_ep_get_ctrl(0)); + udd_ctrl_out_received(); + }else{ + udd_endpoint_ack_transfer_complete(udd_ep_get_ctrl(0 | USB_EP_DIR_IN)); + udd_ctrl_in_sent(); + } +#endif + +udd_interrupt_tc_end: + return; +} + +//-------------------------------------------------------- +//--- INTERNAL ROUTINES TO INITIALIZE ENDPOINT + +static void udd_ep_init(udd_ep_id_t ep, uint8_t bmAttributes, + uint16_t MaxEndpointSize) +{ + USB_EP_TYPE_t type; + USB_EP_BUFSIZE_t size; + UDD_EP_t *ep_ctrl; + +#if (0!=USB_DEVICE_MAX_EP) + // Translate USB attribute to hardware defines + switch (bmAttributes & USB_EP_TYPE_MASK) { + case USB_EP_TYPE_CONTROL: + type = USB_EP_TYPE_CONTROL_gc; + break; + case USB_EP_TYPE_ISOCHRONOUS: + type = USB_EP_TYPE_ISOCHRONOUS_gc; + break; + case USB_EP_TYPE_BULK: + case USB_EP_TYPE_INTERRUPT: //interrupt behaves as bulk + type = USB_EP_TYPE_BULK_gc; + break; + default: + Assert(false); // Wrong value + break; + } +#else + type = USB_EP_TYPE_CONTROL_gc; +#endif + + // Translate USB endpoint size to hardware defines + switch (MaxEndpointSize) { + default: + Assert(false); // Wrong value + case 8: + size = USB_EP_BUFSIZE_8_gc; + break; + case 16: + size = USB_EP_BUFSIZE_16_gc; + break; + case 32: + size = USB_EP_BUFSIZE_32_gc; + break; + case 64: + size = USB_EP_BUFSIZE_64_gc; + break; +#if (0!=USB_DEVICE_MAX_EP) + case 128: + size = USB_EP_BUFSIZE_128_gc; + break; + case 256: + size = USB_EP_BUFSIZE_256_gc; + break; + case 512: + size = USB_EP_BUFSIZE_512_gc; + break; + case 1023: + size =USB_EP_BUFSIZE_1023_gc; + break; +#endif + } + + // Enable endpoint + ep_ctrl = udd_ep_get_ctrl(ep); + udd_endpoint_disable(ep_ctrl); + udd_endpoint_clear_status(ep_ctrl); + udd_endpoint_set_control(ep_ctrl, (uint8_t) type | (uint8_t) size); +} + +static UDD_EP_t *udd_ep_get_ctrl(udd_ep_id_t ep) +{ + return &udd_sram.ep_ctrl[(2 * (ep & USB_EP_ADDR_MASK) + + ((ep & USB_EP_DIR_IN) ? 1 : 0))]; +} + + +//-------------------------------------------------------- +//--- INTERNAL ROUTINES TO MANAGED THE CONTROL ENDPOINT + +static void udd_ctrl_init(void) +{ + udd_disable_overflow_interrupt(); + udd_disable_underflow_interrupt(); + + // Clear status flag from control endpoints + // Mandatory for ATxmega128A1 Rev. K + udd_control_in_set_NACK0(); + udd_control_in_set_bytecnt(0); + udd_control_in_ack_tc(); + udd_control_ack_in_underflow(); + udd_control_out_ack_tc(); + udd_control_ack_out_overflow(); + + udd_g_ctrlreq.callback = NULL; + udd_g_ctrlreq.over_under_run = NULL; + udd_g_ctrlreq.payload_size = 0; + udd_ep_control_state = UDD_EPCTRL_SETUP; +} + +static void udd_ctrl_setup_received(void) +{ + if (UDD_EPCTRL_SETUP != udd_ep_control_state) { + if ((UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP == udd_ep_control_state) + || (UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP == udd_ep_control_state)) { + // Accept that ZLP event can be hidden by setup packet event + // in case of setup packet sending quickly after a ZLP + udd_ctrl_endofrequest(); + } + // Reinitializes control endpoint management + udd_ctrl_init(); + } + // Fill setup request structure + if (8 != udd_control_out_get_bytecnt()) + return; // Error data number don't correspond to SETUP packet + memcpy((uint8_t *) & udd_g_ctrlreq.req, udd_ctrl_buffer, 8); + + // To detect a protocol error on setup, enable nak interrupt on IN/OUT of control endpoint + udd_enable_overflow_interrupt(); + udd_enable_underflow_interrupt(); + + // Decode setup request + if (udc_process_setup() == false) { + // Setup request unknown then stall it + udd_ctrl_stall_data(); + return; + } + + if (Udd_setup_is_in()) { + udd_ctrl_prev_payload_nb_trans = 0; + udd_ctrl_payload_nb_trans = 0; + udd_ep_control_state = UDD_EPCTRL_DATA_IN; + udd_ctrl_in_sent(); // Send first data transfer + } else { + if (0 == udd_g_ctrlreq.req.wLength) { + // No data phase requested + // Send IN ZLP to ACK setup request + udd_ctrl_send_zlp_in(); + return; + } + // OUT data phase requested + udd_ctrl_prev_payload_nb_trans = 0; + udd_ctrl_payload_nb_trans = 0; + udd_ep_control_state = UDD_EPCTRL_DATA_OUT; + // Clear packet to receive first packet + udd_control_out_clear_NACK0(); + } +} + +static void udd_ctrl_in_sent(void) +{ + static bool b_shortpacket = false; + uint16_t nb_remain; + + if (UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP == udd_ep_control_state) { + // ZLP on IN is sent, then valid end of setup request + udd_ctrl_endofrequest(); + // Reinitializes control endpoint management + udd_ctrl_init(); + return; + } + Assert(udd_ep_control_state == UDD_EPCTRL_DATA_IN); + + nb_remain = udd_g_ctrlreq.payload_size - udd_ctrl_payload_nb_trans; + if (0 == nb_remain) { + // Update number of total data sending by previous playload buffer + udd_ctrl_prev_payload_nb_trans += udd_ctrl_payload_nb_trans; + if ((udd_g_ctrlreq.req.wLength == udd_ctrl_prev_payload_nb_trans) + || b_shortpacket) { + // All data requested are transfered or a short packet has been sent + // then it is the end of data phase. + // Generate an OUT ZLP for handshake phase. + udd_ctrl_send_zlp_out(); + return; + } + // Need of new buffer because the data phase is not complete + if ((!udd_g_ctrlreq.over_under_run) + || (!udd_g_ctrlreq.over_under_run())) { + // Underrun then send zlp on IN + // nb_remain == 0 allows to send a IN ZLP + } else { + // A new payload buffer is given + udd_ctrl_payload_nb_trans = 0; + nb_remain = udd_g_ctrlreq.payload_size; + } + } + // Continue transfer an send next data + if (nb_remain >= USB_DEVICE_EP_CTRL_SIZE) { + nb_remain = USB_DEVICE_EP_CTRL_SIZE; + b_shortpacket = false; + } else { + b_shortpacket = true; + } + udd_control_in_set_bytecnt(nb_remain); + + // Link payload buffer directly on USB hardware + udd_control_in_set_buf(udd_g_ctrlreq.payload + udd_ctrl_payload_nb_trans); + udd_ctrl_payload_nb_trans += nb_remain; + + // Valid and sent the data available in control endpoint buffer + udd_control_in_clear_NACK0(); +} + +static void udd_ctrl_out_received(void) +{ + uint16_t nb_data; + + if (UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP == udd_ep_control_state) { + // Valid end of setup request + udd_ctrl_endofrequest(); + // Reinitializes control endpoint management + udd_ctrl_init(); + return; + } + Assert(udd_ep_control_state == UDD_EPCTRL_DATA_OUT); + + // Read data received during OUT phase + nb_data = udd_control_out_get_bytecnt(); + + if (udd_g_ctrlreq.payload_size < (udd_ctrl_payload_nb_trans + nb_data)) { + // Payload buffer too small, ignore data remaining + nb_data = udd_g_ctrlreq.payload_size - udd_ctrl_payload_nb_trans; + } + + memcpy((uint8_t *) (udd_g_ctrlreq.payload + udd_ctrl_payload_nb_trans), + udd_ctrl_buffer, nb_data); + udd_ctrl_payload_nb_trans += nb_data; + + if ((USB_DEVICE_EP_CTRL_SIZE != nb_data) || (udd_g_ctrlreq.req.wLength + <= (udd_ctrl_prev_payload_nb_trans + + udd_ctrl_payload_nb_trans))) { + // End of reception because it is a short packet + // or all data are transfered + + // Before send ZLP, call intermediate callback + // in case of data receive generate a stall + udd_g_ctrlreq.payload_size = udd_ctrl_payload_nb_trans; + if (NULL != udd_g_ctrlreq.over_under_run) { + if (!udd_g_ctrlreq.over_under_run()) { + // Stall ZLP + udd_ctrl_stall_data(); + return; + } + } + // Send IN ZLP to ACK setup request + udd_ctrl_send_zlp_in(); + return; + } + + if (udd_g_ctrlreq.payload_size == udd_ctrl_payload_nb_trans) { + // Overrun then request a new payload buffer + if (!udd_g_ctrlreq.over_under_run) { + // No callback available to request a new payload buffer + udd_ctrl_stall_data(); + return; + } + if (!udd_g_ctrlreq.over_under_run()) { + // No new payload buffer delivered + udd_ctrl_stall_data(); + return; + } + // New payload buffer available + // Update number of total data received + udd_ctrl_prev_payload_nb_trans += udd_ctrl_payload_nb_trans; + // Reinit reception on payload buffer + udd_ctrl_payload_nb_trans = 0; + } + // Free buffer of OUT control endpoint to authorize next reception + udd_control_out_clear_NACK0(); +} + +static void udd_ctrl_underflow(void) +{ + if (udd_is_tc_event() || udd_ctrl_interrupt_tc_setup()) { + return; // underflow ignored if a transfer complete has been no processed + } + if (UDD_EPCTRL_DATA_OUT == udd_ep_control_state) { + // Host want to stop OUT transaction + // then stop to wait OUT data phase and wait IN ZLP handshake + udd_ctrl_send_zlp_in(); + } else if (UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP == udd_ep_control_state) { + // A OUT handshake is waiting by device, + // but host want extra IN data then stall extra IN data and following status stage + udd_control_in_enable_stall(); + udd_control_out_enable_stall(); + } +} + +static void udd_ctrl_overflow(void) +{ + if (udd_is_tc_event() || udd_ctrl_interrupt_tc_setup()) { + return; // overflow ignored if a transfer complete has been no processed + } + if (UDD_EPCTRL_DATA_IN == udd_ep_control_state) { + // Host want to stop IN transaction + // then stop to wait IN data phase and wait OUT ZLP handshake + udd_ctrl_send_zlp_out(); + } else if (UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP == udd_ep_control_state) { + // A IN handshake is waiting by device, + // but host want extra OUT data then stall extra OUT data and following status stage + udd_control_in_enable_stall(); + udd_control_out_enable_stall(); + } +} + +static void udd_ctrl_stall_data(void) +{ + // Stall all packets on IN & OUT control endpoint + udd_ep_control_state = UDD_EPCTRL_STALL_REQ; + udd_control_in_enable_stall(); + udd_control_out_enable_stall(); +} + +static void udd_ctrl_send_zlp_in(void) +{ + udd_ep_control_state = UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP; + // Valid and sent empty IN packet on control endpoint + udd_control_in_set_bytecnt(0); + udd_control_in_clear_NACK0(); +} + +static void udd_ctrl_send_zlp_out(void) +{ + udd_ep_control_state = UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP; + // Valid reception of OUT packet on control endpoint + udd_control_out_clear_NACK0(); +} + +static void udd_ctrl_endofrequest(void) +{ + // If a callback is registered then call it + if (udd_g_ctrlreq.callback) { + udd_g_ctrlreq.callback(); + } +} + +static bool udd_ctrl_interrupt_error(void) +{ + // Underflow only managed for control endpoint + if (udd_is_underflow_event()) { + udd_ack_underflow_event(); + if (udd_control_in_underflow()) { + udd_ctrl_underflow(); + } + return true; + } + // Overflow only managed for control endpoint + if (udd_is_overflow_event()) { + udd_ack_overflow_event(); + if (udd_control_out_overflow()) { + udd_ctrl_overflow(); + } + return true; + } + return false; +} + +static bool udd_ctrl_interrupt_tc_setup(void) +{ + if (!udd_is_setup_event()) { + return false; + } + udd_ack_setup_event(); + + // Clear eventually previous stall events + udd_control_out_ack_stall(); + udd_control_in_ack_stall(); + udd_ack_stall_event(); + + Assert(udd_control_setup()); // A setup must be received on control endpoint + + // Ack SETUP packet and decode request + udd_control_ack_setup(); + udd_ctrl_setup_received(); + return true; +} + + +//-------------------------------------------------------- +//--- INTERNAL ROUTINES TO MANAGED THE BULK/INTERRUPT/ISOCHRONOUS ENDPOINTS + +#if (0!=USB_DEVICE_MAX_EP) + +static uint16_t udd_ep_get_size(UDD_EP_t * ep_ctrl) +{ + // Translate hardware defines to USB endpoint size + switch (udd_endpoint_get_size_field(ep_ctrl)) { + default: + case USB_EP_BUFSIZE_8_gc: + return 8; + case USB_EP_BUFSIZE_16_gc: + return 16; + case USB_EP_BUFSIZE_32_gc: + return 32; + case USB_EP_BUFSIZE_64_gc: + return 64; + case USB_EP_BUFSIZE_128_gc: + return 128; + case USB_EP_BUFSIZE_256_gc: + return 256; + case USB_EP_BUFSIZE_512_gc: + return 512; + case USB_EP_BUFSIZE_1023_gc: + return 1023; + } +} + +static udd_ep_job_t *udd_ep_get_job(udd_ep_id_t ep) +{ + return &udd_ep_job[(2 * (ep & USB_EP_ADDR_MASK) + + ((ep & USB_EP_DIR_IN) ? 1 : 0)) - 2]; +} + +bool udd_ep_is_valid(udd_ep_id_t ep) +{ + ep &= USB_EP_ADDR_MASK; + if (ep == 0) { + return false; + } + return (USB_DEVICE_MAX_EP >= ep); +} + +static void udd_ep_trans_complet(udd_ep_id_t ep) +{ + UDD_EP_t *ep_ctrl; + udd_ep_job_t *ptr_job; + uint16_t ep_size, nb_trans; + iram_size_t next_trans; + + ptr_job = udd_ep_get_job(ep); + ep_ctrl = udd_ep_get_ctrl(ep); + ep_size = udd_ep_get_size(ep_ctrl); + + if (USB_EP_DIR_IN == (ep & USB_EP_DIR_IN)) { + // Transfer complete on IN + nb_trans = udd_endpoint_in_nb_sent(ep_ctrl); + + // Update number of data transfered + ptr_job->nb_trans += nb_trans; + + // Need to send other data + if (ptr_job->nb_trans != ptr_job->buf_size) { + next_trans = ptr_job->buf_size - ptr_job->nb_trans; + if (UDD_ENDPOINT_MAX_TRANS < next_trans) { + // The USB hardware support a maximum + // transfer size of UDD_ENDPOINT_MAX_TRANS Bytes + next_trans = UDD_ENDPOINT_MAX_TRANS - + (UDD_ENDPOINT_MAX_TRANS % ep_size); + } + // Need ZLP, if requested and last packet is not a short packet + ptr_job->b_shortpacket = ptr_job->b_shortpacket + && (0==(next_trans % ep_size)); + udd_endpoint_in_reset_nb_sent(ep_ctrl); + udd_endpoint_in_set_bytecnt(ep_ctrl, next_trans); + // Link the user buffer directly on USB hardware DMA + udd_endpoint_set_buf(ep_ctrl, &ptr_job->buf[ptr_job->nb_trans]); + udd_endpoint_clear_NACK0(ep_ctrl); + return; + } + + // Need to send a ZLP after all data transfer + if (ptr_job->b_shortpacket) { + ptr_job->b_shortpacket = false; + udd_endpoint_in_reset_nb_sent(ep_ctrl); + udd_endpoint_in_set_bytecnt(ep_ctrl, 0); + udd_endpoint_clear_NACK0(ep_ctrl); + return; + } + } + else + { + // Transfer complete on OUT + nb_trans = udd_endpoint_out_nb_receiv(ep_ctrl); + + // Can be necessary to copy data receive from cache buffer to user buffer + if (ptr_job->b_use_out_cache_buffer) { + memcpy(&ptr_job->buf[ptr_job->nb_trans] + , udd_ep_out_cache_buffer[ep - 1] + , ptr_job->buf_size % ep_size); + } + + // Update number of data transfered + ptr_job->nb_trans += nb_trans; + if (ptr_job->nb_trans > ptr_job->buf_size) { + ptr_job->nb_trans = ptr_job->buf_size; + } + + // If all previous data requested are received and user buffer not full + // then need to receive other data + if ((nb_trans == udd_endpoint_out_get_nbbyte_requested(ep_ctrl)) + && (ptr_job->nb_trans != ptr_job->buf_size)) { + next_trans = ptr_job->buf_size - ptr_job->nb_trans; + if (UDD_ENDPOINT_MAX_TRANS < next_trans) { + // The USB hardware support a maximum transfer size + // of UDD_ENDPOINT_MAX_TRANS Bytes + next_trans = UDD_ENDPOINT_MAX_TRANS + - (UDD_ENDPOINT_MAX_TRANS % ep_size); + } else { + next_trans -= next_trans % ep_size; + } + + udd_endpoint_out_reset_nb_received(ep_ctrl); + if (next_trans < ep_size) { + // Use the cache buffer for Bulk or Interrupt size endpoint + ptr_job->b_use_out_cache_buffer = true; + udd_endpoint_set_buf( ep_ctrl, + udd_ep_out_cache_buffer[ep - 1]); + udd_endpoint_out_set_nbbyte(ep_ctrl, ep_size); + } else { + // Link the user buffer directly on USB hardware DMA + udd_endpoint_set_buf(ep_ctrl, &ptr_job->buf[ptr_job->nb_trans]); + udd_endpoint_out_set_nbbyte(ep_ctrl, next_trans); + } + // Start transfer + udd_endpoint_clear_NACK0(ep_ctrl); + return; + } + } + + // Job complete then call callback + if (ptr_job->busy) { + ptr_job->busy = false; + if (NULL != ptr_job->call_trans) { + ptr_job->call_trans(UDD_EP_TRANSFER_OK, + ptr_job->nb_trans, + ep); + } + } + return; +} +#endif // (0!=USB_DEVICE_MAX_EP) +//@} diff --git a/Firmware/Atmel DFU Bootloader/xmega/drivers/usb/usb_device.h b/Firmware/Atmel DFU Bootloader/xmega/drivers/usb/usb_device.h new file mode 100644 index 0000000..89cb8f8 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/xmega/drivers/usb/usb_device.h @@ -0,0 +1,387 @@ +/** + * \file + * + * \brief USB Driver header file for XMEGA products including USB interface. + * + * Copyright (c) 2011-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 _USB_DEVICE_H_ +#define _USB_DEVICE_H_ + +#include + +/** + * \ingroup udd_group + * \defgroup udd_xmega_usb_group Xmega USB Device Driver + * USBC low-level driver for USB Device mode + * + * + * @{ + */ + +//! @name USB Device main management +//! @{ + +/** + * \brief Initializes the USB DP/DM buffers + * + * This functions initializes the USB buffer using the calibration value + * stored in production raw. + * If the calibration value is not found (0xFF) value, a default typical + * value is applied. + * Alternatively user can force calibration values using USB_PAD_USER_CAL0 + * and USB_PAD_USER_CAL1 + * + */ +static inline void usb_pad_init(void) +{ + uint8_t cal; + +#ifdef USB_PAD_USER_CAL0 + USB_CAL0 = USB_PAD_USER_CAL0; +#else + cal = nvm_read_production_signature_row + (nvm_get_production_signature_row_offset(USBCAL0)); + if (cal != 0xFF) { + USB_CAL0 = cal; + } else { + USB_CAL0 = 0x1F; + } +#endif + +#ifdef USB_PAD_USER_CAL1 + USB_CAL1 = USB_PAD_USER_CAL1; +#else + cal = nvm_read_production_signature_row + (nvm_get_production_signature_row_offset(USBCAL1)); + if (cal != 0xFF) { + USB_CAL1 = cal; + } else { + USB_CAL1 = 0x1F; + } +#endif +} + +#define udd_enable_interface() (USB_CTRLA |= USB_ENABLE_bm) +#define udd_disable_interface() (USB_CTRLA &= ~USB_ENABLE_bm) +#define udd_attach_device() (USB_CTRLB |= USB_ATTACH_bm) +#define udd_detach_device() (USB_CTRLB &= ~USB_ATTACH_bm) +#define udd_gnak_disable() (USB_CTRLB &= ~USB_GNACK_bm) +#define udd_gnak_enable() (USB_CTRLB |= USB_GNACK_bm) +#define udd_gnak_is_enable() (USB_CTRLB & USB_GNACK_bm) +#define udd_set_nb_max_ep(n) (USB_CTRLA |= n) +#define udd_enable_store_frame_number() (USB_CTRLA |= USB_STFRNUM_bm) +#define udd_disable_store_frame_number() (USB_CTRLA &= ~USB_STFRNUM_bm) +#define udd_set_full_speed() (USB_CTRLA |= USB_SPEED_bm) +#define udd_set_low_speed() (USB_CTRLA &= ~USB_SPEED_bm) +#define udd_set_ep_table_addr(n) (USB.EPPTR = (uint16_t)n) +#define udd_get_ep_table_addr() (USB.EPPTR) +#define udd_get_fifo_rp() (USB_FIFORP) +#define udd_reset_fifo() (USB_FIFORP=0xFF) +#define udd_enable_interrupt(level) (USB_INTCTRLA |= level&(USB_INTLVL1_bm|USB_INTLVL0_bm)) + +#define udd_set_device_address(n) (USB_ADDR=n) +#define udd_get_device_address() (USB_ADDR) +#define udd_enable_fifo() (USB_CTRLA |= USB_FIFOEN_bm) +#define udd_disable_fifo() (USB_CTRLA &= ~USB_FIFOEN_bm) + +#define udd_send_remote_wake_up() (USB_CTRLB &= ~USB_RWAKEUP_bm, USB_CTRLB |= USB_RWAKEUP_bm) +#define udd_set_global_nack() (USB_CTRLB |= USB_GNACK_bm) +#define udd_is_crc_event() (USB_INTFLAGSASET & USB_CRCIF_bm ? true : false) +#define udd_ack_crc_event() (USB_INTFLAGSACLR = USB_CRCIF_bm) +#define udd_set_crc_event() (USB_INTFLAGSASET = USB_CRCIF_bm) +#define udd_enable_crc_interrupt() (USB_INTCTRLA |= USB_CRCIE_bm) +#define udd_disable_crc_interrupt() (USB_INTCTRLA &= ~USB_CRCIE_bm) + +#define udd_is_start_of_frame_event() (USB_INTFLAGSASET & USB_SOFIF_bm ? true : false) +#define udd_ack_start_of_frame_event() (USB_INTFLAGSACLR = USB_SOFIF_bm) +#define udd_set_start_of_frame_event() (USB_INTFLAGSASET = USB_SOFIF_bm) +#define udd_enable_start_of_frame_interrupt() (USB_INTCTRLA |= USB_SOFIE_bm) +#define udd_disable_start_of_frame_interrupt() (USB_INTCTRLA &= ~USB_SOFIE_bm) +#define udd_is_enable_start_of_frame_interrupt() (0!=(USB_INTCTRLA|USB_SOFIE_bm)) + +#define udd_is_reset_event() (USB_INTFLAGSASET & USB_RSTIF_bm ? true : false) +#define udd_ack_reset_event() (USB_INTFLAGSACLR = USB_RSTIF_bm) +#define udd_set_reset_event() (USB_INTFLAGSASET = USB_RSTIF_bm) + +#define udd_is_suspend_event() (USB_INTFLAGSASET & USB_SUSPENDIF_bm ? true : false) +#define udd_ack_suspend_event() (USB_INTFLAGSACLR = USB_SUSPENDIF_bm) +#define udd_set_suspend_event() (USB_INTFLAGSASET = USB_SUSPENDIF_bm) + +#define udd_is_resume_event() (USB_INTFLAGSASET & USB_RESUMEIF_bm ? true : false) +#define udd_ack_resume_event() (USB_INTFLAGSACLR = USB_RESUMEIF_bm) +#define udd_set_resume_event() (USB_INTFLAGSASET = USB_RESUMEIF_bm) + +#define udd_enable_busevt_interrupt() (USB_INTCTRLA |= USB_BUSEVIE_bm) +#define udd_disable_busevt_interrupt() (USB_INTCTRLA &= ~USB_BUSEVIE_bm) + +#define udd_is_setup_event() (USB_INTFLAGSBCLR & USB_SETUPIF_bm ? true : false) +#define udd_ack_setup_event() (USB_INTFLAGSBCLR = USB_SETUPIF_bm) +#define udd_set_setup_event() (USB_INTFLAGSBSET = USB_SETUPIF_bm) +#define udd_enable_setup_interrupt() (USB_INTCTRLB |= USB_SETUPIE_bm) +#define udd_disable_setup_interrupt() (USB_INTCTRLB &= ~USB_SETUPIE_bm) + +#define udd_is_tc_event() (USB_INTFLAGSBCLR & USB_TRNIF_bm ? true : false) +#define udd_ack_tc_event() (USB_INTFLAGSBCLR = USB_TRNIF_bm) +#define udd_set_tc_event() (USB_INTFLAGSBSET = USB_TRNIF_bm) +#define udd_enable_tc_interrupt() (USB_INTCTRLB |= USB_TRNIE_bm) +#define udd_disable_tc_interrupt() (USB_INTCTRLB &= ~USB_TRNIE_bm) + +#define udd_is_overflow_event() (USB_INTFLAGSASET & USB_OVFIF_bm ? true : false) +#define udd_ack_overflow_event() (USB_INTFLAGSACLR = USB_OVFIF_bm) +#define udd_set_overflow_event() (USB_INTFLAGSASET = USB_OVFIF_bm) +#define udd_enable_overflow_interrupt() (USB_INTCTRLA |= USB_BUSERRIE_bm) +#define udd_disable_overflow_interrupt() (USB_INTCTRLA &= ~USB_BUSERRIE_bm) +#define udd_is_enable_overflow_interrupt() (USB_INTCTRLA&USB_BUSERRIE_bm ? true : false) + +#define udd_is_underflow_event() (USB_INTFLAGSASET & USB_UNFIF_bm ? true : false) +#define udd_ack_underflow_event() (USB_INTFLAGSACLR = USB_UNFIF_bm) +#define udd_set_underflow_event() (USB_INTFLAGSASET = USB_UNFIF_bm) +#define udd_enable_underflow_interrupt() (USB_INTCTRLA |= USB_BUSERRIE_bm) +#define udd_disable_underflow_interrupt() (USB_INTCTRLA &= ~USB_BUSERRIE_bm) +#define udd_is_enable_underflow_interrupt() (USB_INTCTRLA&USB_BUSERRIE_bm ? true : false) + +#define udd_is_stall_event() (USB_INTFLAGSASET & USB_STALLIF_bm ? true : false) +#define udd_ack_stall_event() (USB_INTFLAGSACLR = USB_STALLIF_bm) +#define udd_set_stall_event() (USB_INTFLAGSASET = USB_STALLIF_bm) +#define udd_enable_stall_interrupt() (USB_INTCTRLA |= USB_STALLIE_bm) +#define udd_disable_stall_interrupt() (USB_INTCTRLA &= ~USB_STALLIE_bm) +#define udd_is_enable_stall_interrupt() (USB_INTCTRLA&USB_STALLIE_bm ? true : false) +//! @} + +//! @name USB Device read/modify/write management +//! @{ +#ifndef USB_WORKAROUND_DO_NOT_USE_RMW +/* + * Read modify write new instructions for Xmega + * inline asm implementation with R16 register. + * This should be removed later on when the new instructions + * will be available within the compiler. + * + */ +// Load and Clear +#ifdef __GNUC__ +#define LACR16(addr,msk) \ + __asm__ __volatile__ ( \ + "ldi r16, %1" "\n\t" \ + ".dc.w 0x9306" "\n\t"\ + ::"z" (addr), "M" (msk):"r16") +#else +#define LACR16(addr,msk) __lac((unsigned char)msk,(unsigned char*)addr) +#endif + +// Load and Set +#ifdef __GNUC__ +#define LASR16(addr,msk) \ + __asm__ __volatile__ ( \ + "ldi r16, %1" "\n\t" \ + ".dc.w 0x9305" "\n\t"\ + ::"z" (addr), "M" (msk):"r16") +#else +#define LASR16(addr,msk) __las((unsigned char)msk,(unsigned char*)addr) +#endif + +// Exchange +#ifdef __GNUC__ +#define XCHR16(addr,msk) \ + __asm__ __volatile__ ( \ + "ldi r16, %1" "\n\t" \ + ".dc.w 0x9304" "\n\t"\ + ::"z" (addr), "M" (msk):"r16") +#else +#define XCHR16(addr,msk) __xch(msk,addr) +#endif + +// Load and toggle +#ifdef __GNUC__ +#define LATR16(addr,msk) \ + __asm__ __volatile__ ( \ + "ldi r16, %1" "\n\t" \ + ".dc.w 0x9307" "\n\t"\ + ::"z" (addr), "M" (msk):"r16") +#else +#define LATR16(addr,msk) __lat(msk,addr) +#endif + +#else + +// Load and Clear +#define LACR16(addr,msk) (*addr &= ~msk) +// Load and Set +#define LASR16(addr,msk)(*addr |= msk) + +#endif +//! @} + + +//! @name USB Device endpoints table management +//! @{ + +#define udd_endpoint_set_control(ep_ctrl,val) (ep_ctrl->CTRL=val) +#define udd_endpoint_get_control(ep_ctrl) (ep_ctrl->CTRL) + +#define udd_endpoint_disable(ep_ctrl) udd_endpoint_set_control(ep_ctrl,0) +#define udd_endpoint_is_enable(ep_ctrl) (USB_EP_TYPE_DISABLE_gc!=udd_endpoint_get_type(ep_ctrl)) + + +#define udd_endpoint_enable_stall(ep_ctrl) (ep_ctrl->CTRL |= USB_EP_STALL_bm) +#define udd_endpoint_disable_stall(ep_ctrl) (ep_ctrl->CTRL &= ~USB_EP_STALL_bm) +#define udd_endpoint_is_stall(ep_ctrl) (ep_ctrl->CTRL &USB_EP_STALL_bm ? true : false) +#define udd_endpoint_set_multipacket(ep_ctrl) (ep_ctrl->CTRL |= USB_EP_MULTIPKT_bm) +#define udd_endpoint_TC_int_disable(ep_ctrl) (ep_ctrl->CTRL |= USB_EP_INTDSBL_bm) +#define udd_endpoint_set_pingpong(ep_ctrl) (ep_ctrl->CTRL |= USB_EP_PINGPONG_bm) +#define udd_endpoint_get_size_field(ep_ctrl) (ep_ctrl->CTRL & USB_EP_BUFSIZE_gm) +#define udd_endpoint_get_type(ep_ctrl) (ep_ctrl->CTRL & USB_EP_TYPE_gm) + +#define udd_endpoint_get_status(ep_ctrl) (ep_ctrl->STATUS) +#define udd_endpoint_clear_status(ep_ctrl) (ep_ctrl->STATUS=USB_EP_BUSNACK0_bm|USB_EP_BUSNACK1_bm) + +#define udd_endpoint_setup_received(ep_ctrl) (ep_ctrl->STATUS&USB_EP_SETUP_bm ? true : false) +#define udd_endpoint_ack_setup_received(ep_ctrl) LACR16(&ep_ctrl->STATUS, USB_EP_SETUP_bm) + +#define udd_endpoint_transfer_complete(ep_ctrl) (ep_ctrl->STATUS&USB_EP_TRNCOMPL0_bm ? true : false) +#define udd_endpoint_ack_transfer_complete(ep_ctrl) LACR16(&(ep_ctrl->STATUS), USB_EP_TRNCOMPL0_bm) +#define udd_endpoint_transfer_complete_bank0(ep_ctrl) (ep_ctrl->STATUS&USB_EP_TRNCOMPL0_bm ? true : false) +#define udd_endpoint_ack_transfer_complete_bankO(ep_ctrl) LACR16(&ep_ctrl->STATUS, USB_EP_TRNCOMPL0_bm) +#define udd_endpoint_transfer_complete_bank1(ep_ctrl) (ep_ctrl->STATUS&USB_EP_SETUP_bm ? true : false) +#define udd_endpoint_ack_transfer_complete_bank1(ep_ctrl) LACR16(&ep_ctrl->STATUS, USB_EP_SETUP_bm) + +#define udd_endpoint_get_bank(ep_ctrl) (ep_ctrl->STATUS & USB_EP_BANK_bm ? true : false) +#define udd_endpoint_set_bank(ep_ctrl) LASR16(&ep_ctrl->STATUS, USB_EP_BANK_bm) +#define udd_endpoint_clear_bank(ep_ctrl) LACR16(&ep_ctrl->STATUS, USB_EP_BANK_bm) + +#define udd_endpoint_set_dtgl(ep_ctrl) LASR16(&ep_ctrl->STATUS,USB_EP_TOGGLE_bm) +#define udd_endpoint_clear_dtgl(ep_ctrl) LACR16(&ep_ctrl->STATUS, USB_EP_TOGGLE_bm ) +#define udd_endpoint_get_dtgl(ep_ctrl) ((ep_ctrl->STATUS)&USB_EP_TOGGLE_bm ? true : false) +#define udd_endpoint_toggle_dtgl(ep_ctrl) LATR16(&ep_ctrl->STATUS, USB_EP_TOGGLE_bm) + +#define udd_endpoint_set_NACK0(ep_ctrl) LASR16(&ep_ctrl->STATUS,USB_EP_BUSNACK0_bm) +#define udd_endpoint_set_NACK1(ep_ctrl) LASR16(&ep_ctrl->STATUS,USB_EP_BUSNACK1_bm) +#define udd_endpoint_clear_NACK0(ep_ctrl) LACR16(&ep_ctrl->STATUS, USB_EP_BUSNACK0_bm) +#define udd_endpoint_clear_NACK1(ep_ctrl) LACR16(&ep_ctrl->STATUS, USB_EP_BUSNACK1_bm) +#define udd_endpoint_get_NACK1(ep_ctrl) ((ep_ctrl->STATUS&USB_EP_BUSNACK1_bm) ? true : false) +#define udd_endpoint_get_NACK0(ep_ctrl) ((ep_ctrl->STATUS&USB_EP_BUSNACK0_bm) ? true : false) +#define udd_endpoint_overflow(ep_ctrl) (ep_ctrl->STATUS&USB_EP_OVF_bm ? true : false) +#define udd_endpoint_underflow(ep_ctrl) (ep_ctrl->STATUS&USB_EP_UNF_bm ? true : false) + +#define UDD_ENDPOINT_MAX_TRANS (0x3FF) + +#define udd_endpoint_out_nb_receiv(ep_ctrl) (ep_ctrl->CNT) +#define udd_endpoint_out_reset_nb_received(ep_ctrl) (ep_ctrl->CNT = 0) +#define udd_endpoint_in_set_bytecnt(ep_ctrl,n) (ep_ctrl->CNT = n) +#define udd_endpoint_set_azlp(ep_ctrl) (ep_ctrl->CNT |= 0x8000) +#define udd_endpoint_clear_azlp(ep_ctrl) (ep_ctrl->CNT &= ~0x8000) + +#define udd_endpoint_set_buf(ep_ctrl,buf) (ep_ctrl->DATAPTR = (uint16_t) buf) + +#define udd_endpoint_in_nb_sent(ep_ctrl) (ep_ctrl->AUXDATA) +#define udd_endpoint_in_reset_nb_sent(ep_ctrl) (ep_ctrl->AUXDATA = 0) +#define udd_endpoint_out_set_nbbyte(ep_ctrl,nb) (ep_ctrl->AUXDATA = nb) +#define udd_endpoint_out_get_nbbyte_requested(ep_ctrl) (ep_ctrl->AUXDATA) +#define udd_endpoint_set_aux(ep_ctrl,buf) (ep_ctrl->AUXDATA = (uint16_t) buf) +//! @} + + +//! @name USB Device endpoint control field management +//! @{ + +//! @name USB Device endpoint control setup field management +//! @{ +#define udd_control_setup() (udd_sram.ep_ctrl[0].STATUS&USB_EP_SETUP_bm ? true : false) +#define udd_control_ack_setup() LACR16(&udd_sram.ep_ctrl[0].STATUS,USB_EP_SETUP_bm) +//! @} + +//! @name USB Device endpoint control OUT field management +//! @{ +#define udd_control_out_is_enable_stall() (udd_sram.ep_ctrl[0].CTRL&USB_EP_STALL_bm ? true : false) +#define udd_control_out_enable_stall() LASR16(&udd_sram.ep_ctrl[0].CTRL,USB_EP_STALL_bm) +#define udd_control_out_disable_stall() LACR16(&udd_sram.ep_ctrl[0].CTRL,USB_EP_STALL_bm) +#define udd_control_out_is_stalled() (udd_sram.ep_ctrl[0].STATUS&USB_EP_STALLF_bm ? true : false) +#define udd_control_out_ack_stall() LACR16(&udd_sram.ep_ctrl[0].STATUS,USB_EP_STALLF_bm) +#define udd_control_out_set_NACK0() LASR16(&udd_sram.ep_ctrl[0].STATUS,USB_EP_BUSNACK0_bm) +#define udd_control_out_clear_NACK0() LACR16(&udd_sram.ep_ctrl[0].STATUS,USB_EP_BUSNACK0_bm) + +#define udd_control_out_overflow() (udd_sram.ep_ctrl[0].STATUS&USB_EP_OVF_bm ? true : false) +#define udd_control_ack_out_overflow() LACR16(&udd_sram.ep_ctrl[0].STATUS,USB_EP_OVF_bm) + +#define udd_control_out_tc() (udd_sram.ep_ctrl[0].STATUS&USB_EP_TRNCOMPL0_bm ? true : false) +#define udd_control_out_ack_tc() LACR16(&udd_sram.ep_ctrl[0].STATUS,USB_EP_TRNCOMPL0_bm) +#define udd_control_out_set_tc() LASR16(&udd_sram.ep_ctrl[0].STATUS,USB_EP_TRNCOMPL0_bm) + +#define udd_control_out_dt_get() (udd_sram.ep_ctrl[0].STATUS&USB_EP_TOGGLE_bm ? true : false) +#define udd_control_out_dt_set() LASR16(&udd_sram.ep_ctrl[0].STATUS,USB_EP_TOGGLE_bm ) +#define udd_control_out_dt_clear() LACR16(&udd_sram.ep_ctrl[0].STATUS,USB_EP_TOGGLE_bm ) +#define udd_control_out_dt_toggle() LATR16(&udd_sram.ep_ctrl[0].STATUS,USB_EP_TOGGLE_bm) + +#define udd_control_out_set_buf(buf) (udd_sram.ep_ctrl[0].DATAPTR = (uint16_t) buf) + +#define udd_control_out_get_bytecnt() (udd_sram.ep_ctrl[0].CNT) +//! @} + +//! @name USB Device endpoint control IN field management +//! @{ +#define udd_control_in_is_enable_stall() (udd_sram.ep_ctrl[1].CTRL&USB_EP_STALL_bm ? true : false) +#define udd_control_in_enable_stall() LASR16(&udd_sram.ep_ctrl[1].CTRL,USB_EP_STALL_bm) +#define udd_control_in_disable_stall() LACR16(&udd_sram.ep_ctrl[1].CTRL,USB_EP_STALL_bm) +#define udd_control_in_is_stalled() (udd_sram.ep_ctrl[1].STATUS&USB_EP_STALLF_bm ? true : false) +#define udd_control_in_ack_stall() LACR16(&udd_sram.ep_ctrl[1].STATUS,USB_EP_STALLF_bm) +#define udd_control_in_set_NACK0() LASR16(&udd_sram.ep_ctrl[1].STATUS,USB_EP_BUSNACK0_bm) +#define udd_control_in_clear_NACK0() LACR16(&udd_sram.ep_ctrl[1].STATUS,USB_EP_BUSNACK0_bm) + +#define udd_control_in_underflow() (udd_sram.ep_ctrl[1].STATUS&USB_EP_UNF_bm ? true : false) +#define udd_control_ack_in_underflow() LACR16(&udd_sram.ep_ctrl[1].STATUS,USB_EP_UNF_bm) + +#define udd_control_in_tc() (udd_sram.ep_ctrl[1].STATUS&USB_EP_TRNCOMPL0_bm ? true : false) +#define udd_control_in_ack_tc() LACR16(&udd_sram.ep_ctrl[1].STATUS,USB_EP_TRNCOMPL0_bm) +#define udd_control_in_set_tc() LASR16(&udd_sram.ep_ctrl[1].STATUS,USB_EP_TRNCOMPL0_bm) + +#define udd_control_in_dt_get() (udd_sram.ep_ctrl[1].STATUS&USB_EP_TOGGLE_bm ? true : false) +#define udd_control_in_dt_set() LASR16(&udd_sram.ep_ctrl[1].STATUS,USB_EP_TOGGLE_bm ) +#define udd_control_in_dt_clear() LACR16(&udd_sram.ep_ctrl[1].STATUS,USB_EP_TOGGLE_bm ) +#define udd_control_in_dt_toggle() LATR16(&udd_sram.ep_ctrl[1].STATUS,USB_EP_TOGGLE_bm) + +#define udd_control_in_set_buf(buf) (udd_sram.ep_ctrl[1].DATAPTR = (uint16_t) buf) + +#define udd_control_in_set_bytecnt(n) (udd_sram.ep_ctrl[1].CNT = n) +//! @} +//! @} + +//! @} + +#endif // _USB_DEVICE_H_ diff --git a/Firmware/Atmel DFU Bootloader/xmega/utils/assembler.h b/Firmware/Atmel DFU Bootloader/xmega/utils/assembler.h new file mode 100644 index 0000000..c4451b3 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/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 +#elif defined(__IAR_SYSTEMS_ASM__) +# include "assembler/iar.h" +# include +#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/Firmware/Atmel DFU Bootloader/xmega/utils/assembler/iar.h b/Firmware/Atmel DFU Bootloader/xmega/utils/assembler/iar.h new file mode 100644 index 0000000..61370b5 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/xmega/utils/assembler/iar.h @@ -0,0 +1,109 @@ +/** + * \file + * + * \brief Assembler abstraction layer: IAR 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_IAR_H_INCLUDED +#define ASSEMBLER_IAR_H_INCLUDED + +ld_addr MACRO reg, sym + mov reg, LWRD sym + orh reg, HWRD sym + ENDM + +call MACRO sym + rcall sym + ENDM + +iar_begin_func MACRO name, sect, is_public, is_weak + MODULE name + RSEG CODE:CODE:NOROOT(1) + IF is_weak == 1 + PUBWEAK name + ELSEIF is_public + PUBLIC name + ENDIF +name: + ENDM + +iar_begin_func_segm MACRO name, sect, is_public, is_weak, segment + MODULE name + RSEG segment:CODE:NOROOT(1) + IF is_weak == 1 + PUBWEAK name + ELSEIF is_public + PUBLIC name + ENDIF +name: + ENDM + +iar_weak_alias MACRO name, strong_name + PUBWEAK name +name: + rjmp strong_name + ENDM + +#define lo(x) LWRD x +#define hi(x) HWRD x + +#define REPEAT(count) REPT count +#define END_REPEAT() ENDR +#define SET_LOC(offset) ORG offset +#define END_FILE() END + +#define FILL_BYTES(count) DS8 count + +#define L(name) name +#define EXTERN_SYMBOL(name) EXTERN name +#define FUNCTION(name) iar_begin_func name, text_##name, 0, 0 +#define PUBLIC_FUNCTION(name) iar_begin_func name, text_##name, 1, 0 +#define PUBLIC_FUNCTION_SEGMENT(name, segment) \ + iar_begin_func_segm name, text_##name, 1, 0, segment +#define WEAK_FUNCTION(name) iar_begin_func name, text_##name, 1, 1 +#define WEAK_FUNCTION_ALIAS(name, strong_name) \ + iar_weak_alias name, strong_name +#define END_FUNC(name) ENDMOD + +#define TEXT_SECTION(name) RSEG name:CODE:NOROOT +#define RODATA_SECTION(name) RSEG name:CONST:NOROOT +#define DATA_SECTION(name) RSEG name:DATA:NOROOT +#define BSS_SECTION(name) RSEG name:DATA:NOROOT + +#endif /* ASSEMBLER_IAR_H_INCLUDED */ diff --git a/Firmware/Atmel DFU Bootloader/xmega/utils/bit_handling/clz_ctz.h b/Firmware/Atmel DFU Bootloader/xmega/utils/bit_handling/clz_ctz.h new file mode 100644 index 0000000..c43f6c5 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/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/Firmware/Atmel DFU Bootloader/xmega/utils/compiler.h b/Firmware/Atmel DFU Bootloader/xmega/utils/compiler.h new file mode 100644 index 0000000..8bc7169 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/xmega/utils/compiler.h @@ -0,0 +1,1039 @@ +/** + * \file + * + * \brief Commonly used includes, types and macros. + * + * 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 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 +# include +#elif defined(__ICCAVR__) +# include +# include +#else +# error Unsupported compiler. +#endif + +#include +#include +#include +#include + +#include + +#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 signed char S8 ; //!< 8-bit signed integer. +typedef unsigned char U8 ; //!< 8-bit unsigned integer. +typedef signed short int S16; //!< 16-bit signed integer. +typedef unsigned short int U16; //!< 16-bit unsigned integer. +typedef unsigned short int le16_t; +typedef unsigned short int be16_t; +typedef signed long int S32; //!< 32-bit signed integer. +typedef unsigned long int U32; //!< 32-bit unsigned integer. +typedef uint32_t le32_t; +typedef uint32_t be32_t; +typedef signed long long int S64; //!< 64-bit signed integer. +typedef unsigned long long int 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" + +/** + * \} + */ + +#endif // UTILS_COMPILER_H diff --git a/Firmware/Atmel DFU Bootloader/xmega/utils/preprocessor/mrepeat.h b/Firmware/Atmel DFU Bootloader/xmega/utils/preprocessor/mrepeat.h new file mode 100644 index 0000000..baab4d5 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/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 macro(0, data) macro(1, data) ... macro(count - 1, data) + */ +#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/Firmware/Atmel DFU Bootloader/xmega/utils/preprocessor/preprocessor.h b/Firmware/Atmel DFU Bootloader/xmega/utils/preprocessor/preprocessor.h new file mode 100644 index 0000000..2cae8e0 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/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/Firmware/Atmel DFU Bootloader/xmega/utils/preprocessor/stringz.h b/Firmware/Atmel DFU Bootloader/xmega/utils/preprocessor/stringz.h new file mode 100644 index 0000000..2940eff --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/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/Firmware/Atmel DFU Bootloader/xmega/utils/preprocessor/tpaste.h b/Firmware/Atmel DFU Bootloader/xmega/utils/preprocessor/tpaste.h new file mode 100644 index 0000000..88bed2b --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/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/Firmware/Atmel DFU Bootloader/xmega/utils/progmem.h b/Firmware/Atmel DFU Bootloader/xmega/utils/progmem.h new file mode 100644 index 0000000..320ca5d --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/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 +# 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 +# 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/Firmware/Atmel DFU Bootloader/xmega/utils/status_codes.h b/Firmware/Atmel DFU Bootloader/xmega/utils/status_codes.h new file mode 100644 index 0000000..91e7542 --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/xmega/utils/status_codes.h @@ -0,0 +1,115 @@ +/** + * \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-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 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 + + /** + * \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 */ From 96decc0a0d829c8275a5364baf977672b2a805d6 Mon Sep 17 00:00:00 2001 From: "@shinhub" Date: Tue, 13 Aug 2019 18:59:17 +0200 Subject: [PATCH 2/6] Clean Software dir --- .../{Win32 => Original-Windows}/BOOT_LOADER_EXE.exe | Bin .../Chameleon Mini RevE Rebooted.exe | Bin .../Chameleon Mini RevE Rebooted_en.exe | Bin .../{FlashTools => Original-Windows}/Createbin.exe | Bin .../avr-objcopy.exe | Bin .../dfu-programmer-win-0.7.2.zip | Bin Software/{FlashTools => Original-Windows}/flash.bat | 0 Software/{Win32 => Original-Windows}/libusb0.dll | Bin .../{FlashTools => Original-Windows}/msvcr120d.dll | Bin 9 files changed, 0 insertions(+), 0 deletions(-) rename Software/{Win32 => Original-Windows}/BOOT_LOADER_EXE.exe (100%) rename Software/{Win32 => Original-Windows}/Chameleon Mini RevE Rebooted.exe (100%) rename Software/{Win32 => Original-Windows}/Chameleon Mini RevE Rebooted_en.exe (100%) rename Software/{FlashTools => Original-Windows}/Createbin.exe (100%) rename Software/{FlashTools => Original-Windows}/avr-objcopy.exe (100%) rename Software/{Win32 => Original-Windows}/dfu-programmer-win-0.7.2.zip (100%) rename Software/{FlashTools => Original-Windows}/flash.bat (100%) rename Software/{Win32 => Original-Windows}/libusb0.dll (100%) rename Software/{FlashTools => Original-Windows}/msvcr120d.dll (100%) diff --git a/Software/Win32/BOOT_LOADER_EXE.exe b/Software/Original-Windows/BOOT_LOADER_EXE.exe similarity index 100% rename from Software/Win32/BOOT_LOADER_EXE.exe rename to Software/Original-Windows/BOOT_LOADER_EXE.exe diff --git a/Software/Win32/Chameleon Mini RevE Rebooted.exe b/Software/Original-Windows/Chameleon Mini RevE Rebooted.exe similarity index 100% rename from Software/Win32/Chameleon Mini RevE Rebooted.exe rename to Software/Original-Windows/Chameleon Mini RevE Rebooted.exe diff --git a/Software/Win32/Chameleon Mini RevE Rebooted_en.exe b/Software/Original-Windows/Chameleon Mini RevE Rebooted_en.exe similarity index 100% rename from Software/Win32/Chameleon Mini RevE Rebooted_en.exe rename to Software/Original-Windows/Chameleon Mini RevE Rebooted_en.exe diff --git a/Software/FlashTools/Createbin.exe b/Software/Original-Windows/Createbin.exe similarity index 100% rename from Software/FlashTools/Createbin.exe rename to Software/Original-Windows/Createbin.exe diff --git a/Software/FlashTools/avr-objcopy.exe b/Software/Original-Windows/avr-objcopy.exe similarity index 100% rename from Software/FlashTools/avr-objcopy.exe rename to Software/Original-Windows/avr-objcopy.exe diff --git a/Software/Win32/dfu-programmer-win-0.7.2.zip b/Software/Original-Windows/dfu-programmer-win-0.7.2.zip similarity index 100% rename from Software/Win32/dfu-programmer-win-0.7.2.zip rename to Software/Original-Windows/dfu-programmer-win-0.7.2.zip diff --git a/Software/FlashTools/flash.bat b/Software/Original-Windows/flash.bat similarity index 100% rename from Software/FlashTools/flash.bat rename to Software/Original-Windows/flash.bat diff --git a/Software/Win32/libusb0.dll b/Software/Original-Windows/libusb0.dll similarity index 100% rename from Software/Win32/libusb0.dll rename to Software/Original-Windows/libusb0.dll diff --git a/Software/FlashTools/msvcr120d.dll b/Software/Original-Windows/msvcr120d.dll similarity index 100% rename from Software/FlashTools/msvcr120d.dll rename to Software/Original-Windows/msvcr120d.dll From 7fd274f4b5aeab3966d8df5ed7a22eea007f78f6 Mon Sep 17 00:00:00 2001 From: "@shinhub" Date: Tue, 13 Aug 2019 19:04:12 +0200 Subject: [PATCH 3/6] Rename Firmware subfolders --- .../ASF-License.txt | 0 .../GenerateBootloader.bat | 0 .../atxmega32a4u_104_PA6.hex | 0 .../common/boards/board.h | 0 .../common/services/clock/genclk.h | 0 .../common/services/clock/osc.h | 0 .../common/services/clock/pll.h | 0 .../common/services/clock/sysclk.h | 0 .../common/services/clock/xmega/osc.h | 0 .../common/services/clock/xmega/pll.h | 0 .../common/services/clock/xmega/sysclk.c | 0 .../common/services/clock/xmega/sysclk.h | 0 .../common/services/isp/flip/flip_protocol.h | 0 .../common/services/isp/flip/isp.h | 0 .../common/services/isp/flip/xmega/cstartup.s90 | 0 .../common/services/isp/flip/xmega/isp.c | 0 .../class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/asf.h | 0 .../bootloader/xmega/atxmega32a4u/iar/atxmega32a4u_boot.xcl | 0 .../device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewd | 0 .../device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewp | 0 .../device/bootloader/xmega/atxmega32a4u/iar/xmega_small.eww | 0 .../usb/class/dfu_flip/device/bootloader/xmega/conf/conf_board.h | 0 .../usb/class/dfu_flip/device/bootloader/xmega/conf/conf_clock.h | 0 .../usb/class/dfu_flip/device/bootloader/xmega/conf/conf_isp.h | 0 .../usb/class/dfu_flip/device/bootloader/xmega/conf/conf_usb.h | 0 .../services/usb/class/dfu_flip/device/bootloader/xmega/main.c | 0 .../services/usb/class/dfu_flip/device/bootloader/xmega/main.h | 0 .../usb/class/dfu_flip/device/bootloader/xmega/sysclk_opt.c | 0 .../common/services/usb/class/dfu_flip/device/udi_dfu_atmel.c | 0 .../common/services/usb/class/dfu_flip/device/udi_dfu_atmel.h | 0 .../services/usb/class/dfu_flip/device/udi_dfu_atmel_conf.h | 0 .../services/usb/class/dfu_flip/device/udi_dfu_atmel_desc.c | 0 .../common/services/usb/class/dfu_flip/usb_protocol_dfu.h | 0 .../common/services/usb/udc/udc.h | 0 .../common/services/usb/udc/udc_desc.h | 0 .../common/services/usb/udc/udc_dfu_small.c | 0 .../common/services/usb/udc/udd.h | 0 .../common/services/usb/udc/udi.h | 0 .../common/services/usb/usb_atmel.h | 0 .../common/services/usb/usb_protocol.h | 0 .../common/utils/interrupt.h | 0 .../common/utils/interrupt/interrupt_avr8.h | 0 .../common/utils/parts.h | 0 .../xmega/boards/dummy/dummy_board.h | 0 .../xmega/drivers/cpu/ccp.h | 0 .../xmega/drivers/cpu/ccp.s | 0 .../xmega/drivers/cpu/xmega_reset_cause.h | 0 .../xmega/drivers/nvm/nvm.c | 0 .../xmega/drivers/nvm/nvm.h | 0 .../xmega/drivers/nvm/nvm_asm.s | 0 .../xmega/drivers/usb/usb_device.c | 0 .../xmega/drivers/usb/usb_device.h | 0 .../xmega/utils/assembler.h | 0 .../xmega/utils/assembler/iar.h | 0 .../xmega/utils/bit_handling/clz_ctz.h | 0 .../xmega/utils/compiler.h | 0 .../xmega/utils/preprocessor/mrepeat.h | 0 .../xmega/utils/preprocessor/preprocessor.h | 0 .../xmega/utils/preprocessor/stringz.h | 0 .../xmega/utils/preprocessor/tpaste.h | 0 .../xmega/utils/progmem.h | 0 .../xmega/utils/status_codes.h | 0 .../ChameleonMiniRDV2.0_ATxmega32A4U.hex | 0 Firmware/{Compiled => Original-Compiled}/ITS_A_CARD.hex | 0 64 files changed, 0 insertions(+), 0 deletions(-) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/ASF-License.txt (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/GenerateBootloader.bat (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/atxmega32a4u_104_PA6.hex (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/boards/board.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/clock/genclk.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/clock/osc.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/clock/pll.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/clock/sysclk.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/clock/xmega/osc.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/clock/xmega/pll.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/clock/xmega/sysclk.c (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/clock/xmega/sysclk.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/isp/flip/flip_protocol.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/isp/flip/isp.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/isp/flip/xmega/cstartup.s90 (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/isp/flip/xmega/isp.c (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/asf.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/atxmega32a4u_boot.xcl (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewd (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewp (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.eww (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_board.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_clock.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_isp.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_usb.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/class/dfu_flip/device/bootloader/xmega/main.c (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/class/dfu_flip/device/bootloader/xmega/main.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/class/dfu_flip/device/bootloader/xmega/sysclk_opt.c (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/class/dfu_flip/device/udi_dfu_atmel.c (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/class/dfu_flip/device/udi_dfu_atmel.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/class/dfu_flip/device/udi_dfu_atmel_conf.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/class/dfu_flip/device/udi_dfu_atmel_desc.c (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/class/dfu_flip/usb_protocol_dfu.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/udc/udc.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/udc/udc_desc.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/udc/udc_dfu_small.c (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/udc/udd.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/udc/udi.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/usb_atmel.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/services/usb/usb_protocol.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/utils/interrupt.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/utils/interrupt/interrupt_avr8.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/common/utils/parts.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/xmega/boards/dummy/dummy_board.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/xmega/drivers/cpu/ccp.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/xmega/drivers/cpu/ccp.s (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/xmega/drivers/cpu/xmega_reset_cause.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/xmega/drivers/nvm/nvm.c (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/xmega/drivers/nvm/nvm.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/xmega/drivers/nvm/nvm_asm.s (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/xmega/drivers/usb/usb_device.c (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/xmega/drivers/usb/usb_device.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/xmega/utils/assembler.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/xmega/utils/assembler/iar.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/xmega/utils/bit_handling/clz_ctz.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/xmega/utils/compiler.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/xmega/utils/preprocessor/mrepeat.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/xmega/utils/preprocessor/preprocessor.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/xmega/utils/preprocessor/stringz.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/xmega/utils/preprocessor/tpaste.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/xmega/utils/progmem.h (100%) rename Firmware/{Atmel DFU Bootloader => Atmel-DFU-Bootloader}/xmega/utils/status_codes.h (100%) rename Firmware/{Compiled => Original-Compiled}/ChameleonMiniRDV2.0_ATxmega32A4U.hex (100%) rename Firmware/{Compiled => Original-Compiled}/ITS_A_CARD.hex (100%) diff --git a/Firmware/Atmel DFU Bootloader/ASF-License.txt b/Firmware/Atmel-DFU-Bootloader/ASF-License.txt similarity index 100% rename from Firmware/Atmel DFU Bootloader/ASF-License.txt rename to Firmware/Atmel-DFU-Bootloader/ASF-License.txt diff --git a/Firmware/Atmel DFU Bootloader/GenerateBootloader.bat b/Firmware/Atmel-DFU-Bootloader/GenerateBootloader.bat similarity index 100% rename from Firmware/Atmel DFU Bootloader/GenerateBootloader.bat rename to Firmware/Atmel-DFU-Bootloader/GenerateBootloader.bat diff --git a/Firmware/Atmel DFU Bootloader/atxmega32a4u_104_PA6.hex b/Firmware/Atmel-DFU-Bootloader/atxmega32a4u_104_PA6.hex similarity index 100% rename from Firmware/Atmel DFU Bootloader/atxmega32a4u_104_PA6.hex rename to Firmware/Atmel-DFU-Bootloader/atxmega32a4u_104_PA6.hex diff --git a/Firmware/Atmel DFU Bootloader/common/boards/board.h b/Firmware/Atmel-DFU-Bootloader/common/boards/board.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/boards/board.h rename to Firmware/Atmel-DFU-Bootloader/common/boards/board.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/clock/genclk.h b/Firmware/Atmel-DFU-Bootloader/common/services/clock/genclk.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/clock/genclk.h rename to Firmware/Atmel-DFU-Bootloader/common/services/clock/genclk.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/clock/osc.h b/Firmware/Atmel-DFU-Bootloader/common/services/clock/osc.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/clock/osc.h rename to Firmware/Atmel-DFU-Bootloader/common/services/clock/osc.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/clock/pll.h b/Firmware/Atmel-DFU-Bootloader/common/services/clock/pll.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/clock/pll.h rename to Firmware/Atmel-DFU-Bootloader/common/services/clock/pll.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/clock/sysclk.h b/Firmware/Atmel-DFU-Bootloader/common/services/clock/sysclk.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/clock/sysclk.h rename to Firmware/Atmel-DFU-Bootloader/common/services/clock/sysclk.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/clock/xmega/osc.h b/Firmware/Atmel-DFU-Bootloader/common/services/clock/xmega/osc.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/clock/xmega/osc.h rename to Firmware/Atmel-DFU-Bootloader/common/services/clock/xmega/osc.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/clock/xmega/pll.h b/Firmware/Atmel-DFU-Bootloader/common/services/clock/xmega/pll.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/clock/xmega/pll.h rename to Firmware/Atmel-DFU-Bootloader/common/services/clock/xmega/pll.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/clock/xmega/sysclk.c b/Firmware/Atmel-DFU-Bootloader/common/services/clock/xmega/sysclk.c similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/clock/xmega/sysclk.c rename to Firmware/Atmel-DFU-Bootloader/common/services/clock/xmega/sysclk.c diff --git a/Firmware/Atmel DFU Bootloader/common/services/clock/xmega/sysclk.h b/Firmware/Atmel-DFU-Bootloader/common/services/clock/xmega/sysclk.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/clock/xmega/sysclk.h rename to Firmware/Atmel-DFU-Bootloader/common/services/clock/xmega/sysclk.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/isp/flip/flip_protocol.h b/Firmware/Atmel-DFU-Bootloader/common/services/isp/flip/flip_protocol.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/isp/flip/flip_protocol.h rename to Firmware/Atmel-DFU-Bootloader/common/services/isp/flip/flip_protocol.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/isp/flip/isp.h b/Firmware/Atmel-DFU-Bootloader/common/services/isp/flip/isp.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/isp/flip/isp.h rename to Firmware/Atmel-DFU-Bootloader/common/services/isp/flip/isp.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/isp/flip/xmega/cstartup.s90 b/Firmware/Atmel-DFU-Bootloader/common/services/isp/flip/xmega/cstartup.s90 similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/isp/flip/xmega/cstartup.s90 rename to Firmware/Atmel-DFU-Bootloader/common/services/isp/flip/xmega/cstartup.s90 diff --git a/Firmware/Atmel DFU Bootloader/common/services/isp/flip/xmega/isp.c b/Firmware/Atmel-DFU-Bootloader/common/services/isp/flip/xmega/isp.c similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/isp/flip/xmega/isp.c rename to Firmware/Atmel-DFU-Bootloader/common/services/isp/flip/xmega/isp.c diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/asf.h b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/asf.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/asf.h rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/asf.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/atxmega32a4u_boot.xcl b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/atxmega32a4u_boot.xcl similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/atxmega32a4u_boot.xcl rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/atxmega32a4u_boot.xcl diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewd b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewd similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewd rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewd diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewp b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewp similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewp rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewp diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.eww b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.eww similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.eww rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.eww diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_board.h b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_board.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_board.h rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_board.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_clock.h b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_clock.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_clock.h rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_clock.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_isp.h b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_isp.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_isp.h rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_isp.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_usb.h b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_usb.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_usb.h rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_usb.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/main.c b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/main.c similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/main.c rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/main.c diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/main.h b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/main.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/main.h rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/main.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/sysclk_opt.c b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/sysclk_opt.c similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/sysclk_opt.c rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/sysclk_opt.c diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel.c b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel.c similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel.c rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel.c diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel.h b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel.h rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel_conf.h b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel_conf.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel_conf.h rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel_conf.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel_desc.c b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel_desc.c similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel_desc.c rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/udi_dfu_atmel_desc.c diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/usb_protocol_dfu.h b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/usb_protocol_dfu.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/class/dfu_flip/usb_protocol_dfu.h rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/usb_protocol_dfu.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/udc/udc.h b/Firmware/Atmel-DFU-Bootloader/common/services/usb/udc/udc.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/udc/udc.h rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/udc/udc.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/udc/udc_desc.h b/Firmware/Atmel-DFU-Bootloader/common/services/usb/udc/udc_desc.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/udc/udc_desc.h rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/udc/udc_desc.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/udc/udc_dfu_small.c b/Firmware/Atmel-DFU-Bootloader/common/services/usb/udc/udc_dfu_small.c similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/udc/udc_dfu_small.c rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/udc/udc_dfu_small.c diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/udc/udd.h b/Firmware/Atmel-DFU-Bootloader/common/services/usb/udc/udd.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/udc/udd.h rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/udc/udd.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/udc/udi.h b/Firmware/Atmel-DFU-Bootloader/common/services/usb/udc/udi.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/udc/udi.h rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/udc/udi.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/usb_atmel.h b/Firmware/Atmel-DFU-Bootloader/common/services/usb/usb_atmel.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/usb_atmel.h rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/usb_atmel.h diff --git a/Firmware/Atmel DFU Bootloader/common/services/usb/usb_protocol.h b/Firmware/Atmel-DFU-Bootloader/common/services/usb/usb_protocol.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/services/usb/usb_protocol.h rename to Firmware/Atmel-DFU-Bootloader/common/services/usb/usb_protocol.h diff --git a/Firmware/Atmel DFU Bootloader/common/utils/interrupt.h b/Firmware/Atmel-DFU-Bootloader/common/utils/interrupt.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/utils/interrupt.h rename to Firmware/Atmel-DFU-Bootloader/common/utils/interrupt.h diff --git a/Firmware/Atmel DFU Bootloader/common/utils/interrupt/interrupt_avr8.h b/Firmware/Atmel-DFU-Bootloader/common/utils/interrupt/interrupt_avr8.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/utils/interrupt/interrupt_avr8.h rename to Firmware/Atmel-DFU-Bootloader/common/utils/interrupt/interrupt_avr8.h diff --git a/Firmware/Atmel DFU Bootloader/common/utils/parts.h b/Firmware/Atmel-DFU-Bootloader/common/utils/parts.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/common/utils/parts.h rename to Firmware/Atmel-DFU-Bootloader/common/utils/parts.h diff --git a/Firmware/Atmel DFU Bootloader/xmega/boards/dummy/dummy_board.h b/Firmware/Atmel-DFU-Bootloader/xmega/boards/dummy/dummy_board.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/xmega/boards/dummy/dummy_board.h rename to Firmware/Atmel-DFU-Bootloader/xmega/boards/dummy/dummy_board.h diff --git a/Firmware/Atmel DFU Bootloader/xmega/drivers/cpu/ccp.h b/Firmware/Atmel-DFU-Bootloader/xmega/drivers/cpu/ccp.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/xmega/drivers/cpu/ccp.h rename to Firmware/Atmel-DFU-Bootloader/xmega/drivers/cpu/ccp.h diff --git a/Firmware/Atmel DFU Bootloader/xmega/drivers/cpu/ccp.s b/Firmware/Atmel-DFU-Bootloader/xmega/drivers/cpu/ccp.s similarity index 100% rename from Firmware/Atmel DFU Bootloader/xmega/drivers/cpu/ccp.s rename to Firmware/Atmel-DFU-Bootloader/xmega/drivers/cpu/ccp.s diff --git a/Firmware/Atmel DFU Bootloader/xmega/drivers/cpu/xmega_reset_cause.h b/Firmware/Atmel-DFU-Bootloader/xmega/drivers/cpu/xmega_reset_cause.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/xmega/drivers/cpu/xmega_reset_cause.h rename to Firmware/Atmel-DFU-Bootloader/xmega/drivers/cpu/xmega_reset_cause.h diff --git a/Firmware/Atmel DFU Bootloader/xmega/drivers/nvm/nvm.c b/Firmware/Atmel-DFU-Bootloader/xmega/drivers/nvm/nvm.c similarity index 100% rename from Firmware/Atmel DFU Bootloader/xmega/drivers/nvm/nvm.c rename to Firmware/Atmel-DFU-Bootloader/xmega/drivers/nvm/nvm.c diff --git a/Firmware/Atmel DFU Bootloader/xmega/drivers/nvm/nvm.h b/Firmware/Atmel-DFU-Bootloader/xmega/drivers/nvm/nvm.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/xmega/drivers/nvm/nvm.h rename to Firmware/Atmel-DFU-Bootloader/xmega/drivers/nvm/nvm.h diff --git a/Firmware/Atmel DFU Bootloader/xmega/drivers/nvm/nvm_asm.s b/Firmware/Atmel-DFU-Bootloader/xmega/drivers/nvm/nvm_asm.s similarity index 100% rename from Firmware/Atmel DFU Bootloader/xmega/drivers/nvm/nvm_asm.s rename to Firmware/Atmel-DFU-Bootloader/xmega/drivers/nvm/nvm_asm.s diff --git a/Firmware/Atmel DFU Bootloader/xmega/drivers/usb/usb_device.c b/Firmware/Atmel-DFU-Bootloader/xmega/drivers/usb/usb_device.c similarity index 100% rename from Firmware/Atmel DFU Bootloader/xmega/drivers/usb/usb_device.c rename to Firmware/Atmel-DFU-Bootloader/xmega/drivers/usb/usb_device.c diff --git a/Firmware/Atmel DFU Bootloader/xmega/drivers/usb/usb_device.h b/Firmware/Atmel-DFU-Bootloader/xmega/drivers/usb/usb_device.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/xmega/drivers/usb/usb_device.h rename to Firmware/Atmel-DFU-Bootloader/xmega/drivers/usb/usb_device.h diff --git a/Firmware/Atmel DFU Bootloader/xmega/utils/assembler.h b/Firmware/Atmel-DFU-Bootloader/xmega/utils/assembler.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/xmega/utils/assembler.h rename to Firmware/Atmel-DFU-Bootloader/xmega/utils/assembler.h diff --git a/Firmware/Atmel DFU Bootloader/xmega/utils/assembler/iar.h b/Firmware/Atmel-DFU-Bootloader/xmega/utils/assembler/iar.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/xmega/utils/assembler/iar.h rename to Firmware/Atmel-DFU-Bootloader/xmega/utils/assembler/iar.h diff --git a/Firmware/Atmel DFU Bootloader/xmega/utils/bit_handling/clz_ctz.h b/Firmware/Atmel-DFU-Bootloader/xmega/utils/bit_handling/clz_ctz.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/xmega/utils/bit_handling/clz_ctz.h rename to Firmware/Atmel-DFU-Bootloader/xmega/utils/bit_handling/clz_ctz.h diff --git a/Firmware/Atmel DFU Bootloader/xmega/utils/compiler.h b/Firmware/Atmel-DFU-Bootloader/xmega/utils/compiler.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/xmega/utils/compiler.h rename to Firmware/Atmel-DFU-Bootloader/xmega/utils/compiler.h diff --git a/Firmware/Atmel DFU Bootloader/xmega/utils/preprocessor/mrepeat.h b/Firmware/Atmel-DFU-Bootloader/xmega/utils/preprocessor/mrepeat.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/xmega/utils/preprocessor/mrepeat.h rename to Firmware/Atmel-DFU-Bootloader/xmega/utils/preprocessor/mrepeat.h diff --git a/Firmware/Atmel DFU Bootloader/xmega/utils/preprocessor/preprocessor.h b/Firmware/Atmel-DFU-Bootloader/xmega/utils/preprocessor/preprocessor.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/xmega/utils/preprocessor/preprocessor.h rename to Firmware/Atmel-DFU-Bootloader/xmega/utils/preprocessor/preprocessor.h diff --git a/Firmware/Atmel DFU Bootloader/xmega/utils/preprocessor/stringz.h b/Firmware/Atmel-DFU-Bootloader/xmega/utils/preprocessor/stringz.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/xmega/utils/preprocessor/stringz.h rename to Firmware/Atmel-DFU-Bootloader/xmega/utils/preprocessor/stringz.h diff --git a/Firmware/Atmel DFU Bootloader/xmega/utils/preprocessor/tpaste.h b/Firmware/Atmel-DFU-Bootloader/xmega/utils/preprocessor/tpaste.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/xmega/utils/preprocessor/tpaste.h rename to Firmware/Atmel-DFU-Bootloader/xmega/utils/preprocessor/tpaste.h diff --git a/Firmware/Atmel DFU Bootloader/xmega/utils/progmem.h b/Firmware/Atmel-DFU-Bootloader/xmega/utils/progmem.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/xmega/utils/progmem.h rename to Firmware/Atmel-DFU-Bootloader/xmega/utils/progmem.h diff --git a/Firmware/Atmel DFU Bootloader/xmega/utils/status_codes.h b/Firmware/Atmel-DFU-Bootloader/xmega/utils/status_codes.h similarity index 100% rename from Firmware/Atmel DFU Bootloader/xmega/utils/status_codes.h rename to Firmware/Atmel-DFU-Bootloader/xmega/utils/status_codes.h diff --git a/Firmware/Compiled/ChameleonMiniRDV2.0_ATxmega32A4U.hex b/Firmware/Original-Compiled/ChameleonMiniRDV2.0_ATxmega32A4U.hex similarity index 100% rename from Firmware/Compiled/ChameleonMiniRDV2.0_ATxmega32A4U.hex rename to Firmware/Original-Compiled/ChameleonMiniRDV2.0_ATxmega32A4U.hex diff --git a/Firmware/Compiled/ITS_A_CARD.hex b/Firmware/Original-Compiled/ITS_A_CARD.hex similarity index 100% rename from Firmware/Compiled/ITS_A_CARD.hex rename to Firmware/Original-Compiled/ITS_A_CARD.hex From 1e0bef9b55f39d60c47af01e6f8cbebad921f4c5 Mon Sep 17 00:00:00 2001 From: "@shinhub" Date: Wed, 14 Aug 2019 01:04:57 +0200 Subject: [PATCH 4/6] Update bootloader IAR project and adjust gitignore --- .gitignore | 13 +- Firmware/Atmel-DFU-Bootloader/README.md | 7 + .../atxmega32a4u/iar/atxmega32a4u_boot.xcl | 102 - .../iar/settings/xmega_small.dbgdt | 4 + .../atxmega32a4u/iar/settings/xmega_small.dnx | 21 + .../xmega/atxmega32a4u/iar/xmega_small.dep | 620 +++ .../xmega/atxmega32a4u/iar/xmega_small.ewd | 3905 ++++++++------- .../xmega/atxmega32a4u/iar/xmega_small.ewp | 4437 +++++++++-------- .../xmega/atxmega32a4u/iar/xmega_small.ewt | 2249 +++++++++ .../xmega/atxmega32a4u/iar/xmega_small.eww | 13 +- 10 files changed, 7258 insertions(+), 4113 deletions(-) create mode 100644 Firmware/Atmel-DFU-Bootloader/README.md delete mode 100644 Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/atxmega32a4u_boot.xcl create mode 100644 Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/settings/xmega_small.dbgdt create mode 100644 Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/settings/xmega_small.dnx create mode 100644 Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.dep create mode 100644 Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewt diff --git a/.gitignore b/.gitignore index 236ecba..f8fdeb8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ # don't push these files to the repository .history +*.DS_Store *.log *.eml *.o @@ -11,8 +12,16 @@ *.s19 *.map *.bin -Firmware/Chameleon-Mini/*.hex *.dll *.sym *.lss -*.DS_Store +*.wsdt +*.cspy* +*.xcl* +*.pbd* +*.pbi* +Firmware/Chameleon-Mini/*.hex +Firmware/Chameleon-Mini/*.eep +Firmware/Atmel-DFU-Bootloader/common/*.hex +Firmware/Atmel-DFU-Bootloader/common/*.eep +Firmware/Atmel-DFU-Bootloader/common/*.dbg diff --git a/Firmware/Atmel-DFU-Bootloader/README.md b/Firmware/Atmel-DFU-Bootloader/README.md new file mode 100644 index 0000000..b9fe78b --- /dev/null +++ b/Firmware/Atmel-DFU-Bootloader/README.md @@ -0,0 +1,7 @@ +# Atmel ATxmega32A4U DFU USB bootloader source with changed default ISP I/O pining + +See [Wiki](https://github.com/iceman1001/ChameleonMini-rebooted/wiki/Reference-RevE-Bootloader) for more information. + +This must be compiled with [IAR AVR Workbench](https://www.iar.com/iar-embedded-workbench/#!?architecture=AVR). + +The project workspace can be found in `common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/`. diff --git a/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/atxmega32a4u_boot.xcl b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/atxmega32a4u_boot.xcl deleted file mode 100644 index 640990c..0000000 --- a/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/atxmega32a4u_boot.xcl +++ /dev/null @@ -1,102 +0,0 @@ -/** - * \file - * - * \brief Linker script for ATxmega32A4U USB DFU FLIP bootloader - * - * Copyright (c) 2011 - 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 - * - */ - -// Set up XLINK --ca90 --w29 - -// Memory size definitions for convenience -// The '_..X_' prefix is used by C-SPY as an indication that the label should -// not be displayed in the dissassembly window. --D_..X_FLASH_BASE=8002 --D_..X_CODE_END=8FFF --D_..X_INTVEC_END=81FB - - - -////////////////////////////////////////////////////////////////////////////// -// Code (flash) segments --Z(CODE)INTVEC=81F4-81FF --P(CODE)BOOT=_..X_FLASH_BASE-_..X_CODE_END --P(CODE)CODE=_..X_FLASH_BASE-_..X_CODE_END --P(CODE)FARCODE=_..X_FLASH_BASE-_..X_CODE_END --Z(CODE)INITTAB=81FC-_..X_CODE_END --Z(CODE)NEAR_ID=81FC-_..X_CODE_END - - --D_..X_SRAM_BASE=2000 --D_..X_SRAM_TINY_END=FF --D_..X_SRAM_NEAR_END=FFFF --D_..X_SRAM_FAR_END=FFFFFF --D_..X_SRAM_HUGE_END=FFFFFF - -/* - * Modify the lines below to alter the size of the RSTACK, CSTACK and HEAP - * segments. These need to be fine tuned to suit your specific application. - */ --D_..X_CSTACK_SIZE=70 /* 112 bytes for auto variables and register save. */ --D_..X_RSTACK_SIZE=70 /* 112 bytes for return addresses, equivalent to */ - /* 56 levels of calls, including interrupts. */ --D_..X_NEAR_HEAP_SIZE=1000 /* 4096 bytes of heap. */ --D_..X_HEAP_SIZE=1000 /* 4096 bytes of heap. */ --D_..X_FAR_HEAP_SIZE=1000 /* 4096 bytes of heap. */ --D_..X_HUGE_HEAP_SIZE=1000 /* 4096 bytes of heap. */ -////////////////////////////////////////////////////////////////////////////// -// Data (SRAM, external ROM or external NV RAM) memory --Z(DATA)SRAM_NO_INIT=2000-2001 --Z(DATA)TINY_I,TINY_Z,TINY_N=_..X_SRAM_BASE-_..X_SRAM_NEAR_END --Z(DATA)RSTACK+_..X_RSTACK_SIZE=_..X_SRAM_BASE-_..X_SRAM_NEAR_END --Z(DATA)NEAR_I,NEAR_Z,NEAR_N,NEAR_C=_..X_SRAM_BASE-_..X_SRAM_NEAR_END --Z(DATA)NEAR_HEAP+_..X_NEAR_HEAP_SIZE=_..X_SRAM_BASE-_..X_SRAM_NEAR_END -//-Z(DATA)FAR_I=[10000-_..X_SRAM_FAR_END]/10000 --Z(DATA)CSTACK+_..X_CSTACK_SIZE=[_..X_SRAM_BASE-_..X_SRAM_FAR_END]/10000 --Z(DATA)HEAP+_..X_HEAP_SIZE=[_..X_SRAM_BASE-_..X_SRAM_FAR_END]/10000 --Z(DATA)IOSTREAM_N#[_..X_SRAM_BASE-_..X_SRAM_FAR_END]/10000 --Z(DATA)FAR_Z,FAR_N,FAR_C=[_..X_SRAM_BASE-_..X_SRAM_FAR_END]/10000 --Z(DATA)FAR_HEAP+_..X_FAR_HEAP_SIZE=_..X_SRAM_BASE-_..X_SRAM_FAR_END --Z(DATA)HUGE_I,HUGE_Z,HUGE_N,HUGE_C=_..X_SRAM_BASE-_..X_SRAM_HUGE_END --Z(DATA)HUGE_HEAP+_..X_HUGE_HEAP_SIZE=_..X_SRAM_BASE-_..X_SRAM_HUGE_END - - - - diff --git a/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/settings/xmega_small.dbgdt b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/settings/xmega_small.dbgdt new file mode 100644 index 0000000..88fa334 --- /dev/null +++ b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/settings/xmega_small.dbgdt @@ -0,0 +1,4 @@ + + + + diff --git a/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/settings/xmega_small.dnx b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/settings/xmega_small.dnx new file mode 100644 index 0000000..71671ba --- /dev/null +++ b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/settings/xmega_small.dnx @@ -0,0 +1,21 @@ + + + + 0 + 1 + 90 + 1 + 1 + 1 + main + 0 + 50 + + + 0 + + + 0 + 0 + + diff --git a/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.dep b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.dep new file mode 100644 index 0000000..89e8b4b --- /dev/null +++ b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.dep @@ -0,0 +1,620 @@ + + + 2 + 2474351840 + + Debug + + $PROJ_DIR$\..\..\..\..\..\..\..\..\clock\xmega\sysclk.c + $PROJ_DIR$\..\..\..\..\..\..\..\..\isp\flip\xmega\cstartup.s90 + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\utils\preprocessor\stringz.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\cpu\ccp.s + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\nvm\nvm.c + $PROJ_DIR$\Debug\Obj\sysclk_opt.r90 + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\utils\bit_handling\clz_ctz.h + $PROJ_DIR$\Debug\Obj\udi_dfu_atmel.r90 + $PROJ_DIR$\Debug\Obj\usb_device.pbi + $PROJ_DIR$\..\..\..\..\..\..\..\..\clock\xmega\osc.h + $PROJ_DIR$\Debug\Obj\cstartup.r90 + $TOOLKIT_DIR$\inc\dlib\c\stdbool.h + $PROJ_DIR$\..\..\main.c + $PROJ_DIR$\Debug\Obj\udi_dfu_atmel_desc.pbi + $PROJ_DIR$\..\..\conf\conf_isp.h + $PROJ_DIR$\..\..\..\..\udi_dfu_atmel_conf.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\utils\interrupt.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\isp\flip\xmega\isp.c + $PROJ_DIR$\Debug\Obj\nvm.r90 + $PROJ_DIR$\..\..\sysclk_opt.c + $PROJ_DIR$\..\..\..\..\udi_dfu_atmel.c + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\usb\usb_device.c + $TOOLKIT_DIR$\inc\dlib\c\stdlib.h + $TOOLKIT_DIR$\inc\dlib\c\string.h + $PROJ_DIR$\..\..\..\..\..\..\..\udc\udc_dfu_small.c + $PROJ_DIR$\..\..\..\..\..\..\..\udc\udc_desc.h + $TOOLKIT_DIR$\inc\dlib\c\yvals.h + $PROJ_DIR$\..\..\..\..\udi_dfu_atmel_desc.c + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\nvm\nvm_asm.s + $PROJ_DIR$\..\..\..\..\..\..\..\usb_atmel.h + $TOOLKIT_DIR$\inc\iomacro.h + $PROJ_DIR$\..\..\conf\conf_clock.h + $PROJ_DIR$\Debug\Obj\udi_dfu_atmel_desc.r90 + $PROJ_DIR$\..\..\..\..\..\..\..\..\isp\flip\isp.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\isp\flip\flip_protocol.h + $PROJ_DIR$\..\..\conf\conf_usb.h + $PROJ_DIR$\Debug\Obj\xmega_small.pbd + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\utils\preprocessor\tpaste.h + $TOOLKIT_DIR$\inc\dlib\c\stddef.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\utils\progmem.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\boards\board.h + $TOOLKIT_DIR$\inc\dlib\c\stdio.h + $TOOLKIT_DIR$\inc\dlib\c\pgmspace.h + $TOOLKIT_DIR$\inc\Atmel\iomacro_xmega.h + $PROJ_DIR$\Debug\Obj\sysclk.r90 + $PROJ_DIR$\Debug\Obj\main.r90 + $PROJ_DIR$\..\..\..\..\udi_dfu_atmel.h + $TOOLKIT_DIR$\inc\ioavr.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\clock\xmega\pll.h + $PROJ_DIR$\Debug\Obj\sysclk.pbi + $TOOLKIT_DIR$\inc\dlib\c\DLib_Defaults.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\boards\dummy\dummy_board.h + $TOOLKIT_DIR$\inc\dlib\c\xencoding_limits.h + $PROJ_DIR$\Debug\Obj\nvm_asm.r90 + $TOOLKIT_DIR$\inc\dlib\c\DLib_Threads.h + $TOOLKIT_DIR$\inc\dlib\c\ystdio.h + $PROJ_DIR$\Debug\Obj\nvm.pbi + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\utils\parts.h + $TOOLKIT_DIR$\inc\ioxm32a4u.h + $TOOLKIT_DIR$\inc\dlib\c\stdarg.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\utils\compiler.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\usb\usb_device.h + $PROJ_DIR$\asf.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\clock\pll.h + $TOOLKIT_DIR$\inc\dlib\c\DLib_Product.h + $TOOLKIT_DIR$\inc\intrinsics.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\utils\preprocessor\mrepeat.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\cpu\ccp.h + $PROJ_DIR$\Debug\Obj\usb_device.r90 + $PROJ_DIR$\..\..\..\..\..\usb_protocol_dfu.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\utils\status_codes.h + $PROJ_DIR$\Debug\Obj\isp.r90 + $TOOLKIT_DIR$\lib\dlib\dlAVR-3s-xmega-sf-n.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\nvm\nvm.h + $PROJ_DIR$\..\..\..\..\..\..\..\usb_protocol.h + $PROJ_DIR$\..\..\..\..\..\..\..\udc\udi.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\clock\osc.h + $TOOLKIT_DIR$\inc\Atmel\ATxmega32A4U.h + $PROJ_DIR$\Debug\Obj\sysclk_opt.pbi + $PROJ_DIR$\Debug\Exe\xmega_small.dbg + $PROJ_DIR$\Debug\Obj\udc_dfu_small.r90 + $PROJ_DIR$\Debug\Obj\udi_dfu_atmel.pbi + $PROJ_DIR$\Debug\Obj\udc_dfu_small.pbi + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\utils\preprocessor\preprocessor.h + $PROJ_DIR$\..\..\..\..\..\..\..\udc\udd.h + $PROJ_DIR$\Debug\Obj\main.pbi + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\utils\interrupt\interrupt_avr8.h + $PROJ_DIR$\Debug\Obj\ccp.r90 + $PROJ_DIR$\..\..\..\..\..\..\..\..\clock\sysclk.h + $TOOLKIT_DIR$\inc\dlib\c\ycheck.h + $PROJ_DIR$\..\..\..\..\..\..\..\udc\udc.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\cpu\xmega_reset_cause.h + $TOOLKIT_DIR$\inc\dlib\c\ysizet.h + $PROJ_DIR$\Debug\Obj\isp.pbi + $PROJ_DIR$\..\..\..\..\..\..\..\..\clock\xmega\sysclk.h + $TOOLKIT_DIR$\inc\dlib\c\stdint.h + + + [ROOT_NODE] + + + XLINK + 79 + + + + + $PROJ_DIR$\..\..\..\..\..\..\..\..\clock\xmega\sysclk.c + + + ICCAVR + 44 + + + BICOMP + 49 + + + + + BICOMP + 59 65 30 37 42 60 22 64 89 31 76 95 39 58 26 55 57 40 88 63 73 47 11 38 6 83 16 77 43 52 72 66 23 86 51 48 50 54 92 2 41 94 67 9 + + + + + $PROJ_DIR$\..\..\..\..\..\..\..\..\isp\flip\xmega\cstartup.s90 + + + AAVR + 10 + + + + + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\cpu\ccp.s + + + AAVR + 87 + + + + + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\nvm\nvm.c + + + ICCAVR + 18 + + + BICOMP + 56 + + + + + BICOMP + 26 89 55 22 52 65 30 72 73 95 39 58 64 2 60 67 23 47 11 38 57 6 83 16 77 43 50 54 92 41 86 37 66 42 59 + + + + + $PROJ_DIR$\..\..\main.c + + + ICCAVR + 45 + + + BICOMP + 85 + + + + + BICOMP + 65 52 57 30 83 26 48 60 76 31 74 91 22 89 66 67 14 16 90 95 39 58 72 23 86 40 25 75 35 73 88 84 70 47 11 38 6 77 43 64 37 42 59 55 62 50 54 92 2 41 51 94 63 9 15 34 29 + + + + + $PROJ_DIR$\..\..\..\..\..\..\..\..\isp\flip\xmega\isp.c + + + ICCAVR + 71 + + + BICOMP + 93 + + + + + BICOMP + 26 83 89 58 95 39 64 66 57 33 60 65 22 30 52 72 23 73 47 11 38 6 16 77 43 50 54 92 37 42 59 67 14 2 41 55 86 + + + + + $PROJ_DIR$\..\..\sysclk_opt.c + + + ICCAVR + 5 + + + BICOMP + 78 + + + + + BICOMP + 65 59 30 37 42 60 22 64 89 31 76 95 39 58 26 55 57 40 88 63 73 47 11 38 6 83 16 77 43 52 72 66 23 86 51 48 50 54 92 2 41 94 67 9 + + + + + $PROJ_DIR$\..\..\..\..\udi_dfu_atmel.c + + + ICCAVR + 7 + + + BICOMP + 81 + + + + + BICOMP + 11 77 89 75 34 6 83 26 66 57 74 90 60 43 52 73 69 14 47 38 16 72 23 35 84 46 33 15 65 95 22 39 58 30 64 37 42 59 92 67 25 50 54 2 41 55 86 29 + + + + + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\usb\usb_device.c + + + ICCAVR + 68 + + + BICOMP + 8 + + + + + BICOMP + 72 89 26 63 23 65 30 52 60 35 22 31 48 84 73 15 95 39 58 66 83 57 74 88 61 14 47 11 38 6 16 77 43 64 37 42 59 92 67 94 51 40 29 50 54 2 41 55 86 34 76 9 25 75 + + + + + $PROJ_DIR$\..\..\..\..\..\..\..\udc\udc_dfu_small.c + + + ICCAVR + 80 + + + BICOMP + 82 + + + + + BICOMP + 92 89 47 26 74 25 75 14 38 16 35 84 46 60 11 57 6 83 77 43 2 73 90 15 65 95 22 39 58 30 50 54 41 67 52 72 64 37 66 42 23 59 55 86 34 29 69 + + + + + $PROJ_DIR$\..\..\..\..\udi_dfu_atmel_desc.c + + + ICCAVR + 32 + + + BICOMP + 13 + + + + + BICOMP + 23 73 58 86 34 35 46 15 95 39 72 26 89 52 84 75 65 22 30 66 83 60 74 25 14 47 11 38 57 6 16 77 43 50 64 37 42 59 55 29 54 92 2 41 67 69 + + + + + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\nvm\nvm_asm.s + + + AAVR + 53 + + + + + + Release + + $PROJ_DIR$\..\..\..\..\..\..\..\..\clock\xmega\sysclk.c + $PROJ_DIR$\..\..\..\..\..\..\..\..\isp\flip\xmega\cstartup.s90 + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\utils\preprocessor\stringz.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\cpu\ccp.s + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\nvm\nvm.c + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\utils\bit_handling\clz_ctz.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\clock\xmega\osc.h + $TOOLKIT_DIR$\inc\dlib\c\stdbool.h + $PROJ_DIR$\..\..\main.c + $PROJ_DIR$\..\..\conf\conf_isp.h + $PROJ_DIR$\..\..\..\..\udi_dfu_atmel_conf.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\utils\interrupt.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\isp\flip\xmega\isp.c + $PROJ_DIR$\..\..\sysclk_opt.c + $PROJ_DIR$\..\..\..\..\udi_dfu_atmel.c + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\usb\usb_device.c + $TOOLKIT_DIR$\inc\dlib\c\stdlib.h + $TOOLKIT_DIR$\inc\dlib\c\string.h + $PROJ_DIR$\..\..\..\..\..\..\..\udc\udc_dfu_small.c + $PROJ_DIR$\..\..\..\..\..\..\..\udc\udc_desc.h + $TOOLKIT_DIR$\inc\dlib\c\yvals.h + $PROJ_DIR$\..\..\..\..\udi_dfu_atmel_desc.c + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\nvm\nvm_asm.s + $PROJ_DIR$\..\..\..\..\..\..\..\usb_atmel.h + $TOOLKIT_DIR$\inc\iomacro.h + $PROJ_DIR$\..\..\conf\conf_clock.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\isp\flip\isp.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\isp\flip\flip_protocol.h + $PROJ_DIR$\..\..\conf\conf_usb.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\utils\preprocessor\tpaste.h + $TOOLKIT_DIR$\inc\dlib\c\stddef.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\utils\progmem.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\boards\board.h + $TOOLKIT_DIR$\inc\dlib\c\stdio.h + $TOOLKIT_DIR$\inc\dlib\c\pgmspace.h + $TOOLKIT_DIR$\inc\Atmel\iomacro_xmega.h + $PROJ_DIR$\..\..\..\..\udi_dfu_atmel.h + $TOOLKIT_DIR$\inc\ioavr.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\clock\xmega\pll.h + $TOOLKIT_DIR$\inc\dlib\c\DLib_Defaults.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\boards\dummy\dummy_board.h + $TOOLKIT_DIR$\inc\dlib\c\xencoding_limits.h + $TOOLKIT_DIR$\inc\dlib\c\DLib_Threads.h + $TOOLKIT_DIR$\inc\dlib\c\ystdio.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\utils\parts.h + $TOOLKIT_DIR$\inc\ioxm32a4u.h + $TOOLKIT_DIR$\inc\dlib\c\stdarg.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\utils\compiler.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\usb\usb_device.h + $PROJ_DIR$\asf.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\clock\pll.h + $TOOLKIT_DIR$\inc\dlib\c\DLib_Product.h + $TOOLKIT_DIR$\inc\intrinsics.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\utils\preprocessor\mrepeat.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\cpu\ccp.h + $PROJ_DIR$\..\..\..\..\..\usb_protocol_dfu.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\utils\status_codes.h + $TOOLKIT_DIR$\lib\dlib\dlAVR-3s-xmega-sf-n.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\nvm\nvm.h + $PROJ_DIR$\..\..\..\..\..\..\..\usb_protocol.h + $PROJ_DIR$\..\..\..\..\..\..\..\udc\udi.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\clock\osc.h + $TOOLKIT_DIR$\inc\Atmel\ATxmega32A4U.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\utils\preprocessor\preprocessor.h + $PROJ_DIR$\..\..\..\..\..\..\..\udc\udd.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\utils\interrupt\interrupt_avr8.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\clock\sysclk.h + $TOOLKIT_DIR$\inc\dlib\c\ycheck.h + $PROJ_DIR$\..\..\..\..\..\..\..\udc\udc.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\cpu\xmega_reset_cause.h + $TOOLKIT_DIR$\inc\dlib\c\ysizet.h + $PROJ_DIR$\..\..\..\..\..\..\..\..\clock\xmega\sysclk.h + $TOOLKIT_DIR$\inc\dlib\c\stdint.h + $PROJ_DIR$\Release\Obj\main.r90 + $PROJ_DIR$\Release\Obj\sysclk.r90 + $PROJ_DIR$\Release\Exe\xmega_small.dbg + $PROJ_DIR$\Release\Obj\nvm.pbi + $PROJ_DIR$\Release\Obj\usb_device.pbi + $PROJ_DIR$\Release\Obj\sysclk.pbi + $PROJ_DIR$\Release\Obj\udi_dfu_atmel.r90 + $PROJ_DIR$\Release\Obj\isp.r90 + $PROJ_DIR$\Release\Obj\sysclk_opt.r90 + $PROJ_DIR$\Release\Obj\isp.pbi + $PROJ_DIR$\Release\Obj\udi_dfu_atmel_desc.r90 + $PROJ_DIR$\Release\Obj\main.pbi + $PROJ_DIR$\Release\Obj\udi_dfu_atmel_desc.pbi + $PROJ_DIR$\Release\Obj\nvm_asm.r90 + $PROJ_DIR$\Release\Obj\sysclk_opt.pbi + $PROJ_DIR$\Release\Obj\udc_dfu_small.pbi + $PROJ_DIR$\Release\Obj\udc_dfu_small.r90 + $PROJ_DIR$\Release\Obj\cstartup.r90 + $PROJ_DIR$\Release\Obj\nvm.r90 + $PROJ_DIR$\Release\Obj\usb_device.r90 + $PROJ_DIR$\Release\Obj\ccp.r90 + $PROJ_DIR$\Release\Obj\udi_dfu_atmel.pbi + + + [ROOT_NODE] + + + XLINK + 75 + + + + + $PROJ_DIR$\..\..\..\..\..\..\..\..\clock\xmega\sysclk.c + + + ICCAVR + 74 + + + BICOMP + 78 + + + + + BICOMP + 46 52 24 29 34 47 16 51 67 25 61 72 31 45 20 43 44 32 66 50 58 37 7 30 5 63 11 62 35 41 57 53 17 65 40 38 39 42 70 2 33 71 54 6 + + + + + $PROJ_DIR$\..\..\..\..\..\..\..\..\isp\flip\xmega\cstartup.s90 + + + AAVR + 90 + + + + + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\cpu\ccp.s + + + AAVR + 93 + + + + + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\nvm\nvm.c + + + ICCAVR + 91 + + + BICOMP + 76 + + + + + BICOMP + 20 67 43 16 41 52 24 57 58 72 31 45 51 2 47 54 17 37 7 30 44 5 63 11 62 35 39 42 70 33 65 29 53 34 46 + + + + + $PROJ_DIR$\..\..\main.c + + + ICCAVR + 73 + + + BICOMP + 84 + + + + + BICOMP + 52 41 44 24 63 20 38 47 61 25 59 69 16 67 53 54 9 11 68 72 31 45 57 17 65 32 19 60 28 58 66 64 56 37 7 30 5 62 35 51 29 34 46 43 49 39 42 70 2 33 40 71 50 6 10 27 23 + + + + + $PROJ_DIR$\..\..\..\..\..\..\..\..\isp\flip\xmega\isp.c + + + ICCAVR + 80 + + + BICOMP + 82 + + + + + BICOMP + 20 63 67 45 72 31 51 53 44 26 47 52 16 24 41 57 17 58 37 7 30 5 11 62 35 39 42 70 29 34 46 54 9 2 33 43 65 + + + + + $PROJ_DIR$\..\..\sysclk_opt.c + + + ICCAVR + 81 + + + BICOMP + 87 + + + + + BICOMP + 52 46 24 29 34 47 16 51 67 25 61 72 31 45 20 43 44 32 66 50 58 37 7 30 5 63 11 62 35 41 57 53 17 65 40 38 39 42 70 2 33 71 54 6 + + + + + $PROJ_DIR$\..\..\..\..\udi_dfu_atmel.c + + + ICCAVR + 79 + + + BICOMP + 94 + + + + + BICOMP + 7 62 67 60 27 5 63 20 53 44 59 68 47 35 41 58 55 9 37 30 11 57 17 28 64 36 26 10 52 72 16 31 45 24 51 29 34 46 70 54 19 39 42 2 33 43 65 23 + + + + + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\usb\usb_device.c + + + ICCAVR + 92 + + + BICOMP + 77 + + + + + BICOMP + 57 67 20 50 17 52 24 41 47 28 16 25 38 64 58 10 72 31 45 53 63 44 59 66 48 9 37 7 30 5 11 62 35 51 29 34 46 70 54 71 40 32 23 39 42 2 33 43 65 27 61 6 19 60 + + + + + $PROJ_DIR$\..\..\..\..\..\..\..\udc\udc_dfu_small.c + + + ICCAVR + 89 + + + BICOMP + 88 + + + + + BICOMP + 70 67 37 20 59 19 60 9 30 11 28 64 36 47 7 44 5 63 62 35 2 58 68 10 52 72 16 31 45 24 39 42 33 54 41 57 51 29 53 34 17 46 43 65 27 23 55 + + + + + $PROJ_DIR$\..\..\..\..\udi_dfu_atmel_desc.c + + + ICCAVR + 83 + + + BICOMP + 85 + + + + + BICOMP + 17 58 45 65 27 28 36 10 72 31 57 20 67 41 64 60 52 16 24 53 63 47 59 19 9 37 7 30 44 5 11 62 35 39 51 29 34 46 43 23 42 70 2 33 54 55 + + + + + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\nvm\nvm_asm.s + + + AAVR + 86 + + + + + diff --git a/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewd b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewd index e97d912..e0cb57d 100644 --- a/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewd +++ b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewd @@ -1,1847 +1,2058 @@ - - 2 - - Debug - - AVR - - 1 - - C-SPY - 5 - - 14 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - AVRONE - 3 - - 3 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CCRAVR - 2 - - 1 - 1 - 1 - - - - - - - - - - - - - - - - - - - - ICE200AVR - 2 - - 1 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - JTAGICEAVR - 3 - - 2 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JTAGICEMKIIAVR - 4 - - 6 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DRAGONAVR - 2 - - 2 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SIMAVR - 2 - - 1 - 1 - 1 - - - - - - - THIRDPARTYAVR - 2 - - 1 - 1 - 1 - - - - - - - - - - - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin - 0 - - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin - 0 - - - $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin - 1 - - - - - Release - - AVR - - 0 - - C-SPY - 5 - - 14 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - AVRONE - 3 - - 3 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CCRAVR - 2 - - 1 - 1 - 0 - - - - - - - - - - - - - - - - - - - - ICE200AVR - 2 - - 1 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - JTAGICEAVR - 3 - - 2 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JTAGICEMKIIAVR - 4 - - 6 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DRAGONAVR - 2 - - 2 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SIMAVR - 2 - - 1 - 1 - 0 - - - - - - - THIRDPARTYAVR - 2 - - 1 - 1 - 0 - - - - - - - - - - - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin - 0 - - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin - 0 - - - $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin - 1 - - - - + + + 3 + + Debug + + AVR + + 1 + + C-SPY + 6 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ATMELICEAVR + 7 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AVRONE + 4 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JTAGICE3AVR + 6 + + 7 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JTAGICEMKIIAVR + 5 + + 7 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DRAGONAVR + 3 + + 3 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + POWERDEBUGGERAVR + 7 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SIMAVR + 2 + + 1 + 1 + 1 + + + + + + + THIRDPARTYAVR + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\Stk600\Stk600Plugin.ewplugin + 1 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + AVR + + 0 + + C-SPY + 6 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ATMELICEAVR + 7 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AVRONE + 4 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JTAGICE3AVR + 6 + + 7 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JTAGICEMKIIAVR + 5 + + 7 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DRAGONAVR + 3 + + 3 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + POWERDEBUGGERAVR + 7 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SIMAVR + 2 + + 1 + 1 + 0 + + + + + + + THIRDPARTYAVR + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\Stk600\Stk600Plugin.ewplugin + 1 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewp b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewp index 4d0640e..28e5b9f 100644 --- a/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewp +++ b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewp @@ -1,2156 +1,2281 @@ - - 2 - - Debug - - AVR - - 1 - - General - 11 - - 9 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCAVR - 6 - - 17 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AAVR - 5 - - 11 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CUSTOM - 3 - - - - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - - - - - - XLINK - 2 - - 13 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - XAR - 2 - - 0 - 1 - 1 - - - - - - - BILINK - 0 - - - - - Release - - AVR - - 0 - - General - 11 - - 9 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCAVR - 6 - - 17 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AAVR - 5 - - 11 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CUSTOM - 3 - - - - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - - - - - - XLINK - 2 - - 13 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - XAR - 2 - - 0 - 1 - 0 - - - - - - - BILINK - 0 - - - - - common - - services - - usb - - class - - dfu_flip - - device - - $PROJ_DIR$\..\..\..\..\udi_dfu_atmel.c - - - bootloader - - xmega - - $PROJ_DIR$\..\..\sysclk_opt.c - - - $PROJ_DIR$\..\..\main.c - - - - - $PROJ_DIR$\..\..\..\..\udi_dfu_atmel_desc.c - - - - - - udc - - $PROJ_DIR$\..\..\..\..\..\..\..\udc\udc_dfu_small.c - - - - - clock - - xmega - - $PROJ_DIR$\..\..\..\..\..\..\..\..\clock\xmega\sysclk.c - - - - - isp - - flip - - xmega - - $PROJ_DIR$\..\..\..\..\..\..\..\..\isp\flip\xmega\isp.c - - - $PROJ_DIR$\..\..\..\..\..\..\..\..\isp\flip\xmega\cstartup.s90 - - - - - - - - xmega - - drivers - - nvm - - $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\nvm\nvm.c - - - $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\nvm\nvm_asm.s - - - - usb - - $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\usb\usb_device.c - - - - cpu - - $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\cpu\ccp.s - - - - - - Release - Debug - - + + + 3 + + Debug + + AVR + + 1 + + General + 12 + + 10 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCAVR + 6 + + 17 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AAVR + 5 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 3 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 2 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Release + + AVR + + 0 + + General + 12 + + 10 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCAVR + 6 + + 17 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AAVR + 5 + + 11 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 3 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 2 + + 0 + 1 + 0 + + + + + + + BILINK + 0 + + + + + Debug + Release + + + common + + services + + clock + + xmega + + $PROJ_DIR$\..\..\..\..\..\..\..\..\clock\xmega\sysclk.c + + + + + isp + + flip + + xmega + + $PROJ_DIR$\..\..\..\..\..\..\..\..\isp\flip\xmega\cstartup.s90 + + + $PROJ_DIR$\..\..\..\..\..\..\..\..\isp\flip\xmega\isp.c + + + + + + usb + + class + + dfu_flip + + device + + bootloader + + xmega + + $PROJ_DIR$\..\..\main.c + + + $PROJ_DIR$\..\..\sysclk_opt.c + + + + + $PROJ_DIR$\..\..\..\..\udi_dfu_atmel.c + + + $PROJ_DIR$\..\..\..\..\udi_dfu_atmel_desc.c + + + + + + udc + + $PROJ_DIR$\..\..\..\..\..\..\..\udc\udc_dfu_small.c + + + + + + + xmega + + drivers + + cpu + + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\cpu\ccp.s + + + + nvm + + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\nvm\nvm.c + + + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\nvm\nvm_asm.s + + + + usb + + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\usb\usb_device.c + + + + + + Release + Debug + + diff --git a/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewt b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewt new file mode 100644 index 0000000..775e1f8 --- /dev/null +++ b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.ewt @@ -0,0 +1,2249 @@ + + + 3 + + Debug + + AVR + + 1 + + C-STAT + 261 + + 261 + + 0 + + 1 + 600 + 0 + 3 + 0 + 1 + 100 + + + 1.5.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Release + + AVR + + 0 + + C-STAT + 261 + + 261 + + 0 + + 1 + 600 + 0 + 3 + 0 + 1 + 100 + + + 1.5.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + common + + services + + clock + + xmega + + $PROJ_DIR$\..\..\..\..\..\..\..\..\clock\xmega\sysclk.c + + + + + isp + + flip + + xmega + + $PROJ_DIR$\..\..\..\..\..\..\..\..\isp\flip\xmega\cstartup.s90 + + + $PROJ_DIR$\..\..\..\..\..\..\..\..\isp\flip\xmega\isp.c + + + + + + usb + + class + + dfu_flip + + device + + bootloader + + xmega + + $PROJ_DIR$\..\..\main.c + + + $PROJ_DIR$\..\..\sysclk_opt.c + + + + + $PROJ_DIR$\..\..\..\..\udi_dfu_atmel.c + + + $PROJ_DIR$\..\..\..\..\udi_dfu_atmel_desc.c + + + + + + udc + + $PROJ_DIR$\..\..\..\..\..\..\..\udc\udc_dfu_small.c + + + + + + + xmega + + drivers + + cpu + + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\cpu\ccp.s + + + + nvm + + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\nvm\nvm.c + + + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\nvm\nvm_asm.s + + + + usb + + $PROJ_DIR$\..\..\..\..\..\..\..\..\..\..\xmega\drivers\usb\usb_device.c + + + + + diff --git a/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.eww b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.eww index d1e75ec..1f68449 100644 --- a/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.eww +++ b/Firmware/Atmel-DFU-Bootloader/common/services/usb/class/dfu_flip/device/bootloader/xmega/atxmega32a4u/iar/xmega_small.eww @@ -1,6 +1,7 @@ - - - - $WS_DIR$\xmega_small.ewp - - + + + + $WS_DIR$\xmega_small.ewp + + + From 724f1588e1bce4dd31fc26007960fb4a2fbbfe70 Mon Sep 17 00:00:00 2001 From: "@shinhub" Date: Wed, 14 Aug 2019 01:10:19 +0200 Subject: [PATCH 5/6] Exclude more debug --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index f8fdeb8..c626cee 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,5 @@ Firmware/Chameleon-Mini/*.eep Firmware/Atmel-DFU-Bootloader/common/*.hex Firmware/Atmel-DFU-Bootloader/common/*.eep Firmware/Atmel-DFU-Bootloader/common/*.dbg +*/iar/Debug/* +*/iar/Release/* From 9b603cf2ad9666b3ad5924344753c5d46af526a8 Mon Sep 17 00:00:00 2001 From: "@shinhub" Date: Wed, 14 Aug 2019 01:14:03 +0200 Subject: [PATCH 6/6] Moved bootloader original parts to consistent location --- .../atxmega32a4u_104_PA6.hex | 0 .../Original-Windows}/GenerateBootloader.bat | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename Firmware/{Atmel-DFU-Bootloader => Original-Compiled}/atxmega32a4u_104_PA6.hex (100%) rename {Firmware/Atmel-DFU-Bootloader => Software/Original-Windows}/GenerateBootloader.bat (100%) diff --git a/Firmware/Atmel-DFU-Bootloader/atxmega32a4u_104_PA6.hex b/Firmware/Original-Compiled/atxmega32a4u_104_PA6.hex similarity index 100% rename from Firmware/Atmel-DFU-Bootloader/atxmega32a4u_104_PA6.hex rename to Firmware/Original-Compiled/atxmega32a4u_104_PA6.hex diff --git a/Firmware/Atmel-DFU-Bootloader/GenerateBootloader.bat b/Software/Original-Windows/GenerateBootloader.bat similarity index 100% rename from Firmware/Atmel-DFU-Bootloader/GenerateBootloader.bat rename to Software/Original-Windows/GenerateBootloader.bat