1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-19 09:42:11 +03:00

Moved 'firmware' folder in the proper place

This commit is contained in:
Cristian Maglie
2012-10-18 16:01:53 +02:00
parent aba27c43aa
commit b95a015284
296 changed files with 0 additions and 0 deletions

View File

@ -0,0 +1,467 @@
:1000000090C00000A9C00000A7C00000A5C000006B
:10001000A3C00000A1C000009FC000009DC0000060
:100020009BC0000099C0000097C0000048C40000B9
:100030000CC4000091C000008FC000008DC0000003
:100040008BC0000089C0000087C0000085C0000090
:1000500083C0000081C000007FC0000002C100001A
:100060007BC0000079C0000077C0000075C00000B0
:1000700073C0000071C000006FC000006DC00000C0
:100080006BC0000069C0000067C0000065C00000D0
:1000900063C0000061C000001201100102000008EE
:1000A0004123420001000102DC0109023E0002017D
:1000B00000C0320904000001020201000524000111
:1000C0001004240206052406000107058203080027
:1000D000FF09040100020A000000070504024000B5
:1000E00001070583024000010403090432034100B3
:1000F00072006400750069006E006F002000280027
:100100007700770077002E006100720064007500B0
:1001100069006E006F002E0063006300290000007C
:10012000000011241FBECFEFD2E0DEBFCDBF11E033
:10013000A0E0B1E0ECEAFFE002C005900D92A6312C
:10014000B107D9F712E0A6E1B1E001C01D92AF32CC
:10015000B107E1F7F1D028C753CF9C01DC01AE57BE
:10016000BF4FED91FC91119741911196FC93EE9345
:1001700080589F4FE817F90711F42D933C939FB7D0
:10018000F894F901EC57FF4F8081815080839FBF25
:10019000842F0895DF92EF92FF920F931F93FC013B
:1001A0008489813019F0823021F405C040E3D42ED7
:1001B00004C0DD2402C030E2D32E8389823011F4E2
:1001C00088E0D82A8589873031F0883031F0863050
:1001D00031F482E003C084E001C086E0D82A1092A6
:1001E000C9001092C8001092CA00E784F088018903
:1001F000128980E0E81681EEF80680E0080780E0CA
:10020000180719F420E130E00FC0C801B701969536
:1002100087957795679560587B47814E9F4FA801DA
:100220009701A0D6215030403093CD002093CC00D0
:10023000D092CA0080E0E81681EEF80680E0080758
:1002400080E0180711F082E001C080E08093C800D0
:1002500088E98093C9001F910F91FF90EF90DF9084
:1002600008951F920F920FB60F9211242F938F9320
:100270009F93EF93FF939091CE008EB38430F1F46F
:10028000E0919901F0919A019083E0919901F091A8
:100290009A01CF01019690939A018093990189590F
:1002A000914021F489E191E0928381839FB7F89492
:1002B00080919D018F5F80939D019FBFFF91EF9182
:1002C0009F918F912F910F900FBE0F901F901895B7
:1002D000FC01858580FF02C05F9808955F9A0895AC
:1002E00080E091E0D5C580E091E088C584B7877F44
:1002F00084BF28E10FB6F89420936000109260004C
:100300000FBE87E690E09093CD008093CC0086E00E
:100310008093CA001092C8002093C900539A5A9A39
:100320008AB180638AB98BB180638BB983D284E050
:1003300085BD5F9A579A08950F931F93CF93DF93CC
:10034000D5DF2FB7F8948EE991E090931F02809348
:100350001E0290932102809320022FBF2FB7F894A2
:1003600089E191E090939A018093990190939C0187
:1003700080939B012FBF7894CEE9D1E003E08FB743
:10038000F894909122028FBF903809F180E091E0BB
:10039000ABD497FD1CC0E0911E02F0911F02808338
:1003A000E0911E02F0911F02CF01019690931F026F
:1003B00080931E028E51924011F4D283C1839FB765
:1003C000F894809122028F5F809322029FBF8FB7A3
:1003D000F89410919D018FBFA89902C0113678F151
:1003E000A89A80919D01882361F05D980093160181
:1003F00008C089E191E0B1DE682F80E091E0DAD4B5
:1004000011501123B1F780911601882351F080918A
:10041000160181508093160180911601882309F4FA
:100420005D9A80911701882351F0809117018150C6
:100430008093170180911701882309F45C9A8FB784
:10044000F894909122028FBF992369F08EE991E090
:1004500084DE982F8091C80085FFFCCF9093CE005A
:100460005C980093170180E091E095D42AD487CF5F
:10047000DA01923049F0933061F09130F9F4E8E913
:10048000F0E022E130E01EC0EAEAF0E02EE330E0E6
:1004900019C0813049F0813018F0823079F408C0F9
:1004A000E8EEF0E0849107C0ECEEF0E0849103C048
:1004B000E0E2F1E08491282F30E004C0E0E0F0E0D9
:1004C00020E030E0ED93FC93C901089528E030E08E
:1004D00040E003C04F5F220F331F28173907D0F3C6
:1004E000842F8295807F08958093E9008091EB00AE
:1004F00081608093EB001092ED006093EC004093DC
:10050000ED008091EE00881F8827881F08951092C3
:10051000F40090E09093E9001092F0001092E8004F
:100520001092ED008091EB008E7F8093EB009F5F37
:10053000953081F708958091270288238CF403C0B9
:100540008EB38823B1F08091E80082FFF9CF8091CB
:10055000E8008B778093E80008958EB3882349F0F4
:100560008091E80080FFF9CF8091E8008E7780933A
:10057000E800089594E68091EC0080FF05C080912A
:10058000E80080FF05C023C08091E80082FD1FC005
:100590008EB3882311F482E008958EB3853011F470
:1005A00083E008958091EB0085FF02C081E008950B
:1005B0008091E10082FFDFCF8091E1008B7F80930B
:1005C000E100992311F484E008959150D4CF80E0A4
:1005D00008959C0140912D0250912E024617570715
:1005E00018F4F90120E038C06115710511F0AB0174
:1005F000F8CF8091E8008E778093E80040E050E0EB
:10060000F0CF8091E80083FF02C081E008958091DF
:10061000E80082FD2DC08EB3882381F18EB3853032
:1006200079F18091E80080FF17C09091F20006C038
:1006300081918093F100415050409F5F41155105D9
:1006400011F09830A8F320E0983009F421E080916F
:10065000E8008E778093E8004115510591F622233A
:1006600081F606C08EB3882349F08EB3853041F001
:100670008091E80082FFF6CF80E0089582E008953F
:1006800083E008959C0140912D0250912E0246175F
:10069000570710F490E03BC06115710511F0AB01F4
:1006A000F9CF8091E8008E778093E80040E050E039
:1006B000F1CF8091E80083FF02C081E0089580912E
:1006C000E80082FD30C08EB3882399F18EB3853067
:1006D00091F18091E80080FF1AC08091F20009C07A
:1006E000F9012F5F3F4FE491E093F10041505040FA
:1006F0008F5F4115510511F0883090F390E08830FC
:1007000009F491E08091E8008E778093E80041152C
:10071000510579F6992369F606C08EB3882349F00E
:100720008EB3853041F08091E80082FFF6CF80E003
:10073000089582E0089583E008959C016115710594
:1007400029F48091E8008B778093E800F90120C0BC
:100750008091E80083FF02C081E008958EB3882372
:1007600039F18EB3853031F18091E80082FFF0CF0E
:1007700006C08091F10081936150704021F080911A
:10078000F2008823B1F78091E8008B778093E8002E
:1007900061157105E9F606C08EB3882349F08EB362
:1007A000853041F08091E80080FFF6CF80E0089529
:1007B00082E0089583E0089542D044D01EBA10929A
:1007C0002502109224021092230284E089BD89B58B
:1007D000826089BD09B400FEFDCF8091D800982FBA
:1007E0009F779093D80080688093D80080916300B1
:1007F0008E7F809363008091D8008F7D8093D80096
:100800008091E0008E7F8093E0008091E1008E7FF8
:100810008093E1008091E20081608093E20080910A
:10082000E100877F8093E1008091E20088608093FF
:10083000E2000895C1DF81E08093260208951092BE
:10084000E20008951092E10008951F920F920FB6F2
:100850000F9211241F932F933F934F935F936F93A6
:100860007F938F939F93AF93BF93EF93FF93E9EEA3
:10087000F0E0108117701082E0EFF0E08081877F58
:1008800080837894C3D0F894A9EEB0E01C92E0EF96
:10089000F0E08081886080831C93FF91EF91BF918D
:1008A000AF919F918F917F916F915F914F913F9108
:1008B0002F911F910F900FBE0F901F9018951F92B0
:1008C0000F920FB60F9211242F933F934F935F9384
:1008D0006F937F938F939F93AF93BF93EF93FF9308
:1008E0008091E10080FF1BC08091E20080FF17C073
:1008F0008091E1008E7F8093E1008091E2008E7F05
:100900008093E2008091E20080618093E200809118
:10091000D80080628093D80019BC1EBAD1D18091D2
:10092000E10084FF29C08091E20084FF25C084E0BB
:1009300089BD89B5826089BD09B400FEFDCF809173
:10094000D8008F7D8093D8008091E1008F7E8093C6
:10095000E1008091E2008F7E8093E2008091E200CE
:1009600081608093E20080912502882311F481E068
:1009700001C084E08EBBA4D18091E10083FF27C039
:100980008091E20083FF23C08091E100877F809304
:10099000E10082E08EBB109225028091E1008E7F03
:1009A0008093E1008091E2008E7F8093E20080914D
:1009B000E20080618093E200AADD80E060E042E036
:1009C00093DD8091F00088608093F00079D1809170
:1009D000E10082FF0AC08091E20082FF06C08091A0
:1009E000E1008B7F8093E1006BD1FF91EF91BF918C
:1009F000AF919F918F917F916F915F914F913F91B7
:100A00002F910F900FBE0F901F9018951F93DF939B
:100A1000CF93CDB7DEB7AC970FB6F894DEBF0FBE5D
:100A2000CDBFE7E2F2E08091F100819322E0EF3266
:100A3000F207C9F78091270230912802353009F476
:100A400087C0363040F43130C9F1313070F0333086
:100A500009F01DC133C0383009F4EFC0393009F452
:100A6000FEC0363009F013C192C0803821F08238C0
:100A700009F00DC108C090912302809124028823BF
:100A800099F0926011C080912B0287708093E900E9
:100A90008091EB0090E025E0969587952A95E1F707
:100AA000982F91701092E9008091E800877F8093E1
:100AB000E8009093F1001092F100CAC0882319F069
:100AC000823009F0E4C090E08F719070009721F0BF
:100AD000029709F0DDC00CC080912902813009F035
:100AE000D7C010922402333069F5809324022AC0C3
:100AF00080912902882331F520912B02277009F477
:100B0000C7C02093E9008091EB0080FFC1C0333063
:100B100021F48091EB00806213C08091EB00806132
:100B20008093EB0081E090E002C0880F991F2A9526
:100B3000E2F78093EA001092EA008091EB0088606F
:100B40008093EB001092E9008091E800877F83C0DA
:100B5000882309F09CC0109129028091E800877FCA
:100B60008093E800E8DC04C08EB3882309F490C0C9
:100B70008091E80080FFF8CF812F8F7711F492E009
:100B800001C093E09EBB80688093E30081C08058E1
:100B9000823008F07CC08091290290912A0223E0E3
:100BA0008C3D920799F55FB7F894DE0115964EE0FB
:100BB00020E030E061E2E42FF0E0609357008491A0
:100BC00020FF03C082958F704F5F982F9F70892FF1
:100BD000805D8A3308F0895F8C9311961C9211977F
:100BE0002F5F3F4F12962431310529F75FBF8AE20C
:100BF0008B8383E08C838091E800877F8093E8007B
:100C0000CE0103966AE270E0E4DC11C060912B0231
:100C1000AE014F5F5F4F2CDCBC010097C9F18091A2
:100C2000E800877F8093E80089819A812BDD80919D
:100C3000E8008B778093E8002BC0803841F58091E5
:100C4000E800877F8093E800809125028093F1007F
:100C50008091E8008E778093E8006DDC19C08823CE
:100C6000B1F490912902923098F48091E800877F46
:100C70008093E800909325025EDC80912502882312
:100C800011F483E001C084E08EBB2DDB01C028DBC2
:100C90008091E80083FF0AC08091EB00806280931E
:100CA000EB008091E800877F8093E800AC960FB658
:100CB000F894DEBF0FBECDBFCF91DF911F91089595
:100CC00008951F938EB3882361F01091E90010926C
:100CD000E9008091E80083FF01C098DE177010934F
:100CE000E9001F9108950895FC018EB3843021F529
:100CF00087859089A189B2890097A105B105E1F0A6
:100D000085818093E9008091E80082FF15C0809181
:100D1000F200882319F42FEF3FEF04C08091F10017
:100D2000282F30E08091F200882341F48091E80080
:100D30008B778093E80002C02FEF3FEFC901089541
:100D4000FC018EB3843011F587859089A189B28921
:100D50000097A105B105D1F081818093E9008091D0
:100D6000F2008823A9F09091E8008091E8008E7746
:100D70008093E80095FD0CC0FDDB982F882349F493
:100D80008091E8008E778093E80003C092E001C074
:100D900090E0892F0895FC018EB3843051F487854B
:100DA0009089A189B2890097A105B10511F0CF0101
:100DB000C7CF08951F93FC01162F8EB38430D9F44A
:100DC00087859089A189B2890097A105B10599F01D
:100DD00081818093E9008091E80085FD08C08091C1
:100DE000E8008E778093E800C5DB882329F4109310
:100DF000F10080E001C082E01F9108950F931F93DE
:100E0000CF93DF93EC010D96FC0189E0DF011D9289
:100E10008A95E9F72A813B8109818C81882311F425
:100E200010E001C014E0C90151DB182B1260802FC3
:100E300061E8412F59DB882329F12E813F810D8103
:100E40008885882311F410E001C014E0C9013EDB5D
:100E5000182B1260802F60E8412F46DB882391F029
:100E60002A853B8509858C85882311F410E001C013
:100E700014E0C9012BDB182B1260802F61EC412F8D
:100E800033DB01C080E0DF91CF911F910F91089576
:100E9000CF93DF93EC018091E80083FF60C08881ED
:100EA00090E020912B0230912C022817390709F08D
:100EB00056C080912802813261F0823220F4803263
:100EC00009F04DC019C0823269F1833209F047C080
:100ED00038C080912702813A09F041C08091E80032
:100EE000877F8093E800CE010F9667E070E071DBAA
:100EF0008091E8008B7713C080912702813279F5C9
:100F00008091E800877F8093E800CE010F9667E02C
:100F100070E013DCCE013ED98091E8008E7780939B
:100F2000E8001DC0809127028132C9F48091E80059
:100F3000877F8093E800809129028D87CE01C8D9F0
:100F40000DC080912702813251F48091E800877FA3
:100F50008093E800CE0160912902C5DEECDADF91D2
:100F6000CF910895A1E21A2EAA1BBB1BFD010DC053
:100F7000AA1FBB1FEE1FFF1FA217B307E407F50749
:100F800020F0A21BB30BE40BF50B661F771F881F25
:100F9000991F1A9469F760957095809590959B01BB
:0C0FA000AC01BD01CF010895F894FFCF13
:100FAC0000034000000440000002080000000000A4
:060FBC000000000000002F
:103000004BC0000064C0000062C0000060C000004F
:103010005EC000005CC000005AC0000058C0000044
:1030200056C0000054C0000052C00000EEC40000B2
:103030004EC000004CC000004AC0000048C0000064
:1030400046C0000044C0000042C0000040C0000074
:103050003EC000003CC000003AC0000038C0000084
:1030600036C0000034C0000032C0000030C0000094
:103070002EC000002CC000002AC0000028C00000A4
:1030800026C0000024C0000022C0000020C00000B4
:103090001EC000001CC0000011241FBECFEFD2E0F4
:1030A000DEBFCDBF11E0A0E0B1E0EAEFFCE302C07B
:1030B00005900D92AA33B107D9F711E0AAE3B1E068
:1030C00001C01D92AB35B107E1F772D314C698CF9A
:1030D000982F15C08091F200882371F48091E80048
:1030E0008B7F8093E80003C08EB3882351F08091DA
:1030F000E80082FFF9CF02C08091F100915099233E
:1031000049F7089520914A01309149018091480181
:103110009091470180933F0190934001C9018093B2
:103120004101909342010895DF93CF9300D000D0E6
:1031300000D0CDB7DEB780914501843009F45AC084
:10314000853030F4813059F0833009F0D7C01FC08A
:10315000853009F4A0C0863009F0D0C0C3C080918A
:103160004601823008F0CAC0CDDF80914601882335
:1031700061F480913F019091400123E0FC01209394
:103180005700E89507B600FCFDCF85E008C08091A8
:103190004601882311F0823029F4B4DF89E080935E
:1031A0000101ACC0813009F0A9C020E030E040E06E
:1031B00050E0F90184918F3F81F0CA01AA27BB2713
:1031C00080933E013093400120933F018AE0809339
:1031D000010185E080933B0191C02F5F3F4F4F4F2E
:1031E0005F4F2030F0E33F07F0E04F07F0E05F076C
:1031F00001F784C080914601833051F581E08093CE
:103200003A0180914B0190914C01892B71F0809192
:103210004701813009F072C080914A0190914901C3
:1032200090933D0180933C0169C0809147018823C0
:1032300061F42CE088E190E00FB6F894A8958093B3
:1032400060000FBE2093600059C01092000156C06C
:10325000882309F053C0809147018F3F09F04EC089
:10326000E0E0F0E093E085E090935700E89507B642
:1032700000FCFDCF80935700E89507B600FCFDCF1A
:10328000E058FF4F20E3E030F20771F781E18093CF
:103290005700E89533C0DE011196E5E0F1E083E0E8
:1032A00001900D928150E1F7DE011496E2E0F1E029
:1032B00083E001900D928150E1F790914701809158
:1032C0004601882329F4FE01E90FF11D818107C021
:1032D0008130A1F4FE01BC97E90FF11D808180933C
:1032E00050010CC080914601833041F48091470128
:1032F000882321F48091480180933E0126960FB6E1
:10330000F894DEBF0FBECDBFCF91DF9108952F920D
:103310003F924F925F926F927F929F92AF92BF9235
:10332000CF92DF92EF92FF920F931F93CF93DF9391
:103330008091590190915A0190934C0180934B01D7
:1033400080914D01882351F080914D0181508093EF
:103350004D0180914D01882309F45D9A80914E01C1
:10336000882351F080914E01815080934E018091CD
:103370004E01882309F45C9A80915401833009F44A
:10338000B2C1843030F4813071F0823009F0E3C191
:1033900011C1853009F4C5C1853008F4BAC1863041
:1033A00009F0D9C1CDC15C9883E080934E01809132
:1033B000E800877F8093E80080913A01882329F014
:1033C000B3DE5D9A5C9A10923A0120914B013091E4
:1033D0004C012115310529F42AC08EB3882309F444
:1033E000BAC18091E80082FFF8CF8091F10080930C
:1033F00045012150304030934C0120934B01E6E4CD
:10340000F1E00CC08091F10081932150304081E0C7
:10341000EB34F80719F43183208308C08091F2005F
:10342000882381F730934C0120934B017DDE8091FE
:103430000101853009F0BAC080914B0190914C0197
:10344000892B21F482E080930101B0C08AE140DE43
:1034500080913F018F713CDEC0914101D0914201CA
:1034600020913F013091400121968E01021B130BE8
:10347000219780914601882309F093C01801369462
:103480002794C901A0913E01B0E09C01AD0162E02A
:10349000E62EF12C012D112DE20EF31E041F151F37
:1034A00059016A0190E099249394B5E0A3E048C0E3
:1034B0008091F200882371F48091E8008B7F8093E3
:1034C000E80004C08EB3882309F445C18091E80068
:1034D00082FFF8CF0894210831088091F100682F0D
:1034E0008091F100782FF5010B0190925700E8953B
:1034F00011249F5F903419F021143104A1F4F901D3
:10350000B0935700E89507B600FCFDCF21143104B5
:1035100051F0F701A0935700E89507B600FCFDCFE6
:10352000A801970190E042E0442E512C612C712CAF
:10353000E40CF51C061D171DA40CB51CC61CD71CDD
:103540002114310409F0B4CFD0934001C0933F015E
:1035500081E180935700E89527C08091F20088238D
:1035600071F48091E8008B7F8093E80004C08EB3F3
:10357000882309F4F0C08091E80082FFF8CF6091C1
:10358000F10080913F0190914001A7D380913F01CC
:103590009091400101969093400180933F0101502A
:1035A000104001151105C9F680E192DD8091E80017
:1035B0008B7FC3C08091E800877F8093E8005D988F
:1035C00083E080934D0104C08EB3882309F4C3C007
:1035D0008091E80080FFF8CF80910101893091F05F
:1035E0008A3069F480914601813049F480913F012D
:1035F000909140018093F1009093F1009BC08091E5
:10360000500196C0609141017091420120913F01AB
:10361000309140016F5F7F4F7B01E21AF30A6150E6
:10362000704080914601882389F58701169507959A
:10363000C901A0913E01B0E09C01AD011FC0809185
:10364000F200803271F48091E8008E7F8093E80070
:1036500004C08EB3882309F47EC08091E80080FF07
:10366000F8CFF901859194918093F1009093F10046
:10367000015010402E5F3F4F4F4F5F4F0115110516
:10368000F1F67093400160933F0129C0823039F513
:1036900023C08091F200803271F48091E8008E7F27
:1036A0008093E80004C08EB3882309F454C080914D
:1036B000E80080FFF8CF00913F0110914001C80160
:1036C00004D38093F1000F5F1F4F109340010093CC
:1036D0003F010894E108F108E114F104D1F682E019
:1036E0008093010127C08091E800877F8093E800E4
:1036F00080913B018093F1001092F1001092F10053
:103700001092F100809101018093F1001092F1007C
:1037100011C08091E800877F8093E80010923B0100
:1037200019C08091E800877F8093E80080910101B3
:103730008093F1008091E8008E7F8093E8000AC0BA
:103740008091E800877F8093E8005D9A5C9A82E030
:103750008093010187D0DF91CF911F910F91FF904E
:10376000EF90DF90CF90BF90AF909F907F906F9041
:103770005F904F903F902F9008952BD181E085BFAF
:1037800015BE089584B7877F84BF88E10FB6F8948B
:1037900080936000109260000FBE81E085BF82E0E0
:1037A00085BF8AB180638AB98BB180638BB90CC144
:1037B000E9DF789401C080D2809100018823D9F795
:1037C00080913A018823B9F7D8DFE0913C01F0916C
:1037D0003D010995FA01923071F0933089F09130F2
:1037E00029F488E091E022E130E019C080E090E027
:1037F00020E030E014C08AE191E02BE130E00FC01E
:10380000882339F480913501282F30E085E391E059
:1038100006C080914301282F30E083E491E091833A
:103820008083C90108958091EB0081608093EB0053
:103830001092ED006093EC004093ED008091EE005B
:10384000881F8827881F08951092F4001092F000B6
:103850001092E8001092ED00EBEEF0E080818E7F98
:10386000808308958091530188238CF403C08EB324
:103870008823B1F08091E80082FFF9CF8091E800C1
:103880008B7F8093E80008958EB3882349F0809160
:10389000E80080FFF9CF8091E8008E7F8093E800F8
:1038A00008959C014091590150915A0146175707BC
:1038B00018F4F90120E038C06115710511F0AB0171
:1038C000F8CF8091E8008E7F8093E80040E050E0E0
:1038D000F0CF8091E80083FF02C081E008958091DD
:1038E000E80082FD2DC08EB3882381F18EB3853030
:1038F00079F18091E80080FF17C09091F20006C036
:1039000081918093F100415050409F5F41155105D6
:1039100011F09032A8F320E0903209F421E0809178
:10392000E8008E7F8093E8004115510591F622232F
:1039300081F606C08EB3882349F08EB3853041F0FE
:103940008091E80082FFF6CF80E0089582E008953C
:1039500083E0089554D056D01EBA1092510184E0ED
:1039600089BD89B5826089BD09B400FEFDCF809113
:10397000D800982F9F779093D80080688093D800C4
:10398000809163008E7F809363008091D8008F7D4B
:103990008093D8008091E0008E7F8093E00080913A
:1039A000E1008E7F8093E1008091E200816080934E
:1039B000E2008091E100877F8093E1008091E20046
:1039C00088608093E2000895C5DF81E08093520112
:1039D0000895C0DFE0EEF0E0808181608083E8ED53
:1039E000F0E080818F7780830AD00CD019BCE3E6A9
:1039F000F0E08081816080831092520108951092DE
:103A0000E20008951092E10008951F920F920FB600
:103A10000F9211242F933F934F935F936F937F9354
:103A20008F939F93AF93BF93EF93FF938091E100A8
:103A300080FF1BC08091E20080FF17C08091E100F1
:103A40008E7F8093E1008091E2008E7F8093E20080
:103A50008091E20080618093E2008091D8008062D2
:103A60008093D80019BC1EBA26D18091E10084FF52
:103A700029C08091E20084FF25C084E089BD89B51A
:103A8000826089BD09B400FEFDCF8091D8008F7D92
:103A90008093D8008091E1008F7E8093E100809137
:103AA000E2008F7E8093E2008091E200816080934B
:103AB000E20080915101882311F481E001C084E08B
:103AC0008EBBF9D08091E10083FF22C08091E2009B
:103AD00083FF1EC08091E100877F8093E10082E038
:103AE0008EBB109251018091E1008E7F8093E100A6
:103AF0008091E2008E7F8093E2008091E2008061FD
:103B00008093E200A1DE80E060E042E28CDED3D070
:103B10008091E10082FF0AC08091E20082FF06C02E
:103B20008091E1008B7F8093E100C5D0FF91EF9100
:103B3000BF91AF919F918F917F916F915F914F91C5
:103B40003F912F910F900FBE0F901F9018951F93CC
:103B5000DF93CF9300D0CDB7DEB7E3E5F1E08091FE
:103B6000F100819381E0EB35F807C9F7909153019B
:103B700080915401853011F1863040F48130B9F0E4
:103B8000813070F0833009F081C011C0883009F4B1
:103B900053C0893009F462C0863009F077C02DC067
:103BA000903809F474C0923809F070C070C099233D
:103BB00009F46DC0923009F069C069C0992309F019
:103BC00065C0109155018091E800877F8093E800DF
:103BD00049DE04C08EB3882309F459C08091E800FF
:103BE00080FFF8CF812F8F7711F492E001C093E02E
:103BF0009EBB80688093E3004AC09058923008F0E2
:103C000045C0809155019091560160915701AE01D8
:103C10004F5F5F4FDFDDBC010097C9F18091E80085
:103C2000877F8093E80089819A813BDE8091E8005C
:103C30008B7F8093E8002BC0903841F58091E8009D
:103C4000877F8093E800809151018093F1008091FB
:103C5000E8008E7F8093E80005DE19C09923B1F457
:103C600090915501923098F48091E800877F80937D
:103C7000E80090935101F6DD80915101882311F401
:103C800083E001C084E08EBB16D001C040DB809190
:103C9000E80083FF0AC08091EB0080628093EB0014
:103CA0008091E800877F8093E8000F900F90CF917C
:103CB000DF911F91089508958EB3882329F0809194
:103CC000E80083FF01C043CF0895F999FECF92BD6C
:103CD00081BDF89A992780B50895262FF999FECFCE
:103CE0001FBA92BD81BD20BD0FB6F894FA9AF99A19
:0A3CF0000FBE01960895F894FFCF6F
:103CFA0001021E948920DCFB120110010000002041
:103D0A00EB03EF2F00000001000109021B00010173
:103D1A000080320904000000FE01020009210300AC
:0A3D2A0000000C000104030904006E
:0400000300003000C9
:00000001FF

View File

@ -0,0 +1,467 @@
:1000000090C00000A9C00000A7C00000A5C000006B
:10001000A3C00000A1C000009FC000009DC0000060
:100020009BC0000099C0000097C0000048C40000B9
:100030000CC4000091C000008FC000008DC0000003
:100040008BC0000089C0000087C0000085C0000090
:1000500083C0000081C000007FC0000002C100001A
:100060007BC0000079C0000077C0000075C00000B0
:1000700073C0000071C000006FC000006DC00000C0
:100080006BC0000069C0000067C0000065C00000D0
:1000900063C0000061C000001201100102000008EE
:1000A0004123440001000102DC0109023E0002017B
:1000B00000C0320904000001020201000524000111
:1000C0001004240206052406000107058203080027
:1000D000FF09040100020A000000070504024000B5
:1000E00001070583024000010403090432034100B3
:1000F00072006400750069006E006F002000280027
:100100007700770077002E006100720064007500B0
:1001100069006E006F002E0063006300290000007C
:10012000000011241FBECFEFD2E0DEBFCDBF11E033
:10013000A0E0B1E0ECEAFFE002C005900D92A6312C
:10014000B107D9F712E0A6E1B1E001C01D92AF32CC
:10015000B107E1F7F1D028C753CF9C01DC01AE57BE
:10016000BF4FED91FC91119741911196FC93EE9345
:1001700080589F4FE817F90711F42D933C939FB7D0
:10018000F894F901EC57FF4F8081815080839FBF25
:10019000842F0895DF92EF92FF920F931F93FC013B
:1001A0008489813019F0823021F405C040E3D42ED7
:1001B00004C0DD2402C030E2D32E8389823011F4E2
:1001C00088E0D82A8589873031F0883031F0863050
:1001D00031F482E003C084E001C086E0D82A1092A6
:1001E000C9001092C8001092CA00E784F088018903
:1001F000128980E0E81681EEF80680E0080780E0CA
:10020000180719F420E130E00FC0C801B701969536
:1002100087957795679560587B47814E9F4FA801DA
:100220009701A0D6215030403093CD002093CC00D0
:10023000D092CA0080E0E81681EEF80680E0080758
:1002400080E0180711F082E001C080E08093C800D0
:1002500088E98093C9001F910F91FF90EF90DF9084
:1002600008951F920F920FB60F9211242F938F9320
:100270009F93EF93FF939091CE008EB38430F1F46F
:10028000E0919901F0919A019083E0919901F091A8
:100290009A01CF01019690939A018093990189590F
:1002A000914021F489E191E0928381839FB7F89492
:1002B00080919D018F5F80939D019FBFFF91EF9182
:1002C0009F918F912F910F900FBE0F901F901895B7
:1002D000FC01858580FF02C05F9808955F9A0895AC
:1002E00080E091E0D5C580E091E088C584B7877F44
:1002F00084BF28E10FB6F89420936000109260004C
:100300000FBE87E690E09093CD008093CC0086E00E
:100310008093CA001092C8002093C900539A5A9A39
:100320008AB180638AB98BB180638BB983D284E050
:1003300085BD5F9A579A08950F931F93CF93DF93CC
:10034000D5DF2FB7F8948EE991E090931F02809348
:100350001E0290932102809320022FBF2FB7F894A2
:1003600089E191E090939A018093990190939C0187
:1003700080939B012FBF7894CEE9D1E003E08FB743
:10038000F894909122028FBF903809F180E091E0BB
:10039000ABD497FD1CC0E0911E02F0911F02808338
:1003A000E0911E02F0911F02CF01019690931F026F
:1003B00080931E028E51924011F4D283C1839FB765
:1003C000F894809122028F5F809322029FBF8FB7A3
:1003D000F89410919D018FBFA89902C0113678F151
:1003E000A89A80919D01882361F05D980093160181
:1003F00008C089E191E0B1DE682F80E091E0DAD4B5
:1004000011501123B1F780911601882351F080918A
:10041000160181508093160180911601882309F4FA
:100420005D9A80911701882351F0809117018150C6
:100430008093170180911701882309F45C9A8FB784
:10044000F894909122028FBF992369F08EE991E090
:1004500084DE982F8091C80085FFFCCF9093CE005A
:100460005C980093170180E091E095D42AD487CF5F
:10047000DA01923049F0933061F09130F9F4E8E913
:10048000F0E022E130E01EC0EAEAF0E02EE330E0E6
:1004900019C0813049F0813018F0823079F408C0F9
:1004A000E8EEF0E0849107C0ECEEF0E0849103C048
:1004B000E0E2F1E08491282F30E004C0E0E0F0E0D9
:1004C00020E030E0ED93FC93C901089528E030E08E
:1004D00040E003C04F5F220F331F28173907D0F3C6
:1004E000842F8295807F08958093E9008091EB00AE
:1004F00081608093EB001092ED006093EC004093DC
:10050000ED008091EE00881F8827881F08951092C3
:10051000F40090E09093E9001092F0001092E8004F
:100520001092ED008091EB008E7F8093EB009F5F37
:10053000953081F708958091270288238CF403C0B9
:100540008EB38823B1F08091E80082FFF9CF8091CB
:10055000E8008B778093E80008958EB3882349F0F4
:100560008091E80080FFF9CF8091E8008E7780933A
:10057000E800089594E68091EC0080FF05C080912A
:10058000E80080FF05C023C08091E80082FD1FC005
:100590008EB3882311F482E008958EB3853011F470
:1005A00083E008958091EB0085FF02C081E008950B
:1005B0008091E10082FFDFCF8091E1008B7F80930B
:1005C000E100992311F484E008959150D4CF80E0A4
:1005D00008959C0140912D0250912E024617570715
:1005E00018F4F90120E038C06115710511F0AB0174
:1005F000F8CF8091E8008E778093E80040E050E0EB
:10060000F0CF8091E80083FF02C081E008958091DF
:10061000E80082FD2DC08EB3882381F18EB3853032
:1006200079F18091E80080FF17C09091F20006C038
:1006300081918093F100415050409F5F41155105D9
:1006400011F09830A8F320E0983009F421E080916F
:10065000E8008E778093E8004115510591F622233A
:1006600081F606C08EB3882349F08EB3853041F001
:100670008091E80082FFF6CF80E0089582E008953F
:1006800083E008959C0140912D0250912E0246175F
:10069000570710F490E03BC06115710511F0AB01F4
:1006A000F9CF8091E8008E778093E80040E050E039
:1006B000F1CF8091E80083FF02C081E0089580912E
:1006C000E80082FD30C08EB3882399F18EB3853067
:1006D00091F18091E80080FF1AC08091F20009C07A
:1006E000F9012F5F3F4FE491E093F10041505040FA
:1006F0008F5F4115510511F0883090F390E08830FC
:1007000009F491E08091E8008E778093E80041152C
:10071000510579F6992369F606C08EB3882349F00E
:100720008EB3853041F08091E80082FFF6CF80E003
:10073000089582E0089583E008959C016115710594
:1007400029F48091E8008B778093E800F90120C0BC
:100750008091E80083FF02C081E008958EB3882372
:1007600039F18EB3853031F18091E80082FFF0CF0E
:1007700006C08091F10081936150704021F080911A
:10078000F2008823B1F78091E8008B778093E8002E
:1007900061157105E9F606C08EB3882349F08EB362
:1007A000853041F08091E80080FFF6CF80E0089529
:1007B00082E0089583E0089542D044D01EBA10929A
:1007C0002502109224021092230284E089BD89B58B
:1007D000826089BD09B400FEFDCF8091D800982FBA
:1007E0009F779093D80080688093D80080916300B1
:1007F0008E7F809363008091D8008F7D8093D80096
:100800008091E0008E7F8093E0008091E1008E7FF8
:100810008093E1008091E20081608093E20080910A
:10082000E100877F8093E1008091E20088608093FF
:10083000E2000895C1DF81E08093260208951092BE
:10084000E20008951092E10008951F920F920FB6F2
:100850000F9211241F932F933F934F935F936F93A6
:100860007F938F939F93AF93BF93EF93FF93E9EEA3
:10087000F0E0108117701082E0EFF0E08081877F58
:1008800080837894C3D0F894A9EEB0E01C92E0EF96
:10089000F0E08081886080831C93FF91EF91BF918D
:1008A000AF919F918F917F916F915F914F913F9108
:1008B0002F911F910F900FBE0F901F9018951F92B0
:1008C0000F920FB60F9211242F933F934F935F9384
:1008D0006F937F938F939F93AF93BF93EF93FF9308
:1008E0008091E10080FF1BC08091E20080FF17C073
:1008F0008091E1008E7F8093E1008091E2008E7F05
:100900008093E2008091E20080618093E200809118
:10091000D80080628093D80019BC1EBAD1D18091D2
:10092000E10084FF29C08091E20084FF25C084E0BB
:1009300089BD89B5826089BD09B400FEFDCF809173
:10094000D8008F7D8093D8008091E1008F7E8093C6
:10095000E1008091E2008F7E8093E2008091E200CE
:1009600081608093E20080912502882311F481E068
:1009700001C084E08EBBA4D18091E10083FF27C039
:100980008091E20083FF23C08091E100877F809304
:10099000E10082E08EBB109225028091E1008E7F03
:1009A0008093E1008091E2008E7F8093E20080914D
:1009B000E20080618093E200AADD80E060E042E036
:1009C00093DD8091F00088608093F00079D1809170
:1009D000E10082FF0AC08091E20082FF06C08091A0
:1009E000E1008B7F8093E1006BD1FF91EF91BF918C
:1009F000AF919F918F917F916F915F914F913F91B7
:100A00002F910F900FBE0F901F9018951F93DF939B
:100A1000CF93CDB7DEB7AC970FB6F894DEBF0FBE5D
:100A2000CDBFE7E2F2E08091F100819322E0EF3266
:100A3000F207C9F78091270230912802353009F476
:100A400087C0363040F43130C9F1313070F0333086
:100A500009F01DC133C0383009F4EFC0393009F452
:100A6000FEC0363009F013C192C0803821F08238C0
:100A700009F00DC108C090912302809124028823BF
:100A800099F0926011C080912B0287708093E900E9
:100A90008091EB0090E025E0969587952A95E1F707
:100AA000982F91701092E9008091E800877F8093E1
:100AB000E8009093F1001092F100CAC0882319F069
:100AC000823009F0E4C090E08F719070009721F0BF
:100AD000029709F0DDC00CC080912902813009F035
:100AE000D7C010922402333069F5809324022AC0C3
:100AF00080912902882331F520912B02277009F477
:100B0000C7C02093E9008091EB0080FFC1C0333063
:100B100021F48091EB00806213C08091EB00806132
:100B20008093EB0081E090E002C0880F991F2A9526
:100B3000E2F78093EA001092EA008091EB0088606F
:100B40008093EB001092E9008091E800877F83C0DA
:100B5000882309F09CC0109129028091E800877FCA
:100B60008093E800E8DC04C08EB3882309F490C0C9
:100B70008091E80080FFF8CF812F8F7711F492E009
:100B800001C093E09EBB80688093E30081C08058E1
:100B9000823008F07CC08091290290912A0223E0E3
:100BA0008C3D920799F55FB7F894DE0115964EE0FB
:100BB00020E030E061E2E42FF0E0609357008491A0
:100BC00020FF03C082958F704F5F982F9F70892FF1
:100BD000805D8A3308F0895F8C9311961C9211977F
:100BE0002F5F3F4F12962431310529F75FBF8AE20C
:100BF0008B8383E08C838091E800877F8093E8007B
:100C0000CE0103966AE270E0E4DC11C060912B0231
:100C1000AE014F5F5F4F2CDCBC010097C9F18091A2
:100C2000E800877F8093E80089819A812BDD80919D
:100C3000E8008B778093E8002BC0803841F58091E5
:100C4000E800877F8093E800809125028093F1007F
:100C50008091E8008E778093E8006DDC19C08823CE
:100C6000B1F490912902923098F48091E800877F46
:100C70008093E800909325025EDC80912502882312
:100C800011F483E001C084E08EBB2DDB01C028DBC2
:100C90008091E80083FF0AC08091EB00806280931E
:100CA000EB008091E800877F8093E800AC960FB658
:100CB000F894DEBF0FBECDBFCF91DF911F91089595
:100CC00008951F938EB3882361F01091E90010926C
:100CD000E9008091E80083FF01C098DE177010934F
:100CE000E9001F9108950895FC018EB3843021F529
:100CF00087859089A189B2890097A105B105E1F0A6
:100D000085818093E9008091E80082FF15C0809181
:100D1000F200882319F42FEF3FEF04C08091F10017
:100D2000282F30E08091F200882341F48091E80080
:100D30008B778093E80002C02FEF3FEFC901089541
:100D4000FC018EB3843011F587859089A189B28921
:100D50000097A105B105D1F081818093E9008091D0
:100D6000F2008823A9F09091E8008091E8008E7746
:100D70008093E80095FD0CC0FDDB982F882349F493
:100D80008091E8008E778093E80003C092E001C074
:100D900090E0892F0895FC018EB3843051F487854B
:100DA0009089A189B2890097A105B10511F0CF0101
:100DB000C7CF08951F93FC01162F8EB38430D9F44A
:100DC00087859089A189B2890097A105B10599F01D
:100DD00081818093E9008091E80085FD08C08091C1
:100DE000E8008E778093E800C5DB882329F4109310
:100DF000F10080E001C082E01F9108950F931F93DE
:100E0000CF93DF93EC010D96FC0189E0DF011D9289
:100E10008A95E9F72A813B8109818C81882311F425
:100E200010E001C014E0C90151DB182B1260802FC3
:100E300061E8412F59DB882329F12E813F810D8103
:100E40008885882311F410E001C014E0C9013EDB5D
:100E5000182B1260802F60E8412F46DB882391F029
:100E60002A853B8509858C85882311F410E001C013
:100E700014E0C9012BDB182B1260802F61EC412F8D
:100E800033DB01C080E0DF91CF911F910F91089576
:100E9000CF93DF93EC018091E80083FF60C08881ED
:100EA00090E020912B0230912C022817390709F08D
:100EB00056C080912802813261F0823220F4803263
:100EC00009F04DC019C0823269F1833209F047C080
:100ED00038C080912702813A09F041C08091E80032
:100EE000877F8093E800CE010F9667E070E071DBAA
:100EF0008091E8008B7713C080912702813279F5C9
:100F00008091E800877F8093E800CE010F9667E02C
:100F100070E013DCCE013ED98091E8008E7780939B
:100F2000E8001DC0809127028132C9F48091E80059
:100F3000877F8093E800809129028D87CE01C8D9F0
:100F40000DC080912702813251F48091E800877FA3
:100F50008093E800CE0160912902C5DEECDADF91D2
:100F6000CF910895A1E21A2EAA1BBB1BFD010DC053
:100F7000AA1FBB1FEE1FFF1FA217B307E407F50749
:100F800020F0A21BB30BE40BF50B661F771F881F25
:100F9000991F1A9469F760957095809590959B01BB
:0C0FA000AC01BD01CF010895F894FFCF13
:100FAC0000034000000440000002080000000000A4
:060FBC000000000000002F
:103000004BC0000064C0000062C0000060C000004F
:103010005EC000005CC000005AC0000058C0000044
:1030200056C0000054C0000052C00000EEC40000B2
:103030004EC000004CC000004AC0000048C0000064
:1030400046C0000044C0000042C0000040C0000074
:103050003EC000003CC000003AC0000038C0000084
:1030600036C0000034C0000032C0000030C0000094
:103070002EC000002CC000002AC0000028C00000A4
:1030800026C0000024C0000022C0000020C00000B4
:103090001EC000001CC0000011241FBECFEFD2E0F4
:1030A000DEBFCDBF11E0A0E0B1E0EAEFFCE302C07B
:1030B00005900D92AA33B107D9F711E0AAE3B1E068
:1030C00001C01D92AB35B107E1F772D314C698CF9A
:1030D000982F15C08091F200882371F48091E80048
:1030E0008B7F8093E80003C08EB3882351F08091DA
:1030F000E80082FFF9CF02C08091F100915099233E
:1031000049F7089520914A01309149018091480181
:103110009091470180933F0190934001C9018093B2
:103120004101909342010895DF93CF9300D000D0E6
:1031300000D0CDB7DEB780914501843009F45AC084
:10314000853030F4813059F0833009F0D7C01FC08A
:10315000853009F4A0C0863009F0D0C0C3C080918A
:103160004601823008F0CAC0CDDF80914601882335
:1031700061F480913F019091400123E0FC01209394
:103180005700E89507B600FCFDCF85E008C08091A8
:103190004601882311F0823029F4B4DF89E080935E
:1031A0000101ACC0813009F0A9C020E030E040E06E
:1031B00050E0F90184918F3F81F0CA01AA27BB2713
:1031C00080933E013093400120933F018AE0809339
:1031D000010185E080933B0191C02F5F3F4F4F4F2E
:1031E0005F4F2030F0E33F07F0E04F07F0E05F076C
:1031F00001F784C080914601833051F581E08093CE
:103200003A0180914B0190914C01892B71F0809192
:103210004701813009F072C080914A0190914901C3
:1032200090933D0180933C0169C0809147018823C0
:1032300061F42CE088E190E00FB6F894A8958093B3
:1032400060000FBE2093600059C01092000156C06C
:10325000882309F053C0809147018F3F09F04EC089
:10326000E0E0F0E093E085E090935700E89507B642
:1032700000FCFDCF80935700E89507B600FCFDCF1A
:10328000E058FF4F20E3E030F20771F781E18093CF
:103290005700E89533C0DE011196E5E0F1E083E0E8
:1032A00001900D928150E1F7DE011496E2E0F1E029
:1032B00083E001900D928150E1F790914701809158
:1032C0004601882329F4FE01E90FF11D818107C021
:1032D0008130A1F4FE01BC97E90FF11D808180933C
:1032E00050010CC080914601833041F48091470128
:1032F000882321F48091480180933E0126960FB6E1
:10330000F894DEBF0FBECDBFCF91DF9108952F920D
:103310003F924F925F926F927F929F92AF92BF9235
:10332000CF92DF92EF92FF920F931F93CF93DF9391
:103330008091590190915A0190934C0180934B01D7
:1033400080914D01882351F080914D0181508093EF
:103350004D0180914D01882309F45D9A80914E01C1
:10336000882351F080914E01815080934E018091CD
:103370004E01882309F45C9A80915401833009F44A
:10338000B2C1843030F4813071F0823009F0E3C191
:1033900011C1853009F4C5C1853008F4BAC1863041
:1033A00009F0D9C1CDC15C9883E080934E01809132
:1033B000E800877F8093E80080913A01882329F014
:1033C000B3DE5D9A5C9A10923A0120914B013091E4
:1033D0004C012115310529F42AC08EB3882309F444
:1033E000BAC18091E80082FFF8CF8091F10080930C
:1033F00045012150304030934C0120934B01E6E4CD
:10340000F1E00CC08091F10081932150304081E0C7
:10341000EB34F80719F43183208308C08091F2005F
:10342000882381F730934C0120934B017DDE8091FE
:103430000101853009F0BAC080914B0190914C0197
:10344000892B21F482E080930101B0C08AE140DE43
:1034500080913F018F713CDEC0914101D0914201CA
:1034600020913F013091400121968E01021B130BE8
:10347000219780914601882309F093C01801369462
:103480002794C901A0913E01B0E09C01AD0162E02A
:10349000E62EF12C012D112DE20EF31E041F151F37
:1034A00059016A0190E099249394B5E0A3E048C0E3
:1034B0008091F200882371F48091E8008B7F8093E3
:1034C000E80004C08EB3882309F445C18091E80068
:1034D00082FFF8CF0894210831088091F100682F0D
:1034E0008091F100782FF5010B0190925700E8953B
:1034F00011249F5F903419F021143104A1F4F901D3
:10350000B0935700E89507B600FCFDCF21143104B5
:1035100051F0F701A0935700E89507B600FCFDCFE6
:10352000A801970190E042E0442E512C612C712CAF
:10353000E40CF51C061D171DA40CB51CC61CD71CDD
:103540002114310409F0B4CFD0934001C0933F015E
:1035500081E180935700E89527C08091F20088238D
:1035600071F48091E8008B7F8093E80004C08EB3F3
:10357000882309F4F0C08091E80082FFF8CF6091C1
:10358000F10080913F0190914001A7D380913F01CC
:103590009091400101969093400180933F0101502A
:1035A000104001151105C9F680E192DD8091E80017
:1035B0008B7FC3C08091E800877F8093E8005D988F
:1035C00083E080934D0104C08EB3882309F4C3C007
:1035D0008091E80080FFF8CF80910101893091F05F
:1035E0008A3069F480914601813049F480913F012D
:1035F000909140018093F1009093F1009BC08091E5
:10360000500196C0609141017091420120913F01AB
:10361000309140016F5F7F4F7B01E21AF30A6150E6
:10362000704080914601882389F58701169507959A
:10363000C901A0913E01B0E09C01AD011FC0809185
:10364000F200803271F48091E8008E7F8093E80070
:1036500004C08EB3882309F47EC08091E80080FF07
:10366000F8CFF901859194918093F1009093F10046
:10367000015010402E5F3F4F4F4F5F4F0115110516
:10368000F1F67093400160933F0129C0823039F513
:1036900023C08091F200803271F48091E8008E7F27
:1036A0008093E80004C08EB3882309F454C080914D
:1036B000E80080FFF8CF00913F0110914001C80160
:1036C00004D38093F1000F5F1F4F109340010093CC
:1036D0003F010894E108F108E114F104D1F682E019
:1036E0008093010127C08091E800877F8093E800E4
:1036F00080913B018093F1001092F1001092F10053
:103700001092F100809101018093F1001092F1007C
:1037100011C08091E800877F8093E80010923B0100
:1037200019C08091E800877F8093E80080910101B3
:103730008093F1008091E8008E7F8093E8000AC0BA
:103740008091E800877F8093E8005D9A5C9A82E030
:103750008093010187D0DF91CF911F910F91FF904E
:10376000EF90DF90CF90BF90AF909F907F906F9041
:103770005F904F903F902F9008952BD181E085BFAF
:1037800015BE089584B7877F84BF88E10FB6F8948B
:1037900080936000109260000FBE81E085BF82E0E0
:1037A00085BF8AB180638AB98BB180638BB90CC144
:1037B000E9DF789401C080D2809100018823D9F795
:1037C00080913A018823B9F7D8DFE0913C01F0916C
:1037D0003D010995FA01923071F0933089F09130F2
:1037E00029F488E091E022E130E019C080E090E027
:1037F00020E030E014C08AE191E02BE130E00FC01E
:10380000882339F480913501282F30E085E391E059
:1038100006C080914301282F30E083E491E091833A
:103820008083C90108958091EB0081608093EB0053
:103830001092ED006093EC004093ED008091EE005B
:10384000881F8827881F08951092F4001092F000B6
:103850001092E8001092ED00EBEEF0E080818E7F98
:10386000808308958091530188238CF403C08EB324
:103870008823B1F08091E80082FFF9CF8091E800C1
:103880008B7F8093E80008958EB3882349F0809160
:10389000E80080FFF9CF8091E8008E7F8093E800F8
:1038A00008959C014091590150915A0146175707BC
:1038B00018F4F90120E038C06115710511F0AB0171
:1038C000F8CF8091E8008E7F8093E80040E050E0E0
:1038D000F0CF8091E80083FF02C081E008958091DD
:1038E000E80082FD2DC08EB3882381F18EB3853030
:1038F00079F18091E80080FF17C09091F20006C036
:1039000081918093F100415050409F5F41155105D6
:1039100011F09032A8F320E0903209F421E0809178
:10392000E8008E7F8093E8004115510591F622232F
:1039300081F606C08EB3882349F08EB3853041F0FE
:103940008091E80082FFF6CF80E0089582E008953C
:1039500083E0089554D056D01EBA1092510184E0ED
:1039600089BD89B5826089BD09B400FEFDCF809113
:10397000D800982F9F779093D80080688093D800C4
:10398000809163008E7F809363008091D8008F7D4B
:103990008093D8008091E0008E7F8093E00080913A
:1039A000E1008E7F8093E1008091E200816080934E
:1039B000E2008091E100877F8093E1008091E20046
:1039C00088608093E2000895C5DF81E08093520112
:1039D0000895C0DFE0EEF0E0808181608083E8ED53
:1039E000F0E080818F7780830AD00CD019BCE3E6A9
:1039F000F0E08081816080831092520108951092DE
:103A0000E20008951092E10008951F920F920FB600
:103A10000F9211242F933F934F935F936F937F9354
:103A20008F939F93AF93BF93EF93FF938091E100A8
:103A300080FF1BC08091E20080FF17C08091E100F1
:103A40008E7F8093E1008091E2008E7F8093E20080
:103A50008091E20080618093E2008091D8008062D2
:103A60008093D80019BC1EBA26D18091E10084FF52
:103A700029C08091E20084FF25C084E089BD89B51A
:103A8000826089BD09B400FEFDCF8091D8008F7D92
:103A90008093D8008091E1008F7E8093E100809137
:103AA000E2008F7E8093E2008091E200816080934B
:103AB000E20080915101882311F481E001C084E08B
:103AC0008EBBF9D08091E10083FF22C08091E2009B
:103AD00083FF1EC08091E100877F8093E10082E038
:103AE0008EBB109251018091E1008E7F8093E100A6
:103AF0008091E2008E7F8093E2008091E2008061FD
:103B00008093E200A1DE80E060E042E28CDED3D070
:103B10008091E10082FF0AC08091E20082FF06C02E
:103B20008091E1008B7F8093E100C5D0FF91EF9100
:103B3000BF91AF919F918F917F916F915F914F91C5
:103B40003F912F910F900FBE0F901F9018951F93CC
:103B5000DF93CF9300D0CDB7DEB7E3E5F1E08091FE
:103B6000F100819381E0EB35F807C9F7909153019B
:103B700080915401853011F1863040F48130B9F0E4
:103B8000813070F0833009F081C011C0883009F4B1
:103B900053C0893009F462C0863009F077C02DC067
:103BA000903809F474C0923809F070C070C099233D
:103BB00009F46DC0923009F069C069C0992309F019
:103BC00065C0109155018091E800877F8093E800DF
:103BD00049DE04C08EB3882309F459C08091E800FF
:103BE00080FFF8CF812F8F7711F492E001C093E02E
:103BF0009EBB80688093E3004AC09058923008F0E2
:103C000045C0809155019091560160915701AE01D8
:103C10004F5F5F4FDFDDBC010097C9F18091E80085
:103C2000877F8093E80089819A813BDE8091E8005C
:103C30008B7F8093E8002BC0903841F58091E8009D
:103C4000877F8093E800809151018093F1008091FB
:103C5000E8008E7F8093E80005DE19C09923B1F457
:103C600090915501923098F48091E800877F80937D
:103C7000E80090935101F6DD80915101882311F401
:103C800083E001C084E08EBB16D001C040DB809190
:103C9000E80083FF0AC08091EB0080628093EB0014
:103CA0008091E800877F8093E8000F900F90CF917C
:103CB000DF911F91089508958EB3882329F0809194
:103CC000E80083FF01C043CF0895F999FECF92BD6C
:103CD00081BDF89A992780B50895262FF999FECFCE
:103CE0001FBA92BD81BD20BD0FB6F894FA9AF99A19
:0A3CF0000FBE01960895F894FFCF6F
:103CFA0001021E948920DCFB120110010000002041
:103D0A00EB03EF2F00000001000109021B00010173
:103D1A000080320904000000FE01020009210300AC
:0A3D2A0000000C000104030904006E
:0400000300003000C9
:00000001FF

View File

@ -0,0 +1,467 @@
:1000000090C00000A9C00000A7C00000A5C000006B
:10001000A3C00000A1C000009FC000009DC0000060
:100020009BC0000099C0000097C0000048C40000B9
:100030000CC4000091C000008FC000008DC0000003
:100040008BC0000089C0000087C0000085C0000090
:1000500083C0000081C000007FC0000002C100001A
:100060007BC0000079C0000077C0000075C00000B0
:1000700073C0000071C000006FC000006DC00000C0
:100080006BC0000069C0000067C0000065C00000D0
:1000900063C0000061C000001201100102000008EE
:1000A0004123430001000102DC0109023E0002017C
:1000B00000C0320904000001020201000524000111
:1000C0001004240206052406000107058203080027
:1000D000FF09040100020A000000070504024000B5
:1000E00001070583024000010403090432034100B3
:1000F00072006400750069006E006F002000280027
:100100007700770077002E006100720064007500B0
:1001100069006E006F002E0063006300290000007C
:10012000000011241FBECFEFD2E0DEBFCDBF11E033
:10013000A0E0B1E0ECEAFFE002C005900D92A6312C
:10014000B107D9F712E0A6E1B1E001C01D92AF32CC
:10015000B107E1F7F1D028C753CF9C01DC01AE57BE
:10016000BF4FED91FC91119741911196FC93EE9345
:1001700080589F4FE817F90711F42D933C939FB7D0
:10018000F894F901EC57FF4F8081815080839FBF25
:10019000842F0895DF92EF92FF920F931F93FC013B
:1001A0008489813019F0823021F405C040E3D42ED7
:1001B00004C0DD2402C030E2D32E8389823011F4E2
:1001C00088E0D82A8589873031F0883031F0863050
:1001D00031F482E003C084E001C086E0D82A1092A6
:1001E000C9001092C8001092CA00E784F088018903
:1001F000128980E0E81681EEF80680E0080780E0CA
:10020000180719F420E130E00FC0C801B701969536
:1002100087957795679560587B47814E9F4FA801DA
:100220009701A0D6215030403093CD002093CC00D0
:10023000D092CA0080E0E81681EEF80680E0080758
:1002400080E0180711F082E001C080E08093C800D0
:1002500088E98093C9001F910F91FF90EF90DF9084
:1002600008951F920F920FB60F9211242F938F9320
:100270009F93EF93FF939091CE008EB38430F1F46F
:10028000E0919901F0919A019083E0919901F091A8
:100290009A01CF01019690939A018093990189590F
:1002A000914021F489E191E0928381839FB7F89492
:1002B00080919D018F5F80939D019FBFFF91EF9182
:1002C0009F918F912F910F900FBE0F901F901895B7
:1002D000FC01858580FF02C05F9808955F9A0895AC
:1002E00080E091E0D5C580E091E088C584B7877F44
:1002F00084BF28E10FB6F89420936000109260004C
:100300000FBE87E690E09093CD008093CC0086E00E
:100310008093CA001092C8002093C900539A5A9A39
:100320008AB180638AB98BB180638BB983D284E050
:1003300085BD5F9A579A08950F931F93CF93DF93CC
:10034000D5DF2FB7F8948EE991E090931F02809348
:100350001E0290932102809320022FBF2FB7F894A2
:1003600089E191E090939A018093990190939C0187
:1003700080939B012FBF7894CEE9D1E003E08FB743
:10038000F894909122028FBF903809F180E091E0BB
:10039000ABD497FD1CC0E0911E02F0911F02808338
:1003A000E0911E02F0911F02CF01019690931F026F
:1003B00080931E028E51924011F4D283C1839FB765
:1003C000F894809122028F5F809322029FBF8FB7A3
:1003D000F89410919D018FBFA89902C0113678F151
:1003E000A89A80919D01882361F05D980093160181
:1003F00008C089E191E0B1DE682F80E091E0DAD4B5
:1004000011501123B1F780911601882351F080918A
:10041000160181508093160180911601882309F4FA
:100420005D9A80911701882351F0809117018150C6
:100430008093170180911701882309F45C9A8FB784
:10044000F894909122028FBF992369F08EE991E090
:1004500084DE982F8091C80085FFFCCF9093CE005A
:100460005C980093170180E091E095D42AD487CF5F
:10047000DA01923049F0933061F09130F9F4E8E913
:10048000F0E022E130E01EC0EAEAF0E02EE330E0E6
:1004900019C0813049F0813018F0823079F408C0F9
:1004A000E8EEF0E0849107C0ECEEF0E0849103C048
:1004B000E0E2F1E08491282F30E004C0E0E0F0E0D9
:1004C00020E030E0ED93FC93C901089528E030E08E
:1004D00040E003C04F5F220F331F28173907D0F3C6
:1004E000842F8295807F08958093E9008091EB00AE
:1004F00081608093EB001092ED006093EC004093DC
:10050000ED008091EE00881F8827881F08951092C3
:10051000F40090E09093E9001092F0001092E8004F
:100520001092ED008091EB008E7F8093EB009F5F37
:10053000953081F708958091270288238CF403C0B9
:100540008EB38823B1F08091E80082FFF9CF8091CB
:10055000E8008B778093E80008958EB3882349F0F4
:100560008091E80080FFF9CF8091E8008E7780933A
:10057000E800089594E68091EC0080FF05C080912A
:10058000E80080FF05C023C08091E80082FD1FC005
:100590008EB3882311F482E008958EB3853011F470
:1005A00083E008958091EB0085FF02C081E008950B
:1005B0008091E10082FFDFCF8091E1008B7F80930B
:1005C000E100992311F484E008959150D4CF80E0A4
:1005D00008959C0140912D0250912E024617570715
:1005E00018F4F90120E038C06115710511F0AB0174
:1005F000F8CF8091E8008E778093E80040E050E0EB
:10060000F0CF8091E80083FF02C081E008958091DF
:10061000E80082FD2DC08EB3882381F18EB3853032
:1006200079F18091E80080FF17C09091F20006C038
:1006300081918093F100415050409F5F41155105D9
:1006400011F09830A8F320E0983009F421E080916F
:10065000E8008E778093E8004115510591F622233A
:1006600081F606C08EB3882349F08EB3853041F001
:100670008091E80082FFF6CF80E0089582E008953F
:1006800083E008959C0140912D0250912E0246175F
:10069000570710F490E03BC06115710511F0AB01F4
:1006A000F9CF8091E8008E778093E80040E050E039
:1006B000F1CF8091E80083FF02C081E0089580912E
:1006C000E80082FD30C08EB3882399F18EB3853067
:1006D00091F18091E80080FF1AC08091F20009C07A
:1006E000F9012F5F3F4FE491E093F10041505040FA
:1006F0008F5F4115510511F0883090F390E08830FC
:1007000009F491E08091E8008E778093E80041152C
:10071000510579F6992369F606C08EB3882349F00E
:100720008EB3853041F08091E80082FFF6CF80E003
:10073000089582E0089583E008959C016115710594
:1007400029F48091E8008B778093E800F90120C0BC
:100750008091E80083FF02C081E008958EB3882372
:1007600039F18EB3853031F18091E80082FFF0CF0E
:1007700006C08091F10081936150704021F080911A
:10078000F2008823B1F78091E8008B778093E8002E
:1007900061157105E9F606C08EB3882349F08EB362
:1007A000853041F08091E80080FFF6CF80E0089529
:1007B00082E0089583E0089542D044D01EBA10929A
:1007C0002502109224021092230284E089BD89B58B
:1007D000826089BD09B400FEFDCF8091D800982FBA
:1007E0009F779093D80080688093D80080916300B1
:1007F0008E7F809363008091D8008F7D8093D80096
:100800008091E0008E7F8093E0008091E1008E7FF8
:100810008093E1008091E20081608093E20080910A
:10082000E100877F8093E1008091E20088608093FF
:10083000E2000895C1DF81E08093260208951092BE
:10084000E20008951092E10008951F920F920FB6F2
:100850000F9211241F932F933F934F935F936F93A6
:100860007F938F939F93AF93BF93EF93FF93E9EEA3
:10087000F0E0108117701082E0EFF0E08081877F58
:1008800080837894C3D0F894A9EEB0E01C92E0EF96
:10089000F0E08081886080831C93FF91EF91BF918D
:1008A000AF919F918F917F916F915F914F913F9108
:1008B0002F911F910F900FBE0F901F9018951F92B0
:1008C0000F920FB60F9211242F933F934F935F9384
:1008D0006F937F938F939F93AF93BF93EF93FF9308
:1008E0008091E10080FF1BC08091E20080FF17C073
:1008F0008091E1008E7F8093E1008091E2008E7F05
:100900008093E2008091E20080618093E200809118
:10091000D80080628093D80019BC1EBAD1D18091D2
:10092000E10084FF29C08091E20084FF25C084E0BB
:1009300089BD89B5826089BD09B400FEFDCF809173
:10094000D8008F7D8093D8008091E1008F7E8093C6
:10095000E1008091E2008F7E8093E2008091E200CE
:1009600081608093E20080912502882311F481E068
:1009700001C084E08EBBA4D18091E10083FF27C039
:100980008091E20083FF23C08091E100877F809304
:10099000E10082E08EBB109225028091E1008E7F03
:1009A0008093E1008091E2008E7F8093E20080914D
:1009B000E20080618093E200AADD80E060E042E036
:1009C00093DD8091F00088608093F00079D1809170
:1009D000E10082FF0AC08091E20082FF06C08091A0
:1009E000E1008B7F8093E1006BD1FF91EF91BF918C
:1009F000AF919F918F917F916F915F914F913F91B7
:100A00002F910F900FBE0F901F9018951F93DF939B
:100A1000CF93CDB7DEB7AC970FB6F894DEBF0FBE5D
:100A2000CDBFE7E2F2E08091F100819322E0EF3266
:100A3000F207C9F78091270230912802353009F476
:100A400087C0363040F43130C9F1313070F0333086
:100A500009F01DC133C0383009F4EFC0393009F452
:100A6000FEC0363009F013C192C0803821F08238C0
:100A700009F00DC108C090912302809124028823BF
:100A800099F0926011C080912B0287708093E900E9
:100A90008091EB0090E025E0969587952A95E1F707
:100AA000982F91701092E9008091E800877F8093E1
:100AB000E8009093F1001092F100CAC0882319F069
:100AC000823009F0E4C090E08F719070009721F0BF
:100AD000029709F0DDC00CC080912902813009F035
:100AE000D7C010922402333069F5809324022AC0C3
:100AF00080912902882331F520912B02277009F477
:100B0000C7C02093E9008091EB0080FFC1C0333063
:100B100021F48091EB00806213C08091EB00806132
:100B20008093EB0081E090E002C0880F991F2A9526
:100B3000E2F78093EA001092EA008091EB0088606F
:100B40008093EB001092E9008091E800877F83C0DA
:100B5000882309F09CC0109129028091E800877FCA
:100B60008093E800E8DC04C08EB3882309F490C0C9
:100B70008091E80080FFF8CF812F8F7711F492E009
:100B800001C093E09EBB80688093E30081C08058E1
:100B9000823008F07CC08091290290912A0223E0E3
:100BA0008C3D920799F55FB7F894DE0115964EE0FB
:100BB00020E030E061E2E42FF0E0609357008491A0
:100BC00020FF03C082958F704F5F982F9F70892FF1
:100BD000805D8A3308F0895F8C9311961C9211977F
:100BE0002F5F3F4F12962431310529F75FBF8AE20C
:100BF0008B8383E08C838091E800877F8093E8007B
:100C0000CE0103966AE270E0E4DC11C060912B0231
:100C1000AE014F5F5F4F2CDCBC010097C9F18091A2
:100C2000E800877F8093E80089819A812BDD80919D
:100C3000E8008B778093E8002BC0803841F58091E5
:100C4000E800877F8093E800809125028093F1007F
:100C50008091E8008E778093E8006DDC19C08823CE
:100C6000B1F490912902923098F48091E800877F46
:100C70008093E800909325025EDC80912502882312
:100C800011F483E001C084E08EBB2DDB01C028DBC2
:100C90008091E80083FF0AC08091EB00806280931E
:100CA000EB008091E800877F8093E800AC960FB658
:100CB000F894DEBF0FBECDBFCF91DF911F91089595
:100CC00008951F938EB3882361F01091E90010926C
:100CD000E9008091E80083FF01C098DE177010934F
:100CE000E9001F9108950895FC018EB3843021F529
:100CF00087859089A189B2890097A105B105E1F0A6
:100D000085818093E9008091E80082FF15C0809181
:100D1000F200882319F42FEF3FEF04C08091F10017
:100D2000282F30E08091F200882341F48091E80080
:100D30008B778093E80002C02FEF3FEFC901089541
:100D4000FC018EB3843011F587859089A189B28921
:100D50000097A105B105D1F081818093E9008091D0
:100D6000F2008823A9F09091E8008091E8008E7746
:100D70008093E80095FD0CC0FDDB982F882349F493
:100D80008091E8008E778093E80003C092E001C074
:100D900090E0892F0895FC018EB3843051F487854B
:100DA0009089A189B2890097A105B10511F0CF0101
:100DB000C7CF08951F93FC01162F8EB38430D9F44A
:100DC00087859089A189B2890097A105B10599F01D
:100DD00081818093E9008091E80085FD08C08091C1
:100DE000E8008E778093E800C5DB882329F4109310
:100DF000F10080E001C082E01F9108950F931F93DE
:100E0000CF93DF93EC010D96FC0189E0DF011D9289
:100E10008A95E9F72A813B8109818C81882311F425
:100E200010E001C014E0C90151DB182B1260802FC3
:100E300061E8412F59DB882329F12E813F810D8103
:100E40008885882311F410E001C014E0C9013EDB5D
:100E5000182B1260802F60E8412F46DB882391F029
:100E60002A853B8509858C85882311F410E001C013
:100E700014E0C9012BDB182B1260802F61EC412F8D
:100E800033DB01C080E0DF91CF911F910F91089576
:100E9000CF93DF93EC018091E80083FF60C08881ED
:100EA00090E020912B0230912C022817390709F08D
:100EB00056C080912802813261F0823220F4803263
:100EC00009F04DC019C0823269F1833209F047C080
:100ED00038C080912702813A09F041C08091E80032
:100EE000877F8093E800CE010F9667E070E071DBAA
:100EF0008091E8008B7713C080912702813279F5C9
:100F00008091E800877F8093E800CE010F9667E02C
:100F100070E013DCCE013ED98091E8008E7780939B
:100F2000E8001DC0809127028132C9F48091E80059
:100F3000877F8093E800809129028D87CE01C8D9F0
:100F40000DC080912702813251F48091E800877FA3
:100F50008093E800CE0160912902C5DEECDADF91D2
:100F6000CF910895A1E21A2EAA1BBB1BFD010DC053
:100F7000AA1FBB1FEE1FFF1FA217B307E407F50749
:100F800020F0A21BB30BE40BF50B661F771F881F25
:100F9000991F1A9469F760957095809590959B01BB
:0C0FA000AC01BD01CF010895F894FFCF13
:100FAC0000034000000440000002080000000000A4
:060FBC000000000000002F
:103000004BC0000064C0000062C0000060C000004F
:103010005EC000005CC000005AC0000058C0000044
:1030200056C0000054C0000052C00000EEC40000B2
:103030004EC000004CC000004AC0000048C0000064
:1030400046C0000044C0000042C0000040C0000074
:103050003EC000003CC000003AC0000038C0000084
:1030600036C0000034C0000032C0000030C0000094
:103070002EC000002CC000002AC0000028C00000A4
:1030800026C0000024C0000022C0000020C00000B4
:103090001EC000001CC0000011241FBECFEFD2E0F4
:1030A000DEBFCDBF11E0A0E0B1E0EAEFFCE302C07B
:1030B00005900D92AA33B107D9F711E0AAE3B1E068
:1030C00001C01D92AB35B107E1F772D314C698CF9A
:1030D000982F15C08091F200882371F48091E80048
:1030E0008B7F8093E80003C08EB3882351F08091DA
:1030F000E80082FFF9CF02C08091F100915099233E
:1031000049F7089520914A01309149018091480181
:103110009091470180933F0190934001C9018093B2
:103120004101909342010895DF93CF9300D000D0E6
:1031300000D0CDB7DEB780914501843009F45AC084
:10314000853030F4813059F0833009F0D7C01FC08A
:10315000853009F4A0C0863009F0D0C0C3C080918A
:103160004601823008F0CAC0CDDF80914601882335
:1031700061F480913F019091400123E0FC01209394
:103180005700E89507B600FCFDCF85E008C08091A8
:103190004601882311F0823029F4B4DF89E080935E
:1031A0000101ACC0813009F0A9C020E030E040E06E
:1031B00050E0F90184918F3F81F0CA01AA27BB2713
:1031C00080933E013093400120933F018AE0809339
:1031D000010185E080933B0191C02F5F3F4F4F4F2E
:1031E0005F4F2030F0E33F07F0E04F07F0E05F076C
:1031F00001F784C080914601833051F581E08093CE
:103200003A0180914B0190914C01892B71F0809192
:103210004701813009F072C080914A0190914901C3
:1032200090933D0180933C0169C0809147018823C0
:1032300061F42CE088E190E00FB6F894A8958093B3
:1032400060000FBE2093600059C01092000156C06C
:10325000882309F053C0809147018F3F09F04EC089
:10326000E0E0F0E093E085E090935700E89507B642
:1032700000FCFDCF80935700E89507B600FCFDCF1A
:10328000E058FF4F20E3E030F20771F781E18093CF
:103290005700E89533C0DE011196E5E0F1E083E0E8
:1032A00001900D928150E1F7DE011496E2E0F1E029
:1032B00083E001900D928150E1F790914701809158
:1032C0004601882329F4FE01E90FF11D818107C021
:1032D0008130A1F4FE01BC97E90FF11D808180933C
:1032E00050010CC080914601833041F48091470128
:1032F000882321F48091480180933E0126960FB6E1
:10330000F894DEBF0FBECDBFCF91DF9108952F920D
:103310003F924F925F926F927F929F92AF92BF9235
:10332000CF92DF92EF92FF920F931F93CF93DF9391
:103330008091590190915A0190934C0180934B01D7
:1033400080914D01882351F080914D0181508093EF
:103350004D0180914D01882309F45D9A80914E01C1
:10336000882351F080914E01815080934E018091CD
:103370004E01882309F45C9A80915401833009F44A
:10338000B2C1843030F4813071F0823009F0E3C191
:1033900011C1853009F4C5C1853008F4BAC1863041
:1033A00009F0D9C1CDC15C9883E080934E01809132
:1033B000E800877F8093E80080913A01882329F014
:1033C000B3DE5D9A5C9A10923A0120914B013091E4
:1033D0004C012115310529F42AC08EB3882309F444
:1033E000BAC18091E80082FFF8CF8091F10080930C
:1033F00045012150304030934C0120934B01E6E4CD
:10340000F1E00CC08091F10081932150304081E0C7
:10341000EB34F80719F43183208308C08091F2005F
:10342000882381F730934C0120934B017DDE8091FE
:103430000101853009F0BAC080914B0190914C0197
:10344000892B21F482E080930101B0C08AE140DE43
:1034500080913F018F713CDEC0914101D0914201CA
:1034600020913F013091400121968E01021B130BE8
:10347000219780914601882309F093C01801369462
:103480002794C901A0913E01B0E09C01AD0162E02A
:10349000E62EF12C012D112DE20EF31E041F151F37
:1034A00059016A0190E099249394B5E0A3E048C0E3
:1034B0008091F200882371F48091E8008B7F8093E3
:1034C000E80004C08EB3882309F445C18091E80068
:1034D00082FFF8CF0894210831088091F100682F0D
:1034E0008091F100782FF5010B0190925700E8953B
:1034F00011249F5F903419F021143104A1F4F901D3
:10350000B0935700E89507B600FCFDCF21143104B5
:1035100051F0F701A0935700E89507B600FCFDCFE6
:10352000A801970190E042E0442E512C612C712CAF
:10353000E40CF51C061D171DA40CB51CC61CD71CDD
:103540002114310409F0B4CFD0934001C0933F015E
:1035500081E180935700E89527C08091F20088238D
:1035600071F48091E8008B7F8093E80004C08EB3F3
:10357000882309F4F0C08091E80082FFF8CF6091C1
:10358000F10080913F0190914001A7D380913F01CC
:103590009091400101969093400180933F0101502A
:1035A000104001151105C9F680E192DD8091E80017
:1035B0008B7FC3C08091E800877F8093E8005D988F
:1035C00083E080934D0104C08EB3882309F4C3C007
:1035D0008091E80080FFF8CF80910101893091F05F
:1035E0008A3069F480914601813049F480913F012D
:1035F000909140018093F1009093F1009BC08091E5
:10360000500196C0609141017091420120913F01AB
:10361000309140016F5F7F4F7B01E21AF30A6150E6
:10362000704080914601882389F58701169507959A
:10363000C901A0913E01B0E09C01AD011FC0809185
:10364000F200803271F48091E8008E7F8093E80070
:1036500004C08EB3882309F47EC08091E80080FF07
:10366000F8CFF901859194918093F1009093F10046
:10367000015010402E5F3F4F4F4F5F4F0115110516
:10368000F1F67093400160933F0129C0823039F513
:1036900023C08091F200803271F48091E8008E7F27
:1036A0008093E80004C08EB3882309F454C080914D
:1036B000E80080FFF8CF00913F0110914001C80160
:1036C00004D38093F1000F5F1F4F109340010093CC
:1036D0003F010894E108F108E114F104D1F682E019
:1036E0008093010127C08091E800877F8093E800E4
:1036F00080913B018093F1001092F1001092F10053
:103700001092F100809101018093F1001092F1007C
:1037100011C08091E800877F8093E80010923B0100
:1037200019C08091E800877F8093E80080910101B3
:103730008093F1008091E8008E7F8093E8000AC0BA
:103740008091E800877F8093E8005D9A5C9A82E030
:103750008093010187D0DF91CF911F910F91FF904E
:10376000EF90DF90CF90BF90AF909F907F906F9041
:103770005F904F903F902F9008952BD181E085BFAF
:1037800015BE089584B7877F84BF88E10FB6F8948B
:1037900080936000109260000FBE81E085BF82E0E0
:1037A00085BF8AB180638AB98BB180638BB90CC144
:1037B000E9DF789401C080D2809100018823D9F795
:1037C00080913A018823B9F7D8DFE0913C01F0916C
:1037D0003D010995FA01923071F0933089F09130F2
:1037E00029F488E091E022E130E019C080E090E027
:1037F00020E030E014C08AE191E02BE130E00FC01E
:10380000882339F480913501282F30E085E391E059
:1038100006C080914301282F30E083E491E091833A
:103820008083C90108958091EB0081608093EB0053
:103830001092ED006093EC004093ED008091EE005B
:10384000881F8827881F08951092F4001092F000B6
:103850001092E8001092ED00EBEEF0E080818E7F98
:10386000808308958091530188238CF403C08EB324
:103870008823B1F08091E80082FFF9CF8091E800C1
:103880008B7F8093E80008958EB3882349F0809160
:10389000E80080FFF9CF8091E8008E7F8093E800F8
:1038A00008959C014091590150915A0146175707BC
:1038B00018F4F90120E038C06115710511F0AB0171
:1038C000F8CF8091E8008E7F8093E80040E050E0E0
:1038D000F0CF8091E80083FF02C081E008958091DD
:1038E000E80082FD2DC08EB3882381F18EB3853030
:1038F00079F18091E80080FF17C09091F20006C036
:1039000081918093F100415050409F5F41155105D6
:1039100011F09032A8F320E0903209F421E0809178
:10392000E8008E7F8093E8004115510591F622232F
:1039300081F606C08EB3882349F08EB3853041F0FE
:103940008091E80082FFF6CF80E0089582E008953C
:1039500083E0089554D056D01EBA1092510184E0ED
:1039600089BD89B5826089BD09B400FEFDCF809113
:10397000D800982F9F779093D80080688093D800C4
:10398000809163008E7F809363008091D8008F7D4B
:103990008093D8008091E0008E7F8093E00080913A
:1039A000E1008E7F8093E1008091E200816080934E
:1039B000E2008091E100877F8093E1008091E20046
:1039C00088608093E2000895C5DF81E08093520112
:1039D0000895C0DFE0EEF0E0808181608083E8ED53
:1039E000F0E080818F7780830AD00CD019BCE3E6A9
:1039F000F0E08081816080831092520108951092DE
:103A0000E20008951092E10008951F920F920FB600
:103A10000F9211242F933F934F935F936F937F9354
:103A20008F939F93AF93BF93EF93FF938091E100A8
:103A300080FF1BC08091E20080FF17C08091E100F1
:103A40008E7F8093E1008091E2008E7F8093E20080
:103A50008091E20080618093E2008091D8008062D2
:103A60008093D80019BC1EBA26D18091E10084FF52
:103A700029C08091E20084FF25C084E089BD89B51A
:103A8000826089BD09B400FEFDCF8091D8008F7D92
:103A90008093D8008091E1008F7E8093E100809137
:103AA000E2008F7E8093E2008091E200816080934B
:103AB000E20080915101882311F481E001C084E08B
:103AC0008EBBF9D08091E10083FF22C08091E2009B
:103AD00083FF1EC08091E100877F8093E10082E038
:103AE0008EBB109251018091E1008E7F8093E100A6
:103AF0008091E2008E7F8093E2008091E2008061FD
:103B00008093E200A1DE80E060E042E28CDED3D070
:103B10008091E10082FF0AC08091E20082FF06C02E
:103B20008091E1008B7F8093E100C5D0FF91EF9100
:103B3000BF91AF919F918F917F916F915F914F91C5
:103B40003F912F910F900FBE0F901F9018951F93CC
:103B5000DF93CF9300D0CDB7DEB7E3E5F1E08091FE
:103B6000F100819381E0EB35F807C9F7909153019B
:103B700080915401853011F1863040F48130B9F0E4
:103B8000813070F0833009F081C011C0883009F4B1
:103B900053C0893009F462C0863009F077C02DC067
:103BA000903809F474C0923809F070C070C099233D
:103BB00009F46DC0923009F069C069C0992309F019
:103BC00065C0109155018091E800877F8093E800DF
:103BD00049DE04C08EB3882309F459C08091E800FF
:103BE00080FFF8CF812F8F7711F492E001C093E02E
:103BF0009EBB80688093E3004AC09058923008F0E2
:103C000045C0809155019091560160915701AE01D8
:103C10004F5F5F4FDFDDBC010097C9F18091E80085
:103C2000877F8093E80089819A813BDE8091E8005C
:103C30008B7F8093E8002BC0903841F58091E8009D
:103C4000877F8093E800809151018093F1008091FB
:103C5000E8008E7F8093E80005DE19C09923B1F457
:103C600090915501923098F48091E800877F80937D
:103C7000E80090935101F6DD80915101882311F401
:103C800083E001C084E08EBB16D001C040DB809190
:103C9000E80083FF0AC08091EB0080628093EB0014
:103CA0008091E800877F8093E8000F900F90CF917C
:103CB000DF911F91089508958EB3882329F0809194
:103CC000E80083FF01C043CF0895F999FECF92BD6C
:103CD00081BDF89A992780B50895262FF999FECFCE
:103CE0001FBA92BD81BD20BD0FB6F894FA9AF99A19
:0A3CF0000FBE01960895F894FFCF6F
:103CFA0001021E948920DCFB120110010000002041
:103D0A00EB03EF2F00000001000109021B00010173
:103D1A000080320904000000FE01020009210300AC
:0A3D2A0000000C000104030904006E
:0400000300003000C9
:00000001FF

View File

@ -0,0 +1,234 @@
:20000000A2C00000BBC00000B9C00000B7C00000B5C00000B3C00000B1C00000AFC000004B
:20002000ADC00000ABC00000A9C000005AC400001EC40000A3C00000A1C000009FC000005C
:200040009DC000009BC0000099C0000097C0000095C0000093C0000091C0000014C100006A
:200060008DC000008BC0000089C0000087C0000085C0000083C0000081C000007FC0000050
:200080007DC000007BC0000079C0000077C0000075C0000073C000001201100102000008E2
:2000A0004123100001000102DC0109023E00020100C0320904000001020201000524000170
:2000C00010042402060524060001070582030800FF09040100020A000000070504024000AC
:2000E0000107058302400001040309043203410072006400750069006E006F0020002800CA
:200100007700770077002E00610072006400750069006E006F002E0063006300290000003D
:200120002403410072006400750069006E006F0020004D00650067006100200032003500A5
:2001400036003000000011241FBECFEFD2E0DEBFCDBF11E0A0E0B1E0E0EDFFE002C0059089
:200160000D92A631B107D9F712E0A6E1B1E001C01D92AF32B107E1F7F1D028C741CF9C0139
:20018000DC01AE57BF4FED91FC91119741911196FC93EE9380589F4FE817F90711F42D93A9
:2001A0003C939FB7F894F901EC57FF4F8081815080839FBF842F0895DF92EF92FF920F935B
:2001C0001F93FC018489813019F0823021F405C040E3D42E04C0DD2402C030E2D32E838952
:2001E000823011F488E0D82A8589873031F0883031F0863031F482E003C084E001C086E094
:20020000D82A1092C9001092C8001092CA00E784F0880189128980E0E81681EEF80680E068
:20022000080780E0180719F420E130E00FC0C801B701969587957795679560587B47814E2A
:200240009F4FA8019701A0D6215030403093CD002093CC00D092CA0080E0E81681EEF80612
:2002600080E0080780E0180711F082E001C080E08093C80088E98093C9001F910F91FF9005
:20028000EF90DF9008951F920F920FB60F9211242F938F939F93EF93FF939091CE008EB38C
:2002A0008430F1F4E0919901F0919A019083E0919901F0919A01CF01019690939A0180930C
:2002C00099018959914021F489E191E0928381839FB7F89480919D018F5F80939D019FBF3A
:2002E000FF91EF919F918F912F910F900FBE0F901F901895FC01858580FF02C05F9808959B
:200300005F9A089580E091E0D5C580E091E088C584B7877F84BF28E10FB6F89420936000CD
:20032000109260000FBE87E690E09093CD008093CC0086E08093CA001092C8002093C90019
:20034000539A5A9A8AB180638AB98BB180638BB983D284E085BD5F9A579A08950F931F9322
:20036000CF93DF93D5DF2FB7F8948EE991E090931F0280931E0290932102809320022FBFBB
:200380002FB7F89489E191E090939A018093990190939C0180939B012FBF7894CEE9D1E0D4
:2003A00003E08FB7F894909122028FBF903809F180E091E0ABD497FD1CC0E0911E02F09161
:2003C0001F028083E0911E02F0911F02CF01019690931F0280931E028E51924011F4D283DD
:2003E000C1839FB7F894809122028F5F809322029FBF8FB7F89410919D018FBFA89902C0BD
:20040000113678F1A89A80919D01882361F05D980093160108C089E191E0B1DE682F80E077
:2004200091E0DAD411501123B1F780911601882351F0809116018150809316018091160101
:20044000882309F45D9A80911701882351F08091170181508093170180911701882309F4F2
:200460005C9A8FB7F894909122028FBF992369F08EE991E084DE982F8091C80085FFFCCFD3
:200480009093CE005C980093170180E091E095D42AD487CFDA01923049F0933061F0913093
:2004A000F9F4E8E9F0E022E130E01EC0EAEAF0E02EE330E019C0813049F0813018F08230CA
:2004C00079F408C0E8EEF0E0849107C0ECEEF0E0849103C0E0E2F1E08491282F30E004C010
:2004E000E0E0F0E020E030E0ED93FC93C901089528E030E040E003C04F5F220F331F28177B
:200500003907D0F3842F8295807F08958093E9008091EB0081608093EB001092ED00609319
:20052000EC004093ED008091EE00881F8827881F08951092F40090E09093E9001092F000D2
:200540001092E8001092ED008091EB008E7F8093EB009F5F953081F70895809127028823BE
:200560008CF403C08EB38823B1F08091E80082FFF9CF8091E8008B778093E80008958EB395
:20058000882349F08091E80080FFF9CF8091E8008E778093E800089594E68091EC0080FFAB
:2005A00005C08091E80080FF05C023C08091E80082FD1FC08EB3882311F482E008958EB3CE
:2005C000853011F483E008958091EB0085FF02C081E008958091E10082FFDFCF8091E1000E
:2005E0008B7F8093E100992311F484E008959150D4CF80E008959C0140912D0250912E020C
:200600004617570718F4F90120E038C06115710511F0AB01F8CF8091E8008E778093E800C8
:2006200040E050E0F0CF8091E80083FF02C081E008958091E80082FD2DC08EB3882381F1AD
:200640008EB3853079F18091E80080FF17C09091F20006C081918093F100415050409F5FDD
:200660004115510511F09830A8F320E0983009F421E08091E8008E778093E80041155105FF
:2006800091F6222381F606C08EB3882349F08EB3853041F08091E80082FFF6CF80E00895C9
:2006A00082E0089583E008959C0140912D0250912E024617570710F490E03BC06115710577
:2006C00011F0AB01F9CF8091E8008E778093E80040E050E0F1CF8091E80083FF02C081E0FE
:2006E00008958091E80082FD30C08EB3882399F18EB3853091F18091E80080FF1AC08091A4
:20070000F20009C0F9012F5F3F4FE491E093F100415050408F5F4115510511F0883090F338
:2007200090E0883009F491E08091E8008E778093E8004115510579F6992369F606C08EB3ED
:20074000882349F08EB3853041F08091E80082FFF6CF80E0089582E0089583E008959C01B6
:200760006115710529F48091E8008B778093E800F90120C08091E80083FF02C081E0089565
:200780008EB3882339F18EB3853031F18091E80082FFF0CF06C08091F100819361507040B5
:2007A00021F08091F2008823B1F78091E8008B778093E80061157105E9F606C08EB388235F
:2007C00049F08EB3853041F08091E80080FFF6CF80E0089582E0089583E0089542D044D05A
:2007E0001EBA10922502109224021092230284E089BD89B5826089BD09B400FEFDCF809121
:20080000D800982F9F779093D80080688093D800809163008E7F809363008091D8008F7D69
:200820008093D8008091E0008E7F8093E0008091E1008E7F8093E1008091E2008160809302
:20084000E2008091E100877F8093E1008091E20088608093E2000895C1DF81E08093260221
:2008600008951092E20008951092E10008951F920F920FB60F9211241F932F933F934F9385
:200880005F936F937F938F939F93AF93BF93EF93FF93E9EEF0E0108117701082E0EFF0E066
:2008A0008081877F80837894C3D0F894A9EEB0E01C92E0EFF0E08081886080831C93FF9164
:2008C000EF91BF91AF919F918F917F916F915F914F913F912F911F910F900FBE0F901F90DE
:2008E00018951F920F920FB60F9211242F933F934F935F936F937F938F939F93AF93BF93FA
:20090000EF93FF938091E10080FF1BC08091E20080FF17C08091E1008E7F8093E10080912A
:20092000E2008E7F8093E2008091E20080618093E2008091D80080628093D80019BC1EBAA7
:20094000D1D18091E10084FF29C08091E20084FF25C084E089BD89B5826089BD09B400FE71
:20096000FDCF8091D8008F7D8093D8008091E1008F7E8093E1008091E2008F7E8093E200E3
:200980008091E20081608093E20080912502882311F481E001C084E08EBBA4D18091E10070
:2009A00083FF27C08091E20083FF23C08091E100877F8093E10082E08EBB10922502809105
:2009C000E1008E7F8093E1008091E2008E7F8093E2008091E20080618093E200AADD80E090
:2009E00060E042E093DD8091F00088608093F00079D18091E10082FF0AC08091E20082FF3E
:200A000006C08091E1008B7F8093E1006BD1FF91EF91BF91AF919F918F917F916F915F91F4
:200A20004F913F912F910F900FBE0F901F9018951F93DF93CF93CDB7DEB7AC970FB6F894AC
:200A4000DEBF0FBECDBFE7E2F2E08091F100819322E0EF32F207C9F78091270230912802EE
:200A6000353009F487C0363040F43130C9F1313070F0333009F01DC133C0383009F4EFC016
:200A8000393009F4FEC0363009F013C192C0803821F0823809F00DC108C090912302809144
:200AA0002402882399F0926011C080912B0287708093E9008091EB0090E025E09695879530
:200AC0002A95E1F7982F91701092E9008091E800877F8093E8009093F1001092F100CAC001
:200AE000882319F0823009F0E4C090E08F719070009721F0029709F0DDC00CC080912902A4
:200B0000813009F0D7C010922402333069F5809324022AC080912902882331F520912B02FD
:200B2000277009F4C7C02093E9008091EB0080FFC1C0333021F48091EB00806213C08091C8
:200B4000EB0080618093EB0081E090E002C0880F991F2A95E2F78093EA001092EA008091B7
:200B6000EB0088608093EB001092E9008091E800877F83C0882309F09CC0109129028091FA
:200B8000E800877F8093E800E8DC04C08EB3882309F490C08091E80080FFF8CF812F8F77B6
:200BA00011F492E001C093E09EBB80688093E30081C08058823008F07CC0809129029091F7
:200BC0002A0223E08C3D920799F55FB7F894DE0115964EE020E030E061E2E42FF0E0609373
:200BE0005700849120FF03C082958F704F5F982F9F70892F805D8A3308F0895F8C93119615
:200C00001C9211972F5F3F4F12962431310529F75FBF8AE28B8383E08C838091E800877F06
:200C20008093E800CE0103966AE270E0E4DC11C060912B02AE014F5F5F4F2CDCBC0100979F
:200C4000C9F18091E800877F8093E80089819A812BDD8091E8008B778093E8002BC080381A
:200C600041F58091E800877F8093E800809125028093F1008091E8008E778093E8006DDCC6
:200C800019C08823B1F490912902923098F48091E800877F8093E800909325025EDC809102
:200CA0002502882311F483E001C084E08EBB2DDB01C028DB8091E80083FF0AC08091EB007F
:200CC00080628093EB008091E800877F8093E800AC960FB6F894DEBF0FBECDBFCF91DF91E1
:200CE0001F91089508951F938EB3882361F01091E9001092E9008091E80083FF01C098DE54
:200D000017701093E9001F9108950895FC018EB3843021F587859089A189B2890097A10507
:200D2000B105E1F085818093E9008091E80082FF15C08091F200882319F42FEF3FEF04C010
:200D40008091F100282F30E08091F200882341F48091E8008B778093E80002C02FEF3FEF43
:200D6000C9010895FC018EB3843011F587859089A189B2890097A105B105D1F081818093C1
:200D8000E9008091F2008823A9F09091E8008091E8008E778093E80095FD0CC0FDDB982F24
:200DA000882349F48091E8008E778093E80003C092E001C090E0892F0895FC018EB38430A5
:200DC00051F487859089A189B2890097A105B10511F0CF01C7CF08951F93FC01162F8EB318
:200DE0008430D9F487859089A189B2890097A105B10599F081818093E9008091E80085FDF3
:200E000008C08091E8008E778093E800C5DB882329F41093F10080E001C082E01F91089545
:200E20000F931F93CF93DF93EC010D96FC0189E0DF011D928A95E9F72A813B8109818C8108
:200E4000882311F410E001C014E0C90151DB182B1260802F61E8412F59DB882329F12E8182
:200E60003F810D818885882311F410E001C014E0C9013EDB182B1260802F60E8412F46DBA2
:200E8000882391F02A853B8509858C85882311F410E001C014E0C9012BDB182B1260802F8F
:200EA00061EC412F33DB01C080E0DF91CF911F910F910895CF93DF93EC018091E80083FF4D
:200EC00060C0888190E020912B0230912C022817390709F056C080912802813261F082322B
:200EE00020F4803209F04DC019C0823269F1833209F047C038C080912702813A09F041C0A3
:200F00008091E800877F8093E800CE010F9667E070E071DB8091E8008B7713C08091270278
:200F2000813279F58091E800877F8093E800CE010F9667E070E013DCCE013ED98091E800BD
:200F40008E778093E8001DC0809127028132C9F48091E800877F8093E800809129028D87C0
:200F6000CE01C8D90DC080912702813251F48091E800877F8093E800CE0160912902C5DE7A
:200F8000ECDADF91CF910895A1E21A2EAA1BBB1BFD010DC0AA1FBB1FEE1FFF1FA217B307AC
:200FA000E407F50720F0A21BB30BE40BF50B661F771F881F991F1A9469F760957095809539
:200FC00090959B01AC01BD01CF010895F894FFCF000340000004400000020800000000008D
:200FE000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
:201000004BC0000064C0000062C0000060C000005EC000005CC000005AC0000058C00000F3
:2010200056C0000054C0000052C00000CBC400004EC000004CC000004AC0000048C00000B9
:2010400046C0000044C0000042C0000040C000003EC000003CC000003AC0000038C0000098
:2010600036C0000034C0000032C0000030C000002EC000002CC000002AC0000028C00000F8
:2010800026C0000024C0000022C0000020C000001EC000001CC0000011241FBECFEFD2E088
:2010A000DEBFCDBF11E0A0E0B1E0E4EBFCE102C005900D92A836B107D9F711E0A8E6B1E0ED
:2010C00001C01D92A738B107E1F74FD3F1C598CF982F15C08091F200882371F48091E8004A
:2010E0008B7F8093E80003C08EB3882351F08091E80082FFF9CF02C08091F1009150992358
:2011000049F708952091760130917501809174019091730180936D0190936E01C901809388
:201120006F0190937001089580917101843009F45AC0853030F4813059F0833009F0C3C0BE
:201140001FC0853009F4A0C0863009F0BCC0AFC080917201823008F0B6C0D4DF8091720129
:20116000882361F480916D0190916E0123E0FC0120935700E89507B600FCFDCF85E008C027
:2011800080917201882311F0823029F4BBDF89E0809301010895813009F095C020E030E08C
:2011A00040E050E0F90184918F3F81F0CA01AA27BB2780936C0130936E0120936D018AE0D6
:2011C0008093010185E08093690108952F5F3F4F4F4F5F4F2030F0E13F07F0E04F07F0E0B6
:2011E0005F0701F7089580917201833051F581E0809368018091770190917801892B71F062
:2012000080917301813009F05EC0809176019091750190936B0180936A0108958091730133
:20122000882361F42CE088E190E00FB6F894A895809360000FBE20936000089510920001A8
:201240000895882309F03FC0809173018F3F09F03AC0E0E0F0E093E085E090935700E895A9
:2012600007B600FCFDCF80935700E89507B600FCFDCFE058FF4F20E1E030F20771F781E123
:2012800080935700E8950895E091730180917201882321F4F0E0EB5FFE4F05C0813099F437
:2012A000F0E0EE52FF4F808180937C01089580917201833041F480917301882321F48091E0
:2012C000740180936C0108952F923F924F925F926F927F929F92AF92BF92CF92DF92EF92F0
:2012E000FF920F931F93CF93DF938091850190918601909378018093770180917901882399
:2013000051F08091790181508093790180917901882309F45D9A80917A01882351F08091F0
:201320007A01815080937A0180917A01882309F45C9A80918001833009F4B2C1843030F41C
:20134000813071F0823009F0E3C111C1853009F4C5C1853008F4BAC1863009F0D9C1CDC11F
:201360005C9883E080937A018091E800877F8093E80080916801882329F0D6DE5D9A5C9AAF
:201380001092680120917701309178012115310529F42AC08EB3882309F4BAC18091E8000F
:2013A00082FFF8CF8091F10080937101215030403093780120937701E2E7F1E00CC080919F
:2013C000F10081932150304081E0E737F80719F43183208308C08091F200882381F7309394
:2013E000780120937701A0DE80910101853009F0BAC08091770190917801892B21F482E042
:2014000080930101B0C08AE163DE80916D018F715FDEC0916F01D091700120916D0130916C
:201420006E0121968E01021B130B219780917201882309F093C0180136942794C901A091F0
:201440006C01B0E09C01AD0162E0E62EF12C012D112DE20EF31E041F151F59016A0190E0D8
:2014600099249394B5E0A3E048C08091F200882371F48091E8008B7F8093E80004C08EB352
:20148000882309F445C18091E80082FFF8CF0894210831088091F100682F8091F100782F1D
:2014A000F5010B0190925700E89511249F5F903419F021143104A1F4F901B0935700E89524
:2014C00007B600FCFDCF2114310451F0F701A0935700E89507B600FCFDCFA801970190E0A7
:2014E00042E0442E512C612C712CE40CF51C061D171DA40CB51CC61CD71C2114310409F0A0
:20150000B4CFD0936E01C0936D0181E180935700E89527C08091F200882371F48091E80079
:201520008B7F8093E80004C08EB3882309F4F0C08091E80082FFF8CF6091F10080916D01A7
:2015400090916E01A7D380916D0190916E01019690936E0180936D010150104001151105FB
:20156000C9F680E1B5DD8091E8008B7FC3C08091E800877F8093E8005D9883E08093790154
:2015800004C08EB3882309F4C3C08091E80080FFF8CF80910101893091F08A3069F4809167
:2015A0007201813049F480916D0190916E018093F1009093F1009BC080917C0196C0609173
:2015C0006F017091700120916D0130916E016F5F7F4F7B01E21AF30A6150704080917201E4
:2015E000882389F5870116950795C901A0916C01B0E09C01AD011FC08091F200803271F4B7
:201600008091E8008E7F8093E80004C08EB3882309F47EC08091E80080FFF8CFF90185918F
:2016200094918093F1009093F100015010402E5F3F4F4F4F5F4F01151105F1F670936E01E0
:2016400060936D0129C0823039F523C08091F200803271F48091E8008E7F8093E80004C09E
:201660008EB3882309F454C08091E80080FFF8CF00916D0110916E01C80104D38093F1007B
:201680000F5F1F4F10936E0100936D010894E108F108E114F104D1F682E08093010127C0CE
:2016A0008091E800877F8093E800809169018093F1001092F1001092F1001092F1008091E7
:2016C00001018093F1001092F10011C08091E800877F8093E8001092690119C08091E800C8
:2016E000877F8093E800809101018093F1008091E8008E7F8093E8000AC08091E800877F08
:201700008093E8005D9A5C9A82E08093010187D0DF91CF911F910F91FF90EF90DF90CF9017
:20172000BF90AF909F907F906F905F904F903F902F9008952BD181E085BF15BE089584B799
:20174000877F84BF88E10FB6F89480936000109260000FBE81E085BF82E085BF8AB18063DB
:201760008AB98BB180638BB90CC1E9DF789401C080D2809100018823D9F78091680188235D
:20178000B9F7D8DFE0916A01F0916B010995FA01923071F0933089F0913029F488E091E06A
:2017A00022E130E019C080E090E020E030E014C08AE191E02BE130E00FC0882339F48091D9
:2017C0003501282F30E085E391E006C080913901282F30E089E391E091838083C9010895C0
:2017E0008091EB0081608093EB001092ED006093EC004093ED008091EE00881F8827881FE4
:2018000008951092F4001092F0001092E8001092ED00EBEEF0E080818E7F80830895809182
:201820007F0188238CF403C08EB38823B1F08091E80082FFF9CF8091E8008B7F8093E8006D
:2018400008958EB3882349F08091E80080FFF9CF8091E8008E7F8093E80008959C0140917A
:201860008501509186014617570718F4F90120E038C06115710511F0AB01F8CF8091E80068
:201880008E7F8093E80040E050E0F0CF8091E80083FF02C081E008958091E80082FD2DC091
:2018A0008EB3882381F18EB3853079F18091E80080FF17C09091F20006C081918093F1002C
:2018C000415050409F5F4115510511F09032A8F320E0903209F421E08091E8008E7F809306
:2018E000E8004115510591F6222381F606C08EB3882349F08EB3853041F08091E80082FF85
:20190000F6CF80E0089582E0089583E0089554D056D01EBA10927D0184E089BD89B58260FA
:2019200089BD09B400FEFDCF8091D800982F9F779093D80080688093D800809163008E7FC5
:20194000809363008091D8008F7D8093D8008091E0008E7F8093E0008091E1008E7F80932E
:20196000E1008091E20081608093E2008091E100877F8093E1008091E20088608093E20001
:201980000895C5DF81E080937E010895C0DFE0EEF0E0808181608083E8EDF0E080818F77A8
:2019A00080830AD00CD019BCE3E6F0E080818160808310927E0108951092E200089510929A
:2019C000E10008951F920F920FB60F9211242F933F934F935F936F937F938F939F93AF938A
:2019E000BF93EF93FF938091E10080FF1BC08091E20080FF17C08091E1008E7F8093E100F9
:201A00008091E2008E7F8093E2008091E20080618093E2008091D80080628093D80019BC7D
:201A20001EBA26D18091E10084FF29C08091E20084FF25C084E089BD89B5826089BD09B451
:201A400000FEFDCF8091D8008F7D8093D8008091E1008F7E8093E1008091E2008F7E8093D6
:201A6000E2008091E20081608093E20080917D01882311F481E001C084E08EBBF9D08091D3
:201A8000E10083FF22C08091E20083FF1EC08091E100877F8093E10082E08EBB10927D01F7
:201AA0008091E1008E7F8093E1008091E2008E7F8093E2008091E20080618093E200A1DEF6
:201AC00080E060E042E28CDED3D08091E10082FF0AC08091E20082FF06C08091E1008B7FC2
:201AE0008093E100C5D0FF91EF91BF91AF919F918F917F916F915F914F913F912F910F905E
:201B00000FBE0F901F9018951F93DF93CF9300D0CDB7DEB7EFE7F1E08091F100819381E070
:201B2000E738F807C9F790917F0180918001853011F1863040F48130B9F0813070F08330D5
:201B400009F081C011C0883009F453C0893009F462C0863009F077C02DC0903809F474C00E
:201B6000923809F070C070C0992309F46DC0923009F069C069C0992309F065C01091810152
:201B80008091E800877F8093E80049DE04C08EB3882309F459C08091E80080FFF8CF812F6F
:201BA0008F7711F492E001C093E09EBB80688093E3004AC09058923008F045C080918101F9
:201BC0009091820160918301AE014F5F5F4FDFDDBC010097C9F18091E800877F8093E8001D
:201BE00089819A813BDE8091E8008B7F8093E8002BC0903841F58091E800877F8093E800C6
:201C000080917D018093F1008091E8008E7F8093E80005DE19C09923B1F4909181019230AE
:201C200098F48091E800877F8093E80090937D01F6DD80917D01882311F483E001C084E0E3
:201C40008EBB16D001C040DB8091E80083FF0AC08091EB0080628093EB008091E800877F59
:201C60008093E8000F900F90CF91DF911F91089508958EB3882329F08091E80083FF01C030
:201C800043CF0895F999FECF92BD81BDF89A992780B50895262FF999FECF1FBA92BD81BD6B
:201CA00020BD0FB6F894FA9AF99A0FBE01960895F894FFCF01021E938220DCFB1201100123
:201CC00000000020EB03F72F00000001000109021B0001010080320904000000FE010200E6
:201CE0000921030000000C0001040309042C03410072006400750069006E006F0020004D28
:1C1D000000650067006100200032003500360030002000440046005500000000AE
:00000001FF

View File

@ -0,0 +1,33 @@
Arduino Uno and Mega 2560 Firmwares for the ATmega8U2
This directory contains the firmwares used on the ATmega8U2 on the Arduino
Uno and Arduino Mega 2560. The arduino-usbdfu directory contains the DFU
bootloader on the 8U2; the arduino-usbserial directory contains the actual
usb to serial firmware. Both should be compiled against LUFA 100807. The
two .hex files in this directory combine the dfu and serial firmwares into
a single file to burn onto the 8U2.
To burn (Uno):
avrdude -p at90usb82 -F -P usb -c avrispmkii -U flash:w:UNO-dfu_and_usbserial_combined.hex -U lfuse:w:0xFF:m -U hfuse:w:0xD9:m -U efuse:w:0xF4:m -U lock:w:0x0F:m
To burn (Mega 2560):
avrdude -p at90usb82 -F -P usb -c avrispmkii -U flash:w:MEGA-dfu_and_usbserial_combined.hex -U lfuse:w:0xFF:m -U hfuse:w:0xD9:m -U efuse:w:0xF4:m -U lock:w:0x0F:m
Note on USB Vendor IDs (VID) and Product IDs (PID): The arduino-usbdfu
project uses Atmel's VID and MCU-specific PIDs to maintain compatibility
with their FLIP software. The source code to the arduino-usbserial
project includes Atmel's VID and a PID donated by them to LUFA. This
PID is used in LUFA's USBtoSerial project, which forms the basis for
arduino-usbserial. According to the LUFA documentation, this VID/PID
combination is:
"For use in testing of LUFA powered devices during development only,
by non-commercial entities. All devices must accept collisions on this
VID/PID range (from other in-development LUFA devices) to be resolved
by using a unique release number in the Device Descriptor. No devices
using this VID/PID combination may be released to the general public."
The production version of the arduino-usbserial firmware uses the
Arduino VID. This is only for use with official Arduino hardware and
should not be used on other products.

View File

@ -0,0 +1,234 @@
:200000009CC00000B5C00000B3C00000B1C00000AFC00000ADC00000ABC00000A9C000007B
:20002000A7C00000A5C00000A3C0000054C4000018C400009DC000009BC0000099C000008C
:2000400097C0000095C0000093C0000091C000008FC000008DC000008BC000000EC100009A
:2000600087C0000085C0000083C0000081C000007FC000007DC000007BC0000079C0000080
:2000800077C0000075C0000073C0000071C000006FC000006DC00000120110010200000806
:2000A0004123010001000102DC0109023E00020100C032090400000102020100052400017F
:2000C00010042402060524060001070582030800FF09040100020A000000070504024000AC
:2000E0000107058302400001040309043203410072006400750069006E006F0020002800CA
:200100007700770077002E00610072006400750069006E006F002E0063006300290000003D
:200120001803410072006400750069006E006F00200055006E006F00000011241FBECFEFB0
:20014000D2E0DEBFCDBF11E0A0E0B1E0E4ECFFE002C005900D92A631B107D9F712E0A6E145
:20016000B1E001C01D92AF32B107E1F7F1D028C747CF9C01DC01AE57BF4FED91FC91119707
:2001800041911196FC93EE9380589F4FE817F90711F42D933C939FB7F894F901EC57FF4F10
:2001A0008081815080839FBF842F0895DF92EF92FF920F931F93FC018489813019F082306F
:2001C00021F405C040E3D42E04C0DD2402C030E2D32E8389823011F488E0D82A8589873094
:2001E00031F0883031F0863031F482E003C084E001C086E0D82A1092C9001092C800109201
:20020000CA00E784F0880189128980E0E81681EEF80680E0080780E0180719F420E130E035
:200220000FC0C801B701969587957795679560587B47814E9F4FA8019701A0D62150304050
:200240003093CD002093CC00D092CA0080E0E81681EEF80680E0080780E0180711F082E047
:2002600001C080E08093C80088E98093C9001F910F91FF90EF90DF9008951F920F920FB6B4
:200280000F9211242F938F939F93EF93FF939091CE008EB38430F1F4E0919901F0919A016E
:2002A0009083E0919901F0919A01CF01019690939A01809399018959914021F489E191E08F
:2002C000928381839FB7F89480919D018F5F80939D019FBFFF91EF919F918F912F910F90B8
:2002E0000FBE0F901F901895FC01858580FF02C05F9808955F9A089580E091E0D5C580E0F9
:2003000091E088C584B7877F84BF28E10FB6F89420936000109260000FBE87E690E090935F
:20032000CD008093CC0086E08093CA001092C8002093C900539A5A9A8AB180638AB98BB16A
:2003400080638BB983D284E085BD5F9A579A08950F931F93CF93DF93D5DF2FB7F8948EE92F
:2003600091E090931F0280931E0290932102809320022FBF2FB7F89489E191E090939A0121
:200380008093990190939C0180939B012FBF7894CEE9D1E003E08FB7F894909122028FBF97
:2003A000903809F180E091E0ABD497FD1CC0E0911E02F0911F028083E0911E02F0911F0252
:2003C000CF01019690931F0280931E028E51924011F4D283C1839FB7F894809122028F5FEB
:2003E000809322029FBF8FB7F89410919D018FBFA89902C0113678F1A89A80919D018823BA
:2004000061F05D980093160108C089E191E0B1DE682F80E091E0DAD411501123B1F7809156
:200420001601882351F08091160181508093160180911601882309F45D9A809117018823FB
:2004400051F08091170181508093170180911701882309F45C9A8FB7F894909122028FBF0A
:20046000992369F08EE991E084DE982F8091C80085FFFCCF9093CE005C980093170180E03E
:2004800091E095D42AD487CFDA01923049F0933061F09130F9F4E8E9F0E022E130E01EC004
:2004A000EAEAF0E02EE330E019C0813049F0813018F0823079F408C0E8EEF0E0849107C092
:2004C000ECEEF0E0849103C0E0E2F1E08491282F30E004C0E0E0F0E020E030E0ED93FC9318
:2004E000C901089528E030E040E003C04F5F220F331F28173907D0F3842F8295807F0895C1
:200500008093E9008091EB0081608093EB001092ED006093EC004093ED008091EE00881F30
:200520008827881F08951092F40090E09093E9001092F0001092E8001092ED008091EB000F
:200540008E7F8093EB009F5F953081F708958091270288238CF403C08EB38823B1F08091F2
:20056000E80082FFF9CF8091E8008B778093E80008958EB3882349F08091E80080FFF9CF52
:200580008091E8008E778093E800089594E68091EC0080FF05C08091E80080FF05C023C0EA
:2005A0008091E80082FD1FC08EB3882311F482E008958EB3853011F483E008958091EB00FD
:2005C00085FF02C081E008958091E10082FFDFCF8091E1008B7F8093E100992311F484E0A1
:2005E00008959150D4CF80E008959C0140912D0250912E024617570718F4F90120E038C076
:200600006115710511F0AB01F8CF8091E8008E778093E80040E050E0F0CF8091E80083FFF7
:2006200002C081E008958091E80082FD2DC08EB3882381F18EB3853079F18091E80080FF5F
:2006400017C09091F20006C081918093F100415050409F5F4115510511F09830A8F320E0A5
:20066000983009F421E08091E8008E778093E8004115510591F6222381F606C08EB388231A
:2006800049F08EB3853041F08091E80082FFF6CF80E0089582E0089583E008959C01409151
:2006A0002D0250912E024617570710F490E03BC06115710511F0AB01F9CF8091E8008E7771
:2006C0008093E80040E050E0F1CF8091E80083FF02C081E008958091E80082FD30C08EB32B
:2006E000882399F18EB3853091F18091E80080FF1AC08091F20009C0F9012F5F3F4FE491A4
:20070000E093F100415050408F5F4115510511F0883090F390E0883009F491E08091E800EF
:200720008E778093E8004115510579F6992369F606C08EB3882349F08EB3853041F0809160
:20074000E80082FFF6CF80E0089582E0089583E008959C016115710529F48091E8008B77CE
:200760008093E800F90120C08091E80083FF02C081E008958EB3882339F18EB3853031F13B
:200780008091E80082FFF0CF06C08091F10081936150704021F08091F2008823B1F780916B
:2007A000E8008B778093E80061157105E9F606C08EB3882349F08EB3853041F08091E8007E
:2007C00080FFF6CF80E0089582E0089583E0089542D044D01EBA10922502109224021092A8
:2007E000230284E089BD89B5826089BD09B400FEFDCF8091D800982F9F779093D800806894
:200800008093D800809163008E7F809363008091D8008F7D8093D8008091E0008E7F809305
:20082000E0008091E1008E7F8093E1008091E20081608093E2008091E100877F8093E10030
:200840008091E20088608093E2000895C1DF81E08093260208951092E20008951092E100AE
:2008600008951F920F920FB60F9211241F932F933F934F935F936F937F938F939F93AF932A
:20088000BF93EF93FF93E9EEF0E0108117701082E0EFF0E08081877F80837894C3D0F894CD
:2008A000A9EEB0E01C92E0EFF0E08081886080831C93FF91EF91BF91AF919F918F917F9129
:2008C0006F915F914F913F912F911F910F900FBE0F901F9018951F920F920FB60F921124B4
:2008E0002F933F934F935F936F937F938F939F93AF93BF93EF93FF938091E10080FF1BC034
:200900008091E20080FF17C08091E1008E7F8093E1008091E2008E7F8093E2008091E200B3
:2009200080618093E2008091D80080628093D80019BC1EBAD1D18091E10084FF29C080916D
:20094000E20084FF25C084E089BD89B5826089BD09B400FEFDCF8091D8008F7D8093D800D6
:200960008091E1008F7E8093E1008091E2008F7E8093E2008091E20081608093E2008091B5
:200980002502882311F481E001C084E08EBBA4D18091E10083FF27C08091E20083FF23C089
:2009A0008091E100877F8093E10082E08EBB109225028091E1008E7F8093E1008091E200F1
:2009C0008E7F8093E2008091E20080618093E200AADD80E060E042E093DD8091F0008860AA
:2009E0008093F00079D18091E10082FF0AC08091E20082FF06C08091E1008B7F8093E10043
:200A00006BD1FF91EF91BF91AF919F918F917F916F915F914F913F912F910F900FBE0F902F
:200A20001F9018951F93DF93CF93CDB7DEB7AC970FB6F894DEBF0FBECDBFE7E2F2E0809185
:200A4000F100819322E0EF32F207C9F78091270230912802353009F487C0363040F43130EC
:200A6000C9F1313070F0333009F01DC133C0383009F4EFC0393009F4FEC0363009F013C163
:200A800092C0803821F0823809F00DC108C09091230280912402882399F0926011C080916D
:200AA0002B0287708093E9008091EB0090E025E0969587952A95E1F7982F91701092E90074
:200AC0008091E800877F8093E8009093F1001092F100CAC0882319F0823009F0E4C090E078
:200AE0008F719070009721F0029709F0DDC00CC080912902813009F0D7C0109224023330AB
:200B000069F5809324022AC080912902882331F520912B02277009F4C7C02093E9008091A1
:200B2000EB0080FFC1C0333021F48091EB00806213C08091EB0080618093EB0081E090E0F5
:200B400002C0880F991F2A95E2F78093EA001092EA008091EB0088608093EB001092E900F6
:200B60008091E800877F83C0882309F09CC0109129028091E800877F8093E800E8DC04C0E5
:200B80008EB3882309F490C08091E80080FFF8CF812F8F7711F492E001C093E09EBB80683B
:200BA0008093E30081C08058823008F07CC08091290290912A0223E08C3D920799F55FB7AE
:200BC000F894DE0115964EE020E030E061E2E42FF0E060935700849120FF03C082958F7044
:200BE0004F5F982F9F70892F805D8A3308F0895F8C9311961C9211972F5F3F4F129624310A
:200C0000310529F75FBF8AE28B8383E08C838091E800877F8093E800CE0103966AE270E076
:200C2000E4DC11C060912B02AE014F5F5F4F2CDCBC010097C9F18091E800877F8093E800EA
:200C400089819A812BDD8091E8008B778093E8002BC0803841F58091E800877F8093E8009E
:200C6000809125028093F1008091E8008E778093E8006DDC19C08823B1F4909129029230BF
:200C800098F48091E800877F8093E800909325025EDC80912502882311F483E001C084E0DA
:200CA0008EBB2DDB01C028DB8091E80083FF0AC08091EB0080628093EB008091E800877FFF
:200CC0008093E800AC960FB6F894DEBF0FBECDBFCF91DF911F91089508951F938EB3882338
:200CE00061F01091E9001092E9008091E80083FF01C098DE17701093E9001F9108950895DF
:200D0000FC018EB3843021F587859089A189B2890097A105B105E1F085818093E90080916A
:200D2000E80082FF15C08091F200882319F42FEF3FEF04C08091F100282F30E08091F2003E
:200D4000882341F48091E8008B778093E80002C02FEF3FEFC9010895FC018EB3843011F550
:200D600087859089A189B2890097A105B105D1F081818093E9008091F2008823A9F09091CF
:200D8000E8008091E8008E778093E80095FD0CC0FDDB982F882349F48091E8008E7780937C
:200DA000E80003C092E001C090E0892F0895FC018EB3843051F487859089A189B289009738
:200DC000A105B10511F0CF01C7CF08951F93FC01162F8EB38430D9F487859089A189B28973
:200DE0000097A105B10599F081818093E9008091E80085FD08C08091E8008E778093E8003D
:200E0000C5DB882329F41093F10080E001C082E01F9108950F931F93CF93DF93EC010D964E
:200E2000FC0189E0DF011D928A95E9F72A813B8109818C81882311F410E001C014E0C901A1
:200E400051DB182B1260802F61E8412F59DB882329F12E813F810D818885882311F410E0A6
:200E600001C014E0C9013EDB182B1260802F60E8412F46DB882391F02A853B8509858C8563
:200E8000882311F410E001C014E0C9012BDB182B1260802F61EC412F33DB01C080E0DF916D
:200EA000CF911F910F910895CF93DF93EC018091E80083FF60C0888190E020912B02309171
:200EC0002C022817390709F056C080912802813261F0823220F4803209F04DC019C082320A
:200EE00069F1833209F047C038C080912702813A09F041C08091E800877F8093E800CE0133
:200F00000F9667E070E071DB8091E8008B7713C080912702813279F58091E800877F80930E
:200F2000E800CE010F9667E070E013DCCE013ED98091E8008E778093E8001DC080912702D9
:200F40008132C9F48091E800877F8093E800809129028D87CE01C8D90DC0809127028132AD
:200F600051F48091E800877F8093E800CE0160912902C5DEECDADF91CF910895A1E21A2EA6
:200F8000AA1BBB1BFD010DC0AA1FBB1FEE1FFF1FA217B307E407F50720F0A21BB30BE40B49
:200FA000F50B661F771F881F991F1A9469F760957095809590959B01AC01BD01CF01089501
:200FC000F894FFCF00034000000440000002080000000000000000000000FFFFFFFFFFFF2C
:200FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
:201000004BC0000064C0000062C0000060C000005EC000005CC000005AC0000058C00000F3
:2010200056C0000054C0000052C00000CBC400004EC000004CC000004AC0000048C00000B9
:2010400046C0000044C0000042C0000040C000003EC000003CC000003AC0000038C0000098
:2010600036C0000034C0000032C0000030C000002EC000002CC000002AC0000028C00000F8
:2010800026C0000024C0000022C0000020C000001EC000001CC0000011241FBECFEFD2E088
:2010A000DEBFCDBF11E0A0E0B1E0E4EBFCE102C005900D92AC35B107D9F711E0ACE5B1E0E7
:2010C00001C01D92AB37B107E1F74FD3F1C598CF982F15C08091F200882371F48091E80047
:2010E0008B7F8093E80003C08EB3882351F08091E80082FFF9CF02C08091F1009150992358
:2011000049F7089520916A013091690180916801909167018093610190936201C9018093D0
:20112000630190936401089580916501843009F45AC0853030F4813059F0833009F0C3C0E2
:201140001FC0853009F4A0C0863009F0BCC0AFC080916601823008F0B6C0D4DF8091660141
:20116000882361F4809161019091620123E0FC0120935700E89507B600FCFDCF85E008C03F
:2011800080916601882311F0823029F4BBDF89E0809301010895813009F095C020E030E098
:2011A00040E050E0F90184918F3F81F0CA01AA27BB278093600130936201209361018AE0FA
:2011C0008093010185E080935D0108952F5F3F4F4F4F5F4F2030F0E13F07F0E04F07F0E0C2
:2011E0005F0701F7089580916601833051F581E080935C0180916B0190916C01892B71F092
:2012000080916701813009F05EC080916A019091690190935F0180935E010895809167017B
:20122000882361F42CE088E190E00FB6F894A895809360000FBE20936000089510920001A8
:201240000895882309F03FC0809167018F3F09F03AC0E0E0F0E093E085E090935700E895B5
:2012600007B600FCFDCF80935700E89507B600FCFDCFE058FF4F20E1E030F20771F781E123
:2012800080935700E8950895E091670180916601882321F4F0E0EB5FFE4F05C0813099F44F
:2012A000F0E0EE52FF4F808180937001089580916601833041F480916701882321F4809104
:2012C00068018093600108952F923F924F925F926F927F929F92AF92BF92CF92DF92EF9208
:2012E000FF920F931F93CF93DF938091790190917A0190936C0180936B0180916D018823D5
:2013000051F080916D01815080936D0180916D01882309F45D9A80916E01882351F0809120
:201320006E01815080936E0180916E01882309F45C9A80917401833009F4B2C1843030F44C
:20134000813071F0823009F0E3C111C1853009F4C5C1853008F4BAC1863009F0D9C1CDC11F
:201360005C9883E080936E018091E800877F8093E80080915C01882329F0D6DE5D9A5C9AC7
:2013800010925C0120916B0130916C012115310529F42AC08EB3882309F4BAC18091E80033
:2013A00082FFF8CF8091F100809365012150304030936C0120936B01E6E6F1E00CC08091C0
:2013C000F10081932150304081E0EB36F80719F43183208308C08091F200882381F7309391
:2013E0006C0120936B01A0DE80910101853009F0BAC080916B0190916C01892B21F482E072
:2014000080930101B0C08AE163DE809161018F715FDEC0916301D09164012091610130919C
:20142000620121968E01021B130B219780916601882309F093C0180136942794C901A09108
:201440006001B0E09C01AD0162E0E62EF12C012D112DE20EF31E041F151F59016A0190E0E4
:2014600099249394B5E0A3E048C08091F200882371F48091E8008B7F8093E80004C08EB352
:20148000882309F445C18091E80082FFF8CF0894210831088091F100682F8091F100782F1D
:2014A000F5010B0190925700E89511249F5F903419F021143104A1F4F901B0935700E89524
:2014C00007B600FCFDCF2114310451F0F701A0935700E89507B600FCFDCFA801970190E0A7
:2014E00042E0442E512C612C712CE40CF51C061D171DA40CB51CC61CD71C2114310409F0A0
:20150000B4CFD0936201C093610181E180935700E89527C08091F200882371F48091E80091
:201520008B7F8093E80004C08EB3882309F4F0C08091E80082FFF8CF6091F10080916101B3
:2015400090916201A7D3809161019091620101969093620180936101015010400115110537
:20156000C9F680E1B5DD8091E8008B7FC3C08091E800877F8093E8005D9883E080936D0160
:2015800004C08EB3882309F4C3C08091E80080FFF8CF80910101893091F08A3069F4809167
:2015A0006601813049F480916101909162018093F1009093F1009BC08091700196C06091A3
:2015C00063017091640120916101309162016F5F7F4F7B01E21AF30A615070408091660120
:2015E000882389F5870116950795C901A0916001B0E09C01AD011FC08091F200803271F4C3
:201600008091E8008E7F8093E80004C08EB3882309F47EC08091E80080FFF8CFF90185918F
:2016200094918093F1009093F100015010402E5F3F4F4F4F5F4F01151105F1F670936201EC
:201640006093610129C0823039F523C08091F200803271F48091E8008E7F8093E80004C0AA
:201660008EB3882309F454C08091E80080FFF8CF0091610110916201C80104D38093F10093
:201680000F5F1F4F10936201009361010894E108F108E114F104D1F682E08093010127C0E6
:2016A0008091E800877F8093E80080915D018093F1001092F1001092F1001092F1008091F3
:2016C00001018093F1001092F10011C08091E800877F8093E80010925D0119C08091E800D4
:2016E000877F8093E800809101018093F1008091E8008E7F8093E8000AC08091E800877F08
:201700008093E8005D9A5C9A82E08093010187D0DF91CF911F910F91FF90EF90DF90CF9017
:20172000BF90AF909F907F906F905F904F903F902F9008952BD181E085BF15BE089584B799
:20174000877F84BF88E10FB6F89480936000109260000FBE81E085BF82E085BF8AB18063DB
:201760008AB98BB180638BB90CC1E9DF789401C080D2809100018823D9F780915C01882369
:20178000B9F7D8DFE0915E01F0915F010995FA01923071F0933089F0913029F488E091E082
:2017A00022E130E019C080E090E020E030E014C08AE191E02BE130E00FC0882339F48091D9
:2017C0003501282F30E085E391E006C080913901282F30E089E391E091838083C9010895C0
:2017E0008091EB0081608093EB001092ED006093EC004093ED008091EE00881F8827881FE4
:2018000008951092F4001092F0001092E8001092ED00EBEEF0E080818E7F80830895809182
:20182000730188238CF403C08EB38823B1F08091E80082FFF9CF8091E8008B7F8093E80079
:2018400008958EB3882349F08091E80080FFF9CF8091E8008E7F8093E80008959C0140917A
:20186000790150917A014617570718F4F90120E038C06115710511F0AB01F8CF8091E80080
:201880008E7F8093E80040E050E0F0CF8091E80083FF02C081E008958091E80082FD2DC091
:2018A0008EB3882381F18EB3853079F18091E80080FF17C09091F20006C081918093F1002C
:2018C000415050409F5F4115510511F09032A8F320E0903209F421E08091E8008E7F809306
:2018E000E8004115510591F6222381F606C08EB3882349F08EB3853041F08091E80082FF85
:20190000F6CF80E0089582E0089583E0089554D056D01EBA1092710184E089BD89B5826006
:2019200089BD09B400FEFDCF8091D800982F9F779093D80080688093D800809163008E7FC5
:20194000809363008091D8008F7D8093D8008091E0008E7F8093E0008091E1008E7F80932E
:20196000E1008091E20081608093E2008091E100877F8093E1008091E20088608093E20001
:201980000895C5DF81E0809372010895C0DFE0EEF0E0808181608083E8EDF0E080818F77B4
:2019A00080830AD00CD019BCE3E6F0E08081816080831092720108951092E20008951092A6
:2019C000E10008951F920F920FB60F9211242F933F934F935F936F937F938F939F93AF938A
:2019E000BF93EF93FF938091E10080FF1BC08091E20080FF17C08091E1008E7F8093E100F9
:201A00008091E2008E7F8093E2008091E20080618093E2008091D80080628093D80019BC7D
:201A20001EBA26D18091E10084FF29C08091E20084FF25C084E089BD89B5826089BD09B451
:201A400000FEFDCF8091D8008F7D8093D8008091E1008F7E8093E1008091E2008F7E8093D6
:201A6000E2008091E20081608093E20080917101882311F481E001C084E08EBBF9D08091DF
:201A8000E10083FF22C08091E20083FF1EC08091E100877F8093E10082E08EBB1092710103
:201AA0008091E1008E7F8093E1008091E2008E7F8093E2008091E20080618093E200A1DEF6
:201AC00080E060E042E28CDED3D08091E10082FF0AC08091E20082FF06C08091E1008B7FC2
:201AE0008093E100C5D0FF91EF91BF91AF919F918F917F916F915F914F913F912F910F905E
:201B00000FBE0F901F9018951F93DF93CF9300D0CDB7DEB7E3E7F1E08091F100819381E07C
:201B2000EB37F807C9F79091730180917401853011F1863040F48130B9F0813070F08330EA
:201B400009F081C011C0883009F453C0893009F462C0863009F077C02DC0903809F474C00E
:201B6000923809F070C070C0992309F46DC0923009F069C069C0992309F065C0109175015E
:201B80008091E800877F8093E80049DE04C08EB3882309F459C08091E80080FFF8CF812F6F
:201BA0008F7711F492E001C093E09EBB80688093E3004AC09058923008F045C08091750105
:201BC0009091760160917701AE014F5F5F4FDFDDBC010097C9F18091E800877F8093E80035
:201BE00089819A813BDE8091E8008B7F8093E8002BC0903841F58091E800877F8093E800C6
:201C0000809171018093F1008091E8008E7F8093E80005DE19C09923B1F4909175019230C6
:201C200098F48091E800877F8093E80090937101F6DD80917101882311F483E001C084E0FB
:201C40008EBB16D001C040DB8091E80083FF0AC08091EB0080628093EB008091E800877F59
:201C60008093E8000F900F90CF91DF911F91089508958EB3882329F08091E80083FF01C030
:201C800043CF0895F999FECF92BD81BDF89A992780B50895262FF999FECF1FBA92BD81BD6B
:201CA00020BD0FB6F894FA9AF99A0FBE01960895F894FFCF01021E938220DCFB1201100123
:201CC00000000020EB03F72F00000001000109021B0001010080320904000000FE010200E6
:201CE0000921030000000C0001040309042003410072006400750069006E006F002000552C
:101D0000006E006F002000440046005500000000F7
:00000001FF

View File

@ -0,0 +1,728 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Main source file for the DFU class bootloader. This file contains the complete bootloader logic.
*/
#define INCLUDE_FROM_BOOTLOADER_C
#include "Arduino-usbdfu.h"
/** Flag to indicate if the bootloader should be running, or should exit and allow the application code to run
* via a soft reset. When cleared, the bootloader will abort, the USB interface will shut down and the application
* jumped to via an indirect jump to location 0x0000 (or other location specified by the host).
*/
bool RunBootloader = true;
/** Flag to indicate if the bootloader is waiting to exit. When the host requests the bootloader to exit and
* jump to the application address it specifies, it sends two sequential commands which must be properly
* acknowledged. Upon reception of the first the RunBootloader flag is cleared and the WaitForExit flag is set,
* causing the bootloader to wait for the final exit command before shutting down.
*/
bool WaitForExit = false;
/** Current DFU state machine state, one of the values in the DFU_State_t enum. */
uint8_t DFU_State = dfuIDLE;
/** Status code of the last executed DFU command. This is set to one of the values in the DFU_Status_t enum after
* each operation, and returned to the host when a Get Status DFU request is issued.
*/
uint8_t DFU_Status = OK;
/** Data containing the DFU command sent from the host. */
DFU_Command_t SentCommand;
/** Response to the last issued Read Data DFU command. Unlike other DFU commands, the read command
* requires a single byte response from the bootloader containing the read data when the next DFU_UPLOAD command
* is issued by the host.
*/
uint8_t ResponseByte;
/** Pointer to the start of the user application. By default this is 0x0000 (the reset vector), however the host
* may specify an alternate address when issuing the application soft-start command.
*/
AppPtr_t AppStartPtr = (AppPtr_t)0x0000;
/** 64-bit flash page number. This is concatenated with the current 16-bit address on USB AVRs containing more than
* 64KB of flash memory.
*/
uint8_t Flash64KBPage = 0;
/** Memory start address, indicating the current address in the memory being addressed (either FLASH or EEPROM
* depending on the issued command from the host).
*/
uint16_t StartAddr = 0x0000;
/** Memory end address, indicating the end address to read to/write from in the memory being addressed (either FLASH
* of EEPROM depending on the issued command from the host).
*/
uint16_t EndAddr = 0x0000;
/** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */
volatile struct
{
uint8_t TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */
uint8_t RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */
uint8_t PingPongLEDPulse; /**< Milliseconds remaining for enumeration Tx/Rx ping-pong LED pulse */
} PulseMSRemaining;
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously
* runs the bootloader processing routine until instructed to soft-exit, or hard-reset via the watchdog to start
* the loaded application code.
*/
int main(void)
{
/* Configure hardware required by the bootloader */
SetupHardware();
/* Enable global interrupts so that the USB stack can function */
sei();
/* Run the USB management task while the bootloader is supposed to be running */
while (RunBootloader || WaitForExit)
USB_USBTask();
/* Reset configured hardware back to their original states for the user application */
ResetHardware();
/* Start the user application */
AppStartPtr();
}
/** Configures all hardware required for the bootloader. */
void SetupHardware(void)
{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
wdt_disable();
/* Disable clock division */
// clock_prescale_set(clock_div_1);
/* Relocate the interrupt vector table to the bootloader section */
MCUCR = (1 << IVCE);
MCUCR = (1 << IVSEL);
LEDs_Init();
/* Initialize the USB subsystem */
USB_Init();
}
/** Resets all configured hardware required for the bootloader back to their original states. */
void ResetHardware(void)
{
/* Shut down the USB subsystem */
USB_ShutDown();
/* Relocate the interrupt vector table back to the application section */
MCUCR = (1 << IVCE);
MCUCR = 0;
}
/** Event handler for the USB_UnhandledControlRequest event. This is used to catch standard and class specific
* control requests that are not handled internally by the USB library (including the DFU commands, which are
* all issued via the control endpoint), so that they can be handled appropriately for the application.
*/
void EVENT_USB_Device_UnhandledControlRequest(void)
{
/* Get the size of the command and data from the wLength value */
SentCommand.DataSize = USB_ControlRequest.wLength;
/* Turn off TX LED(s) once the TX pulse period has elapsed */
if (PulseMSRemaining.TxLEDPulse && !(--PulseMSRemaining.TxLEDPulse))
LEDs_TurnOffLEDs(LEDMASK_TX);
/* Turn off RX LED(s) once the RX pulse period has elapsed */
if (PulseMSRemaining.RxLEDPulse && !(--PulseMSRemaining.RxLEDPulse))
LEDs_TurnOffLEDs(LEDMASK_RX);
switch (USB_ControlRequest.bRequest)
{
case DFU_DNLOAD:
LEDs_TurnOnLEDs(LEDMASK_RX);
PulseMSRemaining.RxLEDPulse = TX_RX_LED_PULSE_MS;
Endpoint_ClearSETUP();
/* Check if bootloader is waiting to terminate */
if (WaitForExit)
{
/* Bootloader is terminating - process last received command */
ProcessBootloaderCommand();
/* Turn off TX/RX status LEDs so that they're not left on when application starts */
LEDs_TurnOffLEDs(LEDMASK_TX);
LEDs_TurnOffLEDs(LEDMASK_RX);
/* Indicate that the last command has now been processed - free to exit bootloader */
WaitForExit = false;
}
/* If the request has a data stage, load it into the command struct */
if (SentCommand.DataSize)
{
while (!(Endpoint_IsOUTReceived()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
/* First byte of the data stage is the DNLOAD request's command */
SentCommand.Command = Endpoint_Read_Byte();
/* One byte of the data stage is the command, so subtract it from the total data bytes */
SentCommand.DataSize--;
/* Load in the rest of the data stage as command parameters */
for (uint8_t DataByte = 0; (DataByte < sizeof(SentCommand.Data)) &&
Endpoint_BytesInEndpoint(); DataByte++)
{
SentCommand.Data[DataByte] = Endpoint_Read_Byte();
SentCommand.DataSize--;
}
/* Process the command */
ProcessBootloaderCommand();
}
/* Check if currently downloading firmware */
if (DFU_State == dfuDNLOAD_IDLE)
{
if (!(SentCommand.DataSize))
{
DFU_State = dfuIDLE;
}
else
{
/* Throw away the filler bytes before the start of the firmware */
DiscardFillerBytes(DFU_FILLER_BYTES_SIZE);
/* Throw away the packet alignment filler bytes before the start of the firmware */
DiscardFillerBytes(StartAddr % FIXED_CONTROL_ENDPOINT_SIZE);
/* Calculate the number of bytes remaining to be written */
uint16_t BytesRemaining = ((EndAddr - StartAddr) + 1);
if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x00)) // Write flash
{
/* Calculate the number of words to be written from the number of bytes to be written */
uint16_t WordsRemaining = (BytesRemaining >> 1);
union
{
uint16_t Words[2];
uint32_t Long;
} CurrFlashAddress = {.Words = {StartAddr, Flash64KBPage}};
uint32_t CurrFlashPageStartAddress = CurrFlashAddress.Long;
uint8_t WordsInFlashPage = 0;
while (WordsRemaining--)
{
/* Check if endpoint is empty - if so clear it and wait until ready for next packet */
if (!(Endpoint_BytesInEndpoint()))
{
Endpoint_ClearOUT();
while (!(Endpoint_IsOUTReceived()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
}
/* Write the next word into the current flash page */
boot_page_fill(CurrFlashAddress.Long, Endpoint_Read_Word_LE());
/* Adjust counters */
WordsInFlashPage += 1;
CurrFlashAddress.Long += 2;
/* See if an entire page has been written to the flash page buffer */
if ((WordsInFlashPage == (SPM_PAGESIZE >> 1)) || !(WordsRemaining))
{
/* Commit the flash page to memory */
boot_page_write(CurrFlashPageStartAddress);
boot_spm_busy_wait();
/* Check if programming incomplete */
if (WordsRemaining)
{
CurrFlashPageStartAddress = CurrFlashAddress.Long;
WordsInFlashPage = 0;
/* Erase next page's temp buffer */
boot_page_erase(CurrFlashAddress.Long);
boot_spm_busy_wait();
}
}
}
/* Once programming complete, start address equals the end address */
StartAddr = EndAddr;
/* Re-enable the RWW section of flash */
boot_rww_enable();
}
else // Write EEPROM
{
while (BytesRemaining--)
{
/* Check if endpoint is empty - if so clear it and wait until ready for next packet */
if (!(Endpoint_BytesInEndpoint()))
{
Endpoint_ClearOUT();
while (!(Endpoint_IsOUTReceived()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
}
/* Read the byte from the USB interface and write to to the EEPROM */
eeprom_write_byte((uint8_t*)StartAddr, Endpoint_Read_Byte());
/* Adjust counters */
StartAddr++;
}
}
/* Throw away the currently unused DFU file suffix */
DiscardFillerBytes(DFU_FILE_SUFFIX_SIZE);
}
}
Endpoint_ClearOUT();
Endpoint_ClearStatusStage();
break;
case DFU_UPLOAD:
Endpoint_ClearSETUP();
LEDs_TurnOnLEDs(LEDMASK_TX);
PulseMSRemaining.TxLEDPulse = TX_RX_LED_PULSE_MS;
while (!(Endpoint_IsINReady()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
if (DFU_State != dfuUPLOAD_IDLE)
{
if ((DFU_State == dfuERROR) && IS_ONEBYTE_COMMAND(SentCommand.Data, 0x01)) // Blank Check
{
/* Blank checking is performed in the DFU_DNLOAD request - if we get here we've told the host
that the memory isn't blank, and the host is requesting the first non-blank address */
Endpoint_Write_Word_LE(StartAddr);
}
else
{
/* Idle state upload - send response to last issued command */
Endpoint_Write_Byte(ResponseByte);
}
}
else
{
/* Determine the number of bytes remaining in the current block */
uint16_t BytesRemaining = ((EndAddr - StartAddr) + 1);
if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x00)) // Read FLASH
{
/* Calculate the number of words to be written from the number of bytes to be written */
uint16_t WordsRemaining = (BytesRemaining >> 1);
union
{
uint16_t Words[2];
uint32_t Long;
} CurrFlashAddress = {.Words = {StartAddr, Flash64KBPage}};
while (WordsRemaining--)
{
/* Check if endpoint is full - if so clear it and wait until ready for next packet */
if (Endpoint_BytesInEndpoint() == FIXED_CONTROL_ENDPOINT_SIZE)
{
Endpoint_ClearIN();
while (!(Endpoint_IsINReady()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
}
/* Read the flash word and send it via USB to the host */
#if (FLASHEND > 0xFFFF)
Endpoint_Write_Word_LE(pgm_read_word_far(CurrFlashAddress.Long));
#else
Endpoint_Write_Word_LE(pgm_read_word(CurrFlashAddress.Long));
#endif
/* Adjust counters */
CurrFlashAddress.Long += 2;
}
/* Once reading is complete, start address equals the end address */
StartAddr = EndAddr;
}
else if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x02)) // Read EEPROM
{
while (BytesRemaining--)
{
/* Check if endpoint is full - if so clear it and wait until ready for next packet */
if (Endpoint_BytesInEndpoint() == FIXED_CONTROL_ENDPOINT_SIZE)
{
Endpoint_ClearIN();
while (!(Endpoint_IsINReady()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
}
/* Read the EEPROM byte and send it via USB to the host */
Endpoint_Write_Byte(eeprom_read_byte((uint8_t*)StartAddr));
/* Adjust counters */
StartAddr++;
}
}
/* Return to idle state */
DFU_State = dfuIDLE;
}
Endpoint_ClearIN();
Endpoint_ClearStatusStage();
break;
case DFU_GETSTATUS:
Endpoint_ClearSETUP();
/* Write 8-bit status value */
Endpoint_Write_Byte(DFU_Status);
/* Write 24-bit poll timeout value */
Endpoint_Write_Byte(0);
Endpoint_Write_Word_LE(0);
/* Write 8-bit state value */
Endpoint_Write_Byte(DFU_State);
/* Write 8-bit state string ID number */
Endpoint_Write_Byte(0);
Endpoint_ClearIN();
Endpoint_ClearStatusStage();
break;
case DFU_CLRSTATUS:
Endpoint_ClearSETUP();
/* Reset the status value variable to the default OK status */
DFU_Status = OK;
Endpoint_ClearStatusStage();
break;
case DFU_GETSTATE:
Endpoint_ClearSETUP();
/* Write the current device state to the endpoint */
Endpoint_Write_Byte(DFU_State);
Endpoint_ClearIN();
Endpoint_ClearStatusStage();
break;
case DFU_ABORT:
Endpoint_ClearSETUP();
/* Turn off TX/RX status LEDs so that they're not left on when application starts */
LEDs_TurnOffLEDs(LEDMASK_TX);
LEDs_TurnOffLEDs(LEDMASK_RX);
/* Reset the current state variable to the default idle state */
DFU_State = dfuIDLE;
Endpoint_ClearStatusStage();
break;
}
}
/** Routine to discard the specified number of bytes from the control endpoint stream. This is used to
* discard unused bytes in the stream from the host, including the memory program block suffix.
*
* \param[in] NumberOfBytes Number of bytes to discard from the host from the control endpoint
*/
static void DiscardFillerBytes(uint8_t NumberOfBytes)
{
while (NumberOfBytes--)
{
if (!(Endpoint_BytesInEndpoint()))
{
Endpoint_ClearOUT();
/* Wait until next data packet received */
while (!(Endpoint_IsOUTReceived()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
}
else
{
Endpoint_Discard_Byte();
}
}
}
/** Routine to process an issued command from the host, via a DFU_DNLOAD request wrapper. This routine ensures
* that the command is allowed based on the current secure mode flag value, and passes the command off to the
* appropriate handler function.
*/
static void ProcessBootloaderCommand(void)
{
/* Check if device is in secure mode */
// if (IsSecure)
// {
// /* Don't process command unless it is a READ or chip erase command */
// if (!(((SentCommand.Command == COMMAND_WRITE) &&
// IS_TWOBYTE_COMMAND(SentCommand.Data, 0x00, 0xFF)) ||
// (SentCommand.Command == COMMAND_READ)))
// {
// /* Set the state and status variables to indicate the error */
// DFU_State = dfuERROR;
// DFU_Status = errWRITE;
//
// /* Stall command */
// Endpoint_StallTransaction();
//
// /* Don't process the command */
// return;
// }
// }
/* Dispatch the required command processing routine based on the command type */
switch (SentCommand.Command)
{
case COMMAND_PROG_START:
ProcessMemProgCommand();
break;
case COMMAND_DISP_DATA:
ProcessMemReadCommand();
break;
case COMMAND_WRITE:
ProcessWriteCommand();
break;
case COMMAND_READ:
ProcessReadCommand();
break;
case COMMAND_CHANGE_BASE_ADDR:
if (IS_TWOBYTE_COMMAND(SentCommand.Data, 0x03, 0x00)) // Set 64KB flash page command
Flash64KBPage = SentCommand.Data[2];
break;
}
}
/** Routine to concatenate the given pair of 16-bit memory start and end addresses from the host, and store them
* in the StartAddr and EndAddr global variables.
*/
static void LoadStartEndAddresses(void)
{
union
{
uint8_t Bytes[2];
uint16_t Word;
} Address[2] = {{.Bytes = {SentCommand.Data[2], SentCommand.Data[1]}},
{.Bytes = {SentCommand.Data[4], SentCommand.Data[3]}}};
/* Load in the start and ending read addresses from the sent data packet */
StartAddr = Address[0].Word;
EndAddr = Address[1].Word;
}
/** Handler for a Memory Program command issued by the host. This routine handles the preparations needed
* to write subsequent data from the host into the specified memory.
*/
static void ProcessMemProgCommand(void)
{
if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x00) || // Write FLASH command
IS_ONEBYTE_COMMAND(SentCommand.Data, 0x01)) // Write EEPROM command
{
/* Load in the start and ending read addresses */
LoadStartEndAddresses();
/* If FLASH is being written to, we need to pre-erase the first page to write to */
if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x00))
{
union
{
uint16_t Words[2];
uint32_t Long;
} CurrFlashAddress = {.Words = {StartAddr, Flash64KBPage}};
/* Erase the current page's temp buffer */
boot_page_erase(CurrFlashAddress.Long);
boot_spm_busy_wait();
}
/* Set the state so that the next DNLOAD requests reads in the firmware */
DFU_State = dfuDNLOAD_IDLE;
}
}
/** Handler for a Memory Read command issued by the host. This routine handles the preparations needed
* to read subsequent data from the specified memory out to the host, as well as implementing the memory
* blank check command.
*/
static void ProcessMemReadCommand(void)
{
if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x00) || // Read FLASH command
IS_ONEBYTE_COMMAND(SentCommand.Data, 0x02)) // Read EEPROM command
{
/* Load in the start and ending read addresses */
LoadStartEndAddresses();
/* Set the state so that the next UPLOAD requests read out the firmware */
DFU_State = dfuUPLOAD_IDLE;
}
else if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x01)) // Blank check FLASH command
{
uint32_t CurrFlashAddress = 0;
while (CurrFlashAddress < BOOT_START_ADDR)
{
/* Check if the current byte is not blank */
#if (FLASHEND > 0xFFFF)
if (pgm_read_byte_far(CurrFlashAddress) != 0xFF)
#else
if (pgm_read_byte(CurrFlashAddress) != 0xFF)
#endif
{
/* Save the location of the first non-blank byte for response back to the host */
Flash64KBPage = (CurrFlashAddress >> 16);
StartAddr = CurrFlashAddress;
/* Set state and status variables to the appropriate error values */
DFU_State = dfuERROR;
DFU_Status = errCHECK_ERASED;
break;
}
CurrFlashAddress++;
}
}
}
/** Handler for a Data Write command issued by the host. This routine handles non-programming commands such as
* bootloader exit (both via software jumps and hardware watchdog resets) and flash memory erasure.
*/
static void ProcessWriteCommand(void)
{
if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x03)) // Start application
{
/* Indicate that the bootloader is terminating */
WaitForExit = true;
/* Check if data supplied for the Start Program command - no data executes the program */
if (SentCommand.DataSize)
{
if (SentCommand.Data[1] == 0x01) // Start via jump
{
union
{
uint8_t Bytes[2];
AppPtr_t FuncPtr;
} Address = {.Bytes = {SentCommand.Data[4], SentCommand.Data[3]}};
/* Load in the jump address into the application start address pointer */
AppStartPtr = Address.FuncPtr;
}
}
else
{
if (SentCommand.Data[1] == 0x00) // Start via watchdog
{
/* Start the watchdog to reset the AVR once the communications are finalized */
wdt_enable(WDTO_250MS);
}
else // Start via jump
{
/* Set the flag to terminate the bootloader at next opportunity */
RunBootloader = false;
}
}
}
else if (IS_TWOBYTE_COMMAND(SentCommand.Data, 0x00, 0xFF)) // Erase flash
{
uint32_t CurrFlashAddress = 0;
/* Clear the application section of flash */
while (CurrFlashAddress < BOOT_START_ADDR)
{
boot_page_erase(CurrFlashAddress);
boot_spm_busy_wait();
boot_page_write(CurrFlashAddress);
boot_spm_busy_wait();
CurrFlashAddress += SPM_PAGESIZE;
}
/* Re-enable the RWW section of flash as writing to the flash locks it out */
boot_rww_enable();
/* Memory has been erased, reset the security bit so that programming/reading is allowed */
// IsSecure = false;
}
}
/** Handler for a Data Read command issued by the host. This routine handles bootloader information retrieval
* commands such as device signature and bootloader version retrieval.
*/
static void ProcessReadCommand(void)
{
const uint8_t BootloaderInfo[3] = {BOOTLOADER_VERSION, BOOTLOADER_ID_BYTE1, BOOTLOADER_ID_BYTE2};
const uint8_t SignatureInfo[3] = {AVR_SIGNATURE_1, AVR_SIGNATURE_2, AVR_SIGNATURE_3};
uint8_t DataIndexToRead = SentCommand.Data[1];
if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x00)) // Read bootloader info
ResponseByte = BootloaderInfo[DataIndexToRead];
else if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x01)) // Read signature byte
ResponseByte = SignatureInfo[DataIndexToRead - 0x30];
}

View File

@ -0,0 +1,220 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for Arduino-usbdfu.c.
*/
#ifndef _ARDUINO_USB_DFU_BOOTLOADER_H_
#define _ARDUINO_USB_DFU_BOOTLOADER_H_
/* Includes: */
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/boot.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <avr/power.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include "Descriptors.h"
#include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/USB/USB.h>
/* Macros: */
/** LED mask for the library LED driver, to indicate TX activity. */
#define LEDMASK_TX LEDS_LED1
/** LED mask for the library LED driver, to indicate RX activity. */
#define LEDMASK_RX LEDS_LED2
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
#define LEDMASK_ERROR (LEDS_LED1 | LEDS_LED2)
/** LED mask for the library LED driver, to indicate that the USB interface is busy. */
#define LEDMASK_BUSY (LEDS_LED1 | LEDS_LED2)
/** Configuration define. Define this token to true to case the bootloader to reject all memory commands
* until a memory erase has been performed. When used in conjunction with the lockbits of the AVR, this
* can protect the AVR's firmware from being dumped from a secured AVR. When false, memory operations are
* allowed at any time.
*/
// #define SECURE_MODE false
/** Major bootloader version number. */
#define BOOTLOADER_VERSION_MINOR 2
/** Minor bootloader version number. */
#define BOOTLOADER_VERSION_REV 0
/** Complete bootloader version number expressed as a packed byte, constructed from the
* two individual bootloader version macros.
*/
#define BOOTLOADER_VERSION ((BOOTLOADER_VERSION_MINOR << 4) | BOOTLOADER_VERSION_REV)
/** First byte of the bootloader identification bytes, used to identify a device's bootloader. */
#define BOOTLOADER_ID_BYTE1 0xDC
/** Second byte of the bootloader identification bytes, used to identify a device's bootloader. */
#define BOOTLOADER_ID_BYTE2 0xFB
/** Convenience macro, used to determine if the issued command is the given one-byte long command.
*
* \param[in] dataarr Command byte array to check against
* \param[in] cb1 First command byte to check
*/
#define IS_ONEBYTE_COMMAND(dataarr, cb1) (dataarr[0] == (cb1))
/** Convenience macro, used to determine if the issued command is the given two-byte long command.
*
* \param[in] dataarr Command byte array to check against
* \param[in] cb1 First command byte to check
* \param[in] cb2 Second command byte to check
*/
#define IS_TWOBYTE_COMMAND(dataarr, cb1, cb2) ((dataarr[0] == (cb1)) && (dataarr[1] == (cb2)))
/** Length of the DFU file suffix block, appended to the end of each complete memory write command.
* The DFU file suffix is currently unused (but is designed to give extra file information, such as
* a CRC of the complete firmware for error checking) and so is discarded.
*/
#define DFU_FILE_SUFFIX_SIZE 16
/** Length of the DFU file filler block, appended to the start of each complete memory write command.
* Filler bytes are added to the start of each complete memory write command, and must be discarded.
*/
#define DFU_FILLER_BYTES_SIZE 26
/** DFU class command request to detach from the host. */
#define DFU_DETATCH 0x00
/** DFU class command request to send data from the host to the bootloader. */
#define DFU_DNLOAD 0x01
/** DFU class command request to send data from the bootloader to the host. */
#define DFU_UPLOAD 0x02
/** DFU class command request to get the current DFU status and state from the bootloader. */
#define DFU_GETSTATUS 0x03
/** DFU class command request to reset the current DFU status and state variables to their defaults. */
#define DFU_CLRSTATUS 0x04
/** DFU class command request to get the current DFU state of the bootloader. */
#define DFU_GETSTATE 0x05
/** DFU class command request to abort the current multi-request transfer and return to the dfuIDLE state. */
#define DFU_ABORT 0x06
/** DFU command to begin programming the device's memory. */
#define COMMAND_PROG_START 0x01
/** DFU command to begin reading the device's memory. */
#define COMMAND_DISP_DATA 0x03
/** DFU command to issue a write command. */
#define COMMAND_WRITE 0x04
/** DFU command to issue a read command. */
#define COMMAND_READ 0x05
/** DFU command to issue a memory base address change command, to set the current 64KB flash page
* that subsequent flash operations should use. */
#define COMMAND_CHANGE_BASE_ADDR 0x06
/* Type Defines: */
/** Type define for a non-returning function pointer to the loaded application. */
typedef void (*AppPtr_t)(void) ATTR_NO_RETURN;
/** Type define for a structure containing a complete DFU command issued by the host. */
typedef struct
{
uint8_t Command; /**< Single byte command to perform, one of the COMMAND_* macro values */
uint8_t Data[5]; /**< Command parameters */
uint16_t DataSize; /**< Size of the command parameters */
} DFU_Command_t;
/* Enums: */
/** DFU bootloader states. Refer to the DFU class specification for information on each state. */
enum DFU_State_t
{
appIDLE = 0,
appDETACH = 1,
dfuIDLE = 2,
dfuDNLOAD_SYNC = 3,
dfuDNBUSY = 4,
dfuDNLOAD_IDLE = 5,
dfuMANIFEST_SYNC = 6,
dfuMANIFEST = 7,
dfuMANIFEST_WAIT_RESET = 8,
dfuUPLOAD_IDLE = 9,
dfuERROR = 10
};
/** DFU command status error codes. Refer to the DFU class specification for information on each error code. */
enum DFU_Status_t
{
OK = 0,
errTARGET = 1,
errFILE = 2,
errWRITE = 3,
errERASE = 4,
errCHECK_ERASED = 5,
errPROG = 6,
errVERIFY = 7,
errADDRESS = 8,
errNOTDONE = 9,
errFIRMWARE = 10,
errVENDOR = 11,
errUSBR = 12,
errPOR = 13,
errUNKNOWN = 14,
errSTALLEDPKT = 15
};
/* Function Prototypes: */
void SetupHardware(void);
void ResetHardware(void);
void EVENT_USB_Device_UnhandledControlRequest(void);
#if defined(INCLUDE_FROM_BOOTLOADER_C)
static void DiscardFillerBytes(uint8_t NumberOfBytes);
static void ProcessBootloaderCommand(void);
static void LoadStartEndAddresses(void);
static void ProcessMemProgCommand(void);
static void ProcessMemReadCommand(void);
static void ProcessWriteCommand(void);
static void ProcessReadCommand(void);
#endif
#endif /* _ARDUINO_USB_DFU_BOOTLOADER_H_ */

View File

@ -0,0 +1,110 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/*
Board LEDs driver for the Benito board, from www.dorkbotpdx.org.
*/
#ifndef __LEDS_ARDUINOUNO_H__
#define __LEDS_ARDUINOUNO_H__
/* Includes: */
#include <avr/io.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(INCLUDE_FROM_LEDS_H)
#error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Macros: */
/** LED mask for the first LED on the board. */
#define LEDS_LED1 (1 << 5)
/** LED mask for the second LED on the board. */
#define LEDS_LED2 (1 << 4)
/** LED mask for all the LEDs on the board. */
#define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2)
/** LED mask for the none of the board LEDs */
#define LEDS_NO_LEDS 0
/* Inline Functions: */
#if !defined(__DOXYGEN__)
static inline void LEDs_Init(void)
{
DDRD |= LEDS_ALL_LEDS;
PORTD |= LEDS_ALL_LEDS;
}
static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask)
{
PORTD &= ~LEDMask;
}
static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask)
{
PORTD |= LEDMask;
}
static inline void LEDs_SetAllLEDs(const uint8_t LEDMask)
{
PORTD = ((PORTD | LEDS_ALL_LEDS) & ~LEDMask);
}
static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, const uint8_t ActiveMask)
{
PORTD = ((PORTD | ActiveMask) & ~LEDMask);
}
static inline void LEDs_ToggleLEDs(const uint8_t LEDMask)
{
PORTD ^= LEDMask;
}
static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT;
static inline uint8_t LEDs_GetLEDs(void)
{
return (PORTD & LEDS_ALL_LEDS);
}
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -0,0 +1,189 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special
* computer-readable structures which the host requests upon device enumeration, to determine
* the device's capabilities and functions.
*/
#include "Descriptors.h"
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
* device characteristics, including the supported USB version, control endpoint size and the
* number of device configurations. The descriptor is read out by the USB host when the enumeration
* process begins.
*/
USB_Descriptor_Device_t DeviceDescriptor =
{
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(01.10),
.Class = 0x00,
.SubClass = 0x00,
.Protocol = 0x00,
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
.VendorID = 0x03EB, // Atmel
.ProductID = PRODUCT_ID_CODE, // MCU-dependent
.ReleaseNumber = 0x0000,
.ManufacturerStrIndex = NO_DESCRIPTOR,
.ProductStrIndex = 0x01,
.SerialNumStrIndex = NO_DESCRIPTOR,
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
};
/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
* of the device in one of its supported configurations, including information about any device interfaces
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
* a configuration so that the host may correctly communicate with the USB device.
*/
USB_Descriptor_Configuration_t ConfigurationDescriptor =
{
.Config =
{
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
.TotalInterfaces = 1,
.ConfigurationNumber = 1,
.ConfigurationStrIndex = NO_DESCRIPTOR,
.ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED,
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
},
.DFU_Interface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 0,
.AlternateSetting = 0,
.TotalEndpoints = 0,
.Class = 0xFE,
.SubClass = 0x01,
.Protocol = 0x02,
.InterfaceStrIndex = NO_DESCRIPTOR
},
.DFU_Functional =
{
.Header = {.Size = sizeof(USB_DFU_Functional_Descriptor_t), .Type = DTYPE_DFUFunctional},
.Attributes = (ATTR_CAN_UPLOAD | ATTR_CAN_DOWNLOAD),
.DetachTimeout = 0x0000,
.TransferSize = 0x0c00,
.DFUSpecification = VERSION_BCD(01.01)
}
};
/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
*/
USB_Descriptor_String_t LanguageString =
{
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
.UnicodeString = {LANGUAGE_ID_ENG}
};
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor.
*/
USB_Descriptor_String_t ProductString =
{
#if (ARDUINO_MODEL_PID == ARDUINO_UNO_PID)
.Header = {.Size = USB_STRING_LEN(15), .Type = DTYPE_String},
.UnicodeString = L"Arduino Uno DFU"
#elif (ARDUINO_MODEL_PID == ARDUINO_MEGA2560_PID)
.Header = {.Size = USB_STRING_LEN(21), .Type = DTYPE_String},
.UnicodeString = L"Arduino Mega 2560 DFU"
#endif
};
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
* documentation) by the application code so that the address and size of a requested descriptor can be given
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
* USB host.
*/
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
const uint8_t wIndex,
void** const DescriptorAddress)
{
const uint8_t DescriptorType = (wValue >> 8);
const uint8_t DescriptorNumber = (wValue & 0xFF);
void* Address = NULL;
uint16_t Size = NO_DESCRIPTOR;
switch (DescriptorType)
{
case DTYPE_Device:
Address = &DeviceDescriptor;
Size = sizeof(USB_Descriptor_Device_t);
break;
case DTYPE_Configuration:
Address = &ConfigurationDescriptor;
Size = sizeof(USB_Descriptor_Configuration_t);
break;
case DTYPE_String:
if (!(DescriptorNumber))
{
Address = &LanguageString;
Size = LanguageString.Header.Size;
}
else
{
Address = &ProductString;
Size = ProductString.Header.Size;
}
break;
}
*DescriptorAddress = Address;
return Size;
}

View File

@ -0,0 +1,177 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for Descriptors.c.
*/
#ifndef _DESCRIPTORS_H_
#define _DESCRIPTORS_H_
/* Includes: */
#include <LUFA/Drivers/USB/USB.h>
/* Product-specific definitions: */
#define ARDUINO_UNO_PID 0x0001
#define ARDUINO_MEGA2560_PID 0x0010
/* Macros: */
/** Descriptor type value for a DFU class functional descriptor. */
#define DTYPE_DFUFunctional 0x21
/** DFU attribute mask, indicating that the DFU device will detach and re-attach when a DFU_DETACH
* command is issued, rather than the host issuing a USB Reset.
*/
#define ATTR_WILL_DETATCH (1 << 3)
/** DFU attribute mask, indicating that the DFU device can communicate during the manifestation phase
* (memory programming phase).
*/
#define ATTR_MANEFESTATION_TOLLERANT (1 << 2)
/** DFU attribute mask, indicating that the DFU device can accept DFU_UPLOAD requests to send data from
* the device to the host.
*/
#define ATTR_CAN_UPLOAD (1 << 1)
/** DFU attribute mask, indicating that the DFU device can accept DFU_DNLOAD requests to send data from
* the host to the device.
*/
#define ATTR_CAN_DOWNLOAD (1 << 0)
#if defined(__AVR_AT90USB1287__)
#define PRODUCT_ID_CODE 0x2FFB
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x97
#define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_AT90USB1286__)
#define PRODUCT_ID_CODE 0x2FFB
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x97
#define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_AT90USB647__)
#define PRODUCT_ID_CODE 0x2FF9
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x96
#define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_AT90USB646__)
#define PRODUCT_ID_CODE 0x2FF9
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x96
#define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_ATmega32U6__)
#define PRODUCT_ID_CODE 0x2FFB
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x95
#define AVR_SIGNATURE_3 0x88
#elif defined(__AVR_ATmega32U4__)
#define PRODUCT_ID_CODE 0x2FF4
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x95
#define AVR_SIGNATURE_3 0x87
#elif defined(__AVR_ATmega32U2__)
#define PRODUCT_ID_CODE 0x2FF0
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x95
#define AVR_SIGNATURE_3 0x8A
#elif defined(__AVR_ATmega16U4__)
#define PRODUCT_ID_CODE 0x2FF3
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x94
#define AVR_SIGNATURE_3 0x88
#elif defined(__AVR_ATmega16U2__)
#define PRODUCT_ID_CODE 0x2FEF
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x94
#define AVR_SIGNATURE_3 0x89
#elif defined(__AVR_AT90USB162__)
#define PRODUCT_ID_CODE 0x2FFA
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x94
#define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_AT90USB82__)
#define PRODUCT_ID_CODE 0x2FEE
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x93
#define AVR_SIGNATURE_3 0x89
#elif defined(__AVR_ATmega8U2__)
#define PRODUCT_ID_CODE 0x2FF7
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x93
#define AVR_SIGNATURE_3 0x82
#else
#error The selected AVR part is not currently supported by this bootloader.
#endif
#if !defined(PRODUCT_ID_CODE)
#error Current AVR model is not supported by this bootloader.
#endif
/* Type Defines: */
/** Type define for a DFU class function descriptor. This descriptor gives DFU class information
* to the host when read, indicating the DFU device's capabilities.
*/
typedef struct
{
USB_Descriptor_Header_t Header; /**< Standard descriptor header structure */
uint8_t Attributes; /**< DFU device attributes, a mask comprising of the
* ATTR_* macros listed in this source file
*/
uint16_t DetachTimeout; /**< Timeout in milliseconds between a USB_DETACH
* command being issued and the device detaching
* from the USB bus
*/
uint16_t TransferSize; /**< Maximum number of bytes the DFU device can accept
* from the host in a transaction
*/
uint16_t DFUSpecification; /**< BCD packed DFU specification number this DFU
* device complies with
*/
} USB_DFU_Functional_Descriptor_t;
/** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which
* vary between devices, and which describe the device's usage to the host.
*/
typedef struct
{
USB_Descriptor_Configuration_Header_t Config;
USB_Descriptor_Interface_t DFU_Interface;
USB_DFU_Functional_Descriptor_t DFU_Functional;
} USB_Descriptor_Configuration_t;
/* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
const uint8_t wIndex,
void** const DescriptorAddress) ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
#endif

View File

@ -0,0 +1,710 @@
# Hey Emacs, this is a -*- makefile -*-
#----------------------------------------------------------------------------
# WinAVR Makefile Template written by Eric B. Weddington, J<>rg Wunsch, et al.
# >> Modified for use with the LUFA project. <<
#
# Released to the Public Domain
#
# Additional material for this makefile was written by:
# Peter Fleury
# Tim Henigan
# Colin O'Flynn
# Reiner Patommel
# Markus Pfaff
# Sander Pool
# Frederik Rouleau
# Carlos Lamas
# Dean Camera
# Opendous Inc.
# Denver Gingerich
#
#----------------------------------------------------------------------------
# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make coff = Convert ELF to AVR COFF.
#
# make extcoff = Convert ELF to AVR Extended COFF.
#
# make program = Download the hex file to the device, using avrdude.
# Please customize the avrdude settings below first!
#
# make doxygen = Generate DoxyGen documentation for the project (must have
# DoxyGen installed)
#
# make debug = Start either simulavr or avarice as specified for debugging,
# with avr-gdb or avr-insight as the front end for debugging.
#
# make filename.s = Just compile filename.c into the assembler code only.
#
# make filename.i = Create a preprocessed source file for use in submitting
# bug reports to the GCC project.
#
# To rebuild project do "make clean" then "make all".
#----------------------------------------------------------------------------
# MCU name
MCU = atmega8u2
MCU_AVRDUDE = at90usb82
# Specify the Arduino model using the assigned PID. This is used by Descriptors.c
# to set the product descriptor string (for DFU we must use the PID for each
# chip that dfu-bootloader or Flip expect)
# Uno PID:
ARDUINO_MODEL_PID = 0x0001
# Mega 2560 PID:
#ARDUINO_MODEL_PID = 0x0010
# Target board (see library "Board Types" documentation, NONE for projects not requiring
# LUFA board drivers). If USER is selected, put custom board drivers in a directory called
# "Board" inside the application directory.
BOARD = USER
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency in Hz. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
#
# This will be an integer division of F_CLOCK below, as it is sourced by
# F_CLOCK after it has run through any CPU prescalers. Note that this value
# does not *change* the processor frequency - it should merely be updated to
# reflect the processor speed set externally so that the code can use accurate
# software delays.
F_CPU = 16000000
# Input clock frequency.
# This will define a symbol, F_CLOCK, in all source code files equal to the
# input clock frequency (before any prescaling is performed) in Hz. This value may
# differ from F_CPU if prescaling is used on the latter, and is required as the
# raw input clock is fed directly to the PLL sections of the AVR for high speed
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
# at the end, this will be done automatically to create a 32-bit value in your
# source code.
#
# If no clock division is performed on the input clock inside the AVR (via the
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_CLOCK = $(F_CPU)
# Starting byte address of the bootloader, as a byte address - computed via the formula
# BOOT_START = ((TOTAL_FLASH_BYTES - BOOTLOADER_SECTION_SIZE_BYTES) * 1024)
#
# Note that the bootloader size and start address given in AVRStudio is in words and not
# bytes, and so will need to be doubled to obtain the byte address needed by AVR-GCC.
BOOT_START = 0x1000
# Output format. (can be srec, ihex, binary)
FORMAT = ihex
# Target file name (without extension).
TARGET = Arduino-usbdfu
# Object files directory
# To put object files in current directory, use a dot (.), do NOT make
# this an empty or blank macro!
OBJDIR = .
# Path to the LUFA library
LUFA_PATH = ../..
# LUFA library compile-time options and predefined tokens
LUFA_OPTS = -D USB_DEVICE_ONLY
LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0
LUFA_OPTS += -D CONTROL_ONLY_DEVICE
LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=32
LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1
LUFA_OPTS += -D USE_RAM_DESCRIPTORS
LUFA_OPTS += -D USE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
LUFA_OPTS += -D NO_INTERNAL_SERIAL
LUFA_OPTS += -D NO_DEVICE_SELF_POWER
LUFA_OPTS += -D NO_DEVICE_REMOTE_WAKEUP
LUFA_OPTS += -D NO_STREAM_CALLBACKS
# Create the LUFA source path variables by including the LUFA root makefile
include $(LUFA_PATH)/LUFA/makefile
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c \
Descriptors.c \
$(LUFA_SRC_USB) \
# List C++ source files here. (C dependencies are automatically generated.)
CPPSRC =
# List Assembler source files here.
# Make them always end in a capital .S. Files ending in a lowercase .s
# will not be considered source files but generated files (assembler
# output from the compiler), and will be deleted upon "make clean"!
# Even though the DOS/Win* filesystem matches both .s and .S the same,
# it will preserve the spelling of the filenames, and gcc itself does
# care about how the name is spelled on its command-line.
ASRC =
# Optimization level, can be [0, 1, 2, 3, s].
# 0 = turn off optimization. s = optimize for size.
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = s
# Debugging format.
# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
# AVR Studio 4.10 requires dwarf-2.
# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
DEBUG = dwarf-2
# List any extra directories to look for include files here.
# Each directory must be seperated by a space.
# Use forward slashes for directory separators.
# For a directory that has spaces, enclose it in quotes.
EXTRAINCDIRS = $(LUFA_PATH)/
# Compiler flag to set the C Standard level.
# c89 = "ANSI" C
# gnu89 = c89 plus GCC extensions
# c99 = ISO C99 standard (not yet fully implemented)
# gnu99 = c99 plus GCC extensions
CSTANDARD = -std=c99
# Place -D or -U options here for C sources
CDEFS = -DF_CPU=$(F_CPU)UL
CDEFS += -DARDUINO_MODEL_PID=$(ARDUINO_MODEL_PID)
CDEFS += -DF_CLOCK=$(F_CLOCK)UL
CDEFS += -DBOARD=BOARD_$(BOARD)
CDEFS += -DBOOT_START_ADDR=$(BOOT_START)UL
CDEFS += -DTX_RX_LED_PULSE_MS=3
CDEFS += $(LUFA_OPTS)
# Place -D or -U options here for ASM sources
ADEFS = -DF_CPU=$(F_CPU)
ADEFS += -DF_CLOCK=$(F_CLOCK)UL
ADEFS += -DBOARD=BOARD_$(BOARD)
CDEFS += -DBOOT_START_ADDR=$(BOOT_START)UL
ADEFS += $(LUFA_OPTS)
# Place -D or -U options here for C++ sources
CPPDEFS = -DF_CPU=$(F_CPU)UL
CPPDEFS += -DF_CLOCK=$(F_CLOCK)UL
CPPDEFS += -DBOARD=BOARD_$(BOARD)
CDEFS += -DBOOT_START_ADDR=$(BOOT_START)UL
CPPDEFS += $(LUFA_OPTS)
#CPPDEFS += -D__STDC_LIMIT_MACROS
#CPPDEFS += -D__STDC_CONSTANT_MACROS
#---------------- Compiler Options C ----------------
# -g*: generate debugging information
# -O*: optimization level
# -f...: tuning, see GCC manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns...: create assembler listing
CFLAGS = -g$(DEBUG)
CFLAGS += $(CDEFS)
CFLAGS += -O$(OPT)
CFLAGS += -funsigned-char
CFLAGS += -funsigned-bitfields
CFLAGS += -ffunction-sections
CFLAGS += -fno-inline-small-functions
CFLAGS += -fpack-struct
CFLAGS += -fshort-enums
CFLAGS += -fno-strict-aliasing
CFLAGS += -Wall
CFLAGS += -Wstrict-prototypes
#CFLAGS += -mshort-calls
#CFLAGS += -fno-unit-at-a-time
#CFLAGS += -Wundef
#CFLAGS += -Wunreachable-code
#CFLAGS += -Wsign-compare
CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD)
#---------------- Compiler Options C++ ----------------
# -g*: generate debugging information
# -O*: optimization level
# -f...: tuning, see GCC manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns...: create assembler listing
CPPFLAGS = -g$(DEBUG)
CPPFLAGS += $(CPPDEFS)
CPPFLAGS += -O$(OPT)
CPPFLAGS += -funsigned-char
CPPFLAGS += -funsigned-bitfields
CPPFLAGS += -fpack-struct
CPPFLAGS += -fshort-enums
CPPFLAGS += -fno-exceptions
CPPFLAGS += -Wall
CPPFLAGS += -Wundef
#CPPFLAGS += -mshort-calls
#CPPFLAGS += -fno-unit-at-a-time
#CPPFLAGS += -Wstrict-prototypes
#CPPFLAGS += -Wunreachable-code
#CPPFLAGS += -Wsign-compare
CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
#CPPFLAGS += $(CSTANDARD)
#---------------- Assembler Options ----------------
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns: create listing
# -gstabs: have the assembler create line number information; note that
# for use in COFF files, additional information about filenames
# and function names needs to be present in the assembler source
# files -- see avr-libc docs [FIXME: not yet described there]
# -listing-cont-lines: Sets the maximum number of continuation lines of hex
# dump that will be displayed for a given single line of source input.
ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100
#---------------- Library Options ----------------
# Minimalistic printf version
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
# Floating point printf version (requires MATH_LIB = -lm below)
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
# If this is left blank, then it will use the Standard printf version.
PRINTF_LIB =
#PRINTF_LIB = $(PRINTF_LIB_MIN)
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
# Minimalistic scanf version
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
# If this is left blank, then it will use the Standard scanf version.
SCANF_LIB =
#SCANF_LIB = $(SCANF_LIB_MIN)
#SCANF_LIB = $(SCANF_LIB_FLOAT)
MATH_LIB = -lm
# List any extra directories to look for libraries here.
# Each directory must be seperated by a space.
# Use forward slashes for directory separators.
# For a directory that has spaces, enclose it in quotes.
EXTRALIBDIRS =
#---------------- External Memory Options ----------------
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# used for variables (.data/.bss) and heap (malloc()).
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# only used for heap (malloc()).
#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff
EXTMEMOPTS =
#---------------- Linker Options ----------------
# -Wl,...: tell GCC to pass this to linker.
# -Map: create map file
# --cref: add cross reference to map file
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
LDFLAGS += -Wl,--section-start=.text=$(BOOT_START)
LDFLAGS += -Wl,--relax
LDFLAGS += -Wl,--gc-sections
LDFLAGS += $(EXTMEMOPTS)
LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
#LDFLAGS += -T linker_script.x
#---------------- Programming Options (avrdude) ----------------
# Fuse settings for Arduino Uno DFU bootloader project
AVRDUDE_FUSES = -U efuse:w:0xF4:m -U hfuse:w:0xD9:m -U lfuse:w:0xFF:m
# Lock settings for Arduino Uno DFU bootloader project
AVRDUDE_LOCK = -U lock:w:0x0F:m
# Programming hardware
# Type: avrdude -c ?
# to get a full listing.
#
AVRDUDE_PROGRAMMER = avrispmkii
# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = usb
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
# Uncomment the following if you want avrdude's erase cycle counter.
# Note that this counter needs to be initialized first using -Yn,
# see avrdude manual.
#AVRDUDE_ERASE_COUNTER = -y
# Uncomment the following if you do /not/ wish a verification to be
# performed after programming the device.
#AVRDUDE_NO_VERIFY = -V
# Increase verbosity level. Please use this when submitting bug
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
# to submit bug reports.
#AVRDUDE_VERBOSE = -v -v
AVRDUDE_FLAGS = -p $(MCU_AVRDUDE) -F -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
#---------------- Debugging Options ----------------
# For simulavr only - target MCU frequency.
DEBUG_MFREQ = $(F_CPU)
# Set the DEBUG_UI to either gdb or insight.
# DEBUG_UI = gdb
DEBUG_UI = insight
# Set the debugging back-end to either avarice, simulavr.
DEBUG_BACKEND = avarice
#DEBUG_BACKEND = simulavr
# GDB Init Filename.
GDBINIT_FILE = __avr_gdbinit
# When using avarice settings for the JTAG
JTAG_DEV = /dev/com1
# Debugging port used to communicate between GDB / avarice / simulavr.
DEBUG_PORT = 4242
# Debugging host used to communicate between GDB / avarice / simulavr, normally
# just set to localhost unless doing some sort of crazy debugging when
# avarice is running on a different computer.
DEBUG_HOST = localhost
#============================================================================
# Define programs and commands.
SHELL = sh
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
AR = avr-ar rcs
NM = avr-nm
AVRDUDE = avrdude
REMOVE = rm -f
REMOVEDIR = rm -rf
COPY = cp
WINSHELL = cmd
# Define Messages
# English
MSG_ERRORS_NONE = Errors: none
MSG_BEGIN = -------- begin --------
MSG_END = -------- end --------
MSG_SIZE_BEFORE = Size before:
MSG_SIZE_AFTER = Size after:
MSG_COFF = Converting to AVR COFF:
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
MSG_FLASH = Creating load file for Flash:
MSG_EEPROM = Creating load file for EEPROM:
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_SYMBOL_TABLE = Creating Symbol Table:
MSG_LINKING = Linking:
MSG_COMPILING = Compiling C:
MSG_COMPILING_CPP = Compiling C++:
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project:
MSG_CREATING_LIBRARY = Creating library:
# Define all object files.
OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
# Define all listing files.
LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)
# Compiler flags to generate dependency files.
GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
# Default target.
all: begin gccversion sizebefore build sizeafter end
# Change the build target to build a HEX file or a library.
build: elf hex eep lss sym
#build: lib
elf: $(TARGET).elf
hex: $(TARGET).hex
eep: $(TARGET).eep
lss: $(TARGET).lss
sym: $(TARGET).sym
LIBNAME=lib$(TARGET).a
lib: $(LIBNAME)
# Eye candy.
# AVR Studio 3.x does not check make's exit code but relies on
# the following magic strings to be generated by the compile job.
begin:
@echo
@echo $(MSG_BEGIN)
end:
@echo $(MSG_END)
@echo
# Display size of file.
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
ELFSIZE = $(SIZE) $(MCU_FLAG) $(FORMAT_FLAG) $(TARGET).elf
MCU_FLAG = $(shell $(SIZE) --help | grep -- --mcu > /dev/null && echo --mcu=$(MCU) )
FORMAT_FLAG = $(shell $(SIZE) --help | grep -- --format=.*avr > /dev/null && echo --format=avr )
sizebefore:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
2>/dev/null; echo; fi
sizeafter:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
2>/dev/null; echo; fi
# Display compiler version information.
gccversion :
@$(CC) --version
# Program the device.
program: $(TARGET).hex $(TARGET).eep
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) $(AVRDUDE_FUSES) $(AVRDUDE_LOCK)
# Generate avr-gdb config/init file which does the following:
# define the reset signal, load the target file, connect to target, and set
# a breakpoint at main().
gdb-config:
@$(REMOVE) $(GDBINIT_FILE)
@echo define reset >> $(GDBINIT_FILE)
@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
@echo end >> $(GDBINIT_FILE)
@echo file $(TARGET).elf >> $(GDBINIT_FILE)
@echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE)
ifeq ($(DEBUG_BACKEND),simulavr)
@echo load >> $(GDBINIT_FILE)
endif
@echo break main >> $(GDBINIT_FILE)
debug: gdb-config $(TARGET).elf
ifeq ($(DEBUG_BACKEND), avarice)
@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
@$(WINSHELL) /c pause
else
@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
$(DEBUG_MFREQ) --port $(DEBUG_PORT)
endif
@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT = $(OBJCOPY) --debugging
COFFCONVERT += --change-section-address .data-0x800000
COFFCONVERT += --change-section-address .bss-0x800000
COFFCONVERT += --change-section-address .noinit-0x800000
COFFCONVERT += --change-section-address .eeprom-0x810000
coff: $(TARGET).elf
@echo
@echo $(MSG_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
extcoff: $(TARGET).elf
@echo
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
@echo
@echo $(MSG_FLASH) $@
$(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock $< $@
%.eep: %.elf
@echo
@echo $(MSG_EEPROM) $@
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0
# Create extended listing file from ELF output file.
%.lss: %.elf
@echo
@echo $(MSG_EXTENDED_LISTING) $@
$(OBJDUMP) -h -S -z $< > $@
# Create a symbol table from ELF output file.
%.sym: %.elf
@echo
@echo $(MSG_SYMBOL_TABLE) $@
$(NM) -n $< > $@
# Create library from object files.
.SECONDARY : $(TARGET).a
.PRECIOUS : $(OBJ)
%.a: $(OBJ)
@echo
@echo $(MSG_CREATING_LIBRARY) $@
$(AR) $@ $(OBJ)
# Link: create ELF output file from object files.
.SECONDARY : $(TARGET).elf
.PRECIOUS : $(OBJ)
%.elf: $(OBJ)
@echo
@echo $(MSG_LINKING) $@
$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
# Compile: create object files from C source files.
$(OBJDIR)/%.o : %.c
@echo
@echo $(MSG_COMPILING) $<
$(CC) -c $(ALL_CFLAGS) $< -o $@
# Compile: create object files from C++ source files.
$(OBJDIR)/%.o : %.cpp
@echo
@echo $(MSG_COMPILING_CPP) $<
$(CC) -c $(ALL_CPPFLAGS) $< -o $@
# Compile: create assembler files from C source files.
%.s : %.c
$(CC) -S $(ALL_CFLAGS) $< -o $@
# Compile: create assembler files from C++ source files.
%.s : %.cpp
$(CC) -S $(ALL_CPPFLAGS) $< -o $@
# Assemble: create object files from assembler source files.
$(OBJDIR)/%.o : %.S
@echo
@echo $(MSG_ASSEMBLING) $<
$(CC) -c $(ALL_ASFLAGS) $< -o $@
# Create preprocessed source for use in sending a bug report.
%.i : %.c
$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@
# Target: clean project.
clean: begin clean_list end
clean_list :
@echo
@echo $(MSG_CLEANING)
$(REMOVE) $(TARGET).hex
$(REMOVE) $(TARGET).eep
$(REMOVE) $(TARGET).cof
$(REMOVE) $(TARGET).elf
$(REMOVE) $(TARGET).map
$(REMOVE) $(TARGET).sym
$(REMOVE) $(TARGET).lss
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o)
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst)
$(REMOVE) $(SRC:.c=.s)
$(REMOVE) $(SRC:.c=.d)
$(REMOVE) $(SRC:.c=.i)
$(REMOVEDIR) .dep
doxygen:
@echo Generating Project Documentation...
@doxygen Doxygen.conf
@echo Documentation Generation Complete.
clean_doxygen:
rm -rf Documentation
# Create object files directory
$(shell mkdir $(OBJDIR) 2>/dev/null)
# Include the dependency files.
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion \
build elf hex eep lss sym coff extcoff doxygen clean \
clean_list clean_doxygen program debug gdb-config

View File

@ -0,0 +1,7 @@
To setup the project and program an ATMEG8U2 with the Arduino USB DFU bootloader:
1. unpack the source into LUFA's Bootloader directory
2. set ARDUINO_MODEL_PID in the makefile as appropriate
3. do "make clean; make; make program"
Check that the board enumerates as either "Arduino Uno DFU" or "Arduino Mega 2560 DFU". Test by uploading the Arduino-usbserial application firmware (see instructions in Arduino-usbserial directory)

View File

@ -0,0 +1,254 @@
:1000000090C00000A9C00000A7C00000A5C000006B
:10001000A3C00000A1C000009FC000009DC0000060
:100020009BC0000099C0000097C0000048C40000B9
:100030000CC4000091C000008FC000008DC0000003
:100040008BC0000089C0000087C0000085C0000090
:1000500083C0000081C000007FC0000002C100001A
:100060007BC0000079C0000077C0000075C00000B0
:1000700073C0000071C000006FC000006DC00000C0
:100080006BC0000069C0000067C0000065C00000D0
:1000900063C0000061C000001201100102000008EE
:1000A0004123420001000102DC0109023E0002017D
:1000B00000C0320904000001020201000524000111
:1000C0001004240206052406000107058203080027
:1000D000FF09040100020A000000070504024000B5
:1000E00001070583024000010403090432034100B3
:1000F00072006400750069006E006F002000280027
:100100007700770077002E006100720064007500B0
:1001100069006E006F002E0063006300290000007C
:10012000000011241FBECFEFD2E0DEBFCDBF11E033
:10013000A0E0B1E0ECEAFFE002C005900D92A6312C
:10014000B107D9F712E0A6E1B1E001C01D92AF32CC
:10015000B107E1F7F1D028C753CF9C01DC01AE57BE
:10016000BF4FED91FC91119741911196FC93EE9345
:1001700080589F4FE817F90711F42D933C939FB7D0
:10018000F894F901EC57FF4F8081815080839FBF25
:10019000842F0895DF92EF92FF920F931F93FC013B
:1001A0008489813019F0823021F405C040E3D42ED7
:1001B00004C0DD2402C030E2D32E8389823011F4E2
:1001C00088E0D82A8589873031F0883031F0863050
:1001D00031F482E003C084E001C086E0D82A1092A6
:1001E000C9001092C8001092CA00E784F088018903
:1001F000128980E0E81681EEF80680E0080780E0CA
:10020000180719F420E130E00FC0C801B701969536
:1002100087957795679560587B47814E9F4FA801DA
:100220009701A0D6215030403093CD002093CC00D0
:10023000D092CA0080E0E81681EEF80680E0080758
:1002400080E0180711F082E001C080E08093C800D0
:1002500088E98093C9001F910F91FF90EF90DF9084
:1002600008951F920F920FB60F9211242F938F9320
:100270009F93EF93FF939091CE008EB38430F1F46F
:10028000E0919901F0919A019083E0919901F091A8
:100290009A01CF01019690939A018093990189590F
:1002A000914021F489E191E0928381839FB7F89492
:1002B00080919D018F5F80939D019FBFFF91EF9182
:1002C0009F918F912F910F900FBE0F901F901895B7
:1002D000FC01858580FF02C05F9808955F9A0895AC
:1002E00080E091E0D5C580E091E088C584B7877F44
:1002F00084BF28E10FB6F89420936000109260004C
:100300000FBE87E690E09093CD008093CC0086E00E
:100310008093CA001092C8002093C900539A5A9A39
:100320008AB180638AB98BB180638BB983D284E050
:1003300085BD5F9A579A08950F931F93CF93DF93CC
:10034000D5DF2FB7F8948EE991E090931F02809348
:100350001E0290932102809320022FBF2FB7F894A2
:1003600089E191E090939A018093990190939C0187
:1003700080939B012FBF7894CEE9D1E003E08FB743
:10038000F894909122028FBF903809F180E091E0BB
:10039000ABD497FD1CC0E0911E02F0911F02808338
:1003A000E0911E02F0911F02CF01019690931F026F
:1003B00080931E028E51924011F4D283C1839FB765
:1003C000F894809122028F5F809322029FBF8FB7A3
:1003D000F89410919D018FBFA89902C0113678F151
:1003E000A89A80919D01882361F05D980093160181
:1003F00008C089E191E0B1DE682F80E091E0DAD4B5
:1004000011501123B1F780911601882351F080918A
:10041000160181508093160180911601882309F4FA
:100420005D9A80911701882351F0809117018150C6
:100430008093170180911701882309F45C9A8FB784
:10044000F894909122028FBF992369F08EE991E090
:1004500084DE982F8091C80085FFFCCF9093CE005A
:100460005C980093170180E091E095D42AD487CF5F
:10047000DA01923049F0933061F09130F9F4E8E913
:10048000F0E022E130E01EC0EAEAF0E02EE330E0E6
:1004900019C0813049F0813018F0823079F408C0F9
:1004A000E8EEF0E0849107C0ECEEF0E0849103C048
:1004B000E0E2F1E08491282F30E004C0E0E0F0E0D9
:1004C00020E030E0ED93FC93C901089528E030E08E
:1004D00040E003C04F5F220F331F28173907D0F3C6
:1004E000842F8295807F08958093E9008091EB00AE
:1004F00081608093EB001092ED006093EC004093DC
:10050000ED008091EE00881F8827881F08951092C3
:10051000F40090E09093E9001092F0001092E8004F
:100520001092ED008091EB008E7F8093EB009F5F37
:10053000953081F708958091270288238CF403C0B9
:100540008EB38823B1F08091E80082FFF9CF8091CB
:10055000E8008B778093E80008958EB3882349F0F4
:100560008091E80080FFF9CF8091E8008E7780933A
:10057000E800089594E68091EC0080FF05C080912A
:10058000E80080FF05C023C08091E80082FD1FC005
:100590008EB3882311F482E008958EB3853011F470
:1005A00083E008958091EB0085FF02C081E008950B
:1005B0008091E10082FFDFCF8091E1008B7F80930B
:1005C000E100992311F484E008959150D4CF80E0A4
:1005D00008959C0140912D0250912E024617570715
:1005E00018F4F90120E038C06115710511F0AB0174
:1005F000F8CF8091E8008E778093E80040E050E0EB
:10060000F0CF8091E80083FF02C081E008958091DF
:10061000E80082FD2DC08EB3882381F18EB3853032
:1006200079F18091E80080FF17C09091F20006C038
:1006300081918093F100415050409F5F41155105D9
:1006400011F09830A8F320E0983009F421E080916F
:10065000E8008E778093E8004115510591F622233A
:1006600081F606C08EB3882349F08EB3853041F001
:100670008091E80082FFF6CF80E0089582E008953F
:1006800083E008959C0140912D0250912E0246175F
:10069000570710F490E03BC06115710511F0AB01F4
:1006A000F9CF8091E8008E778093E80040E050E039
:1006B000F1CF8091E80083FF02C081E0089580912E
:1006C000E80082FD30C08EB3882399F18EB3853067
:1006D00091F18091E80080FF1AC08091F20009C07A
:1006E000F9012F5F3F4FE491E093F10041505040FA
:1006F0008F5F4115510511F0883090F390E08830FC
:1007000009F491E08091E8008E778093E80041152C
:10071000510579F6992369F606C08EB3882349F00E
:100720008EB3853041F08091E80082FFF6CF80E003
:10073000089582E0089583E008959C016115710594
:1007400029F48091E8008B778093E800F90120C0BC
:100750008091E80083FF02C081E008958EB3882372
:1007600039F18EB3853031F18091E80082FFF0CF0E
:1007700006C08091F10081936150704021F080911A
:10078000F2008823B1F78091E8008B778093E8002E
:1007900061157105E9F606C08EB3882349F08EB362
:1007A000853041F08091E80080FFF6CF80E0089529
:1007B00082E0089583E0089542D044D01EBA10929A
:1007C0002502109224021092230284E089BD89B58B
:1007D000826089BD09B400FEFDCF8091D800982FBA
:1007E0009F779093D80080688093D80080916300B1
:1007F0008E7F809363008091D8008F7D8093D80096
:100800008091E0008E7F8093E0008091E1008E7FF8
:100810008093E1008091E20081608093E20080910A
:10082000E100877F8093E1008091E20088608093FF
:10083000E2000895C1DF81E08093260208951092BE
:10084000E20008951092E10008951F920F920FB6F2
:100850000F9211241F932F933F934F935F936F93A6
:100860007F938F939F93AF93BF93EF93FF93E9EEA3
:10087000F0E0108117701082E0EFF0E08081877F58
:1008800080837894C3D0F894A9EEB0E01C92E0EF96
:10089000F0E08081886080831C93FF91EF91BF918D
:1008A000AF919F918F917F916F915F914F913F9108
:1008B0002F911F910F900FBE0F901F9018951F92B0
:1008C0000F920FB60F9211242F933F934F935F9384
:1008D0006F937F938F939F93AF93BF93EF93FF9308
:1008E0008091E10080FF1BC08091E20080FF17C073
:1008F0008091E1008E7F8093E1008091E2008E7F05
:100900008093E2008091E20080618093E200809118
:10091000D80080628093D80019BC1EBAD1D18091D2
:10092000E10084FF29C08091E20084FF25C084E0BB
:1009300089BD89B5826089BD09B400FEFDCF809173
:10094000D8008F7D8093D8008091E1008F7E8093C6
:10095000E1008091E2008F7E8093E2008091E200CE
:1009600081608093E20080912502882311F481E068
:1009700001C084E08EBBA4D18091E10083FF27C039
:100980008091E20083FF23C08091E100877F809304
:10099000E10082E08EBB109225028091E1008E7F03
:1009A0008093E1008091E2008E7F8093E20080914D
:1009B000E20080618093E200AADD80E060E042E036
:1009C00093DD8091F00088608093F00079D1809170
:1009D000E10082FF0AC08091E20082FF06C08091A0
:1009E000E1008B7F8093E1006BD1FF91EF91BF918C
:1009F000AF919F918F917F916F915F914F913F91B7
:100A00002F910F900FBE0F901F9018951F93DF939B
:100A1000CF93CDB7DEB7AC970FB6F894DEBF0FBE5D
:100A2000CDBFE7E2F2E08091F100819322E0EF3266
:100A3000F207C9F78091270230912802353009F476
:100A400087C0363040F43130C9F1313070F0333086
:100A500009F01DC133C0383009F4EFC0393009F452
:100A6000FEC0363009F013C192C0803821F08238C0
:100A700009F00DC108C090912302809124028823BF
:100A800099F0926011C080912B0287708093E900E9
:100A90008091EB0090E025E0969587952A95E1F707
:100AA000982F91701092E9008091E800877F8093E1
:100AB000E8009093F1001092F100CAC0882319F069
:100AC000823009F0E4C090E08F719070009721F0BF
:100AD000029709F0DDC00CC080912902813009F035
:100AE000D7C010922402333069F5809324022AC0C3
:100AF00080912902882331F520912B02277009F477
:100B0000C7C02093E9008091EB0080FFC1C0333063
:100B100021F48091EB00806213C08091EB00806132
:100B20008093EB0081E090E002C0880F991F2A9526
:100B3000E2F78093EA001092EA008091EB0088606F
:100B40008093EB001092E9008091E800877F83C0DA
:100B5000882309F09CC0109129028091E800877FCA
:100B60008093E800E8DC04C08EB3882309F490C0C9
:100B70008091E80080FFF8CF812F8F7711F492E009
:100B800001C093E09EBB80688093E30081C08058E1
:100B9000823008F07CC08091290290912A0223E0E3
:100BA0008C3D920799F55FB7F894DE0115964EE0FB
:100BB00020E030E061E2E42FF0E0609357008491A0
:100BC00020FF03C082958F704F5F982F9F70892FF1
:100BD000805D8A3308F0895F8C9311961C9211977F
:100BE0002F5F3F4F12962431310529F75FBF8AE20C
:100BF0008B8383E08C838091E800877F8093E8007B
:100C0000CE0103966AE270E0E4DC11C060912B0231
:100C1000AE014F5F5F4F2CDCBC010097C9F18091A2
:100C2000E800877F8093E80089819A812BDD80919D
:100C3000E8008B778093E8002BC0803841F58091E5
:100C4000E800877F8093E800809125028093F1007F
:100C50008091E8008E778093E8006DDC19C08823CE
:100C6000B1F490912902923098F48091E800877F46
:100C70008093E800909325025EDC80912502882312
:100C800011F483E001C084E08EBB2DDB01C028DBC2
:100C90008091E80083FF0AC08091EB00806280931E
:100CA000EB008091E800877F8093E800AC960FB658
:100CB000F894DEBF0FBECDBFCF91DF911F91089595
:100CC00008951F938EB3882361F01091E90010926C
:100CD000E9008091E80083FF01C098DE177010934F
:100CE000E9001F9108950895FC018EB3843021F529
:100CF00087859089A189B2890097A105B105E1F0A6
:100D000085818093E9008091E80082FF15C0809181
:100D1000F200882319F42FEF3FEF04C08091F10017
:100D2000282F30E08091F200882341F48091E80080
:100D30008B778093E80002C02FEF3FEFC901089541
:100D4000FC018EB3843011F587859089A189B28921
:100D50000097A105B105D1F081818093E9008091D0
:100D6000F2008823A9F09091E8008091E8008E7746
:100D70008093E80095FD0CC0FDDB982F882349F493
:100D80008091E8008E778093E80003C092E001C074
:100D900090E0892F0895FC018EB3843051F487854B
:100DA0009089A189B2890097A105B10511F0CF0101
:100DB000C7CF08951F93FC01162F8EB38430D9F44A
:100DC00087859089A189B2890097A105B10599F01D
:100DD00081818093E9008091E80085FD08C08091C1
:100DE000E8008E778093E800C5DB882329F4109310
:100DF000F10080E001C082E01F9108950F931F93DE
:100E0000CF93DF93EC010D96FC0189E0DF011D9289
:100E10008A95E9F72A813B8109818C81882311F425
:100E200010E001C014E0C90151DB182B1260802FC3
:100E300061E8412F59DB882329F12E813F810D8103
:100E40008885882311F410E001C014E0C9013EDB5D
:100E5000182B1260802F60E8412F46DB882391F029
:100E60002A853B8509858C85882311F410E001C013
:100E700014E0C9012BDB182B1260802F61EC412F8D
:100E800033DB01C080E0DF91CF911F910F91089576
:100E9000CF93DF93EC018091E80083FF60C08881ED
:100EA00090E020912B0230912C022817390709F08D
:100EB00056C080912802813261F0823220F4803263
:100EC00009F04DC019C0823269F1833209F047C080
:100ED00038C080912702813A09F041C08091E80032
:100EE000877F8093E800CE010F9667E070E071DBAA
:100EF0008091E8008B7713C080912702813279F5C9
:100F00008091E800877F8093E800CE010F9667E02C
:100F100070E013DCCE013ED98091E8008E7780939B
:100F2000E8001DC0809127028132C9F48091E80059
:100F3000877F8093E800809129028D87CE01C8D9F0
:100F40000DC080912702813251F48091E800877FA3
:100F50008093E800CE0160912902C5DEECDADF91D2
:100F6000CF910895A1E21A2EAA1BBB1BFD010DC053
:100F7000AA1FBB1FEE1FFF1FA217B307E407F50749
:100F800020F0A21BB30BE40BF50B661F771F881F25
:100F9000991F1A9469F760957095809590959B01BB
:0C0FA000AC01BD01CF010895F894FFCF13
:100FAC0000034000000440000002080000000000A4
:060FBC000000000000002F
:00000001FF

View File

@ -0,0 +1,254 @@
:1000000090C00000A9C00000A7C00000A5C000006B
:10001000A3C00000A1C000009FC000009DC0000060
:100020009BC0000099C0000097C0000048C40000B9
:100030000CC4000091C000008FC000008DC0000003
:100040008BC0000089C0000087C0000085C0000090
:1000500083C0000081C000007FC0000002C100001A
:100060007BC0000079C0000077C0000075C00000B0
:1000700073C0000071C000006FC000006DC00000C0
:100080006BC0000069C0000067C0000065C00000D0
:1000900063C0000061C000001201100102000008EE
:1000A0004123440001000102DC0109023E0002017B
:1000B00000C0320904000001020201000524000111
:1000C0001004240206052406000107058203080027
:1000D000FF09040100020A000000070504024000B5
:1000E00001070583024000010403090432034100B3
:1000F00072006400750069006E006F002000280027
:100100007700770077002E006100720064007500B0
:1001100069006E006F002E0063006300290000007C
:10012000000011241FBECFEFD2E0DEBFCDBF11E033
:10013000A0E0B1E0ECEAFFE002C005900D92A6312C
:10014000B107D9F712E0A6E1B1E001C01D92AF32CC
:10015000B107E1F7F1D028C753CF9C01DC01AE57BE
:10016000BF4FED91FC91119741911196FC93EE9345
:1001700080589F4FE817F90711F42D933C939FB7D0
:10018000F894F901EC57FF4F8081815080839FBF25
:10019000842F0895DF92EF92FF920F931F93FC013B
:1001A0008489813019F0823021F405C040E3D42ED7
:1001B00004C0DD2402C030E2D32E8389823011F4E2
:1001C00088E0D82A8589873031F0883031F0863050
:1001D00031F482E003C084E001C086E0D82A1092A6
:1001E000C9001092C8001092CA00E784F088018903
:1001F000128980E0E81681EEF80680E0080780E0CA
:10020000180719F420E130E00FC0C801B701969536
:1002100087957795679560587B47814E9F4FA801DA
:100220009701A0D6215030403093CD002093CC00D0
:10023000D092CA0080E0E81681EEF80680E0080758
:1002400080E0180711F082E001C080E08093C800D0
:1002500088E98093C9001F910F91FF90EF90DF9084
:1002600008951F920F920FB60F9211242F938F9320
:100270009F93EF93FF939091CE008EB38430F1F46F
:10028000E0919901F0919A019083E0919901F091A8
:100290009A01CF01019690939A018093990189590F
:1002A000914021F489E191E0928381839FB7F89492
:1002B00080919D018F5F80939D019FBFFF91EF9182
:1002C0009F918F912F910F900FBE0F901F901895B7
:1002D000FC01858580FF02C05F9808955F9A0895AC
:1002E00080E091E0D5C580E091E088C584B7877F44
:1002F00084BF28E10FB6F89420936000109260004C
:100300000FBE87E690E09093CD008093CC0086E00E
:100310008093CA001092C8002093C900539A5A9A39
:100320008AB180638AB98BB180638BB983D284E050
:1003300085BD5F9A579A08950F931F93CF93DF93CC
:10034000D5DF2FB7F8948EE991E090931F02809348
:100350001E0290932102809320022FBF2FB7F894A2
:1003600089E191E090939A018093990190939C0187
:1003700080939B012FBF7894CEE9D1E003E08FB743
:10038000F894909122028FBF903809F180E091E0BB
:10039000ABD497FD1CC0E0911E02F0911F02808338
:1003A000E0911E02F0911F02CF01019690931F026F
:1003B00080931E028E51924011F4D283C1839FB765
:1003C000F894809122028F5F809322029FBF8FB7A3
:1003D000F89410919D018FBFA89902C0113678F151
:1003E000A89A80919D01882361F05D980093160181
:1003F00008C089E191E0B1DE682F80E091E0DAD4B5
:1004000011501123B1F780911601882351F080918A
:10041000160181508093160180911601882309F4FA
:100420005D9A80911701882351F0809117018150C6
:100430008093170180911701882309F45C9A8FB784
:10044000F894909122028FBF992369F08EE991E090
:1004500084DE982F8091C80085FFFCCF9093CE005A
:100460005C980093170180E091E095D42AD487CF5F
:10047000DA01923049F0933061F09130F9F4E8E913
:10048000F0E022E130E01EC0EAEAF0E02EE330E0E6
:1004900019C0813049F0813018F0823079F408C0F9
:1004A000E8EEF0E0849107C0ECEEF0E0849103C048
:1004B000E0E2F1E08491282F30E004C0E0E0F0E0D9
:1004C00020E030E0ED93FC93C901089528E030E08E
:1004D00040E003C04F5F220F331F28173907D0F3C6
:1004E000842F8295807F08958093E9008091EB00AE
:1004F00081608093EB001092ED006093EC004093DC
:10050000ED008091EE00881F8827881F08951092C3
:10051000F40090E09093E9001092F0001092E8004F
:100520001092ED008091EB008E7F8093EB009F5F37
:10053000953081F708958091270288238CF403C0B9
:100540008EB38823B1F08091E80082FFF9CF8091CB
:10055000E8008B778093E80008958EB3882349F0F4
:100560008091E80080FFF9CF8091E8008E7780933A
:10057000E800089594E68091EC0080FF05C080912A
:10058000E80080FF05C023C08091E80082FD1FC005
:100590008EB3882311F482E008958EB3853011F470
:1005A00083E008958091EB0085FF02C081E008950B
:1005B0008091E10082FFDFCF8091E1008B7F80930B
:1005C000E100992311F484E008959150D4CF80E0A4
:1005D00008959C0140912D0250912E024617570715
:1005E00018F4F90120E038C06115710511F0AB0174
:1005F000F8CF8091E8008E778093E80040E050E0EB
:10060000F0CF8091E80083FF02C081E008958091DF
:10061000E80082FD2DC08EB3882381F18EB3853032
:1006200079F18091E80080FF17C09091F20006C038
:1006300081918093F100415050409F5F41155105D9
:1006400011F09830A8F320E0983009F421E080916F
:10065000E8008E778093E8004115510591F622233A
:1006600081F606C08EB3882349F08EB3853041F001
:100670008091E80082FFF6CF80E0089582E008953F
:1006800083E008959C0140912D0250912E0246175F
:10069000570710F490E03BC06115710511F0AB01F4
:1006A000F9CF8091E8008E778093E80040E050E039
:1006B000F1CF8091E80083FF02C081E0089580912E
:1006C000E80082FD30C08EB3882399F18EB3853067
:1006D00091F18091E80080FF1AC08091F20009C07A
:1006E000F9012F5F3F4FE491E093F10041505040FA
:1006F0008F5F4115510511F0883090F390E08830FC
:1007000009F491E08091E8008E778093E80041152C
:10071000510579F6992369F606C08EB3882349F00E
:100720008EB3853041F08091E80082FFF6CF80E003
:10073000089582E0089583E008959C016115710594
:1007400029F48091E8008B778093E800F90120C0BC
:100750008091E80083FF02C081E008958EB3882372
:1007600039F18EB3853031F18091E80082FFF0CF0E
:1007700006C08091F10081936150704021F080911A
:10078000F2008823B1F78091E8008B778093E8002E
:1007900061157105E9F606C08EB3882349F08EB362
:1007A000853041F08091E80080FFF6CF80E0089529
:1007B00082E0089583E0089542D044D01EBA10929A
:1007C0002502109224021092230284E089BD89B58B
:1007D000826089BD09B400FEFDCF8091D800982FBA
:1007E0009F779093D80080688093D80080916300B1
:1007F0008E7F809363008091D8008F7D8093D80096
:100800008091E0008E7F8093E0008091E1008E7FF8
:100810008093E1008091E20081608093E20080910A
:10082000E100877F8093E1008091E20088608093FF
:10083000E2000895C1DF81E08093260208951092BE
:10084000E20008951092E10008951F920F920FB6F2
:100850000F9211241F932F933F934F935F936F93A6
:100860007F938F939F93AF93BF93EF93FF93E9EEA3
:10087000F0E0108117701082E0EFF0E08081877F58
:1008800080837894C3D0F894A9EEB0E01C92E0EF96
:10089000F0E08081886080831C93FF91EF91BF918D
:1008A000AF919F918F917F916F915F914F913F9108
:1008B0002F911F910F900FBE0F901F9018951F92B0
:1008C0000F920FB60F9211242F933F934F935F9384
:1008D0006F937F938F939F93AF93BF93EF93FF9308
:1008E0008091E10080FF1BC08091E20080FF17C073
:1008F0008091E1008E7F8093E1008091E2008E7F05
:100900008093E2008091E20080618093E200809118
:10091000D80080628093D80019BC1EBAD1D18091D2
:10092000E10084FF29C08091E20084FF25C084E0BB
:1009300089BD89B5826089BD09B400FEFDCF809173
:10094000D8008F7D8093D8008091E1008F7E8093C6
:10095000E1008091E2008F7E8093E2008091E200CE
:1009600081608093E20080912502882311F481E068
:1009700001C084E08EBBA4D18091E10083FF27C039
:100980008091E20083FF23C08091E100877F809304
:10099000E10082E08EBB109225028091E1008E7F03
:1009A0008093E1008091E2008E7F8093E20080914D
:1009B000E20080618093E200AADD80E060E042E036
:1009C00093DD8091F00088608093F00079D1809170
:1009D000E10082FF0AC08091E20082FF06C08091A0
:1009E000E1008B7F8093E1006BD1FF91EF91BF918C
:1009F000AF919F918F917F916F915F914F913F91B7
:100A00002F910F900FBE0F901F9018951F93DF939B
:100A1000CF93CDB7DEB7AC970FB6F894DEBF0FBE5D
:100A2000CDBFE7E2F2E08091F100819322E0EF3266
:100A3000F207C9F78091270230912802353009F476
:100A400087C0363040F43130C9F1313070F0333086
:100A500009F01DC133C0383009F4EFC0393009F452
:100A6000FEC0363009F013C192C0803821F08238C0
:100A700009F00DC108C090912302809124028823BF
:100A800099F0926011C080912B0287708093E900E9
:100A90008091EB0090E025E0969587952A95E1F707
:100AA000982F91701092E9008091E800877F8093E1
:100AB000E8009093F1001092F100CAC0882319F069
:100AC000823009F0E4C090E08F719070009721F0BF
:100AD000029709F0DDC00CC080912902813009F035
:100AE000D7C010922402333069F5809324022AC0C3
:100AF00080912902882331F520912B02277009F477
:100B0000C7C02093E9008091EB0080FFC1C0333063
:100B100021F48091EB00806213C08091EB00806132
:100B20008093EB0081E090E002C0880F991F2A9526
:100B3000E2F78093EA001092EA008091EB0088606F
:100B40008093EB001092E9008091E800877F83C0DA
:100B5000882309F09CC0109129028091E800877FCA
:100B60008093E800E8DC04C08EB3882309F490C0C9
:100B70008091E80080FFF8CF812F8F7711F492E009
:100B800001C093E09EBB80688093E30081C08058E1
:100B9000823008F07CC08091290290912A0223E0E3
:100BA0008C3D920799F55FB7F894DE0115964EE0FB
:100BB00020E030E061E2E42FF0E0609357008491A0
:100BC00020FF03C082958F704F5F982F9F70892FF1
:100BD000805D8A3308F0895F8C9311961C9211977F
:100BE0002F5F3F4F12962431310529F75FBF8AE20C
:100BF0008B8383E08C838091E800877F8093E8007B
:100C0000CE0103966AE270E0E4DC11C060912B0231
:100C1000AE014F5F5F4F2CDCBC010097C9F18091A2
:100C2000E800877F8093E80089819A812BDD80919D
:100C3000E8008B778093E8002BC0803841F58091E5
:100C4000E800877F8093E800809125028093F1007F
:100C50008091E8008E778093E8006DDC19C08823CE
:100C6000B1F490912902923098F48091E800877F46
:100C70008093E800909325025EDC80912502882312
:100C800011F483E001C084E08EBB2DDB01C028DBC2
:100C90008091E80083FF0AC08091EB00806280931E
:100CA000EB008091E800877F8093E800AC960FB658
:100CB000F894DEBF0FBECDBFCF91DF911F91089595
:100CC00008951F938EB3882361F01091E90010926C
:100CD000E9008091E80083FF01C098DE177010934F
:100CE000E9001F9108950895FC018EB3843021F529
:100CF00087859089A189B2890097A105B105E1F0A6
:100D000085818093E9008091E80082FF15C0809181
:100D1000F200882319F42FEF3FEF04C08091F10017
:100D2000282F30E08091F200882341F48091E80080
:100D30008B778093E80002C02FEF3FEFC901089541
:100D4000FC018EB3843011F587859089A189B28921
:100D50000097A105B105D1F081818093E9008091D0
:100D6000F2008823A9F09091E8008091E8008E7746
:100D70008093E80095FD0CC0FDDB982F882349F493
:100D80008091E8008E778093E80003C092E001C074
:100D900090E0892F0895FC018EB3843051F487854B
:100DA0009089A189B2890097A105B10511F0CF0101
:100DB000C7CF08951F93FC01162F8EB38430D9F44A
:100DC00087859089A189B2890097A105B10599F01D
:100DD00081818093E9008091E80085FD08C08091C1
:100DE000E8008E778093E800C5DB882329F4109310
:100DF000F10080E001C082E01F9108950F931F93DE
:100E0000CF93DF93EC010D96FC0189E0DF011D9289
:100E10008A95E9F72A813B8109818C81882311F425
:100E200010E001C014E0C90151DB182B1260802FC3
:100E300061E8412F59DB882329F12E813F810D8103
:100E40008885882311F410E001C014E0C9013EDB5D
:100E5000182B1260802F60E8412F46DB882391F029
:100E60002A853B8509858C85882311F410E001C013
:100E700014E0C9012BDB182B1260802F61EC412F8D
:100E800033DB01C080E0DF91CF911F910F91089576
:100E9000CF93DF93EC018091E80083FF60C08881ED
:100EA00090E020912B0230912C022817390709F08D
:100EB00056C080912802813261F0823220F4803263
:100EC00009F04DC019C0823269F1833209F047C080
:100ED00038C080912702813A09F041C08091E80032
:100EE000877F8093E800CE010F9667E070E071DBAA
:100EF0008091E8008B7713C080912702813279F5C9
:100F00008091E800877F8093E800CE010F9667E02C
:100F100070E013DCCE013ED98091E8008E7780939B
:100F2000E8001DC0809127028132C9F48091E80059
:100F3000877F8093E800809129028D87CE01C8D9F0
:100F40000DC080912702813251F48091E800877FA3
:100F50008093E800CE0160912902C5DEECDADF91D2
:100F6000CF910895A1E21A2EAA1BBB1BFD010DC053
:100F7000AA1FBB1FEE1FFF1FA217B307E407F50749
:100F800020F0A21BB30BE40BF50B661F771F881F25
:100F9000991F1A9469F760957095809590959B01BB
:0C0FA000AC01BD01CF010895F894FFCF13
:100FAC0000034000000440000002080000000000A4
:060FBC000000000000002F
:00000001FF

View File

@ -0,0 +1,254 @@
:1000000090C00000A9C00000A7C00000A5C000006B
:10001000A3C00000A1C000009FC000009DC0000060
:100020009BC0000099C0000097C0000048C40000B9
:100030000CC4000091C000008FC000008DC0000003
:100040008BC0000089C0000087C0000085C0000090
:1000500083C0000081C000007FC0000002C100001A
:100060007BC0000079C0000077C0000075C00000B0
:1000700073C0000071C000006FC000006DC00000C0
:100080006BC0000069C0000067C0000065C00000D0
:1000900063C0000061C000001201100102000008EE
:1000A0004123430001000102DC0109023E0002017C
:1000B00000C0320904000001020201000524000111
:1000C0001004240206052406000107058203080027
:1000D000FF09040100020A000000070504024000B5
:1000E00001070583024000010403090432034100B3
:1000F00072006400750069006E006F002000280027
:100100007700770077002E006100720064007500B0
:1001100069006E006F002E0063006300290000007C
:10012000000011241FBECFEFD2E0DEBFCDBF11E033
:10013000A0E0B1E0ECEAFFE002C005900D92A6312C
:10014000B107D9F712E0A6E1B1E001C01D92AF32CC
:10015000B107E1F7F1D028C753CF9C01DC01AE57BE
:10016000BF4FED91FC91119741911196FC93EE9345
:1001700080589F4FE817F90711F42D933C939FB7D0
:10018000F894F901EC57FF4F8081815080839FBF25
:10019000842F0895DF92EF92FF920F931F93FC013B
:1001A0008489813019F0823021F405C040E3D42ED7
:1001B00004C0DD2402C030E2D32E8389823011F4E2
:1001C00088E0D82A8589873031F0883031F0863050
:1001D00031F482E003C084E001C086E0D82A1092A6
:1001E000C9001092C8001092CA00E784F088018903
:1001F000128980E0E81681EEF80680E0080780E0CA
:10020000180719F420E130E00FC0C801B701969536
:1002100087957795679560587B47814E9F4FA801DA
:100220009701A0D6215030403093CD002093CC00D0
:10023000D092CA0080E0E81681EEF80680E0080758
:1002400080E0180711F082E001C080E08093C800D0
:1002500088E98093C9001F910F91FF90EF90DF9084
:1002600008951F920F920FB60F9211242F938F9320
:100270009F93EF93FF939091CE008EB38430F1F46F
:10028000E0919901F0919A019083E0919901F091A8
:100290009A01CF01019690939A018093990189590F
:1002A000914021F489E191E0928381839FB7F89492
:1002B00080919D018F5F80939D019FBFFF91EF9182
:1002C0009F918F912F910F900FBE0F901F901895B7
:1002D000FC01858580FF02C05F9808955F9A0895AC
:1002E00080E091E0D5C580E091E088C584B7877F44
:1002F00084BF28E10FB6F89420936000109260004C
:100300000FBE87E690E09093CD008093CC0086E00E
:100310008093CA001092C8002093C900539A5A9A39
:100320008AB180638AB98BB180638BB983D284E050
:1003300085BD5F9A579A08950F931F93CF93DF93CC
:10034000D5DF2FB7F8948EE991E090931F02809348
:100350001E0290932102809320022FBF2FB7F894A2
:1003600089E191E090939A018093990190939C0187
:1003700080939B012FBF7894CEE9D1E003E08FB743
:10038000F894909122028FBF903809F180E091E0BB
:10039000ABD497FD1CC0E0911E02F0911F02808338
:1003A000E0911E02F0911F02CF01019690931F026F
:1003B00080931E028E51924011F4D283C1839FB765
:1003C000F894809122028F5F809322029FBF8FB7A3
:1003D000F89410919D018FBFA89902C0113678F151
:1003E000A89A80919D01882361F05D980093160181
:1003F00008C089E191E0B1DE682F80E091E0DAD4B5
:1004000011501123B1F780911601882351F080918A
:10041000160181508093160180911601882309F4FA
:100420005D9A80911701882351F0809117018150C6
:100430008093170180911701882309F45C9A8FB784
:10044000F894909122028FBF992369F08EE991E090
:1004500084DE982F8091C80085FFFCCF9093CE005A
:100460005C980093170180E091E095D42AD487CF5F
:10047000DA01923049F0933061F09130F9F4E8E913
:10048000F0E022E130E01EC0EAEAF0E02EE330E0E6
:1004900019C0813049F0813018F0823079F408C0F9
:1004A000E8EEF0E0849107C0ECEEF0E0849103C048
:1004B000E0E2F1E08491282F30E004C0E0E0F0E0D9
:1004C00020E030E0ED93FC93C901089528E030E08E
:1004D00040E003C04F5F220F331F28173907D0F3C6
:1004E000842F8295807F08958093E9008091EB00AE
:1004F00081608093EB001092ED006093EC004093DC
:10050000ED008091EE00881F8827881F08951092C3
:10051000F40090E09093E9001092F0001092E8004F
:100520001092ED008091EB008E7F8093EB009F5F37
:10053000953081F708958091270288238CF403C0B9
:100540008EB38823B1F08091E80082FFF9CF8091CB
:10055000E8008B778093E80008958EB3882349F0F4
:100560008091E80080FFF9CF8091E8008E7780933A
:10057000E800089594E68091EC0080FF05C080912A
:10058000E80080FF05C023C08091E80082FD1FC005
:100590008EB3882311F482E008958EB3853011F470
:1005A00083E008958091EB0085FF02C081E008950B
:1005B0008091E10082FFDFCF8091E1008B7F80930B
:1005C000E100992311F484E008959150D4CF80E0A4
:1005D00008959C0140912D0250912E024617570715
:1005E00018F4F90120E038C06115710511F0AB0174
:1005F000F8CF8091E8008E778093E80040E050E0EB
:10060000F0CF8091E80083FF02C081E008958091DF
:10061000E80082FD2DC08EB3882381F18EB3853032
:1006200079F18091E80080FF17C09091F20006C038
:1006300081918093F100415050409F5F41155105D9
:1006400011F09830A8F320E0983009F421E080916F
:10065000E8008E778093E8004115510591F622233A
:1006600081F606C08EB3882349F08EB3853041F001
:100670008091E80082FFF6CF80E0089582E008953F
:1006800083E008959C0140912D0250912E0246175F
:10069000570710F490E03BC06115710511F0AB01F4
:1006A000F9CF8091E8008E778093E80040E050E039
:1006B000F1CF8091E80083FF02C081E0089580912E
:1006C000E80082FD30C08EB3882399F18EB3853067
:1006D00091F18091E80080FF1AC08091F20009C07A
:1006E000F9012F5F3F4FE491E093F10041505040FA
:1006F0008F5F4115510511F0883090F390E08830FC
:1007000009F491E08091E8008E778093E80041152C
:10071000510579F6992369F606C08EB3882349F00E
:100720008EB3853041F08091E80082FFF6CF80E003
:10073000089582E0089583E008959C016115710594
:1007400029F48091E8008B778093E800F90120C0BC
:100750008091E80083FF02C081E008958EB3882372
:1007600039F18EB3853031F18091E80082FFF0CF0E
:1007700006C08091F10081936150704021F080911A
:10078000F2008823B1F78091E8008B778093E8002E
:1007900061157105E9F606C08EB3882349F08EB362
:1007A000853041F08091E80080FFF6CF80E0089529
:1007B00082E0089583E0089542D044D01EBA10929A
:1007C0002502109224021092230284E089BD89B58B
:1007D000826089BD09B400FEFDCF8091D800982FBA
:1007E0009F779093D80080688093D80080916300B1
:1007F0008E7F809363008091D8008F7D8093D80096
:100800008091E0008E7F8093E0008091E1008E7FF8
:100810008093E1008091E20081608093E20080910A
:10082000E100877F8093E1008091E20088608093FF
:10083000E2000895C1DF81E08093260208951092BE
:10084000E20008951092E10008951F920F920FB6F2
:100850000F9211241F932F933F934F935F936F93A6
:100860007F938F939F93AF93BF93EF93FF93E9EEA3
:10087000F0E0108117701082E0EFF0E08081877F58
:1008800080837894C3D0F894A9EEB0E01C92E0EF96
:10089000F0E08081886080831C93FF91EF91BF918D
:1008A000AF919F918F917F916F915F914F913F9108
:1008B0002F911F910F900FBE0F901F9018951F92B0
:1008C0000F920FB60F9211242F933F934F935F9384
:1008D0006F937F938F939F93AF93BF93EF93FF9308
:1008E0008091E10080FF1BC08091E20080FF17C073
:1008F0008091E1008E7F8093E1008091E2008E7F05
:100900008093E2008091E20080618093E200809118
:10091000D80080628093D80019BC1EBAD1D18091D2
:10092000E10084FF29C08091E20084FF25C084E0BB
:1009300089BD89B5826089BD09B400FEFDCF809173
:10094000D8008F7D8093D8008091E1008F7E8093C6
:10095000E1008091E2008F7E8093E2008091E200CE
:1009600081608093E20080912502882311F481E068
:1009700001C084E08EBBA4D18091E10083FF27C039
:100980008091E20083FF23C08091E100877F809304
:10099000E10082E08EBB109225028091E1008E7F03
:1009A0008093E1008091E2008E7F8093E20080914D
:1009B000E20080618093E200AADD80E060E042E036
:1009C00093DD8091F00088608093F00079D1809170
:1009D000E10082FF0AC08091E20082FF06C08091A0
:1009E000E1008B7F8093E1006BD1FF91EF91BF918C
:1009F000AF919F918F917F916F915F914F913F91B7
:100A00002F910F900FBE0F901F9018951F93DF939B
:100A1000CF93CDB7DEB7AC970FB6F894DEBF0FBE5D
:100A2000CDBFE7E2F2E08091F100819322E0EF3266
:100A3000F207C9F78091270230912802353009F476
:100A400087C0363040F43130C9F1313070F0333086
:100A500009F01DC133C0383009F4EFC0393009F452
:100A6000FEC0363009F013C192C0803821F08238C0
:100A700009F00DC108C090912302809124028823BF
:100A800099F0926011C080912B0287708093E900E9
:100A90008091EB0090E025E0969587952A95E1F707
:100AA000982F91701092E9008091E800877F8093E1
:100AB000E8009093F1001092F100CAC0882319F069
:100AC000823009F0E4C090E08F719070009721F0BF
:100AD000029709F0DDC00CC080912902813009F035
:100AE000D7C010922402333069F5809324022AC0C3
:100AF00080912902882331F520912B02277009F477
:100B0000C7C02093E9008091EB0080FFC1C0333063
:100B100021F48091EB00806213C08091EB00806132
:100B20008093EB0081E090E002C0880F991F2A9526
:100B3000E2F78093EA001092EA008091EB0088606F
:100B40008093EB001092E9008091E800877F83C0DA
:100B5000882309F09CC0109129028091E800877FCA
:100B60008093E800E8DC04C08EB3882309F490C0C9
:100B70008091E80080FFF8CF812F8F7711F492E009
:100B800001C093E09EBB80688093E30081C08058E1
:100B9000823008F07CC08091290290912A0223E0E3
:100BA0008C3D920799F55FB7F894DE0115964EE0FB
:100BB00020E030E061E2E42FF0E0609357008491A0
:100BC00020FF03C082958F704F5F982F9F70892FF1
:100BD000805D8A3308F0895F8C9311961C9211977F
:100BE0002F5F3F4F12962431310529F75FBF8AE20C
:100BF0008B8383E08C838091E800877F8093E8007B
:100C0000CE0103966AE270E0E4DC11C060912B0231
:100C1000AE014F5F5F4F2CDCBC010097C9F18091A2
:100C2000E800877F8093E80089819A812BDD80919D
:100C3000E8008B778093E8002BC0803841F58091E5
:100C4000E800877F8093E800809125028093F1007F
:100C50008091E8008E778093E8006DDC19C08823CE
:100C6000B1F490912902923098F48091E800877F46
:100C70008093E800909325025EDC80912502882312
:100C800011F483E001C084E08EBB2DDB01C028DBC2
:100C90008091E80083FF0AC08091EB00806280931E
:100CA000EB008091E800877F8093E800AC960FB658
:100CB000F894DEBF0FBECDBFCF91DF911F91089595
:100CC00008951F938EB3882361F01091E90010926C
:100CD000E9008091E80083FF01C098DE177010934F
:100CE000E9001F9108950895FC018EB3843021F529
:100CF00087859089A189B2890097A105B105E1F0A6
:100D000085818093E9008091E80082FF15C0809181
:100D1000F200882319F42FEF3FEF04C08091F10017
:100D2000282F30E08091F200882341F48091E80080
:100D30008B778093E80002C02FEF3FEFC901089541
:100D4000FC018EB3843011F587859089A189B28921
:100D50000097A105B105D1F081818093E9008091D0
:100D6000F2008823A9F09091E8008091E8008E7746
:100D70008093E80095FD0CC0FDDB982F882349F493
:100D80008091E8008E778093E80003C092E001C074
:100D900090E0892F0895FC018EB3843051F487854B
:100DA0009089A189B2890097A105B10511F0CF0101
:100DB000C7CF08951F93FC01162F8EB38430D9F44A
:100DC00087859089A189B2890097A105B10599F01D
:100DD00081818093E9008091E80085FD08C08091C1
:100DE000E8008E778093E800C5DB882329F4109310
:100DF000F10080E001C082E01F9108950F931F93DE
:100E0000CF93DF93EC010D96FC0189E0DF011D9289
:100E10008A95E9F72A813B8109818C81882311F425
:100E200010E001C014E0C90151DB182B1260802FC3
:100E300061E8412F59DB882329F12E813F810D8103
:100E40008885882311F410E001C014E0C9013EDB5D
:100E5000182B1260802F60E8412F46DB882391F029
:100E60002A853B8509858C85882311F410E001C013
:100E700014E0C9012BDB182B1260802F61EC412F8D
:100E800033DB01C080E0DF91CF911F910F91089576
:100E9000CF93DF93EC018091E80083FF60C08881ED
:100EA00090E020912B0230912C022817390709F08D
:100EB00056C080912802813261F0823220F4803263
:100EC00009F04DC019C0823269F1833209F047C080
:100ED00038C080912702813A09F041C08091E80032
:100EE000877F8093E800CE010F9667E070E071DBAA
:100EF0008091E8008B7713C080912702813279F5C9
:100F00008091E800877F8093E800CE010F9667E02C
:100F100070E013DCCE013ED98091E8008E7780939B
:100F2000E8001DC0809127028132C9F48091E80059
:100F3000877F8093E800809129028D87CE01C8D9F0
:100F40000DC080912702813251F48091E800877FA3
:100F50008093E800CE0160912902C5DEECDADF91D2
:100F6000CF910895A1E21A2EAA1BBB1BFD010DC053
:100F7000AA1FBB1FEE1FFF1FA217B307E407F50749
:100F800020F0A21BB30BE40BF50B661F771F881F25
:100F9000991F1A9469F760957095809590959B01BB
:0C0FA000AC01BD01CF010895F894FFCF13
:100FAC0000034000000440000002080000000000A4
:060FBC000000000000002F
:00000001FF

View File

@ -0,0 +1,256 @@
:10000000A2C00000BBC00000B9C00000B7C0000023
:10001000B5C00000B3C00000B1C00000AFC0000018
:10002000ADC00000ABC00000A9C000005AC4000071
:100030001EC40000A3C00000A1C000009FC00000BB
:100040009DC000009BC0000099C0000097C0000048
:1000500095C0000093C0000091C0000014C10000D2
:100060008DC000008BC0000089C0000087C0000068
:1000700085C0000083C0000081C000007FC0000078
:100080007DC000007BC0000079C0000077C0000088
:1000900075C0000073C000001201100102000008CA
:1000A0004123100001000102DC0109023E000201AF
:1000B00000C0320904000001020201000524000111
:1000C0001004240206052406000107058203080027
:1000D000FF09040100020A000000070504024000B5
:1000E00001070583024000010403090432034100B3
:1000F00072006400750069006E006F002000280027
:100100007700770077002E006100720064007500B0
:1001100069006E006F002E0063006300290000007C
:100120002403410072006400750069006E006F00D6
:1001300020004D006500670061002000320035009E
:1001400036003000000011241FBECFEFD2E0DEBF2A
:10015000CDBF11E0A0E0B1E0E0EDFFE002C005900E
:100160000D92A631B107D9F712E0A6E1B1E001C0C6
:100170001D92AF32B107E1F7F1D028C741CF9C0102
:10018000DC01AE57BF4FED91FC9111974191119653
:10019000FC93EE9380589F4FE817F90711F42D93C5
:1001A0003C939FB7F894F901EC57FF4F8081815041
:1001B00080839FBF842F0895DF92EF92FF920F9369
:1001C0001F93FC018489813019F0823021F405C02D
:1001D00040E3D42E04C0DD2402C030E2D32E838954
:1001E000823011F488E0D82A8589873031F0883050
:1001F00031F0863031F482E003C084E001C086E053
:10020000D82A1092C9001092C8001092CA00E78440
:10021000F0880189128980E0E81681EEF80680E016
:10022000080780E0180719F420E130E00FC0C8018A
:10023000B701969587957795679560587B47814E6E
:100240009F4FA8019701A0D6215030403093CD0098
:100250002093CC00D092CA0080E0E81681EEF80628
:1002600080E0080780E0180711F082E001C080E01C
:100270008093C80088E98093C9001F910F91FF9077
:10028000EF90DF9008951F920F920FB60F921124F6
:100290002F938F939F93EF93FF939091CE008EB304
:1002A0008430F1F4E0919901F0919A019083E0910A
:1002B0009901F0919A01CF01019690939A01809350
:1002C00099018959914021F489E191E092838183D8
:1002D0009FB7F89480919D018F5F80939D019FBF90
:1002E000FF91EF919F918F912F910F900FBE0F90E3
:1002F0001F901895FC01858580FF02C05F980895C6
:100300005F9A089580E091E0D5C580E091E088C5CE
:1003100084B7877F84BF28E10FB6F89420936000EC
:10032000109260000FBE87E690E09093CD0080931E
:10033000CC0086E08093CA001092C8002093C900C8
:10034000539A5A9A8AB180638AB98BB180638BB908
:1003500083D284E085BD5F9A579A08950F931F93C7
:10036000CF93DF93D5DF2FB7F8948EE991E0909388
:100370001F0280931E0290932102809320022FBFC0
:100380002FB7F89489E191E090939A0180939901B5
:1003900090939C0180939B012FBF7894CEE9D1E08C
:1003A00003E08FB7F894909122028FBF903809F143
:1003B00080E091E0ABD497FD1CC0E0911E02F0916B
:1003C0001F028083E0911E02F0911F02CF0101966F
:1003D00090931F0280931E028E51924011F4D2839B
:1003E000C1839FB7F894809122028F5F809322028D
:1003F0009FBF8FB7F89410919D018FBFA89902C03D
:10040000113678F1A89A80919D01882361F05D985A
:100410000093160108C089E191E0B1DE682F80E009
:1004200091E0DAD411501123B1F78091160188239D
:1004300051F0809116018150809316018091160130
:10044000882309F45D9A80911701882351F08091E7
:10045000170181508093170180911701882309F4B7
:100460005C9A8FB7F894909122028FBF992369F01C
:100470008EE991E084DE982F8091C80085FFFCCF43
:100480009093CE005C980093170180E091E095D4A2
:100490002AD487CFDA01923049F0933061F091305D
:1004A000F9F4E8E9F0E022E130E01EC0EAEAF0E029
:1004B0002EE330E019C0813049F0813018F08230ED
:1004C00079F408C0E8EEF0E0849107C0ECEEF0E0CB
:1004D000849103C0E0E2F1E08491282F30E004C071
:1004E000E0E0F0E020E030E0ED93FC93C9010895F6
:1004F00028E030E040E003C04F5F220F331F281791
:100500003907D0F3842F8295807F08958093E90086
:100510008091EB0081608093EB001092ED0060937E
:10052000EC004093ED008091EE00881F8827881F23
:1005300008951092F40090E09093E9001092F0007A
:100540001092E8001092ED008091EB008E7F809376
:10055000EB009F5F953081F70895809127028823F3
:100560008CF403C08EB38823B1F08091E80082FF41
:10057000F9CF8091E8008B778093E80008958EB3DF
:10058000882349F08091E80080FFF9CF8091E8004E
:100590008E778093E800089594E68091EC0080FFC8
:1005A00005C08091E80080FF05C023C08091E8006D
:1005B00082FD1FC08EB3882311F482E008958EB3AC
:1005C000853011F483E008958091EB0085FF02C02F
:1005D00081E008958091E10082FFDFCF8091E1000A
:1005E0008B7F8093E100992311F484E0089591506A
:1005F000D4CF80E008959C0140912D0250912E02AD
:100600004617570718F4F90120E038C06115710545
:1006100011F0AB01F8CF8091E8008E778093E8006D
:1006200040E050E0F0CF8091E80083FF02C081E01D
:1006300008958091E80082FD2DC08EB3882381F15A
:100640008EB3853079F18091E80080FF17C09091DA
:10065000F20006C081918093F100415050409F5FAD
:100660004115510511F09830A8F320E0983009F4B5
:1006700021E08091E8008E778093E80041155105D4
:1006800091F6222381F606C08EB3882349F08EB3FB
:10069000853041F08091E80082FFF6CF80E0089538
:1006A00082E0089583E008959C0140912D025091CD
:1006B0002E024617570710F490E03BC061157105F4
:1006C00011F0AB01F9CF8091E8008E778093E800BC
:1006D00040E050E0F1CF8091E80083FF02C081E06C
:1006E00008958091E80082FD30C08EB3882399F18F
:1006F0008EB3853091F18091E80080FF1AC080911F
:10070000F20009C0F9012F5F3F4FE491E093F1003F
:10071000415050408F5F4115510511F0883090F3E2
:1007200090E0883009F491E08091E8008E77809322
:10073000E8004115510579F6992369F606C08EB394
:10074000882349F08EB3853041F08091E80082FF24
:10075000F6CF80E0089582E0089583E008959C013B
:100760006115710529F48091E8008B778093E8008A
:10077000F90120C08091E80083FF02C081E0089564
:100780008EB3882339F18EB3853031F18091E80042
:1007900082FFF0CF06C08091F100819361507040DC
:1007A00021F08091F2008823B1F78091E8008B77E7
:1007B0008093E80061157105E9F606C08EB38823C1
:1007C00049F08EB3853041F08091E80080FFF6CF8C
:1007D00080E0089582E0089583E0089542D044D0F7
:1007E0001EBA10922502109224021092230284E075
:1007F00089BD89B5826089BD09B400FEFDCF8091B5
:10080000D800982F9F779093D80080688093D80065
:10081000809163008E7F809363008091D8008F7DEC
:100820008093D8008091E0008E7F8093E0008091DB
:10083000E1008E7F8093E1008091E20081608093EF
:10084000E2008091E100877F8093E1008091E200E7
:1008500088608093E2000895C1DF81E080932602E2
:1008600008951092E20008951092E10008951F92F9
:100870000F920FB60F9211241F932F933F934F9314
:100880005F936F937F938F939F93AF93BF93EF93F8
:10089000FF93E9EEF0E0108117701082E0EFF0E0D6
:1008A0008081877F80837894C3D0F894A9EEB0E0EC
:1008B0001C92E0EFF0E08081886080831C93FF91C0
:1008C000EF91BF91AF919F918F917F916F915F91C8
:1008D0004F913F912F911F910F900FBE0F901F903E
:1008E00018951F920F920FB60F9211242F933F93DA
:1008F0004F935F936F937F938F939F93AF93BF9328
:10090000EF93FF938091E10080FF1BC08091E20094
:1009100080FF17C08091E1008E7F8093E10080917D
:10092000E2008E7F8093E2008091E20080618093FC
:10093000E2008091D80080628093D80019BC1EBA72
:10094000D1D18091E10084FF29C08091E20084FF31
:1009500025C084E089BD89B5826089BD09B400FEE7
:10096000FDCF8091D8008F7D8093D8008091E100E9
:100970008F7E8093E1008091E2008F7E8093E20081
:100980008091E20081608093E200809125028823BB
:1009900011F481E001C084E08EBBA4D18091E1001C
:1009A00083FF27C08091E20083FF23C08091E10094
:1009B000877F8093E10082E08EBB109225028091B8
:1009C000E1008E7F8093E1008091E2008E7F809332
:1009D000E2008091E20080618093E200AADD80E085
:1009E00060E042E093DD8091F00088608093F00049
:1009F00079D18091E10082FF0AC08091E20082FFFC
:100A000006C08091E1008B7F8093E1006BD1FF9164
:100A1000EF91BF91AF919F918F917F916F915F9176
:100A20004F913F912F910F900FBE0F901F901895EF
:100A30001F93DF93CF93CDB7DEB7AC970FB6F89483
:100A4000DEBF0FBECDBFE7E2F2E08091F1008193FF
:100A500022E0EF32F207C9F7809127023091280295
:100A6000353009F487C0363040F43130C9F13130C7
:100A700070F0333009F01DC133C0383009F4EFC0D5
:100A8000393009F4FEC0363009F013C192C0803805
:100A900021F0823809F00DC108C0909123028091A5
:100AA0002402882399F0926011C080912B028770F4
:100AB0008093E9008091EB0090E025E09695879582
:100AC0002A95E1F7982F91701092E9008091E80043
:100AD000877F8093E8009093F1001092F100CAC0E4
:100AE000882319F0823009F0E4C090E08F71907093
:100AF000009721F0029709F0DDC00CC08091290217
:100B0000813009F0D7C010922402333069F5809308
:100B100024022AC080912902882331F520912B02DA
:100B2000277009F4C7C02093E9008091EB0080FF93
:100B3000C1C0333021F48091EB00806213C08091FA
:100B4000EB0080618093EB0081E090E002C0880FB1
:100B5000991F2A95E2F78093EA001092EA008091AB
:100B6000EB0088608093EB001092E9008091E80030
:100B7000877F83C0882309F09CC01091290280914F
:100B8000E800877F8093E800E8DC04C08EB3882308
:100B900009F490C08091E80080FFF8CF812F8F7713
:100BA00011F492E001C093E09EBB80688093E30063
:100BB00081C08058823008F07CC0809129029091D9
:100BC0002A0223E08C3D920799F55FB7F894DE0185
:100BD00015964EE020E030E061E2E42FF0E0609313
:100BE0005700849120FF03C082958F704F5F982F2C
:100BF0009F70892F805D8A3308F0895F8C931196EE
:100C00001C9211972F5F3F4F12962431310529F71F
:100C10005FBF8AE28B8383E08C838091E800877FCB
:100C20008093E800CE0103966AE270E0E4DC11C034
:100C300060912B02AE014F5F5F4F2CDCBC0100972F
:100C4000C9F18091E800877F8093E80089819A81CB
:100C50002BDD8091E8008B778093E8002BC08038F3
:100C600041F58091E800877F8093E800809125021C
:100C70008093F1008091E8008E778093E8006DDC2E
:100C800019C08823B1F490912902923098F4809190
:100C9000E800877F8093E800909325025EDC8091D6
:100CA0002502882311F483E001C084E08EBB2DDB94
:100CB00001C028DB8091E80083FF0AC08091EB002F
:100CC00080628093EB008091E800877F8093E8004A
:100CD000AC960FB6F894DEBF0FBECDBFCF91DF91BB
:100CE0001F91089508951F938EB3882361F010918A
:100CF000E9001092E9008091E80083FF01C098DECE
:100D000017701093E9001F9108950895FC018EB3A8
:100D1000843021F587859089A189B2890097A10542
:100D2000B105E1F085818093E9008091E80082FFC0
:100D300015C08091F200882319F42FEF3FEF04C013
:100D40008091F100282F30E08091F200882341F457
:100D50008091E8008B778093E80002C02FEF3FEF8F
:100D6000C9010895FC018EB3843011F587859089FF
:100D7000A189B2890097A105B105D1F08181809345
:100D8000E9008091F2008823A9F09091E800809119
:100D9000E8008E778093E80095FD0CC0FDDB982F6E
:100DA000882349F48091E8008E778093E80003C09F
:100DB00092E001C090E0892F0895FC018EB3843049
:100DC00051F487859089A189B2890097A105B10561
:100DD00011F0CF01C7CF08951F93FC01162F8EB3DA
:100DE0008430D9F487859089A189B2890097A105BB
:100DF000B10599F081818093E9008091E80085FD3B
:100E000008C08091E8008E778093E800C5DB8823D6
:100E100029F41093F10080E001C082E01F91089551
:100E20000F931F93CF93DF93EC010D96FC0189E0A4
:100E3000DF011D928A95E9F72A813B8109818C8126
:100E4000882311F410E001C014E0C90151DB182B14
:100E50001260802F61E8412F59DB882329F12E8110
:100E60003F810D818885882311F410E001C014E0D2
:100E7000C9013EDB182B1260802F60E8412F46DB52
:100E8000882391F02A853B8509858C85882311F478
:100E900010E001C014E0C9012BDB182B1260802F79
:100EA00061EC412F33DB01C080E0DF91CF911F91D6
:100EB0000F910895CF93DF93EC018091E80083FFB9
:100EC00060C0888190E020912B0230912C0228177D
:100ED000390709F056C080912802813261F08232D0
:100EE00020F4803209F04DC019C0823269F183329A
:100EF00009F047C038C080912702813A09F041C00B
:100F00008091E800877F8093E800CE010F9667E02C
:100F100070E071DB8091E8008B7713C0809127022D
:100F2000813279F58091E800877F8093E800CE01D7
:100F30000F9667E070E013DCCE013ED98091E800A7
:100F40008E778093E8001DC0809127028132C9F41A
:100F50008091E800877F8093E800809129028D8747
:100F6000CE01C8D90DC080912702813251F4809101
:100F7000E800877F8093E800CE0160912902C5DEFA
:100F8000ECDADF91CF910895A1E21A2EAA1BBB1BC8
:100F9000FD010DC0AA1FBB1FEE1FFF1FA217B30745
:100FA000E407F50720F0A21BB30BE40BF50B661F5B
:100FB000771F881F991F1A9469F76095709580951F
:100FC00090959B01AC01BD01CF010895F894FFCF2E
:100FD0000003400000044000000208000000000080
:060FE0000000000000000B
:00000001FF

View File

@ -0,0 +1,256 @@
:100000009CC00000B5C00000B3C00000B1C000003B
:10001000AFC00000ADC00000ABC00000A9C0000030
:10002000A7C00000A5C00000A3C0000054C4000089
:1000300018C400009DC000009BC0000099C00000D3
:1000400097C0000095C0000093C0000091C0000060
:100050008FC000008DC000008BC000000EC10000EA
:1000600087C0000085C0000083C0000081C0000080
:100070007FC000007DC000007BC0000079C0000090
:1000800077C0000075C0000073C0000071C00000A0
:100090006FC000006DC000001201100102000008D6
:1000A0004123010001000102DC0109023E000201BE
:1000B00000C0320904000001020201000524000111
:1000C0001004240206052406000107058203080027
:1000D000FF09040100020A000000070504024000B5
:1000E00001070583024000010403090432034100B3
:1000F00072006400750069006E006F002000280027
:100100007700770077002E006100720064007500B0
:1001100069006E006F002E0063006300290000007C
:100120001803410072006400750069006E006F00E2
:10013000200055006E006F00000011241FBECFEF9D
:10014000D2E0DEBFCDBF11E0A0E0B1E0E4ECFFE023
:1001500002C005900D92A631B107D9F712E0A6E1D1
:10016000B1E001C01D92AF32B107E1F7F1D028C76D
:1001700047CF9C01DC01AE57BF4FED91FC91119729
:1001800041911196FC93EE9380589F4FE817F90721
:1001900011F42D933C939FB7F894F901EC57FF4F5E
:1001A0008081815080839FBF842F0895DF92EF92DA
:1001B000FF920F931F93FC018489813019F08230E4
:1001C00021F405C040E3D42E04C0DD2402C030E297
:1001D000D32E8389823011F488E0D82A858987302C
:1001E00031F0883031F0863031F482E003C084E0B1
:1001F00001C086E0D82A1092C9001092C80010925F
:10020000CA00E784F0880189128980E0E81681EE4F
:10021000F80680E0080780E0180719F420E130E0D4
:100220000FC0C801B7019695879577956795605877
:100230007B47814E9F4FA8019701A0D621503040A7
:100240003093CD002093CC00D092CA0080E0E81615
:1002500081EEF80680E0080780E0180711F082E0E0
:1002600001C080E08093C80088E98093C9001F9195
:100270000F91FF90EF90DF9008951F920F920FB6AD
:100280000F9211242F938F939F93EF93FF9390914D
:10029000CE008EB38430F1F4E0919901F0919A018F
:1002A0009083E0919901F0919A01CF01019690938A
:1002B0009A01809399018959914021F489E191E053
:1002C000928381839FB7F89480919D018F5F809383
:1002D0009D019FBFFF91EF919F918F912F910F9063
:1002E0000FBE0F901F901895FC01858580FF02C0FE
:1002F0005F9808955F9A089580E091E0D5C580E009
:1003000091E088C584B7877F84BF28E10FB6F89451
:1003100020936000109260000FBE87E690E09093FB
:10032000CD008093CC0086E08093CA001092C80074
:100330002093C900539A5A9A8AB180638AB98BB1C3
:1003400080638BB983D284E085BD5F9A579A089504
:100350000F931F93CF93DF93D5DF2FB7F8948EE9D8
:1003600091E090931F0280931E029093210280934C
:1003700020022FBF2FB7F89489E191E090939A0162
:100380008093990190939C0180939B012FBF789457
:10039000CEE9D1E003E08FB7F894909122028FBFAD
:1003A000903809F180E091E0ABD497FD1CC0E0915A
:1003B0001E02F0911F028083E0911E02F0911F0245
:1003C000CF01019690931F0280931E028E5192409E
:1003D00011F4D283C1839FB7F894809122028F5F7A
:1003E000809322029FBF8FB7F89410919D018FBF19
:1003F000A89902C0113678F1A89A80919D018823AE
:1004000061F05D980093160108C089E191E0B1DECA
:10041000682F80E091E0DAD411501123B1F7809178
:100420001601882351F080911601815080931601A6
:1004300080911601882309F45D9A80911701882321
:1004400051F080911701815080931701809117011D
:10045000882309F45C9A8FB7F894909122028FBF99
:10046000992369F08EE991E084DE982F8091C8008D
:1004700085FFFCCF9093CE005C980093170180E03D
:1004800091E095D42AD487CFDA01923049F09330A5
:1004900061F09130F9F4E8E9F0E022E130E01EC0CB
:1004A000EAEAF0E02EE330E019C0813049F0813013
:1004B00018F0823079F408C0E8EEF0E0849107C0CB
:1004C000ECEEF0E0849103C0E0E2F1E08491282FAB
:1004D00030E004C0E0E0F0E020E030E0ED93FC9399
:1004E000C901089528E030E040E003C04F5F220FCB
:1004F000331F28173907D0F3842F8295807F089502
:100500008093E9008091EB0081608093EB00109272
:10051000ED006093EC004093ED008091EE00881FA9
:100520008827881F08951092F40090E09093E900C6
:100530001092F0001092E8001092ED008091EB0014
:100540008E7F8093EB009F5F953081F708958091B7
:10055000270288238CF403C08EB38823B1F08091E6
:10056000E80082FFF9CF8091E8008B778093E80064
:1005700008958EB3882349F08091E80080FFF9CF79
:100580008091E8008E778093E800089594E680914A
:10059000EC0080FF05C08091E80080FF05C023C00B
:1005A0008091E80082FD1FC08EB3882311F482E0A1
:1005B00008958EB3853011F483E008958091EB00A7
:1005C00085FF02C081E008958091E10082FFDFCFC6
:1005D0008091E1008B7F8093E100992311F484E006
:1005E00008959150D4CF80E008959C0140912D0250
:1005F00050912E024617570718F4F90120E038C031
:100600006115710511F0AB01F8CF8091E8008E778C
:100610008093E80040E050E0F0CF8091E80083FF55
:1006200002C081E008958091E80082FD2DC08EB364
:10063000882381F18EB3853079F18091E80080FFC5
:1006400017C09091F20006C081918093F100415053
:1006500050409F5F4115510511F09830A8F320E0FC
:10066000983009F421E08091E8008E778093E800CB
:100670004115510591F6222381F606C08EB38823D9
:1006800049F08EB3853041F08091E80082FFF6CFCB
:1006900080E0089582E0089583E008959C014091F0
:1006A0002D0250912E024617570710F490E03BC0E0
:1006B0006115710511F0AB01F9CF8091E8008E77DB
:1006C0008093E80040E050E0F1CF8091E80083FFA4
:1006D00002C081E008958091E80082FD30C08EB3B1
:1006E000882399F18EB3853091F18091E80080FFE5
:1006F0001AC08091F20009C0F9012F5F3F4FE491C9
:10070000E093F100415050408F5F4115510511F0C9
:10071000883090F390E0883009F491E08091E8000F
:100720008E778093E8004115510579F6992369F693
:1007300006C08EB3882349F08EB3853041F0809196
:10074000E80082FFF6CF80E0089582E0089583E01C
:1007500008959C016115710529F48091E8008B775B
:100760008093E800F90120C08091E80083FF02C077
:1007700081E008958EB3882339F18EB3853031F14D
:100780008091E80082FFF0CF06C08091F100819354
:100790006150704021F08091F2008823B1F7809180
:1007A000E8008B778093E80061157105E9F606C0D3
:1007B0008EB3882349F08EB3853041F08091E800F4
:1007C00080FFF6CF80E0089582E0089583E00895E9
:1007D00042D044D01EBA10922502109224021092E8
:1007E000230284E089BD89B5826089BD09B400FE19
:1007F000FDCF8091D800982F9F779093D800806884
:100800008093D800809163008E7F809363008091F5
:10081000D8008F7D8093D8008091E0008E7F8093F8
:10082000E0008091E1008E7F8093E1008091E20002
:1008300081608093E2008091E100877F8093E100F6
:100840008091E20088608093E2000895C1DF81E03A
:100850008093260208951092E20008951092E1001C
:1008600008951F920F920FB60F9211241F932F938A
:100870003F934F935F936F937F938F939F93AF9328
:10088000BF93EF93FF93E9EEF0E0108117701082B1
:10089000E0EFF0E08081877F80837894C3D0F89484
:1008A000A9EEB0E01C92E0EFF0E0808188608083E8
:1008B0001C93FF91EF91BF91AF919F918F917F9189
:1008C0006F915F914F913F912F911F910F900FBEAC
:1008D0000F901F9018951F920F920FB60F92112430
:1008E0002F933F934F935F936F937F938F939F9338
:1008F000AF93BF93EF93FF938091E10080FF1BC004
:100900008091E20080FF17C08091E1008E7F80938C
:10091000E1008091E2008E7F8093E2008091E2000E
:1009200080618093E2008091D80080628093D8003B
:1009300019BC1EBAD1D18091E10084FF29C08091F9
:10094000E20084FF25C084E089BD89B5826089BD4D
:1009500009B400FEFDCF8091D8008F7D8093D80030
:100960008091E1008F7E8093E1008091E2008F7E94
:100970008093E2008091E20081608093E2008091A8
:100980002502882311F481E001C084E08EBBA4D14C
:100990008091E10083FF27C08091E20083FF23C0A4
:1009A0008091E100877F8093E10082E08EBB10920E
:1009B00025028091E1008E7F8093E1008091E2002A
:1009C0008E7F8093E2008091E20080618093E2005C
:1009D000AADD80E060E042E093DD8091F000886075
:1009E0008093F00079D18091E10082FF0AC080916C
:1009F000E20082FF06C08091E1008B7F8093E100DE
:100A00006BD1FF91EF91BF91AF919F918F917F91AA
:100A10006F915F914F913F912F910F900FBE0F906B
:100A20001F9018951F93DF93CF93CDB7DEB7AC9788
:100A30000FB6F894DEBF0FBECDBFE7E2F2E08091C3
:100A4000F100819322E0EF32F207C9F7809127028B
:100A500030912802353009F487C0363040F4313007
:100A6000C9F1313070F0333009F01DC133C0383076
:100A700009F4EFC0393009F4FEC0363009F013C173
:100A800092C0803821F0823809F00DC108C09091E1
:100A9000230280912402882399F0926011C08091F2
:100AA0002B0287708093E9008091EB0090E025E0B5
:100AB000969587952A95E1F7982F91701092E90005
:100AC0008091E800877F8093E8009093F100109276
:100AD000F100CAC0882319F0823009F0E4C090E028
:100AE0008F719070009721F0029709F0DDC00CC063
:100AF00080912902813009F0D7C01092240233304E
:100B000069F5809324022AC080912902882331F557
:100B100020912B02277009F4C7C02093E90080912F
:100B2000EB0080FFC1C0333021F48091EB00806284
:100B300013C08091EB0080618093EB0081E090E036
:100B400002C0880F991F2A95E2F78093EA0010925D
:100B5000EA008091EB0088608093EB001092E9003E
:100B60008091E800877F83C0882309F09CC01091A2
:100B700029028091E800877F8093E800E8DC04C0C8
:100B80008EB3882309F490C08091E80080FFF8CFED
:100B9000812F8F7711F492E001C093E09EBB8068B3
:100BA0008093E30081C08058823008F07CC080913F
:100BB000290290912A0223E08C3D920799F55FB7B4
:100BC000F894DE0115964EE020E030E061E2E42F7B
:100BD000F0E060935700849120FF03C082958F70EE
:100BE0004F5F982F9F70892F805D8A3308F0895F4F
:100BF0008C9311961C9211972F5F3F4F12962431C0
:100C0000310529F75FBF8AE28B8383E08C83809173
:100C1000E800877F8093E800CE0103966AE270E0E7
:100C2000E4DC11C060912B02AE014F5F5F4F2CDC02
:100C3000BC010097C9F18091E800877F8093E800AC
:100C400089819A812BDD8091E8008B778093E80081
:100C50002BC0803841F58091E800877F8093E800C1
:100C6000809125028093F1008091E8008E77809337
:100C7000E8006DDC19C08823B1F49091290292300C
:100C800098F48091E800877F8093E8009093250294
:100C90005EDC80912502882311F483E001C084E0AA
:100CA0008EBB2DDB01C028DB8091E80083FF0AC0EA
:100CB0008091EB0080628093EB008091E800877F59
:100CC0008093E800AC960FB6F894DEBF0FBECDBFA0
:100CD000CF91DF911F91089508951F938EB38823BC
:100CE00061F01091E9001092E9008091E80083FF23
:100CF00001C098DE17701093E9001F9108950895C0
:100D0000FC018EB3843021F587859089A189B28951
:100D10000097A105B105E1F085818093E9008091FC
:100D2000E80082FF15C08091F200882319F42FEFAC
:100D30003FEF04C08091F100282F30E08091F20055
:100D4000882341F48091E8008B778093E80002C00B
:100D50002FEF3FEFC9010895FC018EB3843011F5E8
:100D600087859089A189B2890097A105B105D1F045
:100D700081818093E9008091F2008823A9F090910D
:100D8000E8008091E8008E778093E80095FD0CC024
:100D9000FDDB982F882349F48091E8008E778093BB
:100DA000E80003C092E001C090E0892F0895FC01A3
:100DB0008EB3843051F487859089A189B2890097D8
:100DC000A105B10511F0CF01C7CF08951F93FC0114
:100DD000162F8EB38430D9F487859089A189B28982
:100DE0000097A105B10599F081818093E900809178
:100DF000E80085FD08C08091E8008E778093E800C8
:100E0000C5DB882329F41093F10080E001C082E063
:100E10001F9108950F931F93CF93DF93EC010D96CD
:100E2000FC0189E0DF011D928A95E9F72A813B8167
:100E300009818C81882311F410E001C014E0C901FC
:100E400051DB182B1260802F61E8412F59DB88237A
:100E500029F12E813F810D818885882311F410E0CE
:100E600001C014E0C9013EDB182B1260802F60E83E
:100E7000412F46DB882391F02A853B8509858C85A7
:100E8000882311F410E001C014E0C9012BDB182BFA
:100E90001260802F61EC412F33DB01C080E0DF91D5
:100EA000CF911F910F910895CF93DF93EC01809123
:100EB000E80083FF60C0888190E020912B02309190
:100EC0002C022817390709F056C080912802813278
:100ED00061F0823220F4803209F04DC019C08232B4
:100EE00069F1833209F047C038C080912702813A06
:100EF00009F041C08091E800877F8093E800CE012F
:100F00000F9667E070E071DB8091E8008B7713C08B
:100F100080912702813279F58091E800877F809364
:100F2000E800CE010F9667E070E013DCCE013ED9F9
:100F30008091E8008E778093E8001DC080912702A1
:100F40008132C9F48091E800877F8093E800809126
:100F500029028D87CE01C8D90DC080912702813228
:100F600051F48091E800877F8093E800CE01609182
:100F70002902C5DEECDADF91CF910895A1E21A2EA5
:100F8000AA1BBB1BFD010DC0AA1FBB1FEE1FFF1F2D
:100F9000A217B307E407F50720F0A21BB30BE40B7D
:100FA000F50B661F771F881F991F1A9469F76095C4
:100FB0007095809590959B01AC01BD01CF0108957E
:040FC000F894FFCFD3
:100FC400000340000004400000020800000000008C
:060FD40000000000000017
:00000001FF

View File

@ -0,0 +1,242 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Main source file for the Arduino-usbserial project. This file contains the main tasks of
* the project and is responsible for the initial application hardware configuration.
*/
#include "Arduino-usbserial.h"
/** Circular buffer to hold data from the host before it is sent to the device via the serial port. */
RingBuff_t USBtoUSART_Buffer;
/** Circular buffer to hold data from the serial port before it is sent to the host. */
RingBuff_t USARTtoUSB_Buffer;
/** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */
volatile struct
{
uint8_t TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */
uint8_t RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */
uint8_t PingPongLEDPulse; /**< Milliseconds remaining for enumeration Tx/Rx ping-pong LED pulse */
} PulseMSRemaining;
/** LUFA CDC Class driver interface configuration and state information. This structure is
* passed to all CDC Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another.
*/
USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface =
{
.Config =
{
.ControlInterfaceNumber = 0,
.DataINEndpointNumber = CDC_TX_EPNUM,
.DataINEndpointSize = CDC_TXRX_EPSIZE,
.DataINEndpointDoubleBank = false,
.DataOUTEndpointNumber = CDC_RX_EPNUM,
.DataOUTEndpointSize = CDC_TXRX_EPSIZE,
.DataOUTEndpointDoubleBank = false,
.NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,
.NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
.NotificationEndpointDoubleBank = false,
},
};
/** Main program entry point. This routine contains the overall program flow, including initial
* setup of all components and the main program loop.
*/
int main(void)
{
SetupHardware();
RingBuffer_InitBuffer(&USBtoUSART_Buffer);
RingBuffer_InitBuffer(&USARTtoUSB_Buffer);
sei();
for (;;)
{
/* Only try to read in bytes from the CDC interface if the transmit buffer is not full */
if (!(RingBuffer_IsFull(&USBtoUSART_Buffer)))
{
int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);
/* Read bytes from the USB OUT endpoint into the USART transmit buffer */
if (!(ReceivedByte < 0))
RingBuffer_Insert(&USBtoUSART_Buffer, ReceivedByte);
}
/* Check if the UART receive buffer flush timer has expired or the buffer is nearly full */
RingBuff_Count_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer);
if ((TIFR0 & (1 << TOV0)) || (BufferCount > BUFFER_NEARLY_FULL))
{
TIFR0 |= (1 << TOV0);
if (USARTtoUSB_Buffer.Count) {
LEDs_TurnOnLEDs(LEDMASK_TX);
PulseMSRemaining.TxLEDPulse = TX_RX_LED_PULSE_MS;
}
/* Read bytes from the USART receive buffer into the USB IN endpoint */
while (BufferCount--)
CDC_Device_SendByte(&VirtualSerial_CDC_Interface, RingBuffer_Remove(&USARTtoUSB_Buffer));
/* Turn off TX LED(s) once the TX pulse period has elapsed */
if (PulseMSRemaining.TxLEDPulse && !(--PulseMSRemaining.TxLEDPulse))
LEDs_TurnOffLEDs(LEDMASK_TX);
/* Turn off RX LED(s) once the RX pulse period has elapsed */
if (PulseMSRemaining.RxLEDPulse && !(--PulseMSRemaining.RxLEDPulse))
LEDs_TurnOffLEDs(LEDMASK_RX);
}
/* Load the next byte from the USART transmit buffer into the USART */
if (!(RingBuffer_IsEmpty(&USBtoUSART_Buffer))) {
Serial_TxByte(RingBuffer_Remove(&USBtoUSART_Buffer));
LEDs_TurnOnLEDs(LEDMASK_RX);
PulseMSRemaining.RxLEDPulse = TX_RX_LED_PULSE_MS;
}
CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
USB_USBTask();
}
}
/** Configures the board hardware and chip peripherals for the demo's functionality. */
void SetupHardware(void)
{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
wdt_disable();
/* Hardware Initialization */
Serial_Init(9600, false);
LEDs_Init();
USB_Init();
/* Start the flush timer so that overflows occur rapidly to push received bytes to the USB interface */
TCCR0B = (1 << CS02);
/* Pull target /RESET line high */
AVR_RESET_LINE_PORT |= AVR_RESET_LINE_MASK;
AVR_RESET_LINE_DDR |= AVR_RESET_LINE_MASK;
}
/** Event handler for the library USB Configuration Changed event. */
void EVENT_USB_Device_ConfigurationChanged(void)
{
CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface);
}
/** Event handler for the library USB Unhandled Control Request event. */
void EVENT_USB_Device_UnhandledControlRequest(void)
{
CDC_Device_ProcessControlRequest(&VirtualSerial_CDC_Interface);
}
/** Event handler for the CDC Class driver Line Encoding Changed event.
*
* \param[in] CDCInterfaceInfo Pointer to the CDC class interface configuration structure being referenced
*/
void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
{
uint8_t ConfigMask = 0;
switch (CDCInterfaceInfo->State.LineEncoding.ParityType)
{
case CDC_PARITY_Odd:
ConfigMask = ((1 << UPM11) | (1 << UPM10));
break;
case CDC_PARITY_Even:
ConfigMask = (1 << UPM11);
break;
}
if (CDCInterfaceInfo->State.LineEncoding.CharFormat == CDC_LINEENCODING_TwoStopBits)
ConfigMask |= (1 << USBS1);
switch (CDCInterfaceInfo->State.LineEncoding.DataBits)
{
case 6:
ConfigMask |= (1 << UCSZ10);
break;
case 7:
ConfigMask |= (1 << UCSZ11);
break;
case 8:
ConfigMask |= ((1 << UCSZ11) | (1 << UCSZ10));
break;
}
/* Must turn off USART before reconfiguring it, otherwise incorrect operation may occur */
UCSR1B = 0;
UCSR1A = 0;
UCSR1C = 0;
/* Special case 57600 baud for compatibility with the ATmega328 bootloader. */
UBRR1 = (CDCInterfaceInfo->State.LineEncoding.BaudRateBPS == 57600)
? SERIAL_UBBRVAL(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)
: SERIAL_2X_UBBRVAL(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS);
UCSR1C = ConfigMask;
UCSR1A = (CDCInterfaceInfo->State.LineEncoding.BaudRateBPS == 57600) ? 0 : (1 << U2X1);
UCSR1B = ((1 << RXCIE1) | (1 << TXEN1) | (1 << RXEN1));
}
/** ISR to manage the reception of data from the serial port, placing received bytes into a circular buffer
* for later transmission to the host.
*/
ISR(USART1_RX_vect, ISR_BLOCK)
{
uint8_t ReceivedByte = UDR1;
if (USB_DeviceState == DEVICE_STATE_Configured)
RingBuffer_Insert(&USARTtoUSB_Buffer, ReceivedByte);
}
/** Event handler for the CDC Class driver Host-to-Device Line Encoding Changed event.
*
* \param[in] CDCInterfaceInfo Pointer to the CDC class interface configuration structure being referenced
*/
void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
{
bool CurrentDTRState = (CDCInterfaceInfo->State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR);
if (CurrentDTRState)
AVR_RESET_LINE_PORT &= ~AVR_RESET_LINE_MASK;
else
AVR_RESET_LINE_PORT |= AVR_RESET_LINE_MASK;
}

View File

@ -0,0 +1,79 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for Arduino-usbserial.c.
*/
#ifndef _ARDUINO_USBSERIAL_H_
#define _ARDUINO_USBSERIAL_H_
/* Includes: */
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <avr/power.h>
#include "Descriptors.h"
#include "Lib/LightweightRingBuff.h"
#include <LUFA/Version.h>
#include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/Peripheral/Serial.h>
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/CDC.h>
/* Macros: */
/** LED mask for the library LED driver, to indicate TX activity. */
#define LEDMASK_TX LEDS_LED1
/** LED mask for the library LED driver, to indicate RX activity. */
#define LEDMASK_RX LEDS_LED2
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
#define LEDMASK_ERROR (LEDS_LED1 | LEDS_LED2)
/** LED mask for the library LED driver, to indicate that the USB interface is busy. */
#define LEDMASK_BUSY (LEDS_LED1 | LEDS_LED2)
/* Function Prototypes: */
void SetupHardware(void);
void EVENT_USB_Device_Connect(void);
void EVENT_USB_Device_Disconnect(void);
void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void);
void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo);
void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo);
#endif /* _ARDUINO_USBSERIAL_H_ */

View File

@ -0,0 +1,110 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/*
Board LEDs driver for the Benito board, from www.dorkbotpdx.org.
*/
#ifndef __LEDS_ARDUINOUNO_H__
#define __LEDS_ARDUINOUNO_H__
/* Includes: */
#include <avr/io.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(INCLUDE_FROM_LEDS_H)
#error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Macros: */
/** LED mask for the first LED on the board. */
#define LEDS_LED1 (1 << 5)
/** LED mask for the second LED on the board. */
#define LEDS_LED2 (1 << 4)
/** LED mask for all the LEDs on the board. */
#define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2)
/** LED mask for the none of the board LEDs */
#define LEDS_NO_LEDS 0
/* Inline Functions: */
#if !defined(__DOXYGEN__)
static inline void LEDs_Init(void)
{
DDRD |= LEDS_ALL_LEDS;
PORTD |= LEDS_ALL_LEDS;
}
static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask)
{
PORTD &= ~LEDMask;
}
static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask)
{
PORTD |= LEDMask;
}
static inline void LEDs_SetAllLEDs(const uint8_t LEDMask)
{
PORTD = ((PORTD | LEDS_ALL_LEDS) & ~LEDMask);
}
static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, const uint8_t ActiveMask)
{
PORTD = ((PORTD | ActiveMask) & ~LEDMask);
}
static inline void LEDs_ToggleLEDs(const uint8_t LEDMask)
{
PORTD ^= LEDMask;
}
static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT;
static inline uint8_t LEDs_GetLEDs(void)
{
return (PORTD & LEDS_ALL_LEDS);
}
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -0,0 +1,277 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special
* computer-readable structures which the host requests upon device enumeration, to determine
* the device's capabilities and functions.
*/
#include "Descriptors.h"
/* On some devices, there is a factory set internal serial number which can be automatically sent to the host as
* the device's serial number when the Device Descriptor's .SerialNumStrIndex entry is set to USE_INTERNAL_SERIAL.
* This allows the host to track a device across insertions on different ports, allowing them to retain allocated
* resources like COM port numbers and drivers. On demos using this feature, give a warning on unsupported devices
* so that the user can supply their own serial number descriptor instead or remove the USE_INTERNAL_SERIAL value
* from the Device Descriptor (forcing the host to generate a serial number for each device from the VID, PID and
* port location).
*/
#if (USE_INTERNAL_SERIAL == NO_DESCRIPTOR)
#warning USE_INTERNAL_SERIAL is not available on this AVR - please manually construct a device serial descriptor.
#endif
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
* device characteristics, including the supported USB version, control endpoint size and the
* number of device configurations. The descriptor is read out by the USB host when the enumeration
* process begins.
*/
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
{
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(01.10),
.Class = 0x02,
.SubClass = 0x00,
.Protocol = 0x00,
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
.VendorID = 0x03EB, // Atmel
.ProductID = 0x204B, // LUFA USB to Serial Demo Application
.ReleaseNumber = 0x0001,
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,
.SerialNumStrIndex = USE_INTERNAL_SERIAL,
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
};
/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
* of the device in one of its supported configurations, including information about any device interfaces
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
* a configuration so that the host may correctly communicate with the USB device.
*/
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
{
.Config =
{
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
.TotalInterfaces = 2,
.ConfigurationNumber = 1,
.ConfigurationStrIndex = NO_DESCRIPTOR,
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
},
.CDC_CCI_Interface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 0,
.AlternateSetting = 0,
.TotalEndpoints = 1,
.Class = 0x02,
.SubClass = 0x02,
.Protocol = 0x01,
.InterfaceStrIndex = NO_DESCRIPTOR
},
.CDC_Functional_IntHeader =
{
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
.SubType = 0x00,
.Data = {0x01, 0x10}
},
.CDC_Functional_AbstractControlManagement =
{
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(1)), .Type = 0x24},
.SubType = 0x02,
.Data = {0x06}
},
.CDC_Functional_Union =
{
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
.SubType = 0x06,
.Data = {0x00, 0x01}
},
.CDC_NotificationEndpoint =
{
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC_NOTIFICATION_EPNUM),
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = CDC_NOTIFICATION_EPSIZE,
.PollingIntervalMS = 0xFF
},
.CDC_DCI_Interface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 1,
.AlternateSetting = 0,
.TotalEndpoints = 2,
.Class = 0x0A,
.SubClass = 0x00,
.Protocol = 0x00,
.InterfaceStrIndex = NO_DESCRIPTOR
},
.CDC_DataOutEndpoint =
{
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | CDC_RX_EPNUM),
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = CDC_TXRX_EPSIZE,
.PollingIntervalMS = 0x01
},
.CDC_DataInEndpoint =
{
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC_TX_EPNUM),
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = CDC_TXRX_EPSIZE,
.PollingIntervalMS = 0x01
}
};
/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
*/
USB_Descriptor_String_t PROGMEM LanguageString =
{
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
.UnicodeString = {LANGUAGE_ID_ENG}
};
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
* form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor.
*/
USB_Descriptor_String_t PROGMEM ManufacturerString =
{
.Header = {.Size = USB_STRING_LEN(24), .Type = DTYPE_String},
.UnicodeString = L"Arduino (www.arduino.cc)"
};
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor.
*/
USB_Descriptor_String_t PROGMEM ProductString =
{
#if (ARDUINO_MODEL_PID == ARDUINO_UNO_PID)
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
.UnicodeString = L"Arduino Uno"
#elif (ARDUINO_MODEL_PID == ARDUINO_MEGA2560_PID)
.Header = {.Size = USB_STRING_LEN(17), .Type = DTYPE_String},
.UnicodeString = L"Arduino Mega 2560"
#endif
};
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
* documentation) by the application code so that the address and size of a requested descriptor can be given
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
* USB host.
*/
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
const uint8_t wIndex,
void** const DescriptorAddress)
{
const uint8_t DescriptorType = (wValue >> 8);
const uint8_t DescriptorNumber = (wValue & 0xFF);
void* Address = NULL;
uint16_t Size = NO_DESCRIPTOR;
switch (DescriptorType)
{
case DTYPE_Device:
Address = (void*)&DeviceDescriptor;
Size = sizeof(USB_Descriptor_Device_t);
break;
case DTYPE_Configuration:
Address = (void*)&ConfigurationDescriptor;
Size = sizeof(USB_Descriptor_Configuration_t);
break;
case DTYPE_String:
switch (DescriptorNumber)
{
case 0x00:
Address = (void*)&LanguageString;
Size = pgm_read_byte(&LanguageString.Header.Size);
break;
case 0x01:
Address = (void*)&ManufacturerString;
Size = pgm_read_byte(&ManufacturerString.Header.Size);
break;
case 0x02:
Address = (void*)&ProductString;
Size = pgm_read_byte(&ProductString.Header.Size);
break;
}
break;
}
*DescriptorAddress = Address;
return Size;
}

View File

@ -0,0 +1,88 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for Descriptors.c.
*/
#ifndef _DESCRIPTORS_H_
#define _DESCRIPTORS_H_
/* Includes: */
#include <avr/pgmspace.h>
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/CDC.h>
/* Product-specific definitions: */
#define ARDUINO_UNO_PID 0x0001
#define ARDUINO_MEGA2560_PID 0x0010
/* Macros: */
/** Endpoint number of the CDC device-to-host notification IN endpoint. */
#define CDC_NOTIFICATION_EPNUM 2
/** Endpoint number of the CDC device-to-host data IN endpoint. */
#define CDC_TX_EPNUM 3
/** Endpoint number of the CDC host-to-device data OUT endpoint. */
#define CDC_RX_EPNUM 4
/** Size in bytes of the CDC device-to-host notification IN endpoint. */
#define CDC_NOTIFICATION_EPSIZE 8
/** Size in bytes of the CDC data IN and OUT endpoints. */
#define CDC_TXRX_EPSIZE 64
/* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which
* vary between devices, and which describe the device's usage to the host.
*/
typedef struct
{
USB_Descriptor_Configuration_Header_t Config;
USB_Descriptor_Interface_t CDC_CCI_Interface;
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_IntHeader;
CDC_FUNCTIONAL_DESCRIPTOR(1) CDC_Functional_AbstractControlManagement;
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_Union;
USB_Descriptor_Endpoint_t CDC_NotificationEndpoint;
USB_Descriptor_Interface_t CDC_DCI_Interface;
USB_Descriptor_Endpoint_t CDC_DataOutEndpoint;
USB_Descriptor_Endpoint_t CDC_DataInEndpoint;
} USB_Descriptor_Configuration_t;
/* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
const uint8_t wIndex,
void** const DescriptorAddress) ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
#endif

View File

@ -0,0 +1,197 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Ultra lightweight ring buffer, for fast insertion/deletion.
*/
#ifndef _ULW_RING_BUFF_H_
#define _ULW_RING_BUFF_H_
/* Includes: */
#include <util/atomic.h>
#include <stdint.h>
#include <stdbool.h>
/* Defines: */
/** Size of each ring buffer, in data elements - must be between 1 and 255. */
#define BUFFER_SIZE 128
/** Maximum number of data elements to buffer before forcing a flush.
* Must be less than BUFFER_SIZE
*/
#define BUFFER_NEARLY_FULL 96
/** Type of data to store into the buffer. */
#define RingBuff_Data_t uint8_t
/** Datatype which may be used to store the count of data stored in a buffer, retrieved
* via a call to \ref RingBuffer_GetCount().
*/
#if (BUFFER_SIZE <= 0xFF)
#define RingBuff_Count_t uint8_t
#else
#define RingBuff_Count_t uint16_t
#endif
/* Type Defines: */
/** Type define for a new ring buffer object. Buffers should be initialized via a call to
* \ref RingBuffer_InitBuffer() before use.
*/
typedef struct
{
RingBuff_Data_t Buffer[BUFFER_SIZE]; /**< Internal ring buffer data, referenced by the buffer pointers. */
RingBuff_Data_t* In; /**< Current storage location in the circular buffer */
RingBuff_Data_t* Out; /**< Current retrieval location in the circular buffer */
RingBuff_Count_t Count;
} RingBuff_t;
/* Inline Functions: */
/** Initializes a ring buffer ready for use. Buffers must be initialized via this function
* before any operations are called upon them. Already initialized buffers may be reset
* by re-initializing them using this function.
*
* \param[out] Buffer Pointer to a ring buffer structure to initialize
*/
static inline void RingBuffer_InitBuffer(RingBuff_t* const Buffer)
{
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
Buffer->In = Buffer->Buffer;
Buffer->Out = Buffer->Buffer;
}
}
/** Retrieves the minimum number of bytes stored in a particular buffer. This value is computed
* by entering an atomic lock on the buffer while the IN and OUT locations are fetched, so that
* the buffer cannot be modified while the computation takes place. This value should be cached
* when reading out the contents of the buffer, so that as small a time as possible is spent
* in an atomic lock.
*
* \note The value returned by this function is guaranteed to only be the minimum number of bytes
* stored in the given buffer; this value may change as other threads write new data and so
* the returned number should be used only to determine how many successive reads may safely
* be performed on the buffer.
*
* \param[in] Buffer Pointer to a ring buffer structure whose count is to be computed
*/
static inline RingBuff_Count_t RingBuffer_GetCount(RingBuff_t* const Buffer)
{
RingBuff_Count_t Count;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
Count = Buffer->Count;
}
return Count;
}
/** Atomically determines if the specified ring buffer contains any free space. This should
* be tested before storing data to the buffer, to ensure that no data is lost due to a
* buffer overrun.
*
* \param[in,out] Buffer Pointer to a ring buffer structure to insert into
*
* \return Boolean true if the buffer contains no free space, false otherwise
*/
static inline bool RingBuffer_IsFull(RingBuff_t* const Buffer)
{
return (RingBuffer_GetCount(Buffer) == BUFFER_SIZE);
}
/** Atomically determines if the specified ring buffer contains any data. This should
* be tested before removing data from the buffer, to ensure that the buffer does not
* underflow.
*
* If the data is to be removed in a loop, store the total number of bytes stored in the
* buffer (via a call to the \ref RingBuffer_GetCount() function) in a temporary variable
* to reduce the time spent in atomicity locks.
*
* \param[in,out] Buffer Pointer to a ring buffer structure to insert into
*
* \return Boolean true if the buffer contains no free space, false otherwise
*/
static inline bool RingBuffer_IsEmpty(RingBuff_t* const Buffer)
{
return (RingBuffer_GetCount(Buffer) == 0);
}
/** Inserts an element into the ring buffer.
*
* \note Only one execution thread (main program thread or an ISR) may insert into a single buffer
* otherwise data corruption may occur. Insertion and removal may occur from different execution
* threads.
*
* \param[in,out] Buffer Pointer to a ring buffer structure to insert into
* \param[in] Data Data element to insert into the buffer
*/
static inline void RingBuffer_Insert(RingBuff_t* const Buffer,
const RingBuff_Data_t Data)
{
*Buffer->In = Data;
if (++Buffer->In == &Buffer->Buffer[BUFFER_SIZE])
Buffer->In = Buffer->Buffer;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
Buffer->Count++;
}
}
/** Removes an element from the ring buffer.
*
* \note Only one execution thread (main program thread or an ISR) may remove from a single buffer
* otherwise data corruption may occur. Insertion and removal may occur from different execution
* threads.
*
* \param[in,out] Buffer Pointer to a ring buffer structure to retrieve from
*
* \return Next data element stored in the buffer
*/
static inline RingBuff_Data_t RingBuffer_Remove(RingBuff_t* const Buffer)
{
RingBuff_Data_t Data = *Buffer->Out;
if (++Buffer->Out == &Buffer->Buffer[BUFFER_SIZE])
Buffer->Out = Buffer->Buffer;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
Buffer->Count--;
}
return Data;
}
#endif

View File

@ -0,0 +1,776 @@
# Hey Emacs, this is a -*- makefile -*-
#----------------------------------------------------------------------------
# WinAVR Makefile Template written by Eric B. Weddington, J<>rg Wunsch, et al.
# >> Modified for use with the LUFA project. <<
#
# Released to the Public Domain
#
# Additional material for this makefile was written by:
# Peter Fleury
# Tim Henigan
# Colin O'Flynn
# Reiner Patommel
# Markus Pfaff
# Sander Pool
# Frederik Rouleau
# Carlos Lamas
# Dean Camera
# Opendous Inc.
# Denver Gingerich
#
#----------------------------------------------------------------------------
# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make coff = Convert ELF to AVR COFF.
#
# make extcoff = Convert ELF to AVR Extended COFF.
#
# make program = Download the hex file to the device, using avrdude.
# Please customize the avrdude settings below first!
#
# make dfu = Download the hex file to the device, using dfu-programmer (must
# have dfu-programmer installed).
#
# make flip = Download the hex file to the device, using Atmel FLIP (must
# have Atmel FLIP installed).
#
# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
# (must have dfu-programmer installed).
#
# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
# (must have Atmel FLIP installed).
#
# make doxygen = Generate DoxyGen documentation for the project (must have
# DoxyGen installed)
#
# make debug = Start either simulavr or avarice as specified for debugging,
# with avr-gdb or avr-insight as the front end for debugging.
#
# make filename.s = Just compile filename.c into the assembler code only.
#
# make filename.i = Create a preprocessed source file for use in submitting
# bug reports to the GCC project.
#
# To rebuild project do "make clean" then "make all".
#----------------------------------------------------------------------------
# MCU name(s)
# Since the ATMEGA8U2 part is not directly supported by the current
# versions of either avrdude or dfu-programmer, we specify a dummy
# part; AT90USB82 which is close enough in memory size and organization
MCU = atmega8u2
MCU_AVRDUDE = at90usb82
MCU_DFU = at90usb82
# Specify the Arduino model using the assigned PID. This is used by Descriptors.c
# to set PID and product descriptor string
# Uno PID:
ARDUINO_MODEL_PID = 0x0001
# Mega 2560 PID:
#ARDUINO_MODEL_PID = 0x0010
# Target board (see library "Board Types" documentation, NONE for projects not requiring
# LUFA board drivers). If USER is selected, put custom board drivers in a directory called
# "Board" inside the application directory.
BOARD = USER
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency in Hz. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
#
# This will be an integer division of F_CLOCK below, as it is sourced by
# F_CLOCK after it has run through any CPU prescalers. Note that this value
# does not *change* the processor frequency - it should merely be updated to
# reflect the processor speed set externally so that the code can use accurate
# software delays.
F_CPU = 16000000
# Input clock frequency.
# This will define a symbol, F_CLOCK, in all source code files equal to the
# input clock frequency (before any prescaling is performed) in Hz. This value may
# differ from F_CPU if prescaling is used on the latter, and is required as the
# raw input clock is fed directly to the PLL sections of the AVR for high speed
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
# at the end, this will be done automatically to create a 32-bit value in your
# source code.
#
# If no clock division is performed on the input clock inside the AVR (via the
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_CLOCK = $(F_CPU)
# Output format. (can be srec, ihex, binary)
FORMAT = ihex
# Target file name (without extension).
TARGET = Arduino-usbserial
# Object files directory
# To put object files in current directory, use a dot (.), do NOT make
# this an empty or blank macro!
OBJDIR = .
# Path to the LUFA library
LUFA_PATH = ../..
# LUFA library compile-time options
LUFA_OPTS = -D USB_DEVICE_ONLY
LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8
LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1
LUFA_OPTS += -D USE_FLASH_DESCRIPTORS
LUFA_OPTS += -D INTERRUPT_CONTROL_ENDPOINT
LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0
LUFA_OPTS += -D USE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
# Create the LUFA source path variables by including the LUFA root makefile
include $(LUFA_PATH)/LUFA/makefile
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c \
Descriptors.c \
$(LUFA_SRC_USB) \
$(LUFA_SRC_USBCLASS) \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Device.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c \
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/HostStandardReq.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Pipe.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/USBController.c \
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/Events.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/USBInterrupt.c \
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c \
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/DeviceStandardReq.c \
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c \
$(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/CDC.c \
$(LUFA_PATH)/LUFA/Drivers/USB/Class/Host/CDC.c
# List C++ source files here. (C dependencies are automatically generated.)
CPPSRC =
# List Assembler source files here.
# Make them always end in a capital .S. Files ending in a lowercase .s
# will not be considered source files but generated files (assembler
# output from the compiler), and will be deleted upon "make clean"!
# Even though the DOS/Win* filesystem matches both .s and .S the same,
# it will preserve the spelling of the filenames, and gcc itself does
# care about how the name is spelled on its command-line.
ASRC =
# Optimization level, can be [0, 1, 2, 3, s].
# 0 = turn off optimization. s = optimize for size.
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = s
# Debugging format.
# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
# AVR Studio 4.10 requires dwarf-2.
# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
DEBUG = dwarf-2
# List any extra directories to look for include files here.
# Each directory must be seperated by a space.
# Use forward slashes for directory separators.
# For a directory that has spaces, enclose it in quotes.
EXTRAINCDIRS = $(LUFA_PATH)/
# Compiler flag to set the C Standard level.
# c89 = "ANSI" C
# gnu89 = c89 plus GCC extensions
# c99 = ISO C99 standard (not yet fully implemented)
# gnu99 = c99 plus GCC extensions
CSTANDARD = -std=gnu99
# Place -D or -U options here for C sources
CDEFS = -DF_CPU=$(F_CPU)UL
CDEFS += -DF_CLOCK=$(F_CLOCK)UL
CDEFS += -DARDUINO_MODEL_PID=$(ARDUINO_MODEL_PID)
CDEFS += -DBOARD=BOARD_$(BOARD)
CDEFS += $(LUFA_OPTS)
CDEFS += -DAVR_RESET_LINE_PORT="PORTD"
CDEFS += -DAVR_RESET_LINE_DDR="DDRD"
CDEFS += -DAVR_RESET_LINE_MASK="(1 << 7)"
CDEFS += -DTX_RX_LED_PULSE_MS=3
CDEFS += -DPING_PONG_LED_PULSE_MS=100
# Place -D or -U options here for ASM sources
ADEFS = -DF_CPU=$(F_CPU)
ADEFS += -DF_CLOCK=$(F_CLOCK)UL
ADEFS += -DBOARD=BOARD_$(BOARD)
ADEFS += $(LUFA_OPTS)
# Place -D or -U options here for C++ sources
CPPDEFS = -DF_CPU=$(F_CPU)UL
CPPDEFS += -DF_CLOCK=$(F_CLOCK)UL
CPPDEFS += -DBOARD=BOARD_$(BOARD)
CPPDEFS += $(LUFA_OPTS)
#CPPDEFS += -D__STDC_LIMIT_MACROS
#CPPDEFS += -D__STDC_CONSTANT_MACROS
#---------------- Compiler Options C ----------------
# -g*: generate debugging information
# -O*: optimization level
# -f...: tuning, see GCC manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns...: create assembler listing
CFLAGS = -g$(DEBUG)
CFLAGS += $(CDEFS)
CFLAGS += -O$(OPT)
CFLAGS += -funsigned-char
CFLAGS += -funsigned-bitfields
CFLAGS += -ffunction-sections
CFLAGS += -fno-inline-small-functions
CFLAGS += -fpack-struct
CFLAGS += -fshort-enums
CFLAGS += -fno-strict-aliasing
CFLAGS += -Wall
CFLAGS += -Wstrict-prototypes
#CFLAGS += -mshort-calls
#CFLAGS += -fno-unit-at-a-time
#CFLAGS += -Wundef
#CFLAGS += -Wunreachable-code
#CFLAGS += -Wsign-compare
CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD)
#---------------- Compiler Options C++ ----------------
# -g*: generate debugging information
# -O*: optimization level
# -f...: tuning, see GCC manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns...: create assembler listing
CPPFLAGS = -g$(DEBUG)
CPPFLAGS += $(CPPDEFS)
CPPFLAGS += -O$(OPT)
CPPFLAGS += -funsigned-char
CPPFLAGS += -funsigned-bitfields
CPPFLAGS += -fpack-struct
CPPFLAGS += -fshort-enums
CPPFLAGS += -fno-exceptions
CPPFLAGS += -Wall
CPPFLAGS += -Wundef
CFLAGS += -Wundef
#CPPFLAGS += -mshort-calls
#CPPFLAGS += -fno-unit-at-a-time
#CPPFLAGS += -Wstrict-prototypes
#CPPFLAGS += -Wunreachable-code
#CPPFLAGS += -Wsign-compare
CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
#CPPFLAGS += $(CSTANDARD)
#---------------- Assembler Options ----------------
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns: create listing
# -gstabs: have the assembler create line number information; note that
# for use in COFF files, additional information about filenames
# and function names needs to be present in the assembler source
# files -- see avr-libc docs [FIXME: not yet described there]
# -listing-cont-lines: Sets the maximum number of continuation lines of hex
# dump that will be displayed for a given single line of source input.
ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100
#---------------- Library Options ----------------
# Minimalistic printf version
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
# Floating point printf version (requires MATH_LIB = -lm below)
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
# If this is left blank, then it will use the Standard printf version.
PRINTF_LIB =
#PRINTF_LIB = $(PRINTF_LIB_MIN)
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
# Minimalistic scanf version
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
# If this is left blank, then it will use the Standard scanf version.
SCANF_LIB =
#SCANF_LIB = $(SCANF_LIB_MIN)
#SCANF_LIB = $(SCANF_LIB_FLOAT)
MATH_LIB = -lm
# List any extra directories to look for libraries here.
# Each directory must be seperated by a space.
# Use forward slashes for directory separators.
# For a directory that has spaces, enclose it in quotes.
EXTRALIBDIRS =
#---------------- External Memory Options ----------------
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# used for variables (.data/.bss) and heap (malloc()).
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# only used for heap (malloc()).
#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff
EXTMEMOPTS =
#---------------- Linker Options ----------------
# -Wl,...: tell GCC to pass this to linker.
# -Map: create map file
# --cref: add cross reference to map file
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
LDFLAGS += -Wl,--relax
LDFLAGS += -Wl,--gc-sections
LDFLAGS += $(EXTMEMOPTS)
LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
#LDFLAGS += -T linker_script.x
#---------------- Programming Options (avrdude) ----------------
# Programming hardware
# Type: avrdude -c ?
# to get a full listing.
#
AVRDUDE_PROGRAMMER = avrispmkii
# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = usb
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
# Uncomment the following if you want avrdude's erase cycle counter.
# Note that this counter needs to be initialized first using -Yn,
# see avrdude manual.
#AVRDUDE_ERASE_COUNTER = -y
# Uncomment the following if you do /not/ wish a verification to be
# performed after programming the device.
#AVRDUDE_NO_VERIFY = -V
# Increase verbosity level. Please use this when submitting bug
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
# to submit bug reports.
#AVRDUDE_VERBOSE = -v -v
AVRDUDE_FORCE = -F
AVRDUDE_FLAGS = -p $(MCU_AVRDUDE) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
AVRDUDE_FLAGS += $(AVRDUDE_FORCE)
#---------------- Debugging Options ----------------
# For simulavr only - target MCU frequency.
DEBUG_MFREQ = $(F_CPU)
# Set the DEBUG_UI to either gdb or insight.
# DEBUG_UI = gdb
DEBUG_UI = insight
# Set the debugging back-end to either avarice, simulavr.
DEBUG_BACKEND = avarice
#DEBUG_BACKEND = simulavr
# GDB Init Filename.
GDBINIT_FILE = __avr_gdbinit
# When using avarice settings for the JTAG
JTAG_DEV = /dev/com1
# Debugging port used to communicate between GDB / avarice / simulavr.
DEBUG_PORT = 4242
# Debugging host used to communicate between GDB / avarice / simulavr, normally
# just set to localhost unless doing some sort of crazy debugging when
# avarice is running on a different computer.
DEBUG_HOST = localhost
#============================================================================
# Define programs and commands.
SHELL = sh
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
AR = avr-ar rcs
NM = avr-nm
AVRDUDE = avrdude
REMOVE = rm -f
REMOVEDIR = rm -rf
COPY = cp
WINSHELL = cmd
# Define Messages
# English
MSG_ERRORS_NONE = Errors: none
MSG_BEGIN = -------- begin --------
MSG_END = -------- end --------
MSG_SIZE_BEFORE = Size before:
MSG_SIZE_AFTER = Size after:
MSG_COFF = Converting to AVR COFF:
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
MSG_FLASH = Creating load file for Flash:
MSG_EEPROM = Creating load file for EEPROM:
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_SYMBOL_TABLE = Creating Symbol Table:
MSG_LINKING = Linking:
MSG_COMPILING = Compiling C:
MSG_COMPILING_CPP = Compiling C++:
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project:
MSG_CREATING_LIBRARY = Creating library:
# Define all object files.
OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
# Define all listing files.
LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)
# Compiler flags to generate dependency files.
GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
# Default target.
#all: begin gccversion sizebefore build checkinvalidevents showliboptions showtarget sizeafter end
all: begin gccversion sizebefore build showliboptions showtarget sizeafter end
# Change the build target to build a HEX file or a library.
build: elf hex eep lss sym asm
#build: lib
elf: $(TARGET).elf
hex: $(TARGET).hex
eep: $(TARGET).eep
lss: $(TARGET).lss
sym: $(TARGET).sym
asm: $(TARGET).s
LIBNAME=lib$(TARGET).a
lib: $(LIBNAME)
# Eye candy.
# AVR Studio 3.x does not check make's exit code but relies on
# the following magic strings to be generated by the compile job.
begin:
@echo
@echo $(MSG_BEGIN)
end:
@echo $(MSG_END)
@echo
# Display size of file.
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
ELFSIZE = $(SIZE) $(MCU_FLAG) $(FORMAT_FLAG) $(TARGET).elf
MCU_FLAG = $(shell $(SIZE) --help | grep -- --mcu > /dev/null && echo --mcu=$(MCU) )
FORMAT_FLAG = $(shell $(SIZE) --help | grep -- --format=.*avr > /dev/null && echo --format=avr )
sizebefore:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
2>/dev/null; echo; fi
sizeafter:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
2>/dev/null; echo; fi
#$(LUFA_PATH)/LUFA/LUFA_Events.lst:
# @make -C $(LUFA_PATH)/LUFA/ LUFA_Events.lst
#checkinvalidevents: $(LUFA_PATH)/LUFA/LUFA_Events.lst
# @echo
# @echo Checking for invalid events...
# @$(shell) avr-nm $(OBJ) | sed -n -e 's/^.*EVENT_/EVENT_/p' | \
# grep -F -v --file=$(LUFA_PATH)/LUFA/LUFA_Events.lst > InvalidEvents.tmp || true
# @sed -n -e 's/^/ WARNING - INVALID EVENT NAME: /p' InvalidEvents.tmp
# @if test -s InvalidEvents.tmp; then exit 1; fi
showliboptions:
@echo
@echo ---- Compile Time Library Options ----
@for i in $(LUFA_OPTS:-D%=%); do \
echo $$i; \
done
@echo --------------------------------------
showtarget:
@echo
@echo --------- Target Information ---------
@echo AVR Model: $(MCU)
@echo Board: $(BOARD)
@echo Clock: $(F_CPU)Hz CPU, $(F_CLOCK)Hz Master
@echo --------------------------------------
# Display compiler version information.
gccversion :
@$(CC) --version
# Program the device.
program: $(TARGET).hex $(TARGET).eep
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
flip: $(TARGET).hex
batchisp -hardware usb -device $(MCU_DFU) -operation erase f
batchisp -hardware usb -device $(MCU_DFU) -operation loadbuffer $(TARGET).hex program
batchisp -hardware usb -device $(MCU_DFU) -operation start reset 0
dfu: $(TARGET).hex
dfu-programmer $(MCU_DFU) erase
dfu-programmer $(MCU_DFU) flash --debug 1 $(TARGET).hex
dfu-programmer $(MCU_DFU) reset
flip-ee: $(TARGET).hex $(TARGET).eep
$(COPY) $(TARGET).eep $(TARGET)eep.hex
batchisp -hardware usb -device $(MCU_DFU) -operation memory EEPROM erase
batchisp -hardware usb -device $(MCU_DFU) -operation memory EEPROM loadbuffer $(TARGET)eep.hex program
batchisp -hardware usb -device $(MCU_DFU) -operation start reset 0
$(REMOVE) $(TARGET)eep.hex
dfu-ee: $(TARGET).hex $(TARGET).eep
dfu-programmer $(MCU_DFU) flash-eeprom --debug 1 --suppress-bootloader-mem $(TARGET).eep
dfu-programmer $(MCU_DFU) reset
# Generate avr-gdb config/init file which does the following:
# define the reset signal, load the target file, connect to target, and set
# a breakpoint at main().
gdb-config:
@$(REMOVE) $(GDBINIT_FILE)
@echo define reset >> $(GDBINIT_FILE)
@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
@echo end >> $(GDBINIT_FILE)
@echo file $(TARGET).elf >> $(GDBINIT_FILE)
@echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE)
ifeq ($(DEBUG_BACKEND),simulavr)
@echo load >> $(GDBINIT_FILE)
endif
@echo break main >> $(GDBINIT_FILE)
debug: gdb-config $(TARGET).elf
ifeq ($(DEBUG_BACKEND), avarice)
@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
@$(WINSHELL) /c pause
else
@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
$(DEBUG_MFREQ) --port $(DEBUG_PORT)
endif
@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT = $(OBJCOPY) --debugging
COFFCONVERT += --change-section-address .data-0x800000
COFFCONVERT += --change-section-address .bss-0x800000
COFFCONVERT += --change-section-address .noinit-0x800000
COFFCONVERT += --change-section-address .eeprom-0x810000
coff: $(TARGET).elf
@echo
@echo $(MSG_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
extcoff: $(TARGET).elf
@echo
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
@echo
@echo $(MSG_FLASH) $@
$(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock $< $@
%.eep: %.elf
@echo
@echo $(MSG_EEPROM) $@
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0
# Create extended listing file from ELF output file.
%.lss: %.elf
@echo
@echo $(MSG_EXTENDED_LISTING) $@
$(OBJDUMP) -h -S -z $< > $@
# Create a symbol table from ELF output file.
%.sym: %.elf
@echo
@echo $(MSG_SYMBOL_TABLE) $@
$(NM) -n $< > $@
# Create library from object files.
.SECONDARY : $(TARGET).a
.PRECIOUS : $(OBJ)
%.a: $(OBJ)
@echo
@echo $(MSG_CREATING_LIBRARY) $@
$(AR) $@ $(OBJ)
# Link: create ELF output file from object files.
.SECONDARY : $(TARGET).elf
.PRECIOUS : $(OBJ)
%.elf: $(OBJ)
@echo
@echo $(MSG_LINKING) $@
$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
# Compile: create object files from C source files.
$(OBJDIR)/%.o : %.c
@echo
@echo $(MSG_COMPILING) $<
$(CC) -c $(ALL_CFLAGS) $< -o $@
# Compile: create object files from C++ source files.
$(OBJDIR)/%.o : %.cpp
@echo
@echo $(MSG_COMPILING_CPP) $<
$(CC) -c $(ALL_CPPFLAGS) $< -o $@
# Compile: create assembler files from C source files.
%.s : %.c
$(CC) -S $(ALL_CFLAGS) $< -o $@
# Compile: create assembler files from C++ source files.
%.s : %.cpp
$(CC) -S $(ALL_CPPFLAGS) $< -o $@
# Assemble: create object files from assembler source files.
$(OBJDIR)/%.o : %.S
@echo
@echo $(MSG_ASSEMBLING) $<
$(CC) -c $(ALL_ASFLAGS) $< -o $@
# Create preprocessed source for use in sending a bug report.
%.i : %.c
$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@
# Target: clean project.
clean: begin clean_list clean_binary end
clean_binary:
$(REMOVE) $(TARGET).hex
clean_list:
@echo $(MSG_CLEANING)
$(REMOVE) $(TARGET).hex
$(REMOVE) $(TARGET).eep
$(REMOVE) $(TARGET).cof
$(REMOVE) $(TARGET).elf
$(REMOVE) $(TARGET).map
$(REMOVE) $(TARGET).sym
$(REMOVE) $(TARGET).lss
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o)
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst)
$(REMOVE) $(SRC:.c=.s)
$(REMOVE) $(SRC:.c=.d)
$(REMOVE) $(SRC:.c=.i)
$(REMOVEDIR) .dep
doxygen:
@echo Generating Project Documentation...
@doxygen Doxygen.conf
@echo Documentation Generation Complete.
clean_doxygen:
rm -rf Documentation
# Create object files directory
$(shell mkdir $(OBJDIR) 2>/dev/null)
# Include the dependency files.
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion \
build elf hex eep lss sym coff extcoff doxygen clean \
clean_list clean_doxygen program dfu flip flip-ee dfu-ee \
debug gdb-config

View File

@ -0,0 +1,13 @@
To setup the project and upload the Arduino usbserial application firmware to an ATMEGA8U2 using the Arduino USB DFU bootloader:
1. unpack the source into LUFA's Projects directory
2. set ARDUINO_MODEL_PID in the makefile as appropriate
3. do "make clean; make"
4. put the 8U2 into USB DFU mode:
4.a. assert and hold the 8U2's RESET line
4.b. assert and hold the 8U2's HWB line
4.c. release the 8U2's RESET line
4.d. release the 8U2's HWB line
5. confirm that the board enumerates as either "Arduino Uno DFU" or "Arduino Mega 2560 DFU"
6. do "make dfu" (OS X or Linux - dfu-programmer must be installed first) or "make flip" (Windows - Flip must be installed first)
Check that the board enumerates as either "Arduino Uno" or "Arduino Mega 2560". Test by uploading a new Arduino sketch from the Arduino IDE.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,96 @@
#!/bin/sh
WIFI_FW_PATH="/hardware/arduino/firmwares/wifi-shield"
AVR_TOOLS_PATH="/hardware/tools/avr/bin"
progname=$0
usage () {
cat <<EOF
Usage: $progname [-a Arduino_path] [-f which_firmware] [-h]
-a set the path where the Arduino IDE is installed
-f the firmware you want to upload, valid parameters are:
shield - to upgrade the WiFi shield firmware
all - to upgrade both firmwares
-h help
EOF
exit 0
}
upgradeHDmodule () {
sleep 1 # Give time to the shield to end the boot
echo "****Upgrade HD WiFi module firmware****\n"
dfu-programmer at32uc3a1256 erase
dfu-programmer at32uc3a1256 flash --suppress-bootloader-mem $WIFI_FW_PATH/wifi_dnld.hex
dfu-programmer at32uc3a1256 start
echo -n "\nRemove the J3 jumper then press the RESET button on the shield then type [ENTER] to upgrade the firmware of the shield..\n"
read readEnter
}
upgradeShield () {
sleep 1 # Give time to the shield to end the boot
echo "****Upgrade WiFi Shield firmware****\n"
dfu-programmer at32uc3a1256 erase
dfu-programmer at32uc3a1256 flash --suppress-bootloader-mem $WIFI_FW_PATH/wifiHD.hex
dfu-programmer at32uc3a1256 start
echo "\nDone. Remove the J3 jumper and press the RESET button on the shield."
echo "Thank you!\n"
}
cat <<EOF
Arduino WiFi Shield upgrade
=========================================
Disclaimer: to access to the USB devices correctly, the dfu-programmer needs to be used as root. Run this script as root.
EOF
if [ $USER = 'root' ] ; then #check if the current user is root
while getopts ":a:f:h" opt; do
case $opt in
a)
ARDUINO_PATH=$OPTARG
WIFI_FW_PATH=$ARDUINO_PATH$WIFI_FW_PATH
AVR_TOOLS_PATH=$ARDUINO_PATH$AVR_TOOLS_PATH
cd $AVR_TOOLS_PATH
./avr-objcopy --output-target=ihex $WIFI_FW_PATH/wifi_dnld.elf $WIFI_FW_PATH/wifi_dnld.hex
./avr-objcopy --output-target=ihex $WIFI_FW_PATH/wifiHD.elf $WIFI_FW_PATH/wifiHD.hex
;;
f)
if [ "$ARDUINO_PATH" != "" ] ; then
if [ "$OPTARG" = "all" ] ; then
upgradeHDmodule
upgradeShield
exit 0
else
if [ "$OPTARG" = "shield" ] ; then
upgradeShield
exit 0
else
echo "invalid parameter for the -f [firmware] option, please retry."
echo "Type -h for help\n"
exit 1
fi
fi
else
echo "Arduino Path not setted. Retry...\n"
fi
;;
h)
usage ;;
\?)
echo "Invalid option: $OPTARG" >&2
usage
exit 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
exit 1
;;
esac
done
else
echo "You are not root!\n"
fi
shift $(($OPTIND - 1))

View File

@ -0,0 +1,96 @@
#!/bin/sh
WIFI_FW_PATH="/hardware/arduino/firmwares/wifi-shield"
AVR_TOOLS_PATH="/hardware/tools/avr/bin"
progname=$0
usage () {
cat <<EOF
Usage: $progname [-a Arduino_path] [-f which_firmware] [-h]
-a set the path where the Arduino IDE is installed
-f the firmware you want to upload, valid parameters are:
shield - to upgrade the WiFi shield firmware
all - to upgrade both firmwares
-h help
EOF
exit 0
}
upgradeHDmodule () {
sleep 1 # Give time to the shield to end the boot
echo "****Upgrade HD WiFi module firmware****\n"
dfu-programmer at32uc3a1256 erase
dfu-programmer at32uc3a1256 flash --suppress-bootloader-mem $WIFI_FW_PATH/wifi_dnld.hex
dfu-programmer at32uc3a1256 start
echo -n "\nRemove the J3 jumper then press the RESET button on the shield then type [ENTER] to upgrade the firmware of the shield..\n"
read readEnter
}
upgradeShield () {
sleep 1 # Give time to the shield to end the boot
echo "****Upgrade WiFi Shield firmware****\n"
dfu-programmer at32uc3a1256 erase
dfu-programmer at32uc3a1256 flash --suppress-bootloader-mem $WIFI_FW_PATH/wifiHD.hex
dfu-programmer at32uc3a1256 start
echo "\nDone. Remove the J3 jumper and press the RESET button on the shield."
echo "Thank you!\n"
}
cat <<EOF
Arduino WiFi Shield upgrade
=========================================
Disclaimer: to access to the USB devices correctly, the dfu-programmer needs to be used as root. Run this script as root.
EOF
if [ $USER = 'root' ] ; then #check if the current user is root
while getopts ":a:f:h" opt; do
case $opt in
a)
ARDUINO_PATH=$OPTARG
WIFI_FW_PATH=$ARDUINO_PATH$WIFI_FW_PATH
AVR_TOOLS_PATH=$ARDUINO_PATH$AVR_TOOLS_PATH
cd $AVR_TOOLS_PATH
./avr-objcopy --output-target=ihex $WIFI_FW_PATH/wifi_dnld.elf $WIFI_FW_PATH/wifi_dnld.hex
./avr-objcopy --output-target=ihex $WIFI_FW_PATH/wifiHD.elf $WIFI_FW_PATH/wifiHD.hex
;;
f)
if [ "$ARDUINO_PATH" != "" ] ; then
if [ "$OPTARG" = "all" ] ; then
upgradeHDmodule
upgradeShield
exit 0
else
if [ "$OPTARG" = "shield" ] ; then
upgradeShield
exit 0
else
echo "invalid parameter for the -f [firmware] option, please retry."
echo "Type -h for help\n"
exit 1
fi
fi
else
echo "Arduino Path not setted. Retry...\n"
fi
;;
h)
usage ;;
\?)
echo "Invalid option: $OPTARG" >&2
usage
exit 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
exit 1
;;
esac
done
else
echo "You are not root!\n"
fi
shift $(($OPTIND - 1))

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>wifiHD</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
<dictionary>
<key>?name?</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.append_environment</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildArguments</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildCommand</key>
<value>make</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildLocation</key>
<value>${workspace_loc:/wifiHD/Debug}</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.contents</key>
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
<value>false</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.stopOnError</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
<value>true</value>
</dictionary>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.atmel.avr32.core.nature</nature>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
<linkedResources>
<link>
<name>UC3 Software Framework</name>
<type>2</type>
<locationURI>framework:/com.atmel.avr32.sf.uc3</locationURI>
</link>
</linkedResources>
</projectDescription>

View File

@ -0,0 +1,170 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Memory access control configuration file.
*
* This file contains the possible external configuration of the memory access
* control.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _CONF_ACCESS_H_
#define _CONF_ACCESS_H_
#include "compiler.h"
#include "board.h"
/*! \name Activation of Logical Unit Numbers
*/
//! @{
#define LUN_0 DISABLE //!< On-Chip Virtual Memory.
#define LUN_1 ENABLE //!< AT45DBX Data Flash.
#define LUN_2 DISABLE //!< SD/MMC Card over SPI.
#define LUN_3 DISABLE
#define LUN_4 DISABLE
#define LUN_5 DISABLE
#define LUN_6 DISABLE
#define LUN_7 DISABLE
#define LUN_USB DISABLE //!< Host Mass-Storage Memory.
//! @}
/*! \name LUN 0 Definitions
*/
//! @{
#define VIRTUAL_MEM LUN_0
#define LUN_ID_VIRTUAL_MEM LUN_ID_0
#define LUN_0_INCLUDE "virtual_mem.h"
#define Lun_0_test_unit_ready virtual_test_unit_ready
#define Lun_0_read_capacity virtual_read_capacity
#define Lun_0_wr_protect virtual_wr_protect
#define Lun_0_removal virtual_removal
#define Lun_0_usb_read_10 virtual_usb_read_10
#define Lun_0_usb_write_10 virtual_usb_write_10
#define Lun_0_mem_2_ram virtual_mem_2_ram
#define Lun_0_ram_2_mem virtual_ram_2_mem
#define LUN_0_NAME "\"On-Chip Virtual Memory\""
//! @}
/*! \name LUN 1 Definitions
*/
//! @{
#define AT45DBX_MEM LUN_1
#define LUN_ID_AT45DBX_MEM LUN_ID_1
#define LUN_1_INCLUDE "at45dbx_mem.h"
#define Lun_1_test_unit_ready at45dbx_test_unit_ready
#define Lun_1_read_capacity at45dbx_read_capacity
#define Lun_1_wr_protect at45dbx_wr_protect
#define Lun_1_removal at45dbx_removal
#define Lun_1_usb_read_10 at45dbx_usb_read_10
#define Lun_1_usb_write_10 at45dbx_usb_write_10
#define Lun_1_mem_2_ram at45dbx_df_2_ram
#define Lun_1_ram_2_mem at45dbx_ram_2_df
#define LUN_1_NAME "\"AT45DBX Data Flash\""
//! @}
/*! \name LUN 2 Definitions
*/
//! @{
#define SD_MMC_SPI_MEM LUN_2
#define LUN_ID_SD_MMC_SPI_MEM LUN_ID_2
#define LUN_2_INCLUDE "sd_mmc_spi_mem.h"
#define Lun_2_test_unit_ready sd_mmc_spi_test_unit_ready
#define Lun_2_read_capacity sd_mmc_spi_read_capacity
#define Lun_2_wr_protect sd_mmc_spi_wr_protect
#define Lun_2_removal sd_mmc_spi_removal
#define Lun_2_usb_read_10 sd_mmc_spi_usb_read_10
#define Lun_2_usb_write_10 sd_mmc_spi_usb_write_10
#define Lun_2_mem_2_ram sd_mmc_spi_mem_2_ram
#define Lun_2_ram_2_mem sd_mmc_spi_ram_2_mem
#define LUN_2_NAME "\"SD/MMC Card over SPI\""
//! @}
/*! \name USB LUNs Definitions
*/
//! @{
#define MEM_USB LUN_USB
#define LUN_ID_MEM_USB LUN_ID_USB
#define LUN_USB_INCLUDE "host_mem.h"
#define Lun_usb_test_unit_ready(lun) host_test_unit_ready(lun)
#define Lun_usb_read_capacity(lun, nb_sect) host_read_capacity(lun, nb_sect)
#define Lun_usb_read_sector_size(lun) host_read_sector_size(lun)
#define Lun_usb_wr_protect(lun) host_wr_protect(lun)
#define Lun_usb_removal() host_removal()
#define Lun_usb_mem_2_ram(addr, ram) host_read_10_ram(addr, ram)
#define Lun_usb_ram_2_mem(addr, ram) host_write_10_ram(addr, ram)
#define LUN_USB_NAME "\"Host Mass-Storage Memory\""
//! @}
/*! \name Actions Associated with Memory Accesses
*
* Write here the action to associate with each memory access.
*
* \warning Be careful not to waste time in order not to disturb the functions.
*/
//! @{
#define memory_start_read_action(nb_sectors)
#define memory_stop_read_action()
#define memory_start_write_action(nb_sectors)
#define memory_stop_write_action()
//! @}
/*! \name Activation of Interface Features
*/
//! @{
#define ACCESS_USB DISABLED //!< MEM <-> USB interface.
#define ACCESS_MEM_TO_RAM ENABLED //!< MEM <-> RAM interface.
#define ACCESS_STREAM ENABLED //!< Streaming MEM <-> MEM interface. //mlf
#define ACCESS_STREAM_RECORD DISABLED //!< Streaming MEM <-> MEM interface in record mode.
#define ACCESS_MEM_TO_MEM DISABLED //!< MEM <-> MEM interface.
#define ACCESS_CODEC DISABLED //!< Codec interface.
//! @}
/*! \name Specific Options for Access Control
*/
//! @{
#define GLOBAL_WR_PROTECT DISABLED //!< Management of a global write protection.
//! @}
#endif // _CONF_ACCESS_H_

View File

@ -0,0 +1,83 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief AT45DBX configuration file.
*
* This file contains the possible external configuration of the AT45DBX.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with an SPI module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _CONF_AT45DBX_H_
#define _CONF_AT45DBX_H_
#include "conf_access.h"
#if AT45DBX_MEM == DISABLE
#error conf_at45dbx.h is #included although AT45DBX_MEM is disabled
#endif
#include "at45dbx.h"
//_____ D E F I N I T I O N S ______________________________________________
//! Size of AT45DBX data flash memories to manage.
#define AT45DBX_MEM_SIZE AT45DBX_1MB
//! Number of AT45DBX components to manage.
#define AT45DBX_MEM_CNT 1
//! First chip select used by AT45DBX components on the SPI module instance.
//! AT45DBX_SPI_NPCS0_PIN always corresponds to this first NPCS, whatever it is.
#define AT45DBX_SPI_FIRST_NPCS AT45DBX_SPI_NPCS
//! SPI master speed in Hz.
#define AT45DBX_SPI_MASTER_SPEED 12000000
//! Number of bits in each SPI transfer.
#define AT45DBX_SPI_BITS 8
#endif // _CONF_AT45DBX_H_

View File

@ -0,0 +1,108 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief CONF_EBI EBI/SMC driver for AVR32 UC3.
*
* \note The values defined in this file are device-specific. See the device
* datasheet for further information.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with an SMC module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _CONF_EBI_H_
#define _CONF_EBI_H_
#include "compiler.h"
#include "board.h"
#if (ET024006DHU_SMC_USE_NCS == 0)
#define SMC_USE_NCS0
#define SMC_COMPONENT_CS0 ET024006DHU_SMC_COMPONENT_CS
#else
#if (ET024006DHU_SMC_USE_NCS == 2)
#define SMC_USE_NCS2
#define SMC_COMPONENT_CS2 ET024006DHU_SMC_COMPONENT_CS
#else
#error This board is not supported
#endif
#endif
#define EBI_DATA_0 ET024006DHU_EBI_DATA_0
#define EBI_DATA_1 ET024006DHU_EBI_DATA_1
#define EBI_DATA_2 ET024006DHU_EBI_DATA_2
#define EBI_DATA_3 ET024006DHU_EBI_DATA_3
#define EBI_DATA_4 ET024006DHU_EBI_DATA_4
#define EBI_DATA_5 ET024006DHU_EBI_DATA_5
#define EBI_DATA_6 ET024006DHU_EBI_DATA_6
#define EBI_DATA_7 ET024006DHU_EBI_DATA_7
#define EBI_DATA_8 ET024006DHU_EBI_DATA_8
#define EBI_DATA_9 ET024006DHU_EBI_DATA_9
#define EBI_DATA_10 ET024006DHU_EBI_DATA_10
#define EBI_DATA_11 ET024006DHU_EBI_DATA_11
#define EBI_DATA_12 ET024006DHU_EBI_DATA_12
#define EBI_DATA_13 ET024006DHU_EBI_DATA_13
#define EBI_DATA_14 ET024006DHU_EBI_DATA_14
#define EBI_DATA_15 ET024006DHU_EBI_DATA_15
#if BOARD==EVK1105
#ifdef EVK1105_REV3
#define EBI_ADDR_19 AVR32_EBI_ADDR_19
#define EBI_NCS_2 ET024006DHU_EBI_NCS
#else
#define EBI_ADDR_21 ET024006DHU_EBI_ADDR_21
#define EBI_NCS_0 ET024006DHU_EBI_NCS
#endif
#elif BOARD == UC3C_EK
#define EBI_ADDR_22 AVR32_EBI_ADDR_22
#define EBI_NCS_0 ET024006DHU_EBI_NCS
#elif BOARD == EVK1104
#define EBI_ADDR_21 ET024006DHU_EBI_ADDR_21
#define EBI_NCS_0 ET024006DHU_EBI_NCS
#endif
#define EBI_NWE0 ET024006DHU_EBI_NWE
#define EBI_NRD ET024006DHU_EBI_NRD
#endif // _CONF_EBI_H_

View File

@ -0,0 +1,73 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief SD/MMC configuration file.
*
* This file contains the possible external configuration of the SD/MMC.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with an SPI module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _CONF_SD_MMC_SPI_H_
#define _CONF_SD_MMC_SPI_H_
#include "conf_access.h"
#if SD_MMC_SPI_MEM == DISABLE
#error conf_sd_mmc_spi.h is #included although SD_MMC_SPI_MEM is disabled
#endif
#include "sd_mmc_spi.h"
//_____ D E F I N I T I O N S ______________________________________________
//! SPI master speed in Hz.
#define SD_MMC_SPI_MASTER_SPEED 12000000
//! Number of bits in each SPI transfer.
#define SD_MMC_SPI_BITS 8
#endif // _CONF_SD_MMC_SPI_H_

View File

@ -0,0 +1,74 @@
/* This file is part of the ATMEL AVR32-SoftwareFramework-AT32UC3A-1.4.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief AVR32 UC3 ISP trampoline.
*
* In order to be able to program a project with both BatchISP and JTAGICE mkII
* without having to take the general-purpose fuses into consideration, add this
* file to the project and change the program entry point to _trampoline.
*
* The pre-programmed ISP will be erased if JTAGICE mkII is used.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32UC devices can be used.
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (C) 2006-2008, Atmel Corporation All rights reserved.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 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.
*/
#include "conf_isp.h"
//! @{
//! \verbatim
// This must be linked @ 0x80000000 if it is to be run upon reset.
.section .reset, "ax", @progbits
.global _trampoline
.type _trampoline, @function
_trampoline:
// Jump to program start.
rjmp program_start
.org PROGRAM_START_OFFSET
program_start:
// Jump to the C runtime startup routine.
lda.w pc, _stext
//! \endverbatim
//! @}

View File

@ -0,0 +1,236 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief AT32UC3A EVK1100 board header file.
*
* This file contains definitions and services related to the features of the
* EVK1100 board rev. B and C.
*
* To use this board, define BOARD=EVK1100.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 AT32UC3A devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _ARDUINO_H_
#define _ARDUINO_H_
#include "compiler.h"
#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling.
# include "led.h"
#endif // __AVR32_ABI_COMPILER__
/*! \name Oscillator Definitions
*/
//! @{
// RCOsc has no custom calibration by default. Set the following definition to
// the appropriate value if a custom RCOsc calibration has been applied to your
// part.
//#define FRCOSC AVR32_PM_RCOSC_FREQUENCY //!< RCOsc frequency: Hz.
#define FOSC32 32768 //!< Osc32 frequency: Hz.
#define OSC32_STARTUP AVR32_PM_OSCCTRL32_STARTUP_8192_RCOSC //!< Osc32 startup time: RCOsc periods.
#define FOSC0 12000000 //!< Osc0 frequency: Hz.
#define OSC0_STARTUP AVR32_PM_OSCCTRL0_STARTUP_2048_RCOSC //!< Osc0 startup time: RCOsc periods.
// Osc1 crystal is not mounted by default. Set the following definitions to the
// appropriate values if a custom Osc1 crystal is mounted on your board.
//#define FOSC1 12000000 //!< Osc1 frequency: Hz.
//#define OSC1_STARTUP AVR32_PM_OSCCTRL1_STARTUP_2048_RCOSC //!< Osc1 startup time: RCOsc periods.
//! @}
//! Number of LEDs.
#define LED_COUNT 0
/*! \name GPIO Connections of LEDs
*/
//! @{
#define LED0_GPIO AVR32_PIN_PB19
#define LED1_GPIO AVR32_PIN_PB20
#define LED2_GPIO AVR32_PIN_PB21
#define DEB_PIN_GPIO AVR32_PIN_PA20
//! @}
/*! \name PWM Channels of LEDs
*/
//! @{
#define LED0_PWM 0
#define LED1_PWM 1
#define LED2_PWM 2
//! @}
/*! \name PWM Functions of LEDs
*/
//! @{
#define LED0_PWM_FUNCTION AVR32_PWM_0_FUNCTION
#define LED1_PWM_FUNCTION AVR32_PWM_1_FUNCTION
#define LED2_PWM_FUNCTION AVR32_PWM_2_FUNCTION
//! @}
/*! \name Color Identifiers of LEDs to Use with LED Functions
*/
//! @{
#define LED_MONO0_GREEN LED0
#define LED_MONO1_RED LED1
#define LED_MONO2_BLU LED2
//! @}
#if 0
/*! \name SPI Connections of the DIP204 LCD
*/
//! @{
#define DIP204_SPI (&AVR32_SPI1)
#define DIP204_SPI_NPCS 2
#define DIP204_SPI_SCK_PIN AVR32_SPI1_SCK_0_0_PIN
#define DIP204_SPI_SCK_FUNCTION AVR32_SPI1_SCK_0_0_FUNCTION
#define DIP204_SPI_MISO_PIN AVR32_SPI1_MISO_0_0_PIN
#define DIP204_SPI_MISO_FUNCTION AVR32_SPI1_MISO_0_0_FUNCTION
#define DIP204_SPI_MOSI_PIN AVR32_SPI1_MOSI_0_0_PIN
#define DIP204_SPI_MOSI_FUNCTION AVR32_SPI1_MOSI_0_0_FUNCTION
#define DIP204_SPI_NPCS_PIN AVR32_SPI1_NPCS_2_0_PIN
#define DIP204_SPI_NPCS_FUNCTION AVR32_SPI1_NPCS_2_0_FUNCTION
//! @}
/*! \name GPIO and PWM Connections of the DIP204 LCD Backlight
*/
//! @{
#define DIP204_BACKLIGHT_PIN AVR32_PIN_PB18
#define DIP204_PWM_CHANNEL 6
#define DIP204_PWM_PIN AVR32_PWM_6_PIN
#define DIP204_PWM_FUNCTION AVR32_PWM_6_FUNCTION
//! @}
#endif
/*! \name SPI Connections of the AT45DBX Data Flash Memory
*/
//! @{
#define AT45DBX_SPI (&AVR32_SPI1)
#define AT45DBX_SPI_NPCS 2
#define AT45DBX_SPI_SCK_PIN AVR32_SPI1_SCK_0_0_PIN
#define AT45DBX_SPI_SCK_FUNCTION AVR32_SPI1_SCK_0_0_FUNCTION
#define AT45DBX_SPI_MISO_PIN AVR32_SPI1_MISO_0_0_PIN
#define AT45DBX_SPI_MISO_FUNCTION AVR32_SPI1_MISO_0_0_FUNCTION
#define AT45DBX_SPI_MOSI_PIN AVR32_SPI1_MOSI_0_0_PIN
#define AT45DBX_SPI_MOSI_FUNCTION AVR32_SPI1_MOSI_0_0_FUNCTION
#define AT45DBX_SPI_NPCS2_PIN AVR32_SPI1_NPCS_2_0_PIN
#define AT45DBX_SPI_NPCS2_FUNCTION AVR32_SPI1_NPCS_2_0_FUNCTION
#define AT45DBX_CHIP_RESET AVR32_PIN_PA02
//! @}
/*! \name GPIO and SPI Connections of the SD/MMC Connector
*/
//! @{
//#define SD_MMC_CARD_DETECT_PIN AVR32_PIN_PA02
//#define SD_MMC_WRITE_PROTECT_PIN AVR32_PIN_PA07
#define SD_MMC_SPI (&AVR32_SPI1)
#define SD_MMC_SPI_NPCS 1
#define SD_MMC_SPI_SCK_PIN AVR32_SPI1_SCK_0_0_PIN
#define SD_MMC_SPI_SCK_FUNCTION AVR32_SPI1_SCK_0_0_FUNCTION
#define SD_MMC_SPI_MISO_PIN AVR32_SPI1_MISO_0_0_PIN
#define SD_MMC_SPI_MISO_FUNCTION AVR32_SPI1_MISO_0_0_FUNCTION
#define SD_MMC_SPI_MOSI_PIN AVR32_SPI1_MOSI_0_0_PIN
#define SD_MMC_SPI_MOSI_FUNCTION AVR32_SPI1_MOSI_0_0_FUNCTION
#define SD_MMC_SPI_NPCS_PIN AVR32_SPI1_NPCS_1_0_PIN
#define SD_MMC_SPI_NPCS_FUNCTION AVR32_SPI1_NPCS_1_0_FUNCTION
//! @}
/* Timer Counter to generate clock for WiFi chip*/
# define WIFI_TC (&AVR32_TC)
# define WIFI_TC_CHANNEL_ID 0
# define WIFI_TC_CHANNEL_PIN AVR32_TC_A0_0_0_PIN
# define WIFI_TC_CHANNEL_FUNCTION AVR32_TC_A0_0_0_FUNCTION
// Note that TC_A0_0_0 pin is pin 6 (PB23) on AT32UC3A1512 QFP100.
/* Pin related to WiFi chip communication */
#ifndef USE_POLL
#define USE_POLL
#endif
#define SPI_CS 0
#define AVR32_SPI AVR32_SPI1
#define GPIO_IRQ_PIN AVR32_PIN_PA03
#define GPIO_IRQ AVR32_GPIO_IRQ_7
#define GPIO_W_RESET_PIN AVR32_PIN_PA07
#define GPIO_W_SHUTDOWN_PIN AVR32_PIN_PA09
/* Pin related to shield communication */
#define ARDUINO_HANDSHAKE_PIN AVR32_PIN_PA25
#define ARDUINO_EXTINT_PIN AVR32_PIN_PA04 //not used
#define AVR32_PDCA_PID_TX AVR32_PDCA_PID_SPI1_TX
#define AVR32_PDCA_PID_RX AVR32_PDCA_PID_SPI1_RX
#if 0
/*! \name TWI Connections of the Spare TWI Connector
*/
//! @{
#define SPARE_TWI (&AVR32_TWI)
#define SPARE_TWI_SCL_PIN AVR32_TWI_SCL_0_0_PIN
#define SPARE_TWI_SCL_FUNCTION AVR32_TWI_SCL_0_0_FUNCTION
#define SPARE_TWI_SDA_PIN AVR32_TWI_SDA_0_0_PIN
#define SPARE_TWI_SDA_FUNCTION AVR32_TWI_SDA_0_0_FUNCTION
//! @}
/*! \name SPI Connections of the Spare SPI Connector
*/
//! @{
#define SPARE_SPI (&AVR32_SPI0)
#define SPARE_SPI_NPCS 0
#define SPARE_SPI_SCK_PIN AVR32_SPI0_SCK_0_0_PIN
#define SPARE_SPI_SCK_FUNCTION AVR32_SPI0_SCK_0_0_FUNCTION
#define SPARE_SPI_MISO_PIN AVR32_SPI0_MISO_0_0_PIN
#define SPARE_SPI_MISO_FUNCTION AVR32_SPI0_MISO_0_0_FUNCTION
#define SPARE_SPI_MOSI_PIN AVR32_SPI0_MOSI_0_0_PIN
#define SPARE_SPI_MOSI_FUNCTION AVR32_SPI0_MOSI_0_0_FUNCTION
#define SPARE_SPI_NPCS_PIN AVR32_SPI0_NPCS_0_0_PIN
#define SPARE_SPI_NPCS_FUNCTION AVR32_SPI0_NPCS_0_0_FUNCTION
//! @}
#endif
#endif // _ARDUINO_H_

View File

@ -0,0 +1,346 @@
/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief AT32UC3A EVK1100 board LEDs support package.
*
* This file contains definitions and services related to the LED features of
* the EVK1100 board.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 AT32UC3A devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#include <avr32/io.h>
#include "preprocessor.h"
#include "compiler.h"
#include "arduino.h"
#include "led.h"
//! Structure describing LED hardware connections.
typedef const struct
{
struct
{
U32 PORT; //!< LED GPIO port.
U32 PIN_MASK; //!< Bit-mask of LED pin in GPIO port.
} GPIO; //!< LED GPIO descriptor.
struct
{
S32 CHANNEL; //!< LED PWM channel (< 0 if N/A).
S32 FUNCTION; //!< LED pin PWM function (< 0 if N/A).
} PWM; //!< LED PWM descriptor.
} tLED_DESCRIPTOR;
//! Hardware descriptors of all LEDs.
static tLED_DESCRIPTOR LED_DESCRIPTOR[LED_COUNT] =
{
#define INSERT_LED_DESCRIPTOR(LED_NO, unused) \
{ \
{LED##LED_NO##_GPIO / 32, 1 << (LED##LED_NO##_GPIO % 32)},\
{LED##LED_NO##_PWM, LED##LED_NO##_PWM_FUNCTION } \
},
MREPEAT(LED_COUNT, INSERT_LED_DESCRIPTOR, ~)
#undef INSERT_LED_DESCRIPTOR
};
//! Saved state of all LEDs.
static volatile U32 LED_State = (1 << LED_COUNT) - 1;
U32 LED_Read_Display(void)
{
return LED_State;
}
void LED_Display(U32 leds)
{
// Use the LED descriptors to get the connections of a given LED to the MCU.
tLED_DESCRIPTOR *led_descriptor;
volatile avr32_gpio_port_t *led_gpio_port;
// Make sure only existing LEDs are specified.
leds &= (1 << LED_COUNT) - 1;
// Update the saved state of all LEDs with the requested changes.
LED_State = leds;
// For all LEDs...
for (led_descriptor = &LED_DESCRIPTOR[0];
led_descriptor < LED_DESCRIPTOR + LED_COUNT;
led_descriptor++)
{
// Set the LED to the requested state.
led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
if (leds & 1)
{
led_gpio_port->ovrc = led_descriptor->GPIO.PIN_MASK;
}
else
{
led_gpio_port->ovrs = led_descriptor->GPIO.PIN_MASK;
}
led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
leds >>= 1;
}
}
U32 LED_Read_Display_Mask(U32 mask)
{
return Rd_bits(LED_State, mask);
}
void LED_Display_Mask(U32 mask, U32 leds)
{
// Use the LED descriptors to get the connections of a given LED to the MCU.
tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
volatile avr32_gpio_port_t *led_gpio_port;
U8 led_shift;
// Make sure only existing LEDs are specified.
mask &= (1 << LED_COUNT) - 1;
// Update the saved state of all LEDs with the requested changes.
Wr_bits(LED_State, mask, leds);
// While there are specified LEDs left to manage...
while (mask)
{
// Select the next specified LED and set it to the requested state.
led_shift = 1 + ctz(mask);
led_descriptor += led_shift;
led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
leds >>= led_shift - 1;
if (leds & 1)
{
led_gpio_port->ovrc = led_descriptor->GPIO.PIN_MASK;
}
else
{
led_gpio_port->ovrs = led_descriptor->GPIO.PIN_MASK;
}
led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
leds >>= 1;
mask >>= led_shift;
}
}
Bool LED_Test(U32 leds)
{
return Tst_bits(LED_State, leds);
}
void LED_Off(U32 leds)
{
// Use the LED descriptors to get the connections of a given LED to the MCU.
tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
volatile avr32_gpio_port_t *led_gpio_port;
U8 led_shift;
// Make sure only existing LEDs are specified.
leds &= (1 << LED_COUNT) - 1;
// Update the saved state of all LEDs with the requested changes.
Clr_bits(LED_State, leds);
// While there are specified LEDs left to manage...
while (leds)
{
// Select the next specified LED and turn it off.
led_shift = 1 + ctz(leds);
led_descriptor += led_shift;
led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
led_gpio_port->ovrs = led_descriptor->GPIO.PIN_MASK;
led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
leds >>= led_shift;
}
}
void LED_On(U32 leds)
{
// Use the LED descriptors to get the connections of a given LED to the MCU.
tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
volatile avr32_gpio_port_t *led_gpio_port;
U8 led_shift;
// Make sure only existing LEDs are specified.
leds &= (1 << LED_COUNT) - 1;
// Update the saved state of all LEDs with the requested changes.
Set_bits(LED_State, leds);
// While there are specified LEDs left to manage...
while (leds)
{
// Select the next specified LED and turn it on.
led_shift = 1 + ctz(leds);
led_descriptor += led_shift;
led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
led_gpio_port->ovrc = led_descriptor->GPIO.PIN_MASK;
led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
leds >>= led_shift;
}
}
void LED_Toggle(U32 leds)
{
// Use the LED descriptors to get the connections of a given LED to the MCU.
tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
volatile avr32_gpio_port_t *led_gpio_port;
U8 led_shift;
// Make sure only existing LEDs are specified.
leds &= (1 << LED_COUNT) - 1;
// Update the saved state of all LEDs with the requested changes.
Tgl_bits(LED_State, leds);
// While there are specified LEDs left to manage...
while (leds)
{
// Select the next specified LED and toggle it.
led_shift = 1 + ctz(leds);
led_descriptor += led_shift;
led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
led_gpio_port->ovrt = led_descriptor->GPIO.PIN_MASK;
led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
leds >>= led_shift;
}
}
U32 LED_Read_Display_Field(U32 field)
{
return Rd_bitfield(LED_State, field);
}
void LED_Display_Field(U32 field, U32 leds)
{
// Move the bit-field to the appropriate position for the bit-mask.
LED_Display_Mask(field, leds << ctz(field));
}
U8 LED_Get_Intensity(U32 led)
{
tLED_DESCRIPTOR *led_descriptor;
// Check that the argument value is valid.
led = ctz(led);
led_descriptor = &LED_DESCRIPTOR[led];
if (led >= LED_COUNT || led_descriptor->PWM.CHANNEL < 0) return 0;
// Return the duty cycle value if the LED PWM channel is enabled, else 0.
return (AVR32_PWM.sr & (1 << led_descriptor->PWM.CHANNEL)) ?
AVR32_PWM.channel[led_descriptor->PWM.CHANNEL].cdty : 0;
}
void LED_Set_Intensity(U32 leds, U8 intensity)
{
tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
volatile avr32_pwm_channel_t *led_pwm_channel;
volatile avr32_gpio_port_t *led_gpio_port;
U8 led_shift;
// For each specified LED...
for (leds &= (1 << LED_COUNT) - 1; leds; leds >>= led_shift)
{
// Select the next specified LED and check that it has a PWM channel.
led_shift = 1 + ctz(leds);
led_descriptor += led_shift;
if (led_descriptor->PWM.CHANNEL < 0) continue;
// Initialize or update the LED PWM channel.
led_pwm_channel = &AVR32_PWM.channel[led_descriptor->PWM.CHANNEL];
if (!(AVR32_PWM.sr & (1 << led_descriptor->PWM.CHANNEL)))
{
led_pwm_channel->cmr = (AVR32_PWM_CPRE_MCK << AVR32_PWM_CPRE_OFFSET) &
~(AVR32_PWM_CALG_MASK |
AVR32_PWM_CPOL_MASK |
AVR32_PWM_CPD_MASK);
led_pwm_channel->cprd = 0x000000FF;
led_pwm_channel->cdty = intensity;
AVR32_PWM.ena = 1 << led_descriptor->PWM.CHANNEL;
}
else
{
AVR32_PWM.isr;
while (!(AVR32_PWM.isr & (1 << led_descriptor->PWM.CHANNEL)));
led_pwm_channel->cupd = intensity;
}
// Switch the LED pin to its PWM function.
led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
if (led_descriptor->PWM.FUNCTION & 0x1)
{
led_gpio_port->pmr0s = led_descriptor->GPIO.PIN_MASK;
}
else
{
led_gpio_port->pmr0c = led_descriptor->GPIO.PIN_MASK;
}
if (led_descriptor->PWM.FUNCTION & 0x2)
{
led_gpio_port->pmr1s = led_descriptor->GPIO.PIN_MASK;
}
else
{
led_gpio_port->pmr1c = led_descriptor->GPIO.PIN_MASK;
}
led_gpio_port->gperc = led_descriptor->GPIO.PIN_MASK;
}
}

View File

@ -0,0 +1,191 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief AT32UC3A EVK1100 board LEDs support package.
*
* This file contains definitions and services related to the LED features of
* the EVK1100 board.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 AT32UC3A devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _LED_H_
#define _LED_H_
#include "compiler.h"
/*! \name Identifiers of LEDs to Use with LED Functions
*/
//! @{
#define LED0 0x01
#define LED1 0x02
#define LED2 0x04
#define LED3 0x08
#define LED4 0x10
#define LED5 0x20
#define LED6 0x40
#define LED7 0x80
//! @}
/*! \brief Gets the last state of all LEDs set through the LED API.
*
* \return State of all LEDs (1 bit per LED).
*
* \note The GPIO pin configuration of all LEDs is left unchanged.
*/
extern U32 LED_Read_Display(void);
/*! \brief Sets the state of all LEDs.
*
* \param leds New state of all LEDs (1 bit per LED).
*
* \note The pins of all LEDs are set to GPIO output mode.
*/
extern void LED_Display(U32 leds);
/*! \brief Gets the last state of the specified LEDs set through the LED API.
*
* \param mask LEDs of which to get the state (1 bit per LED).
*
* \return State of the specified LEDs (1 bit per LED).
*
* \note The GPIO pin configuration of all LEDs is left unchanged.
*/
extern U32 LED_Read_Display_Mask(U32 mask);
/*! \brief Sets the state of the specified LEDs.
*
* \param mask LEDs of which to set the state (1 bit per LED).
*
* \param leds New state of the specified LEDs (1 bit per LED).
*
* \note The pins of the specified LEDs are set to GPIO output mode.
*/
extern void LED_Display_Mask(U32 mask, U32 leds);
/*! \brief Tests the last state of the specified LEDs set through the LED API.
*
* \param leds LEDs of which to test the state (1 bit per LED).
*
* \return \c TRUE if at least one of the specified LEDs has a state on, else
* \c FALSE.
*
* \note The GPIO pin configuration of all LEDs is left unchanged.
*/
extern Bool LED_Test(U32 leds);
/*! \brief Turns off the specified LEDs.
*
* \param leds LEDs to turn off (1 bit per LED).
*
* \note The pins of the specified LEDs are set to GPIO output mode.
*/
extern void LED_Off(U32 leds);
/*! \brief Turns on the specified LEDs.
*
* \param leds LEDs to turn on (1 bit per LED).
*
* \note The pins of the specified LEDs are set to GPIO output mode.
*/
extern void LED_On(U32 leds);
/*! \brief Toggles the specified LEDs.
*
* \param leds LEDs to toggle (1 bit per LED).
*
* \note The pins of the specified LEDs are set to GPIO output mode.
*/
extern void LED_Toggle(U32 leds);
/*! \brief Gets as a bit-field the last state of the specified LEDs set through
* the LED API.
*
* \param field LEDs of which to get the state (1 bit per LED).
*
* \return State of the specified LEDs (1 bit per LED, beginning with the first
* specified LED).
*
* \note The GPIO pin configuration of all LEDs is left unchanged.
*/
extern U32 LED_Read_Display_Field(U32 field);
/*! \brief Sets as a bit-field the state of the specified LEDs.
*
* \param field LEDs of which to set the state (1 bit per LED).
* \param leds New state of the specified LEDs (1 bit per LED, beginning with
* the first specified LED).
*
* \note The pins of the specified LEDs are set to GPIO output mode.
*/
extern void LED_Display_Field(U32 field, U32 leds);
/*! \brief Gets the intensity of the specified LED.
*
* \param led LED of which to get the intensity (1 bit per LED; only the least
* significant set bit is used).
*
* \return Intensity of the specified LED (0x00 to 0xFF).
*
* \warning The PWM channel of the specified LED is supposed to be used only by
* this module.
*
* \note The GPIO pin configuration of all LEDs is left unchanged.
*/
extern U8 LED_Get_Intensity(U32 led);
/*! \brief Sets the intensity of the specified LEDs.
*
* \param leds LEDs of which to set the intensity (1 bit per LED).
* \param intensity New intensity of the specified LEDs (0x00 to 0xFF).
*
* \warning The PWM channels of the specified LEDs are supposed to be used only
* by this module.
*
* \note The pins of the specified LEDs are set to PWM output mode.
*/
extern void LED_Set_Intensity(U32 leds, U8 intensity);
#endif // _LED_H_

View File

@ -0,0 +1,433 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief AT32UC3A EVK1105 board header file.
*
* This file contains definitions and services related to the features of the
* EVK1105 board rev. B.
*
* To use this board, define BOARD=EVK1105.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 AT32UC3A devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _EVK1105_H_
#define _EVK1105_H_
#ifdef EVK1105_REV3
# include "evk1105_rev3.h"
#else
#include "compiler.h"
#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling.
# include "led.h"
#endif // __AVR32_ABI_COMPILER__
/*! \name Oscillator Definitions
*/
//! @{
// RCOsc has no custom calibration by default. Set the following definition to
// the appropriate value if a custom RCOsc calibration has been applied to your
// part.
//#define FRCOSC AVR32_PM_RCOSC_FREQUENCY //!< RCOsc frequency: Hz.
#define FOSC32 32768 //!< Osc32 frequency: Hz.
#define OSC32_STARTUP AVR32_PM_OSCCTRL32_STARTUP_8192_RCOSC //!< Osc32 startup time: RCOsc periods.
#define FOSC0 12000000 //!< Osc0 frequency: Hz.
#define OSC0_STARTUP AVR32_PM_OSCCTRL0_STARTUP_2048_RCOSC //!< Osc0 startup time: RCOsc periods.
#define FOSC1 11289600 //!< Osc1 frequency: Hz
#define OSC1_STARTUP AVR32_PM_OSCCTRL1_STARTUP_2048_RCOSC //!< Osc1 startup time: RCOsc periods.
//! @}
/*! \name SDRAM Definitions
*/
//! @{
//! Part header file of used SDRAM(s).
#define SDRAM_PART_HDR "MT48LC16M16A2TG7E/mt48lc16m16a2tg7e.h"
//! Data bus width to use the SDRAM(s) with (16 or 32 bits; always 16 bits on
//! UC3).
#define SDRAM_DBW 16
//! @}
/*! \name USB Definitions
*/
//! @{
//! Multiplexed pin used for USB_ID: AVR32_USBB_USB_ID_x_x.
//! To be selected according to the AVR32_USBB_USB_ID_x_x_PIN and
//! AVR32_USBB_USB_ID_x_x_FUNCTION definitions from <avr32/uc3axxxx.h>.
#define AVR32_USBB_USB_ID_0_2_PIN 21
#define AVR32_USBB_USB_ID_0_2_FUNCTION 2
#define USB_ID AVR32_USBB_USB_ID_0_2
//! Multiplexed pin used for USB_VBOF: AVR32_USBB_USB_VBOF_x_x.
//! To be selected according to the AVR32_USBB_USB_VBOF_x_x_PIN and
//! AVR32_USBB_USB_VBOF_x_x_FUNCTION definitions from <avr32/uc3axxxx.h>.
# define USB_VBOF AVR32_USBB_USB_VBOF_0_1
//! Active level of the USB_VBOF output pin.
# define USB_VBOF_ACTIVE_LEVEL LOW
//! USB overcurrent detection pin.
# define USB_OVERCURRENT_DETECT_PIN AVR32_PIN_PX15
//! @}
//! GPIO connection of the MAC PHY PWR_DOWN/INT signal.
# define MACB_INTERRUPT_PIN AVR32_PIN_PA26
//! Number of LEDs.
#define LED_COUNT 4
/*! \name GPIO Connections of LEDs
*/
//! @{
# define LED0_GPIO AVR32_PIN_PB27
# define LED1_GPIO AVR32_PIN_PB28
# define LED2_GPIO AVR32_PIN_PA05
# define LED3_GPIO AVR32_PIN_PA06
//! @}
/*! \name Color Identifiers of LEDs to Use with LED Functions
*/
//! @{
#define LED_MONO0_GREEN LED0
#define LED_MONO1_GREEN LED1
#define LED_MONO2_GREEN LED2
#define LED_MONO3_GREEN LED3
//! @}
/*! \name PWM Channels of LEDs
*/
//! @{
#define LED0_PWM 4
#define LED1_PWM 5
#define LED2_PWM (-1)
#define LED3_PWM (-1)
//! @}
/*! \name PWM Functions of LEDs
*/
//! @{
/* TODO: Implement PWM functionality */
#define LED0_PWM_FUNCTION (-1)//AVR32_PWM_0_FUNCTION
#define LED1_PWM_FUNCTION (-1)//AVR32_PWM_1_FUNCTION
#define LED2_PWM_FUNCTION (-1)
#define LED3_PWM_FUNCTION (-1)
//! @}
//! External interrupt connection of touch sensor.
#define QT1081_EIC_EXTINT_PIN AVR32_EIC_EXTINT_1_PIN
#define QT1081_EIC_EXTINT_FUNCTION AVR32_EIC_EXTINT_1_FUNCTION
#define QT1081_EIC_EXTINT_IRQ AVR32_EIC_IRQ_1
#define QT1081_EIC_EXTINT_INT AVR32_EIC_INT1
/*! \name Touch sensor low power mode select
*/
#define QT1081_LP_MODE AVR32_PIN_PB29
/*! \name GPIO Connections of touch buttons
*/
//! @{
#define QT1081_TOUCH_SENSOR_0 AVR32_PIN_PB22
#define QT1081_TOUCH_SENSOR_0_PRESSED 1
#define QT1081_TOUCH_SENSOR_1 AVR32_PIN_PB23
#define QT1081_TOUCH_SENSOR_1_PRESSED 1
#define QT1081_TOUCH_SENSOR_2 AVR32_PIN_PB24
#define QT1081_TOUCH_SENSOR_2_PRESSED 1
#define QT1081_TOUCH_SENSOR_3 AVR32_PIN_PB25
#define QT1081_TOUCH_SENSOR_3_PRESSED 1
#define QT1081_TOUCH_SENSOR_4 AVR32_PIN_PB26
#define QT1081_TOUCH_SENSOR_4_PRESSED 1
#define QT1081_TOUCH_SENSOR_ENTER QT1081_TOUCH_SENSOR_4
#define QT1081_TOUCH_SENSOR_ENTER_PRESSED QT1081_TOUCH_SENSOR_4_PRESSED
#define QT1081_TOUCH_SENSOR_LEFT QT1081_TOUCH_SENSOR_3
#define QT1081_TOUCH_SENSOR_LEFT_PRESSED QT1081_TOUCH_SENSOR_3_PRESSED
#define QT1081_TOUCH_SENSOR_RIGHT QT1081_TOUCH_SENSOR_2
#define QT1081_TOUCH_SENSOR_RIGHT_PRESSED QT1081_TOUCH_SENSOR_2_PRESSED
#define QT1081_TOUCH_SENSOR_UP QT1081_TOUCH_SENSOR_0
#define QT1081_TOUCH_SENSOR_UP_PRESSED QT1081_TOUCH_SENSOR_0_PRESSED
#define QT1081_TOUCH_SENSOR_DOWN QT1081_TOUCH_SENSOR_1
#define QT1081_TOUCH_SENSOR_DOWN_PRESSED QT1081_TOUCH_SENSOR_1_PRESSED
//! @}
/*! \name SPI Connections of the AT45DBX Data Flash Memory
*/
//! @{
#define AT45DBX_SPI (&AVR32_SPI0)
#define AT45DBX_SPI_NPCS 0
#define AT45DBX_SPI_SCK_PIN AVR32_SPI0_SCK_0_0_PIN
#define AT45DBX_SPI_SCK_FUNCTION AVR32_SPI0_SCK_0_0_FUNCTION
#define AT45DBX_SPI_MISO_PIN AVR32_SPI0_MISO_0_0_PIN
#define AT45DBX_SPI_MISO_FUNCTION AVR32_SPI0_MISO_0_0_FUNCTION
#define AT45DBX_SPI_MOSI_PIN AVR32_SPI0_MOSI_0_0_PIN
#define AT45DBX_SPI_MOSI_FUNCTION AVR32_SPI0_MOSI_0_0_FUNCTION
#define AT45DBX_SPI_NPCS0_PIN AVR32_SPI0_NPCS_0_0_PIN
#define AT45DBX_SPI_NPCS0_FUNCTION AVR32_SPI0_NPCS_0_0_FUNCTION
//! @}
/*! \name GPIO and SPI Connections of the SD/MMC Connector
*/
//! @{
#define SD_MMC_CARD_DETECT_PIN AVR32_PIN_PA02
#define SD_MMC_WRITE_PROTECT_PIN AVR32_PIN_PA18
#define SD_MMC_SPI (&AVR32_SPI0)
#define SD_MMC_SPI_NPCS 1
#define SD_MMC_SPI_SCK_PIN AVR32_SPI0_SCK_0_0_PIN
#define SD_MMC_SPI_SCK_FUNCTION AVR32_SPI0_SCK_0_0_FUNCTION
#define SD_MMC_SPI_MISO_PIN AVR32_SPI0_MISO_0_0_PIN
#define SD_MMC_SPI_MISO_FUNCTION AVR32_SPI0_MISO_0_0_FUNCTION
#define SD_MMC_SPI_MOSI_PIN AVR32_SPI0_MOSI_0_0_PIN
#define SD_MMC_SPI_MOSI_FUNCTION AVR32_SPI0_MOSI_0_0_FUNCTION
#define SD_MMC_SPI_NPCS_PIN AVR32_SPI0_NPCS_1_0_PIN
#define SD_MMC_SPI_NPCS_FUNCTION AVR32_SPI0_NPCS_1_0_FUNCTION
//! @}
/*! \name TWI expansion
*/
//! @{
#define EXPANSION_TWI (&AVR32_TWI)
#define EXPANSION_RESET AVR32_PIN_PX16
#define EXPANSION_TWI_SCL_PIN AVR32_TWI_SCL_0_0_PIN
#define EXPANSION_TWI_SCL_FUNCTION AVR32_TWI_SCL_0_0_FUNCTION
#define EXPANSION_TWI_SDA_PIN AVR32_TWI_SDA_0_0_PIN
#define EXPANSION_TWI_SDA_FUNCTION AVR32_TWI_SDA_0_0_FUNCTION
//! @}
/*! \name Wireless expansion
*/
#define WEXPANSION_EXTINT_PIN AVR32_EIC_EXTINT_8_PIN
#define WEXPANSION_EXTINT_FUNCTION AVR32_EIC_EXTINT_8_FUNCTION
#define WEXPANSION_GPIO1 AVR32_PIN_PB30
#define WEXPANSION_GPIO2 AVR32_PIN_PB31
#define WEXPANSION_SPI (&AVR32_SPI0)
#define WEXPANSION_SPI_NPCS 2
#define WEXPANSION_SPI_SCK_PIN AVR32_SPI0_SCK_0_0_PIN
#define WEXPANSION_SPI_SCK_FUNCTION AVR32_SPI0_SCK_0_0_FUNCTION
#define WEXPANSION_SPI_MISO_PIN AVR32_SPI0_MISO_0_0_PIN
#define WEXPANSION_SPI_MISO_FUNCTION AVR32_SPI0_MISO_0_0_FUNCTION
#define WEXPANSION_SPI_MOSI_PIN AVR32_SPI0_MOSI_0_0_PIN
#define WEXPANSION_SPI_MOSI_FUNCTION AVR32_SPI0_MOSI_0_0_FUNCTION
#define WEXPANSION_SPI_NPCS_PIN AVR32_SPI0_NPCS_2_0_PIN
#define WEXPANSION_SPI_NPCS_FUNCTION AVR32_SPI0_NPCS_2_0_FUNCTION
//! @}
/*! \name ET024006DHU TFT display
*/
//! @{
#define ET024006DHU_TE_PIN AVR32_PIN_PX19
#define ET024006DHU_RESET_PIN AVR32_PIN_PX22
#define ET024006DHU_BL_PIN AVR32_PWM_6_PIN
#define ET024006DHU_BL_FUNCTION AVR32_PWM_6_FUNCTION
#define ET024006DHU_DNC_PIN AVR32_EBI_ADDR_21_1_PIN
#define ET024006DHU_DNC_FUNCTION AVR32_EBI_ADDR_21_1_FUNCTION
#define ET024006DHU_EBI_NCS_PIN AVR32_EBI_NCS_0_1_PIN
#define ET024006DHU_EBI_NCS_FUNCTION AVR32_EBI_NCS_0_1_FUNCTION
//! @}
/*! \name Optional SPI connection to the TFT
*/
//! @{
#define ET024006DHU_SPI (&AVR32_SPI0)
#define ET024006DHU_SPI_NPCS 3
#define ET024006DHU_SPI_SCK_PIN AVR32_SPI0_SCK_0_0_PIN
#define ET024006DHU_SPI_SCK_FUNCTION AVR32_SPI0_SCK_0_0_FUNCTION
#define ET024006DHU_SPI_MISO_PIN AVR32_SPI0_MISO_0_0_PIN
#define ET024006DHU_SPI_MISO_FUNCTION AVR32_SPI0_MISO_0_0_FUNCTION
#define ET024006DHU_SPI_MOSI_PIN AVR32_SPI0_MOSI_0_0_PIN
#define ET024006DHU_SPI_MOSI_FUNCTION AVR32_SPI0_MOSI_0_0_FUNCTION
#define ET024006DHU_SPI_NPCS_PIN AVR32_SPI1_NPCS_3_0_PIN
#define ET024006DHU_SPI_NPCS_FUNCTION AVR32_SPI1_NPCS_3_0_FUNCTION
//! @}
/*! \name Audio amplifier connection to the DAC
*/
//! @{
#define TPA6130_ABDAC (&AVR32_ABDAC)
#define TPA6130_DATA0_PIN AVR32_ABDAC_DATA_0_1_PIN
#define TPA6130_DATA0_FUNCTION AVR32_ABDAC_DATA_0_1_FUNCTION
#define TPA6130_DATAN0_PIN AVR32_ABDAC_DATAN_0_1_PIN
#define TPA6130_DATAN0_FUNCTION AVR32_ABDAC_DATAN_0_1_FUNCTION
#define TPA6130_DATA1_PIN AVR32_ABDAC_DATA_1_1_PIN
#define TPA6130_DATA1_FUNCTION AVR32_ABDAC_DATA_1_1_FUNCTION
#define TPA6130_DATAN1_PIN AVR32_ABDAC_DATAN_1_1_PIN
#define TPA6130_DATAN1_FUNCTION AVR32_ABDAC_DATAN_1_1_FUNCTION
#define TPA6130_ABDAC_PDCA_PID AVR32_PDCA_PID_ABDAC_TX
#define TPA6130_ABDAC_PDCA_CHANNEL 0
#define TPA6130_ABDAC_PDCA_IRQ AVR32_PDCA_IRQ_0
#define TPA6130_ABDAC_PDCA_INT_LEVEL AVR32_INTC_INT3
#define TPA6130_TWI (&AVR32_TWI)
#define TPA6130_TWI_SCL_PIN AVR32_TWI_SCL_0_0_PIN
#define TPA6130_TWI_SCL_FUNCTION AVR32_TWI_SCL_0_0_FUNCTION
#define TPA6130_TWI_SDA_PIN AVR32_TWI_SDA_0_0_PIN
#define TPA6130_TWI_SDA_FUNCTION AVR32_TWI_SDA_0_0_FUNCTION
//! }@
/*! \name TI TLV320AIC23B sound chip
*/
//! @{
#define TLV320_SSC (&AVR32_SSC)
#define TLV320_SSC_TX_CLOCK_PIN AVR32_SSC_TX_CLOCK_0_PIN
#define TLV320_SSC_TX_CLOCK_FUNCTION AVR32_SSC_TX_CLOCK_0_FUNCTION
#define TLV320_SSC_TX_DATA_PIN AVR32_SSC_TX_DATA_0_PIN
#define TLV320_SSC_TX_DATA_FUNCTION AVR32_SSC_TX_DATA_0_FUNCTION
#define TLV320_SSC_TX_FRAME_SYNC_PIN AVR32_SSC_TX_FRAME_SYNC_0_PIN
#define TLV320_SSC_TX_FRAME_SYNC_FUNCTION AVR32_SSC_TX_FRAME_SYNC_0_FUNCTION
#define TLV320_TWI (&AVR32_TWI)
#define TLV320_TWI_SCL_PIN AVR32_TWI_SCL_0_0_PIN
#define TLV320_TWI_SCL_FUNCTION AVR32_TWI_SCL_0_0_FUNCTION
#define TLV320_TWI_SDA_PIN AVR32_TWI_SDA_0_0_PIN
#define TLV320_TWI_SDA_FUNCTION AVR32_TWI_SDA_0_0_FUNCTION
#define TLV320_PM_GCLK_PIN AVR32_PM_GCLK_0_0_PIN
#define TLV320_PM_GCLK_FUNCTION AVR32_PM_GCLK_0_0_FUNCTION
//! @}
////! \name SPI: Apple Authentication Chip Hardware Connections
////! @{
#define IPOD_AUTH_CHIP_SPI (&AVR32_SPI0)
#define IPOD_AUTH_CHIP_SPI_IRQ AVR32_SPI0_IRQ
#define IPOD_AUTH_CHIP_SPI_NPCS 2
#define IPOD_AUTH_CHIP_SPI_SCK_PIN AVR32_SPI0_SCK_0_0_PIN
#define IPOD_AUTH_CHIP_SPI_SCK_FUNCTION AVR32_SPI0_SCK_0_0_FUNCTION
#define IPOD_AUTH_CHIP_SPI_MISO_PIN AVR32_SPI0_MISO_0_0_PIN
#define IPOD_AUTH_CHIP_SPI_MISO_FUNCTION AVR32_SPI0_MISO_0_0_FUNCTION
#define IPOD_AUTH_CHIP_SPI_MOSI_PIN AVR32_SPI0_MOSI_0_0_PIN
#define IPOD_AUTH_CHIP_SPI_MOSI_FUNCTION AVR32_SPI0_MOSI_0_0_FUNCTION
#define IPOD_AUTH_CHIP_SPI_NPCS_PIN AVR32_SPI0_NPCS_2_0_PIN
#define IPOD_AUTH_CHIP_SPI_NPCS_FUNCTION AVR32_SPI0_NPCS_2_0_FUNCTION
#define IPOD_AUTH_CHIP_SPI_N_RESET_PIN AVR32_PIN_PB30
#define IPOD_AUTH_CHIP_SPI_CP_READY_PIN AVR32_PIN_PB31
//! }@
/*! \name Connections of the iPOD Authentication Coprocessor
*/
//! @{
#define IPOD_AUTH_CHIP_TWI (&AVR32_TWI)
#define IPOD_AUTH_CHIP_TWI_SCL_PIN AVR32_TWI_SCL_0_0_PIN
#define IPOD_AUTH_CHIP_TWI_SCL_FUNCTION AVR32_TWI_SCL_0_0_FUNCTION
#define IPOD_AUTH_CHIP_TWI_SDA_PIN AVR32_TWI_SDA_0_0_PIN
#define IPOD_AUTH_CHIP_TWI_SDA_FUNCTION AVR32_TWI_SDA_0_0_FUNCTION
#define IPOD_AUTH_CHIP_TWI_N_RESET_PIN AVR32_PIN_PX16
//! @}
/*! \name USART connection to the UC3B board controller
*/
//! @{
#define USART0_RXD_PIN AVR32_USART0_RXD_0_0_PIN
#define USART0_RXD_FUNCTION AVR32_USART0_RXD_0_0_FUNCTION
#define USART0_TXD_PIN AVR32_USART0_TXD_0_0_PIN
#define USART0_TXD_FUNCTION AVR32_USART0_TXD_0_0_FUNCTION
#define USART0_RTS_PIN AVR32_USART0_RTS_0_0_PIN
#define USART0_RTS_FUNCTION AVR32_USART0_RTS_0_0_FUNCTION
#define USART0_CTS_PIN AVR32_USART0_CTS_0_0_PIN
#define USART0_CTS_FUNCTION AVR32_USART0_CTS_0_0_FUNCTION
//! @}
#define ADC_VEXT_PIN AVR32_ADC_AD_7_PIN
#define ADC_VEXT_FUNCTION AVR32_ADC_AD_7_FUNCTION
/*! \name LCD Connections of the ET024006DHU display
*/
//! @{
#define ET024006DHU_SMC_USE_NCS 0
#define ET024006DHU_SMC_COMPONENT_CS "smc_et024006dhu.h"
#define ET024006DHU_EBI_DATA_0 AVR32_EBI_DATA_0
#define ET024006DHU_EBI_DATA_1 AVR32_EBI_DATA_1
#define ET024006DHU_EBI_DATA_2 AVR32_EBI_DATA_2
#define ET024006DHU_EBI_DATA_3 AVR32_EBI_DATA_3
#define ET024006DHU_EBI_DATA_4 AVR32_EBI_DATA_4
#define ET024006DHU_EBI_DATA_5 AVR32_EBI_DATA_5
#define ET024006DHU_EBI_DATA_6 AVR32_EBI_DATA_6
#define ET024006DHU_EBI_DATA_7 AVR32_EBI_DATA_7
#define ET024006DHU_EBI_DATA_8 AVR32_EBI_DATA_8
#define ET024006DHU_EBI_DATA_9 AVR32_EBI_DATA_9
#define ET024006DHU_EBI_DATA_10 AVR32_EBI_DATA_10
#define ET024006DHU_EBI_DATA_11 AVR32_EBI_DATA_11
#define ET024006DHU_EBI_DATA_12 AVR32_EBI_DATA_12
#define ET024006DHU_EBI_DATA_13 AVR32_EBI_DATA_13
#define ET024006DHU_EBI_DATA_14 AVR32_EBI_DATA_14
#define ET024006DHU_EBI_DATA_15 AVR32_EBI_DATA_15
#define ET024006DHU_EBI_ADDR_21 AVR32_EBI_ADDR_21_1
#define ET024006DHU_EBI_NWE AVR32_EBI_NWE0_0
#define ET024006DHU_EBI_NRD AVR32_EBI_NRD_0
#define ET024006DHU_EBI_NCS AVR32_EBI_NCS_0_1
//! @}
#endif // !EVK1105_REVA
#endif // _EVK1105_H_

View File

@ -0,0 +1,346 @@
/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief AT32UC3A EVK1105 board LEDs support package.
*
* This file contains definitions and services related to the LED features of
* the EVK1105 board.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 AT32UC3A devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#include <avr32/io.h>
#include "preprocessor.h"
#include "compiler.h"
#include "evk1105.h"
#include "led.h"
//! Structure describing LED hardware connections.
typedef const struct
{
struct
{
U32 PORT; //!< LED GPIO port.
U32 PIN_MASK; //!< Bit-mask of LED pin in GPIO port.
} GPIO; //!< LED GPIO descriptor.
struct
{
S32 CHANNEL; //!< LED PWM channel (< 0 if N/A).
S32 FUNCTION; //!< LED pin PWM function (< 0 if N/A).
} PWM; //!< LED PWM descriptor.
} tLED_DESCRIPTOR;
//! Hardware descriptors of all LEDs.
static tLED_DESCRIPTOR LED_DESCRIPTOR[LED_COUNT] =
{
#define INSERT_LED_DESCRIPTOR(LED_NO, unused) \
{ \
{LED##LED_NO##_GPIO / 32, 1 << (LED##LED_NO##_GPIO % 32)},\
{LED##LED_NO##_PWM, LED##LED_NO##_PWM_FUNCTION } \
},
MREPEAT(LED_COUNT, INSERT_LED_DESCRIPTOR, ~)
#undef INSERT_LED_DESCRIPTOR
};
//! Saved state of all LEDs.
static volatile U32 LED_State = (1 << LED_COUNT) - 1;
U32 LED_Read_Display(void)
{
return LED_State;
}
void LED_Display(U32 leds)
{
// Use the LED descriptors to get the connections of a given LED to the MCU.
tLED_DESCRIPTOR *led_descriptor;
volatile avr32_gpio_port_t *led_gpio_port;
// Make sure only existing LEDs are specified.
leds &= (1 << LED_COUNT) - 1;
// Update the saved state of all LEDs with the requested changes.
LED_State = leds;
// For all LEDs...
for (led_descriptor = &LED_DESCRIPTOR[0];
led_descriptor < LED_DESCRIPTOR + LED_COUNT;
led_descriptor++)
{
// Set the LED to the requested state.
led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
if (leds & 1)
{
led_gpio_port->ovrc = led_descriptor->GPIO.PIN_MASK;
}
else
{
led_gpio_port->ovrs = led_descriptor->GPIO.PIN_MASK;
}
led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
leds >>= 1;
}
}
U32 LED_Read_Display_Mask(U32 mask)
{
return Rd_bits(LED_State, mask);
}
void LED_Display_Mask(U32 mask, U32 leds)
{
// Use the LED descriptors to get the connections of a given LED to the MCU.
tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
volatile avr32_gpio_port_t *led_gpio_port;
U8 led_shift;
// Make sure only existing LEDs are specified.
mask &= (1 << LED_COUNT) - 1;
// Update the saved state of all LEDs with the requested changes.
Wr_bits(LED_State, mask, leds);
// While there are specified LEDs left to manage...
while (mask)
{
// Select the next specified LED and set it to the requested state.
led_shift = 1 + ctz(mask);
led_descriptor += led_shift;
led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
leds >>= led_shift - 1;
if (leds & 1)
{
led_gpio_port->ovrc = led_descriptor->GPIO.PIN_MASK;
}
else
{
led_gpio_port->ovrs = led_descriptor->GPIO.PIN_MASK;
}
led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
leds >>= 1;
mask >>= led_shift;
}
}
Bool LED_Test(U32 leds)
{
return Tst_bits(LED_State, leds);
}
void LED_Off(U32 leds)
{
// Use the LED descriptors to get the connections of a given LED to the MCU.
tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
volatile avr32_gpio_port_t *led_gpio_port;
U8 led_shift;
// Make sure only existing LEDs are specified.
leds &= (1 << LED_COUNT) - 1;
// Update the saved state of all LEDs with the requested changes.
Clr_bits(LED_State, leds);
// While there are specified LEDs left to manage...
while (leds)
{
// Select the next specified LED and turn it off.
led_shift = 1 + ctz(leds);
led_descriptor += led_shift;
led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
led_gpio_port->ovrs = led_descriptor->GPIO.PIN_MASK;
led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
leds >>= led_shift;
}
}
void LED_On(U32 leds)
{
// Use the LED descriptors to get the connections of a given LED to the MCU.
tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
volatile avr32_gpio_port_t *led_gpio_port;
U8 led_shift;
// Make sure only existing LEDs are specified.
leds &= (1 << LED_COUNT) - 1;
// Update the saved state of all LEDs with the requested changes.
Set_bits(LED_State, leds);
// While there are specified LEDs left to manage...
while (leds)
{
// Select the next specified LED and turn it on.
led_shift = 1 + ctz(leds);
led_descriptor += led_shift;
led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
led_gpio_port->ovrc = led_descriptor->GPIO.PIN_MASK;
led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
leds >>= led_shift;
}
}
void LED_Toggle(U32 leds)
{
// Use the LED descriptors to get the connections of a given LED to the MCU.
tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
volatile avr32_gpio_port_t *led_gpio_port;
U8 led_shift;
// Make sure only existing LEDs are specified.
leds &= (1 << LED_COUNT) - 1;
// Update the saved state of all LEDs with the requested changes.
Tgl_bits(LED_State, leds);
// While there are specified LEDs left to manage...
while (leds)
{
// Select the next specified LED and toggle it.
led_shift = 1 + ctz(leds);
led_descriptor += led_shift;
led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
led_gpio_port->ovrt = led_descriptor->GPIO.PIN_MASK;
led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
leds >>= led_shift;
}
}
U32 LED_Read_Display_Field(U32 field)
{
return Rd_bitfield(LED_State, field);
}
void LED_Display_Field(U32 field, U32 leds)
{
// Move the bit-field to the appropriate position for the bit-mask.
LED_Display_Mask(field, leds << ctz(field));
}
U8 LED_Get_Intensity(U32 led)
{
tLED_DESCRIPTOR *led_descriptor;
// Check that the argument value is valid.
led = ctz(led);
led_descriptor = &LED_DESCRIPTOR[led];
if (led >= LED_COUNT || led_descriptor->PWM.CHANNEL < 0) return 0;
// Return the duty cycle value if the LED PWM channel is enabled, else 0.
return (AVR32_PWM.sr & (1 << led_descriptor->PWM.CHANNEL)) ?
AVR32_PWM.channel[led_descriptor->PWM.CHANNEL].cdty : 0;
}
void LED_Set_Intensity(U32 leds, U8 intensity)
{
tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
volatile avr32_pwm_channel_t *led_pwm_channel;
volatile avr32_gpio_port_t *led_gpio_port;
U8 led_shift;
// For each specified LED...
for (leds &= (1 << LED_COUNT) - 1; leds; leds >>= led_shift)
{
// Select the next specified LED and check that it has a PWM channel.
led_shift = 1 + ctz(leds);
led_descriptor += led_shift;
if (led_descriptor->PWM.CHANNEL < 0) continue;
// Initialize or update the LED PWM channel.
led_pwm_channel = &AVR32_PWM.channel[led_descriptor->PWM.CHANNEL];
if (!(AVR32_PWM.sr & (1 << led_descriptor->PWM.CHANNEL)))
{
led_pwm_channel->cmr = (AVR32_PWM_CPRE_MCK << AVR32_PWM_CPRE_OFFSET) &
~(AVR32_PWM_CALG_MASK |
AVR32_PWM_CPOL_MASK |
AVR32_PWM_CPD_MASK);
led_pwm_channel->cprd = 0x000000FF;
led_pwm_channel->cdty = intensity;
AVR32_PWM.ena = 1 << led_descriptor->PWM.CHANNEL;
}
else
{
AVR32_PWM.isr;
while (!(AVR32_PWM.isr & (1 << led_descriptor->PWM.CHANNEL)));
led_pwm_channel->cupd = intensity;
}
// Switch the LED pin to its PWM function.
led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
if (led_descriptor->PWM.FUNCTION & 0x1)
{
led_gpio_port->pmr0s = led_descriptor->GPIO.PIN_MASK;
}
else
{
led_gpio_port->pmr0c = led_descriptor->GPIO.PIN_MASK;
}
if (led_descriptor->PWM.FUNCTION & 0x2)
{
led_gpio_port->pmr1s = led_descriptor->GPIO.PIN_MASK;
}
else
{
led_gpio_port->pmr1c = led_descriptor->GPIO.PIN_MASK;
}
led_gpio_port->gperc = led_descriptor->GPIO.PIN_MASK;
}
}

View File

@ -0,0 +1,187 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief AT32UC3A EVK1105 board LEDs support package.
*
* This file contains definitions and services related to the LED features of
* the EVK1105 board.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 AT32UC3A devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _LED_H_
#define _LED_H_
#include "compiler.h"
/*! \name Identifiers of LEDs to Use with LED Functions
*/
//! @{
#define LED0 0x01
#define LED1 0x02
#define LED2 0x04
#define LED3 0x08
//! @}
/*! \brief Gets the last state of all LEDs set through the LED API.
*
* \return State of all LEDs (1 bit per LED).
*
* \note The GPIO pin configuration of all LEDs is left unchanged.
*/
extern U32 LED_Read_Display(void);
/*! \brief Sets the state of all LEDs.
*
* \param leds New state of all LEDs (1 bit per LED).
*
* \note The pins of all LEDs are set to GPIO output mode.
*/
extern void LED_Display(U32 leds);
/*! \brief Gets the last state of the specified LEDs set through the LED API.
*
* \param mask LEDs of which to get the state (1 bit per LED).
*
* \return State of the specified LEDs (1 bit per LED).
*
* \note The GPIO pin configuration of all LEDs is left unchanged.
*/
extern U32 LED_Read_Display_Mask(U32 mask);
/*! \brief Sets the state of the specified LEDs.
*
* \param mask LEDs of which to set the state (1 bit per LED).
*
* \param leds New state of the specified LEDs (1 bit per LED).
*
* \note The pins of the specified LEDs are set to GPIO output mode.
*/
extern void LED_Display_Mask(U32 mask, U32 leds);
/*! \brief Tests the last state of the specified LEDs set through the LED API.
*
* \param leds LEDs of which to test the state (1 bit per LED).
*
* \return \c TRUE if at least one of the specified LEDs has a state on, else
* \c FALSE.
*
* \note The GPIO pin configuration of all LEDs is left unchanged.
*/
extern Bool LED_Test(U32 leds);
/*! \brief Turns off the specified LEDs.
*
* \param leds LEDs to turn off (1 bit per LED).
*
* \note The pins of the specified LEDs are set to GPIO output mode.
*/
extern void LED_Off(U32 leds);
/*! \brief Turns on the specified LEDs.
*
* \param leds LEDs to turn on (1 bit per LED).
*
* \note The pins of the specified LEDs are set to GPIO output mode.
*/
extern void LED_On(U32 leds);
/*! \brief Toggles the specified LEDs.
*
* \param leds LEDs to toggle (1 bit per LED).
*
* \note The pins of the specified LEDs are set to GPIO output mode.
*/
extern void LED_Toggle(U32 leds);
/*! \brief Gets as a bit-field the last state of the specified LEDs set through
* the LED API.
*
* \param field LEDs of which to get the state (1 bit per LED).
*
* \return State of the specified LEDs (1 bit per LED, beginning with the first
* specified LED).
*
* \note The GPIO pin configuration of all LEDs is left unchanged.
*/
extern U32 LED_Read_Display_Field(U32 field);
/*! \brief Sets as a bit-field the state of the specified LEDs.
*
* \param field LEDs of which to set the state (1 bit per LED).
* \param leds New state of the specified LEDs (1 bit per LED, beginning with
* the first specified LED).
*
* \note The pins of the specified LEDs are set to GPIO output mode.
*/
extern void LED_Display_Field(U32 field, U32 leds);
/*! \brief Gets the intensity of the specified LED.
*
* \param led LED of which to get the intensity (1 bit per LED; only the least
* significant set bit is used).
*
* \return Intensity of the specified LED (0x00 to 0xFF).
*
* \warning The PWM channel of the specified LED is supposed to be used only by
* this module.
*
* \note The GPIO pin configuration of all LEDs is left unchanged.
*/
extern U8 LED_Get_Intensity(U32 led);
/*! \brief Sets the intensity of the specified LEDs.
*
* \param leds LEDs of which to set the intensity (1 bit per LED).
* \param intensity New intensity of the specified LEDs (0x00 to 0xFF).
*
* \warning The PWM channels of the specified LEDs are supposed to be used only
* by this module.
*
* \note The pins of the specified LEDs are set to PWM output mode.
*/
extern void LED_Set_Intensity(U32 leds, U8 intensity);
#endif // _LED_H_

View File

@ -0,0 +1,120 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Standard board header file.
*
* This file includes the appropriate board header file according to the
* defined board.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _BOARD_H_
#define _BOARD_H_
#include <avr32/io.h>
/*! \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 STK1000 6 //!< AT32AP7000 STK1000 board.
#define NGW100 7 //!< AT32AP7000 NGW100 board.
#define STK600_RCUC3L0 8 //!< STK600 RCUC3L0 board.
#define UC3L_EK 9 //!< AT32UC3L-EK board.
#define USER_BOARD 99 //!< User-reserved board (if any).
//! @}
/*! \name Extension Boards
*/
//! @{
#define EXT1102 1 //!< AT32UC3B EXT1102 board.
#define MC300 2 //!< AT32UC3 MC300 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 == STK1000
#include "STK1000/stk1000.h"
#elif BOARD == NGW100
#include "NGW100/ngw100.h"
#elif BOARD == STK600_RCUC3L0
#include "STK600/RCUC3L0/stk600_rcuc3l0.h"
#elif BOARD == UC3L_EK
#include "UC3L_EK/uc3l_ek.h"
#elif BOARD == ARDUINO
#include "ARDUINO/arduino.h"
#else
#error No known AVR32 board defined
#endif
#if (defined EXT_BOARD)
#if EXT_BOARD == EXT1102
#include "EXT1102/ext1102.h"
#elif EXT_BOARD == MC300
#include "MC300/mc300.h"
#elif EXT_BOARD == USER_EXT_BOARD
// User-reserved area: #include the header file of your extension board here
// (if any).
#endif
#endif
#ifndef FRCOSC
#define FRCOSC AVR32_PM_RCOSC_FREQUENCY //!< Default RCOsc frequency.
#endif
#endif // _BOARD_H_

View File

@ -0,0 +1,120 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Standard board header file.
*
* This file includes the appropriate board header file according to the
* defined board.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _BOARD_H_
#define _BOARD_H_
#include <avr32/io.h>
/*! \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 STK1000 6 //!< AT32AP7000 STK1000 board.
#define NGW100 7 //!< AT32AP7000 NGW100 board.
#define STK600_RCUC3L0 8 //!< STK600 RCUC3L0 board.
#define UC3L_EK 9 //!< AT32UC3L-EK board.
#define USER_BOARD 99 //!< User-reserved board (if any).
//! @}
/*! \name Extension Boards
*/
//! @{
#define EXT1102 1 //!< AT32UC3B EXT1102 board.
#define MC300 2 //!< AT32UC3 MC300 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 == STK1000
#include "STK1000/stk1000.h"
#elif BOARD == NGW100
#include "NGW100/ngw100.h"
#elif BOARD == STK600_RCUC3L0
#include "STK600/RCUC3L0/stk600_rcuc3l0.h"
#elif BOARD == UC3L_EK
#include "UC3L_EK/uc3l_ek.h"
#elif BOARD == ARDUINO
#include "ARDUINO/arduino.h"
#else
#error No known AVR32 board defined
#endif
#if (defined EXT_BOARD)
#if EXT_BOARD == EXT1102
#include "EXT1102/ext1102.h"
#elif EXT_BOARD == MC300
#include "MC300/mc300.h"
#elif EXT_BOARD == USER_EXT_BOARD
// User-reserved area: #include the header file of your extension board here
// (if any).
#endif
#endif
#ifndef FRCOSC
#define FRCOSC AVR32_PM_RCOSC_FREQUENCY //!< Default RCOsc frequency.
#endif
#endif // _BOARD_H_

View File

@ -0,0 +1,653 @@
/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Management of the AT45DBX data flash controller through SPI.
*
* This file manages the accesses to the AT45DBX data flash components.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with an SPI module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
//_____ I N C L U D E S ___________________________________________________
#include "conf_access.h"
#if AT45DBX_MEM == ENABLE
#include "compiler.h"
#include "board.h"
#include "gpio.h"
#include "spi.h"
#include "conf_at45dbx.h"
#include "at45dbx.h"
#if AT45DBX_MEM_CNT > 4
#error AT45DBX_MEM_CNT must not exceed 4
#endif
//_____ D E F I N I T I O N S ______________________________________________
/*! \name AT45DBX Group A Commands
*/
//! @{
#define AT45DBX_CMDA_RD_PAGE 0xD2 //!< Main Memory Page Read (Serial/8-bit Mode).
#define AT45DBX_CMDA_RD_ARRAY_LEG 0xE8 //!< Continuous Array Read, Legacy Command (Serial/8-bit Mode).
#define AT45DBX_CMDA_RD_ARRAY_LF_SM 0x03 //!< Continuous Array Read, Low-Frequency Mode (Serial Mode).
#define AT45DBX_CMDA_RD_ARRAY_AF_SM 0x0B //!< Continuous Array Read, Any-Frequency Mode (Serial Mode).
#define AT45DBX_CMDA_RD_SECTOR_PROT_REG 0x32 //!< Read Sector Protection Register (Serial/8-bit Mode).
#define AT45DBX_CMDA_RD_SECTOR_LKDN_REG 0x35 //!< Read Sector Lockdown Register (Serial/8-bit Mode).
#define AT45DBX_CMDA_RD_SECURITY_REG 0x77 //!< Read Security Register (Serial/8-bit Mode).
//! @}
/*! \name AT45DBX Group B Commands
*/
//! @{
#define AT45DBX_CMDB_ER_PAGE 0x81 //!< Page Erase (Serial/8-bit Mode).
#define AT45DBX_CMDB_ER_BLOCK 0x50 //!< Block Erase (Serial/8-bit Mode).
#define AT45DBX_CMDB_ER_SECTOR 0x7C //!< Sector Erase (Serial/8-bit Mode).
#define AT45DBX_CMDB_ER_CHIP 0xC794809A //!< Chip Erase (Serial/8-bit Mode).
#define AT45DBX_CMDB_XFR_PAGE_TO_BUF1 0x53 //!< Main Memory Page to Buffer 1 Transfer (Serial/8-bit Mode).
#define AT45DBX_CMDB_XFR_PAGE_TO_BUF2 0x55 //!< Main Memory Page to Buffer 2 Transfer (Serial/8-bit Mode).
#define AT45DBX_CMDB_CMP_PAGE_TO_BUF1 0x60 //!< Main Memory Page to Buffer 1 Compare (Serial/8-bit Mode).
#define AT45DBX_CMDB_CMP_PAGE_TO_BUF2 0x61 //!< Main Memory Page to Buffer 2 Compare (Serial/8-bit Mode).
#define AT45DBX_CMDB_PR_BUF1_TO_PAGE_ER 0x83 //!< Buffer 1 to Main Memory Page Program with Built-in Erase (Serial/8-bit Mode).
#define AT45DBX_CMDB_PR_BUF2_TO_PAGE_ER 0x86 //!< Buffer 2 to Main Memory Page Program with Built-in Erase (Serial/8-bit Mode).
#define AT45DBX_CMDB_PR_BUF1_TO_PAGE 0x88 //!< Buffer 1 to Main Memory Page Program without Built-in Erase (Serial/8-bit Mode).
#define AT45DBX_CMDB_PR_BUF2_TO_PAGE 0x89 //!< Buffer 2 to Main Memory Page Program without Built-in Erase (Serial/8-bit Mode).
#define AT45DBX_CMDB_PR_PAGE_TH_BUF1 0x82 //!< Main Memory Page Program through Buffer 1 (Serial/8-bit Mode).
#define AT45DBX_CMDB_PR_PAGE_TH_BUF2 0x85 //!< Main Memory Page Program through Buffer 2 (Serial/8-bit Mode).
#define AT45DBX_CMDB_RWR_PAGE_TH_BUF1 0x58 //!< Auto Page Rewrite through Buffer 1 (Serial/8-bit Mode).
#define AT45DBX_CMDB_RWR_PAGE_TH_BUF2 0x59 //!< Auto Page Rewrite through Buffer 2 (Serial/8-bit Mode).
//! @}
/*! \name AT45DBX Group C Commands
*/
//! @{
#define AT45DBX_CMDC_RD_BUF1_LF_SM 0xD1 //!< Buffer 1 Read, Low-Frequency Mode (Serial Mode).
#define AT45DBX_CMDC_RD_BUF2_LF_SM 0xD3 //!< Buffer 2 Read, Low-Frequency Mode (Serial Mode).
#define AT45DBX_CMDC_RD_BUF1_AF_SM 0xD4 //!< Buffer 1 Read, Any-Frequency Mode (Serial Mode).
#define AT45DBX_CMDC_RD_BUF2_AF_SM 0xD6 //!< Buffer 2 Read, Any-Frequency Mode (Serial Mode).
#define AT45DBX_CMDC_RD_BUF1_AF_8M 0x54 //!< Buffer 1 Read, Any-Frequency Mode (8-bit Mode).
#define AT45DBX_CMDC_RD_BUF2_AF_8M 0x56 //!< Buffer 2 Read, Any-Frequency Mode (8-bit Mode).
#define AT45DBX_CMDC_WR_BUF1 0x84 //!< Buffer 1 Write (Serial/8-bit Mode).
#define AT45DBX_CMDC_WR_BUF2 0x87 //!< Buffer 2 Write (Serial/8-bit Mode).
#define AT45DBX_CMDC_RD_STATUS_REG 0xD7 //!< Status Register Read (Serial/8-bit Mode).
#define AT45DBX_CMDC_RD_MNFCT_DEV_ID_SM 0x9F //!< Manufacturer and Device ID Read (Serial Mode).
//! @}
/*! \name AT45DBX Group D Commands
*/
//! @{
#define AT45DBX_CMDD_EN_SECTOR_PROT 0x3D2A7FA9 //!< Enable Sector Protection (Serial/8-bit Mode).
#define AT45DBX_CMDD_DIS_SECTOR_PROT 0x3D2A7F9A //!< Disable Sector Protection (Serial/8-bit Mode).
#define AT45DBX_CMDD_ER_SECTOR_PROT_REG 0x3D2A7FCF //!< Erase Sector Protection Register (Serial/8-bit Mode).
#define AT45DBX_CMDD_PR_SECTOR_PROT_REG 0x3D2A7FFC //!< Program Sector Protection Register (Serial/8-bit Mode).
#define AT45DBX_CMDD_LKDN_SECTOR 0x3D2A7F30 //!< Sector Lockdown (Serial/8-bit Mode).
#define AT45DBX_CMDD_PR_SECURITY_REG 0x9B000000 //!< Program Security Register (Serial/8-bit Mode).
#define AT45DBX_CMDD_PR_CONF_REG 0x3D2A80A6 //!< Program Configuration Register (Serial/8-bit Mode).
#define AT45DBX_CMDD_DEEP_PWR_DN 0xB9 //!< Deep Power-down (Serial/8-bit Mode).
#define AT45DBX_CMDD_RSM_DEEP_PWR_DN 0xAB //!< Resume from Deep Power-down (Serial/8-bit Mode).
//! @}
/*! \name Bit-Masks and Values for the Status Register
*/
//! @{
#define AT45DBX_MSK_BUSY 0x80 //!< Busy status bit-mask.
#define AT45DBX_BUSY 0x00 //!< Busy status value (0x00 when busy, 0x80 when ready).
#define AT45DBX_MSK_DENSITY 0x3C //!< Device density bit-mask.
//! @}
#if AT45DBX_MEM_SIZE == AT45DBX_1MB
/*! \name AT45DB081 Memories
*/
//! @{
#define AT45DBX_DENSITY 0x24 //!< Device density value.
#define AT45DBX_BYTE_ADDR_BITS 9 //!< Address bits for byte position within buffer.
//! @}
#elif AT45DBX_MEM_SIZE == AT45DBX_2MB
/*! \name AT45DB161 Memories
*/
//! @{
#define AT45DBX_DENSITY 0x2C //!< Device density value.
#define AT45DBX_BYTE_ADDR_BITS 10 //!< Address bits for byte position within buffer.
//! @}
#elif AT45DBX_MEM_SIZE == AT45DBX_4MB
/*! \name AT45DB321 Memories
*/
//! @{
#define AT45DBX_DENSITY 0x34 //!< Device density value.
#define AT45DBX_BYTE_ADDR_BITS 10 //!< Address bits for byte position within buffer.
//! @}
#elif AT45DBX_MEM_SIZE == AT45DBX_8MB
/*! \name AT45DB642 Memories
*/
//! @{
#define AT45DBX_DENSITY 0x3C //!< Device density value.
#define AT45DBX_BYTE_ADDR_BITS 11 //!< Address bits for byte position within buffer.
//! @}
#else
#error AT45DBX_MEM_SIZE is not defined to a supported value
#endif
//! Address bits for page selection.
#define AT45DBX_PAGE_ADDR_BITS (AT45DBX_MEM_SIZE - AT45DBX_PAGE_BITS)
//! Number of bits for addresses within pages.
#define AT45DBX_PAGE_BITS (AT45DBX_BYTE_ADDR_BITS - 1)
//! Page size in bytes.
#define AT45DBX_PAGE_SIZE (1 << AT45DBX_PAGE_BITS)
//! Bit-mask for byte position within buffer in \ref gl_ptr_mem.
#define AT45DBX_MSK_PTR_BYTE ((1 << AT45DBX_PAGE_BITS) - 1)
//! Bit-mask for page selection in \ref gl_ptr_mem.
#define AT45DBX_MSK_PTR_PAGE (((1 << AT45DBX_PAGE_ADDR_BITS) - 1) << AT45DBX_PAGE_BITS)
//! Bit-mask for byte position within sector in \ref gl_ptr_mem.
#define AT45DBX_MSK_PTR_SECTOR ((1 << AT45DBX_SECTOR_BITS) - 1)
/*! \brief Sends a dummy byte through SPI.
*/
#define spi_write_dummy() spi_write(AT45DBX_SPI, 0xFF)
//! Boolean indicating whether memory is in busy state.
static Bool at45dbx_busy;
//! Memory data pointer.
static U32 gl_ptr_mem;
//! Sector buffer.
static U8 sector_buf[AT45DBX_SECTOR_SIZE];
/*! \name Control Functions
*/
//! @{
Bool at45dbx_init(spi_options_t spiOptions, unsigned int pba_hz)
{
// Setup SPI registers according to spiOptions.
for (spiOptions.reg = AT45DBX_SPI_FIRST_NPCS;
spiOptions.reg < AT45DBX_SPI_FIRST_NPCS + AT45DBX_MEM_CNT;
spiOptions.reg++)
{
if (spi_setupChipReg(AT45DBX_SPI, &spiOptions, pba_hz) != SPI_OK) return KO;
}
// Memory ready.
at45dbx_busy = FALSE;
return OK;
}
/*! \brief Selects or unselects a DF memory.
*
* \param memidx Memory ID of DF to select or unselect.
* \param bSelect Boolean indicating whether the DF memory has to be selected.
*/
static void at45dbx_chipselect_df(U8 memidx, Bool bSelect)
{
if (bSelect)
{
// Select SPI chip.
spi_selectChip(AT45DBX_SPI, AT45DBX_SPI_FIRST_NPCS + memidx);
}
else
{
// Unselect SPI chip.
spi_unselectChip(AT45DBX_SPI, AT45DBX_SPI_FIRST_NPCS + memidx);
}
}
Bool at45dbx_mem_check(void)
{
U8 df;
U16 status = 0;
// DF memory check.
for (df = 0; df < AT45DBX_MEM_CNT; df++)
{
// Select the DF memory to check.
at45dbx_chipselect_df(df, TRUE);
// Send the Status Register Read command.
spi_write(AT45DBX_SPI, AT45DBX_CMDC_RD_STATUS_REG);
// Send a dummy byte to read the status register.
spi_write_dummy();
spi_read(AT45DBX_SPI, &status);
// Unselect the checked DF memory.
at45dbx_chipselect_df(df, FALSE);
// Unexpected device density value.
if ((status & AT45DBX_MSK_DENSITY) < AT45DBX_DENSITY) return KO;
}
return OK;
}
/*! \brief Waits until the DF is ready.
*/
static void at45dbx_wait_ready(void)
{
U16 status;
// Select the DF memory gl_ptr_mem points to.
at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, TRUE);
// Send the Status Register Read command.
spi_write(AT45DBX_SPI, AT45DBX_CMDC_RD_STATUS_REG);
// Read the status register until the DF is ready.
do
{
// Send a dummy byte to read the status register.
spi_write_dummy();
spi_read(AT45DBX_SPI, &status);
} while ((status & AT45DBX_MSK_BUSY) == AT45DBX_BUSY);
// Unselect the DF memory gl_ptr_mem points to.
at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE);
}
Bool at45dbx_read_open(U32 sector)
{
U32 addr;
// Set the global memory pointer to a byte address.
gl_ptr_mem = sector << AT45DBX_SECTOR_BITS; // gl_ptr_mem = sector * AT45DBX_SECTOR_SIZE.
// If the DF memory is busy, wait until it's ready.
if (at45dbx_busy) at45dbx_wait_ready();
at45dbx_busy = FALSE;
// Select the DF memory gl_ptr_mem points to.
at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, TRUE);
// Initiate a page read at a given sector.
// Send the Main Memory Page Read command.
spi_write(AT45DBX_SPI, AT45DBX_CMDA_RD_PAGE);
// Send the three address bytes, which comprise:
// - (24 - (AT45DBX_PAGE_ADDR_BITS + AT45DBX_BYTE_ADDR_BITS)) reserved bits;
// - then AT45DBX_PAGE_ADDR_BITS bits specifying the page in main memory to be read;
// - then AT45DBX_BYTE_ADDR_BITS bits specifying the starting byte address within that page.
// NOTE: The bits of gl_ptr_mem above the AT45DBX_MEM_SIZE bits are useless for the local
// DF addressing. They are used for DF discrimination when there are several DFs.
addr = (Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_PAGE) << AT45DBX_BYTE_ADDR_BITS) |
Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_BYTE);
spi_write(AT45DBX_SPI, LSB2W(addr));
spi_write(AT45DBX_SPI, LSB1W(addr));
spi_write(AT45DBX_SPI, LSB0W(addr));
// Send 32 don't care clock cycles to initialize the read operation.
spi_write_dummy();
spi_write_dummy();
spi_write_dummy();
spi_write_dummy();
return OK;
}
void at45dbx_read_close(void)
{
// Unselect the DF memory gl_ptr_mem points to.
at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE);
// Memory ready.
at45dbx_busy = FALSE;
}
Bool at45dbx_write_open(U32 sector)
{
U32 addr;
// Set the global memory pointer to a byte address.
gl_ptr_mem = sector << AT45DBX_SECTOR_BITS; // gl_ptr_mem = sector * AT45DBX_SECTOR_SIZE.
// If the DF memory is busy, wait until it's ready.
if (at45dbx_busy) at45dbx_wait_ready();
at45dbx_busy = FALSE;
#if AT45DBX_PAGE_SIZE > AT45DBX_SECTOR_SIZE
// Select the DF memory gl_ptr_mem points to.
at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, TRUE);
// Transfer the content of the current page to buffer 1.
// Send the Main Memory Page to Buffer 1 Transfer command.
spi_write(AT45DBX_SPI, AT45DBX_CMDB_XFR_PAGE_TO_BUF1);
// Send the three address bytes, which comprise:
// - (24 - (AT45DBX_PAGE_ADDR_BITS + AT45DBX_BYTE_ADDR_BITS)) reserved bits;
// - then AT45DBX_PAGE_ADDR_BITS bits specifying the page in main memory to be read;
// - then AT45DBX_BYTE_ADDR_BITS don't care bits.
// NOTE: The bits of gl_ptr_mem above the AT45DBX_MEM_SIZE bits are useless for the local
// DF addressing. They are used for DF discrimination when there are several DFs.
addr = Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_PAGE) << AT45DBX_BYTE_ADDR_BITS;
spi_write(AT45DBX_SPI, LSB2W(addr));
spi_write(AT45DBX_SPI, LSB1W(addr));
spi_write(AT45DBX_SPI, LSB0W(addr));
// Unselect the DF memory gl_ptr_mem points to.
at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE);
// Wait for end of page transfer.
at45dbx_wait_ready();
#endif
// Select the DF memory gl_ptr_mem points to.
at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, TRUE);
// Initiate a page write at a given sector.
// Send the Main Memory Page Program through Buffer 1 command.
spi_write(AT45DBX_SPI, AT45DBX_CMDB_PR_PAGE_TH_BUF1);
// Send the three address bytes, which comprise:
// - (24 - (AT45DBX_PAGE_ADDR_BITS + AT45DBX_BYTE_ADDR_BITS)) reserved bits;
// - then AT45DBX_PAGE_ADDR_BITS bits specifying the page in main memory to be written;
// - then AT45DBX_BYTE_ADDR_BITS bits specifying the starting byte address within that page.
// NOTE: The bits of gl_ptr_mem above the AT45DBX_MEM_SIZE bits are useless for the local
// DF addressing. They are used for DF discrimination when there are several DFs.
addr = (Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_PAGE) << AT45DBX_BYTE_ADDR_BITS) |
Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_BYTE);
spi_write(AT45DBX_SPI, LSB2W(addr));
spi_write(AT45DBX_SPI, LSB1W(addr));
spi_write(AT45DBX_SPI, LSB0W(addr));
return OK;
}
void at45dbx_write_close(void)
{
// While end of logical sector not reached, zero-fill remaining memory bytes.
while (Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_SECTOR))
{
spi_write(AT45DBX_SPI, 0x00);
gl_ptr_mem++;
}
// Unselect the DF memory gl_ptr_mem points to.
at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE);
// Memory busy.
at45dbx_busy = TRUE;
}
//! @}
/*! \name Single-Byte Access Functions
*/
//! @{
U8 at45dbx_read_byte(void)
{
U16 data;
// Memory busy.
if (at45dbx_busy)
{
// Being here, we know that we previously finished a page read.
// => We have to access the next page.
// Memory ready.
at45dbx_busy = FALSE;
// Eventually select the next DF and open the next page.
// NOTE: at45dbx_read_open input parameter is a sector.
at45dbx_read_open(gl_ptr_mem >> AT45DBX_SECTOR_BITS); // gl_ptr_mem / AT45DBX_SECTOR_SIZE.
}
// Send a dummy byte to read the next data byte.
spi_write_dummy();
spi_read(AT45DBX_SPI, &data);
gl_ptr_mem++;
// If end of page reached,
if (!Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_BYTE))
{
// unselect the DF memory gl_ptr_mem points to.
at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE);
// Memory busy.
at45dbx_busy = TRUE;
}
return data;
}
Bool at45dbx_write_byte(U8 b)
{
// Memory busy.
if (at45dbx_busy)
{
// Being here, we know that we previously launched a page programming.
// => We have to access the next page.
// Eventually select the next DF and open the next page.
// NOTE: at45dbx_write_open input parameter is a sector.
at45dbx_write_open(gl_ptr_mem >> AT45DBX_SECTOR_BITS); // gl_ptr_mem / AT45DBX_SECTOR_SIZE.
}
// Write the next data byte.
spi_write(AT45DBX_SPI, b);
gl_ptr_mem++;
// If end of page reached,
if (!Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_BYTE))
{
// unselect the DF memory gl_ptr_mem points to in order to program the page.
at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE);
// Memory busy.
at45dbx_busy = TRUE;
}
return OK;
}
//! @}
/*! \name Multiple-Sector Access Functions
*/
//! @{
Bool at45dbx_read_multiple_sector(U16 nb_sector)
{
while (nb_sector--)
{
// Read the next sector.
at45dbx_read_sector_2_ram(sector_buf);
at45dbx_read_multiple_sector_callback(sector_buf);
}
return OK;
}
Bool at45dbx_write_multiple_sector(U16 nb_sector)
{
while (nb_sector--)
{
// Write the next sector.
at45dbx_write_multiple_sector_callback(sector_buf);
at45dbx_write_sector_from_ram(sector_buf);
}
return OK;
}
//! @}
/*! \name Single-Sector Access Functions
*/
//! @{
Bool at45dbx_read_sector_2_ram(void *ram)
{
U8 *_ram = ram;
U16 i;
U16 data;
// Memory busy.
if (at45dbx_busy)
{
// Being here, we know that we previously finished a page read.
// => We have to access the next page.
// Memory ready.
at45dbx_busy = FALSE;
// Eventually select the next DF and open the next page.
// NOTE: at45dbx_read_open input parameter is a sector.
at45dbx_read_open(gl_ptr_mem >> AT45DBX_SECTOR_BITS); // gl_ptr_mem / AT45DBX_SECTOR_SIZE.
}
// Read the next sector.
for (i = AT45DBX_SECTOR_SIZE; i; i--)
{
// Send a dummy byte to read the next data byte.
spi_write_dummy();
spi_read(AT45DBX_SPI, &data);
*_ram++ = data;
}
// Update the memory pointer.
gl_ptr_mem += AT45DBX_SECTOR_SIZE;
#if AT45DBX_PAGE_SIZE > AT45DBX_SECTOR_SIZE
// If end of page reached,
if (!Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_BYTE))
#endif
{
// unselect the DF memory gl_ptr_mem points to.
at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE);
// Memory busy.
at45dbx_busy = TRUE;
}
return OK;
}
Bool at45dbx_write_sector_from_ram(const void *ram)
{
const U8 *_ram = ram;
U16 i;
// Memory busy.
if (at45dbx_busy)
{
// Being here, we know that we previously launched a page programming.
// => We have to access the next page.
// Eventually select the next DF and open the next page.
// NOTE: at45dbx_write_open input parameter is a sector.
at45dbx_write_open(gl_ptr_mem >> AT45DBX_SECTOR_BITS); // gl_ptr_mem / AT45DBX_SECTOR_SIZE.
}
// Write the next sector.
for (i = AT45DBX_SECTOR_SIZE; i; i--)
{
// Write the next data byte.
spi_write(AT45DBX_SPI, *_ram++);
}
// Update the memory pointer.
gl_ptr_mem += AT45DBX_SECTOR_SIZE;
#if AT45DBX_PAGE_SIZE > AT45DBX_SECTOR_SIZE
// If end of page reached,
if (!Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_BYTE))
#endif
{
// unselect the DF memory gl_ptr_mem points to in order to program the page.
at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE);
// Memory busy.
at45dbx_busy = TRUE;
}
return OK;
}
//! @}
#endif // AT45DBX_MEM == ENABLE

View File

@ -0,0 +1,270 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Management of the AT45DBX data flash controller through SPI.
*
* This file manages the accesses to the AT45DBX data flash components.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with an SPI module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _AT45DBX_H_
#define _AT45DBX_H_
#include "conf_access.h"
#if AT45DBX_MEM == DISABLE
#error at45dbx.h is #included although AT45DBX_MEM is disabled
#endif
#include "spi.h"
//_____ D E F I N I T I O N S ______________________________________________
/*! \name Available AT45DBX Sizes
*
* Number of address bits of available AT45DBX data flash memories.
*
* \note Only memories with page sizes of at least 512 bytes (sector size) are
* supported.
*/
//! @{
#define AT45DBX_1MB 20
#define AT45DBX_2MB 21
#define AT45DBX_4MB 22
#define AT45DBX_8MB 23
//! @}
// AT45DBX_1MB
#define AT45DBX_SECTOR_BITS 8 //! Number of bits for addresses within sectors.
// AT45DBX_2MB AT45DBX_4MB AT45DBX_8MB
//#define AT45DBX_SECTOR_BITS 9 //! Number of bits for addresses within sectors.
//! Sector size in bytes.
#define AT45DBX_SECTOR_SIZE (1 << AT45DBX_SECTOR_BITS)
//_____ D E C L A R A T I O N S ____________________________________________
/*! \name Control Functions
*/
//! @{
/*! \brief Initializes the data flash controller and the SPI channel by which
* the DF is controlled.
*
* \param spiOptions Initialization options of the DF SPI channel.
* \param pba_hz SPI module input clock frequency (PBA clock, Hz).
*
* \retval OK Success.
* \retval KO Failure.
*/
extern Bool at45dbx_init(spi_options_t spiOptions, unsigned int pba_hz);
/*! \brief Performs a memory check on all DFs.
*
* \retval OK Success.
* \retval KO Failure.
*/
extern Bool at45dbx_mem_check(void);
/*! \brief Opens a DF memory in read mode at a given sector.
*
* \param sector Start sector.
*
* \retval OK Success.
* \retval KO Failure.
*
* \note Sector may be page-unaligned (depending on the DF page size).
*/
extern Bool at45dbx_read_open(U32 sector);
/*! \brief Unselects the current DF memory.
*/
extern void at45dbx_read_close(void);
/*! \brief This function opens a DF memory in write mode at a given sector.
*
* \param sector Start sector.
*
* \retval OK Success.
* \retval KO Failure.
*
* \note Sector may be page-unaligned (depending on the DF page size).
*
* \note If \ref AT45DBX_PAGE_SIZE > \ref AT45DBX_SECTOR_SIZE, page content is
* first loaded in buffer to then be partially updated by write byte or
* write sector functions.
*/
extern Bool at45dbx_write_open(U32 sector);
/*! \brief Fills the end of the current logical sector and launches page programming.
*/
extern void at45dbx_write_close(void);
//! @}
/*! \name Single-Byte Access Functions
*/
//! @{
/*! \brief Performs a single byte read from DF memory.
*
* \return The read byte.
*
* \note First call must be preceded by a call to the \ref at45dbx_read_open
* function.
*/
extern U8 at45dbx_read_byte(void);
/*! \brief Performs a single byte write to DF memory.
*
* \param b The byte to write.
*
* \retval OK Success.
* \retval KO Failure.
*
* \note First call must be preceded by a call to the \ref at45dbx_write_open
* function.
*/
extern Bool at45dbx_write_byte(U8 b);
//! @}
/*! \name Multiple-Sector Access Functions
*/
//! @{
/*! \brief Reads \a nb_sector sectors from DF memory.
*
* Data flow is: DF -> callback.
*
* \param nb_sector Number of contiguous sectors to read.
*
* \retval OK Success.
* \retval KO Failure.
*
* \note First call must be preceded by a call to the \ref at45dbx_read_open
* function.
*
* \note As \ref AT45DBX_PAGE_SIZE is always a multiple of
* \ref AT45DBX_SECTOR_SIZE, there is no need to check page end for each
* byte.
*/
extern Bool at45dbx_read_multiple_sector(U16 nb_sector);
/*! \brief Callback function invoked after each sector read during
* \ref at45dbx_read_multiple_sector.
*
* \param psector Pointer to read sector.
*/
extern void at45dbx_read_multiple_sector_callback(const void *psector);
/*! \brief Writes \a nb_sector sectors to DF memory.
*
* Data flow is: callback -> DF.
*
* \param nb_sector Number of contiguous sectors to write.
*
* \retval OK Success.
* \retval KO Failure.
*
* \note First call must be preceded by a call to the \ref at45dbx_write_open
* function.
*
* \note As \ref AT45DBX_PAGE_SIZE is always a multiple of
* \ref AT45DBX_SECTOR_SIZE, there is no need to check page end for each
* byte.
*/
extern Bool at45dbx_write_multiple_sector(U16 nb_sector);
/*! \brief Callback function invoked before each sector write during
* \ref at45dbx_write_multiple_sector.
*
* \param psector Pointer to sector to write.
*/
extern void at45dbx_write_multiple_sector_callback(void *psector);
//! @}
/*! \name Single-Sector Access Functions
*/
//! @{
/*! \brief Reads 1 DF sector to a RAM buffer.
*
* Data flow is: DF -> RAM.
*
* \param ram Pointer to RAM buffer.
*
* \retval OK Success.
* \retval KO Failure.
*
* \note First call must be preceded by a call to the \ref at45dbx_read_open
* function.
*/
extern Bool at45dbx_read_sector_2_ram(void *ram);
/*! \brief Writes 1 DF sector from a RAM buffer.
*
* Data flow is: RAM -> DF.
*
* \param ram Pointer to RAM buffer.
*
* \retval OK Success.
* \retval KO Failure.
*
* \note First call must be preceded by a call to the \ref at45dbx_write_open
* function.
*/
extern Bool at45dbx_write_sector_from_ram(const void *ram);
//! @}
#endif // _AT45DBX_H_

View File

@ -0,0 +1,234 @@
/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief CTRL_ACCESS interface for the AT45DBX data flash controller.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with an SPI module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
//_____ I N C L U D E S ___________________________________________________
#include "conf_access.h"
#if AT45DBX_MEM == ENABLE
#include "conf_at45dbx.h"
#include "at45dbx.h"
#include "at45dbx_mem.h"
//_____ D E F I N I T I O N S ______________________________________________
//! Whether to detect write accesses to the memory.
#define AT45DBX_MEM_TEST_CHANGE_STATE ENABLED
#if (ACCESS_USB == ENABLED || ACCESS_MEM_TO_RAM == ENABLED) && AT45DBX_MEM_TEST_CHANGE_STATE == ENABLED
//! Memory data modified flag.
static volatile Bool s_b_data_modify = FALSE;
#endif
/*! \name Control Interface
*/
//! @{
Ctrl_status at45dbx_test_unit_ready(void)
{
return (at45dbx_mem_check() == OK) ? CTRL_GOOD : CTRL_NO_PRESENT;
}
Ctrl_status at45dbx_read_capacity(U32 *u32_nb_sector)
{
*u32_nb_sector = (AT45DBX_MEM_CNT << (AT45DBX_MEM_SIZE - AT45DBX_SECTOR_BITS)) - 1;
return CTRL_GOOD;
}
Bool at45dbx_wr_protect(void)
{
return FALSE;
}
Bool at45dbx_removal(void)
{
return FALSE;
}
//! @}
#if ACCESS_USB == ENABLED
#include "usb_drv.h"
#include "scsi_decoder.h"
/*! \name MEM <-> USB Interface
*/
//! @{
Ctrl_status at45dbx_usb_read_10(U32 addr, U16 nb_sector)
{
if (addr + nb_sector > AT45DBX_MEM_CNT << (AT45DBX_MEM_SIZE - AT45DBX_SECTOR_BITS)) return CTRL_FAIL;
at45dbx_read_open(addr);
at45dbx_read_multiple_sector(nb_sector);
at45dbx_read_close();
return CTRL_GOOD;
}
void at45dbx_read_multiple_sector_callback(const void *psector)
{
U16 data_to_transfer = AT45DBX_SECTOR_SIZE;
// Transfer read sector to the USB interface.
while (data_to_transfer)
{
while (!Is_usb_in_ready(g_scsi_ep_ms_in))
{
if(!Is_usb_endpoint_enabled(g_scsi_ep_ms_in))
return; // USB Reset
}
Usb_reset_endpoint_fifo_access(g_scsi_ep_ms_in);
data_to_transfer = usb_write_ep_txpacket(g_scsi_ep_ms_in, psector,
data_to_transfer, &psector);
Usb_ack_in_ready_send(g_scsi_ep_ms_in);
}
}
Ctrl_status at45dbx_usb_write_10(U32 addr, U16 nb_sector)
{
if (addr + nb_sector > AT45DBX_MEM_CNT << (AT45DBX_MEM_SIZE - AT45DBX_SECTOR_BITS)) return CTRL_FAIL;
#if AT45DBX_MEM_TEST_CHANGE_STATE == ENABLED
if (nb_sector) s_b_data_modify = TRUE;
#endif
at45dbx_write_open(addr);
at45dbx_write_multiple_sector(nb_sector);
at45dbx_write_close();
return CTRL_GOOD;
}
void at45dbx_write_multiple_sector_callback(void *psector)
{
U16 data_to_transfer = AT45DBX_SECTOR_SIZE;
// Transfer sector to write from the USB interface.
while (data_to_transfer)
{
while (!Is_usb_out_received(g_scsi_ep_ms_out))
{
if(!Is_usb_endpoint_enabled(g_scsi_ep_ms_out))
return; // USB Reset
}
Usb_reset_endpoint_fifo_access(g_scsi_ep_ms_out);
data_to_transfer = usb_read_ep_rxpacket(g_scsi_ep_ms_out, psector,
data_to_transfer, &psector);
Usb_ack_out_received_free(g_scsi_ep_ms_out);
}
}
//! @}
#endif // ACCESS_USB == ENABLED
#if ACCESS_MEM_TO_RAM == ENABLED
/*! \name MEM <-> RAM Interface
*/
//! @{
Ctrl_status at45dbx_df_2_ram(U32 addr, void *ram)
{
if (addr + 1 > AT45DBX_MEM_CNT << (AT45DBX_MEM_SIZE - AT45DBX_SECTOR_BITS)) return CTRL_FAIL;
at45dbx_read_open(addr);
at45dbx_read_sector_2_ram(ram);
at45dbx_read_close();
return CTRL_GOOD;
}
Ctrl_status at45dbx_ram_2_df(U32 addr, const void *ram)
{
if (addr + 1 > AT45DBX_MEM_CNT << (AT45DBX_MEM_SIZE - AT45DBX_SECTOR_BITS)) return CTRL_FAIL;
#if AT45DBX_MEM_TEST_CHANGE_STATE == ENABLED
s_b_data_modify = TRUE;
#endif
at45dbx_write_open(addr);
at45dbx_write_sector_from_ram(ram);
at45dbx_write_close();
return CTRL_GOOD;
}
//! @}
#endif // ACCESS_MEM_TO_RAM == ENABLED
#endif // AT45DBX_MEM == ENABLE

View File

@ -0,0 +1,164 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief CTRL_ACCESS interface for the AT45DBX data flash controller.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with an SPI module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _AT45DBX_MEM_H_
#define _AT45DBX_MEM_H_
#include "conf_access.h"
#if AT45DBX_MEM == DISABLE
#error at45dbx_mem.h is #included although AT45DBX_MEM is disabled
#endif
#include "ctrl_access.h"
//_____ D E C L A R A T I O N S ____________________________________________
/*! \name Control Interface
*/
//! @{
/*! \brief Tests the memory state and initializes the memory if required.
*
* The TEST UNIT READY SCSI primary command allows an application client to poll
* a LUN until it is ready without having to allocate memory for returned data.
*
* This command may be used to check the media status of LUNs with removable
* media.
*
* \return Status.
*/
extern Ctrl_status at45dbx_test_unit_ready(void);
/*! \brief Returns the address of the last valid sector in the memory.
*
* \param u32_nb_sector Pointer to the address of the last valid sector.
*
* \return Status.
*/
extern Ctrl_status at45dbx_read_capacity(U32 *u32_nb_sector);
/*! \brief Returns the write-protection state of the memory.
*
* \return \c TRUE if the memory is write-protected, else \c FALSE.
*
* \note Only used by removable memories with hardware-specific write
* protection.
*/
extern Bool at45dbx_wr_protect(void);
/*! \brief Tells whether the memory is removable.
*
* \return \c TRUE if the memory is removable, else \c FALSE.
*/
extern Bool at45dbx_removal(void);
//! @}
#if ACCESS_USB == ENABLED
/*! \name MEM <-> USB Interface
*/
//! @{
/*! \brief Tranfers data from the memory to USB.
*
* \param addr Address of first memory sector to read.
* \param nb_sector Number of sectors to transfer.
*
* \return Status.
*/
extern Ctrl_status at45dbx_usb_read_10(U32 addr, U16 nb_sector);
/*! \brief Tranfers data from USB to the memory.
*
* \param addr Address of first memory sector to write.
* \param nb_sector Number of sectors to transfer.
*
* \return Status.
*/
extern Ctrl_status at45dbx_usb_write_10(U32 addr, U16 nb_sector);
//! @}
#endif
#if ACCESS_MEM_TO_RAM == ENABLED
/*! \name MEM <-> RAM Interface
*/
//! @{
/*! \brief Copies 1 data sector from the memory to RAM.
*
* \param addr Address of first memory sector to read.
* \param ram Pointer to RAM buffer to write.
*
* \return Status.
*/
extern Ctrl_status at45dbx_df_2_ram(U32 addr, void *ram);
/*! \brief Copies 1 data sector from RAM to the memory.
*
* \param addr Address of first memory sector to write.
* \param ram Pointer to RAM buffer to read.
*
* \return Status.
*/
extern Ctrl_status at45dbx_ram_2_df(U32 addr, const void *ram);
//! @}
#endif
#endif // _AT45DBX_MEM_H_

View File

@ -0,0 +1,35 @@
#ifndef WL_OS_H
#define WL_OS_H
#include <stdarg.h>
#include <stdlib.h>
void *owl_os_alloc(size_t size);
void *owl_os_realloc(void *ptr, size_t size);
void owl_os_free(void *p);
void *owl_os_memcpy(void *dst, const void *src, size_t n);
void *owl_os_memset(void *s, int c, size_t n);
void *owl_os_memmove(void *dst, const void *src, size_t n);
size_t owl_os_strlen(char *s);
char *owl_os_strncpy(char *dst, const char *src, size_t n);
int owl_os_strncmp(const char *s1, const char *s2, size_t n);
int owl_os_strcmp(const char *s1, const char *s2);
char *owl_os_strcpy(char *dst, const char *src);
char *owl_os_strdup(const char *s);
char *owl_os_strndup(const char *s, size_t n);
int owl_os_memcmp(const void *s1, const void *s2, size_t n);
long int owl_os_strtol(const char *nptr, char **endptr, int base);
char *owl_os_strchr(const char *s, int c);
char *owl_os_strrchr(const char *s, int c);
int owl_os_strcasecmp(const char *s1, const char *s2);
char *owl_os_strstr(const char *haystack, const char *needle);
int owl_os_snprintf(char *str, size_t size, const char *format, ...)
__attribute__((format(printf, 3, 4)));
int owl_os_vprintf(const char *format, va_list arg); /* debug only */
int owl_os_printf(const char *format, ...) /* debug only */
__attribute__((format(printf, 1, 2)));
#endif /* WL_OS_H */

View File

@ -0,0 +1,172 @@
/*!
* \file wl_sdio.h
* \brief SDIO interface for wl_api.
* Copyright (C) 2010 HD Wireless AB
*
* You should have received a copy of the license along with this library.
*/
#ifndef WL_SDIO_H
#define WL_SDIO_H
/** \defgroup wl_sdio SDIO Interface
*
* These functions implement the interface that the wl_api library
* needs to work with a SDIO transport layer.
*
* The functions prototyped here must be implemented when porting the
* wl_api library to a new platform with a different SDIO configuration
*
* On platforms supported by H&D Wireless these functions are
* implemented in the file avr32_sdio.c
*
* @{
*/
/**
* Maximum transfer size. This will set an upper limit on the len parameter
* passed to owl_sdio_tx() and owl_sdio_rx().
*
*/
#define MAX_BLOCK_LEN 512
/**
* This flag might be set when owl_sdio_cmd() is called in case the cmd will
* be followed by a data transfer. If the flag is set, the transfer direction is
* from the device to the host (read). Otherwise, the transfer direction is
* from the host to the device (write).
*
*/
#define CMD_FLAG_TO_HOST (1 << 0)
/**
* Indicates that the sdio driver needs to be polled in order to make
* forward progress, i.e. it does not support interrupts
*
* The actual polling will result in owl_sdio_cmd() being called to
* request status information from the device.
*
* To activate polling, this flag should be set in owl_sdio_init().
*/
#define SDIO_FLAG_POLL (1 << 0)
/**
* Indicates that the sdio driver only supports 1-bit mode.
*
* To set 1-bit mode, this flag should be set in owl_sdio_init().
*/
#define SDIO_FLAG_1BIT_MODE (1 << 1)
/**
* This function will be invoked when wlan initialization should be performed,
* this happens when the wl_fw_download() function in the transport group of
* wl_api is invoked.
*
* The wifi device supports sdio high speed mode and clock frequencies up to
* 50 MHz.
*
* The function is responsible for doing any necessary sdio initialization such
* as allocating gpio's, setting up the mci master, one time allocations of
* dma buffers etc.
*
* @param flags is an out parameter that should hold any sdio flags upon return.
* The avaible flags are prefixed with SDIO_FLAG_
*
*
*/
void owl_sdio_init(uint8_t *flags);
/**
* This function will be invoked when an sdio cmd should be sent to the
* device.
*
* @param idx is the sdio command number
* @param arg is the sdio command argument
* @param flags specifies other options, such as any transfer direction.
* @param rsp should hold the command response upon return. If null, the
* response can be ignored.
* @param data holds a pointer to any data that might follow the command. This
* allows the sdio driver to setup dma transfers while waiting for the
* command response. NULL if no data transfer will follow. Note that
* the same data pointer will be passed to owl_sdio_tx(), which should
* start the actual transfer.
* @param len is the length of the data buffer.
*
*/
void owl_sdio_cmd(uint8_t idx, uint32_t arg, uint8_t flags, uint32_t *rsp,
const uint8_t *data, uint16_t len);
/**
* This function will be invoked when data should be transmitted to the device.
*
* If wl_fw_downlad() was called with the size_align parameter set to non-zero,
* the pad parameter should be used. If the pad parameter is not 0, additional
* data must be transmitted after the data buffer has be sent. Depending on
* how the data buffer was first allocated (probably by an TCP/IP stack), it
* might be safe or unsafe to continue reading beyond the data buffer to
* transmit the additional padding bytes.
*
* @param data holds a pointer to the data to transmit, the pointer is the
* same as the one passed to wl_tx().
* @param len is the number of bytes that should be transmitted, including
* padding.
* @param pad is the number of padding bytes to send.
*
*/
void owl_sdio_tx(const uint8_t *data, uint16_t len, uint8_t pad);
/**
* This function will be invoked when data should be received from the device.
*
* @param data should hold the read data upon return.
* @param len is the number of bytes to read.
*
*/
void owl_sdio_rx(uint8_t *data, uint16_t len);
/**
* Invoked when sdio rx interrupts from the device should be enabled or
* disabled.
*
* If SDIO_FLAG_POLL was set in wl_spi_init(), then this function can be
* left empty.
*
* @param enable specifies if interrupts should be enabled or disabled.
*
*/
void owl_sdio_irq(uint8_t enable);
/**
* Delay executiom for the specified number of ms. This function will be called
* with delays in the 10-20 ms range during fw download and startup of the
* Wi-Fi device. This function can be implemented with a simple for-loop if
* desired (beware of optimization). The timing does not have to be accurate as
* long as the actual delay becomes at least the specified number of ms.
*
* @param ms is the minimal amount of time to wait [ms].
*
*/
void owl_sdio_mdelay(uint32_t ms);
/**
* This function should be called whenever an interrupt is detected. It can
* be called from an interrupt context.
*
* If SDIO_FLAG_POLL was set in owl_sdio_init(), then wl_sdio_irq()
* should never be called.
*
*/
extern void wl_sdio_irq(void);
/*! @} */
#endif

View File

@ -0,0 +1,185 @@
/*!
* \file wl_spi.h
* \brief SPI interface for wl_api.
* Copyright (C) 2010 HD Wireless AB
*
* You should have received a copy of the license along with this library.
*/
#ifndef WL_SPI_H
#define WL_SPI_H
#ifndef WITHOUT_STDINT
#include <stdint.h>
#endif
/** \defgroup wl_spi SPI Interface
*
* These functions implement the interface that the wl_api library
* needs to work with a SPI transport layer.
*
* The functions prototyped here must be implemented when porting the
* wl_api library to a new platform with a different SPI configuration
*
* On platforms supported by H&D Wireless these functions are
* implemented in the file avr32_spi.c
*
* @{
*/
/**
* Maximum transfer size. This will set an upper limit on the len parameter
* passed to owl_spi_txrx().
*
*
*/
#define MAX_BLOCK_LEN 512
/**
* Indicates that the spi driver needs to be polled in order to make
* forward progress, i.e. it does not support interrupts through SD pin 8.
*
* The actual polling will result in owl_spi_txrx() being call to
* request status information from the device.
*
* To activate polling, this flag should be set in owl_spi_init().
*
* See wl_poll() and wl_register_rx_isr() for more information regarding
* polled and interrupt modes.
*
*/
#define SPI_FLAG_POLL (1 << 0)
/**
* This function will be invoked when wlan device initialization should be
* performed, this happens when the wl_fw_download() function in the transport
* group of wl_api is invoked.
*
* The wifi device requires spi mode 3, i.e. clock polarity high and sample
* on second phase. This corresponds to CPOL=1, CPHA=1. Maximum frequency on
* spi clock is 30 MHz.
*
* The function is also responsible for doing any necessary spi initialization
* such as allocating gpio's, setting up the SPI master, one time allocations of
* dma buffers etc.
*
*
* If the SPB105 device is used, two signals; POWER (pin 10 on SPB105) and
* SHUTDOWN (pin 4 on SPB105) might be connected to gpio's on the host.
* The GPIO_POWER_PIN is the main power supply to the device. The
* GPIO_SHUTDOWN_PIN (active low) should be defined as an input.
*
* After GPIO_POWER_PIN is pulled high by the host, the device will pull the
* GPIO_SHUTDOWN_PIN high once the device is properly powered.
*
* However, if pin 4 (GPIO_SHUTDOWN_PIN) is not connected to the host, a delay
* of up to 250 ms must be added after GPIO_POWER_PIN is pulled high to ensure
* that startup is completed. The actual time is usually much shorter, therefore
* one might try to reduce the delay for a particualar hardware design.
*
* On SPB104, the GPIO_POWER_PIN will be connected to VCC and GPIO_SHUTDOWN_PIN
* will be unconnected; hence we have to make sure that we have enough delay
* after powering on the host. Since the device power-on usually happens at the
* same time as the host power-on, the startup time of the host can be
* subtracted from any delay put into owl_spi_init().
*
* @param flags is an out parameter that should hold any spi flags upon return.
* The avaible flags are prefixed with SPI_FLAG_
*
* @return 0 on success
* -1 if any error occurs
*
*/
int owl_spi_init(uint8_t *flags);
/**
* Invoked when a spi transfer should be performed.
*
* All buffers that are allocated by the wl library will have a size that is
* aligned to 4. If size-unaligned data is passed to this function, it is
* always allocated by the ip stack. If 4-byte size alignment (e.g. for DMA)
* is required, 1-3 extra padding bytes can be transmitted after the in buffer.
* These bytes must be 0xff.
*
* Since size-unaligned data always comes from the ip stack, the out ptr is
* always NULL for such data.
*
* @param in points a buffer which holds the data to be transmitted. If NULL,
* then \a len bytes with the value 0xff should be transmitted on the
* bus.
* @param out points a buffer should hold the data received from the device. If
* NULL, any received data can be discarded.
* @param len is the length of the in and out buffers.
*
*/
void owl_spi_txrx(const uint8_t *in, uint8_t* out, uint16_t len);
/**
* Invoked when spi rx interrupts from the device should be enabled or disabled.
* Note that the spi interrupts are obtained from pin 8 on SPB104 or pin 3 from
* SPB105. This pin can be be connected to a gpio on the host. The irq line
* will signal an interrupt on both edges.
*
* In general, the wifi device will not issue a new interrupt unless the
* last interrupt has been handled. Also, during normal operation (i.e after
* the complete callback registered in wl_init() has been invoked),
* owl_spi_irq() will never be invoked so interrupts will be enabled all
* the time. For the SPI-mode, the purpose of owl_spi_irq() is basically to
* make sure that the first interrupt (coming after the reset performed in
* owl_spi_init()) is ignored.
*
* If SPI_FLAG_POLL was set in owl_spi_init(), then this function can be
* left empty and the wifi device will be used in polled mode. In polled mode,
* the interrupt line is not used. Regardless of polled or interrupt-mode,
* wl_poll() must be called to ensure progress of the driver.
*
* @param enable specifies if interrupts should be enabled or disabled.
*
*/
void owl_spi_irq(uint8_t enable);
/**
* Invoked when the spi cs for the wifi device should be enabled. Note that
* multiple calls to owl_spi_txrx() might be done during a 'single' chip
* select.
*
* @param enable specifies whether chip select should be asserted or deasserted,
* The chip select signal is active low, so if enable is '1' then the
* chip select connected to the wifi device should be set to '0'.
*
*/
void owl_spi_cs(uint8_t enable);
/**
* Delay executiom for the specified number of ms. This function will be called
* with delays in the 10-20 ms range during fw download and startup of the
* Wi-Fi device. This function can be implemented with a simple for-loop if
* desired (beware of optimization). The timing does not have to be accurate as
* long as the actual delay becomes at least the specified number of ms.
*
* @param ms is the minimal amount of time to wait [ms].
*
*/
void owl_spi_mdelay(uint32_t ms);
/**
* This function should be called whenever an interrupt is detected. It can
* be called from an interrupt context.
*
* If SPI_FLAG_POLL was set in owl_spi_init(), then wl_spi_irq()
* should never be called.
*
*/
extern void wl_spi_irq(void);
/*! @} */
#endif

View File

@ -0,0 +1,154 @@
/*
* Programming interface for wlap_api.
* Copyright (C) 2011 HD Wireless AB
*
* You should have received a copy of the license along with this library.
*/
/*! \file wlap_api.h *************************************************************
*
* \brief WiFi AP API
*
* This file provides the wlap_api interface.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices:
* \li SPB104 + EVK1100
* \li SPB104 + EVK1101
* \li SPB104 + EVK1104
* \li SPB104 + EVK1105 (SPI)
* \li SPB104 + EVK1105 (SPI + irq)
* \li SPB105 + EVK1105 (SPI)
* - AppNote:
*
* \author H&D Wireless AB: \n
*
*****************************************************************************
*
* \section intro Introduction
* This is the documentation for the WiFi AP Driver API \a wlap_api.
*
* \section files Main Files
* - wlap_api.h : WiFi driver interface.
* - libwlap_api_*.*.a - Driver library.
*
*/
#ifndef WLAP_API_H
#define WLAP_API_H
#define WLAP_API_RELEASE_NAME "unknown"
#include <wl_api.h>
/** \defgroup wl_softap Access Point Mode
*
* \brief Support the WiFi Access Point mode.
*
* @{
*/
/*
* Station representation
*
*/
struct wl_sta_t
{
struct wl_mac_addr_t bssid; /**< The BSSID of the network. */
uint8_t queued_pkt_cnt; /**< Number of queueud packets for
this STA. */
uint8_t in_ps; /**< Is the STA in power save mode. */
uint8_t aid; /**< STA AID */
};
/* Station list representation. Array of pointers to wl_sta_t entries. */
struct wl_sta_list_t
{
struct wl_sta_t **sta; /**< The list of pointers to stations */
size_t cnt; /**< Number of stations */
};
/*! \brief Get the list of currently associated stations (SoftAP).
*
* Retrieves the list of current stations from
* the driver.
*
* This function is not thread safe. It must be called in the
* same execution context as wl_poll().
*
* @param network_list Output buffer. The API call returns
* a pointer to allocated memory containing the network list.
* @return
* - WL_SUCCESS
* - WL_FAILURE.
*/
wl_err_t wlap_get_sta_list(struct wl_sta_list_t **network_list);
/*! Callback used to read data from a TX packet.
* This function is supplied by the user of the API.
*
* @param dst Destination buffer. The data should be copied
* to this buffer.
* @param src_handle Handle to the source packet from where
* the data should be copied. This handle is the same one that
* is passed in parameter \a pkt_handle to \a wl_process_tx().
* @param read_len Number of bytes to copy from \a src_handle
* to \a dst.
* @param offset The offset in bytes, counting from the
* beginning of the Ethernet header, from where to copy data.
* @return
* - The number of bytes copied. This number may be smaller
* than the length requested in \a read_len but it may not
* be shorter than the length of the packet counting from
* \a offset. In other words, if the caller of this function
* receives a return count that is shorter than \a read_len
* he will assume that all packet data has been read.
* - < 0 on error.
*/
typedef ssize_t (*wl_pkt_read_cb_t)(char *dst,
void *src_handle,
size_t read_len,
int offset);
/*! \brief Register a data access function for TX packets (SoftAP).
*
* When a TX data packet has a different representation than a single
* contiguous buffer in memory then a packet read function must be
* implemented and registered with this call. Whenever the library
* needs to read packet data it will call this function to do it.
*
* This function can be ignored if the TX packet representation is
* a single contiguous buffer. This function is only needed in SoftAP
* mode.
*
* @param pkt_read_cb Read callback.
* @param ctx Context
*/
void wl_register_pkt_read_cb(wl_pkt_read_cb_t pkt_read_cb);
/*! \brief Start a network using the SoftAP mode.
*
* This call will cause the WiFi chip to start sending beacons
* and accept associations from WiFi stations.
*
*/
wl_err_t wlap_start_ap(const char *ssid,
const size_t ssid_len,
const uint8_t channel,
const enum wl_auth_mode auth_mode,
const enum wl_enc_type enc_type);
/*! \brief Disconnect a STA (SoftAP)
*
* @param bssid The BSSID of the station to disconnect.
* @return
* - WL_SUCCESS
* - WL_FAILURE.
*/
wl_err_t wlap_disconnect_sta(const struct wl_mac_addr_t bssid);
/*! @} */ /* End wl_softap group */
#endif

View File

@ -0,0 +1,309 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Cycle counter driver.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32UC devices.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
*****************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _CYCLE_COUNTER_H_
#define _CYCLE_COUNTER_H_
#include "compiler.h"
//! Structure holding private information, automatically initialized by the
//! cpu_set_timeout() function.
typedef struct
{
//! The cycle count at the begining of the timeout.
unsigned long delay_start_cycle;
//! The cycle count at the end of the timeout.
unsigned long delay_end_cycle;
//! Enable/disable the timout detection
unsigned char timer_state;
#define CPU_TIMER_STATE_STARTED 0
#define CPU_TIMER_STATE_REACHED 1
#define CPU_TIMER_STATE_STOPPED 2
} t_cpu_time;
/*!
* \brief Convert milli-seconds into CPU cycles.
*
* \param ms: Number of millisecond.
* \param fcpu_hz: CPU frequency in Hz.
*
* \return the converted number of CPU cycles.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ U32 cpu_ms_2_cy(unsigned long ms, unsigned long fcpu_hz)
{
return ((unsigned long long)ms * fcpu_hz + 999) / 1000;
}
/*!
* \brief Convert micro-seconds into CPU cycles.
*
* \param us: Number of microsecond.
* \param fcpu_hz: CPU frequency in Hz.
*
* \return the converted number of CPU cycles.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ U32 cpu_us_2_cy(unsigned long us, unsigned long fcpu_hz)
{
return ((unsigned long long)us * fcpu_hz + 999999) / 1000000;
}
/*!
* \brief Convert CPU cycles into milli-seconds.
*
* \param cy: Number of CPU cycles.
* \param fcpu_hz: CPU frequency in Hz.
*
* \return the converted number of milli-second.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ U32 cpu_cy_2_ms(unsigned long cy, unsigned long fcpu_hz)
{
return ((unsigned long long)cy * 1000 + fcpu_hz-1) / fcpu_hz;
}
/*!
* \brief Convert CPU cycles into micro-seconds.
*
* \param cy: Number of CPU cycles.
* \param fcpu_hz: CPU frequency in Hz.
*
* \return the converted number of micro-second.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ U32 cpu_cy_2_us(unsigned long cy, unsigned long fcpu_hz)
{
return ((unsigned long long)cy * 1000000 + fcpu_hz-1) / fcpu_hz;
}
/*!
* \brief Set a timer variable.
*
* Ex: t_cpu_time timer;
* cpu_set_timeout( cpu_ms_2_cy(10, FOSC0), &timer ); // timeout in 10 ms
* if( cpu_is_timeout(&timer) )
* cpu_stop_timeout(&timer);
* ../..
*
* \param delay: (input) delay in CPU cycles before timeout.
* \param cpu_time: (output) internal information used by the timer API.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void cpu_set_timeout(unsigned long delay, t_cpu_time *cpu_time)
{
cpu_time->delay_start_cycle = Get_system_register(AVR32_COUNT);
cpu_time->delay_end_cycle = cpu_time->delay_start_cycle + delay;
cpu_time->timer_state = CPU_TIMER_STATE_STARTED;
}
/*!
* \brief Test if a timer variable reached its timeout.
*
* Once the timeout is reached, the function will always return TRUE,
* until the cpu_stop_timeout() function is called.
*
* Ex: t_cpu_time timer;
* cpu_set_timeout( 10, FOSC0, &timer ); // timeout in 10 ms
* if( cpu_is_timeout(&timer) )
* cpu_stop_timeout(&timer);
* ../..
*
* \param cpu_time: (input) internal information used by the timer API.
*
* \return TRUE if timeout occured, otherwise FALSE.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ unsigned long cpu_is_timeout(t_cpu_time *cpu_time)
{
unsigned long current_cycle_count = Get_system_register(AVR32_COUNT);
if( cpu_time->timer_state==CPU_TIMER_STATE_STOPPED )
return FALSE;
// Test if the timeout as already occured.
else if (cpu_time->timer_state == CPU_TIMER_STATE_REACHED)
return TRUE;
// If the ending cycle count of this timeout is wrapped, ...
else if (cpu_time->delay_start_cycle > cpu_time->delay_end_cycle)
{
if (current_cycle_count < cpu_time->delay_start_cycle && current_cycle_count > cpu_time->delay_end_cycle)
{
cpu_time->timer_state = CPU_TIMER_STATE_REACHED;
return TRUE;
}
return FALSE;
}
else
{
if (current_cycle_count < cpu_time->delay_start_cycle || current_cycle_count > cpu_time->delay_end_cycle)
{
cpu_time->timer_state = CPU_TIMER_STATE_REACHED;
return TRUE;
}
return FALSE;
}
}
/*!
* \brief Stop a timeout detection.
*
* Ex: t_cpu_time timer;
* cpu_set_timeout( 10, FOSC0, &timer ); // timeout in 10 ms
* if( cpu_is_timeout(&timer) )
* cpu_stop_timeout(&timer);
* ../..
*
* \param cpu_time: (input) internal information used by the timer API.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void cpu_stop_timeout(t_cpu_time *cpu_time)
{
cpu_time->timer_state = CPU_TIMER_STATE_STOPPED;
}
/*!
* \brief Test if a timer is stopped.
*
* \param cpu_time: (input) internal information used by the timer API.
*
* \return TRUE if timer is stopped, otherwise FALSE.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ unsigned long cpu_is_timer_stopped(t_cpu_time *cpu_time)
{
if( cpu_time->timer_state==CPU_TIMER_STATE_STOPPED )
return TRUE;
else
return FALSE;
}
/*!
* \brief Waits during at least the specified delay (in millisecond) before returning.
*
* \param delay: Number of millisecond to wait.
* \param fcpu_hz: CPU frequency in Hz.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void cpu_delay_ms(unsigned long delay, unsigned long fcpu_hz)
{
t_cpu_time timer;
cpu_set_timeout( cpu_ms_2_cy(delay, fcpu_hz), &timer);
while( !cpu_is_timeout(&timer) );
}
/*!
* \brief Waits during at least the specified delay (in microsecond) before returning.
*
* \param delay: Number of microsecond to wait.
* \param fcpu_hz: CPU frequency in Hz.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void cpu_delay_us(unsigned long delay, unsigned long fcpu_hz)
{
t_cpu_time timer;
cpu_set_timeout( cpu_us_2_cy(delay, fcpu_hz), &timer);
while( !cpu_is_timeout(&timer) );
}
/*!
* \brief Waits during at least the specified delay (in CPU cycles) before returning.
*
* \param delay: Number of CPU cycles to wait.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void cpu_delay_cy(unsigned long delay)
{
t_cpu_time timer;
cpu_set_timeout( delay, &timer);
while( !cpu_is_timeout(&timer) );
}
#define Get_sys_count() ( Get_system_register(AVR32_COUNT) )
#define Set_sys_count(x) ( Set_system_register(AVR32_COUNT, (x)) )
#define Get_sys_compare() ( Get_system_register(AVR32_COMPARE) )
#define Set_sys_compare(x) ( Set_system_register(AVR32_COMPARE, (x)) )
#endif // _CYCLE_COUNTER_H_

View File

@ -0,0 +1,995 @@
/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief SMC on EBI driver for AVR32 UC3.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with a SMC module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#include "compiler.h"
#include "preprocessor.h"
#include "gpio.h"
#include "smc.h"
// Configure the SM Controller with SM setup and timing information for all chip select
#define SMC_CS_SETUP(ncs) { \
U32 nwe_setup = ((NWE_SETUP * hsb_mhz_up + 999) / 1000); \
U32 ncs_wr_setup = ((NCS_WR_SETUP * hsb_mhz_up + 999) / 1000); \
U32 nrd_setup = ((NRD_SETUP * hsb_mhz_up + 999) / 1000); \
U32 ncs_rd_setup = ((NCS_RD_SETUP * hsb_mhz_up + 999) / 1000); \
U32 nwe_pulse = ((NWE_PULSE * hsb_mhz_up + 999) / 1000); \
U32 ncs_wr_pulse = ((NCS_WR_PULSE * hsb_mhz_up + 999) / 1000); \
U32 nrd_pulse = ((NRD_PULSE * hsb_mhz_up + 999) / 1000); \
U32 ncs_rd_pulse = ((NCS_RD_PULSE * hsb_mhz_up + 999) / 1000); \
U32 nwe_cycle = ((NWE_CYCLE * hsb_mhz_up + 999) / 1000); \
U32 nrd_cycle = ((NRD_CYCLE * hsb_mhz_up + 999) / 1000); \
\
/* Some coherence checks... */ \
/* Ensures CS is active during Rd or Wr */ \
if( ncs_rd_setup + ncs_rd_pulse < nrd_setup + nrd_pulse ) \
ncs_rd_pulse = nrd_setup + nrd_pulse - ncs_rd_setup; \
if( ncs_wr_setup + ncs_wr_pulse < nwe_setup + nwe_pulse ) \
ncs_wr_pulse = nwe_setup + nwe_pulse - ncs_wr_setup; \
\
/* ncs_hold = n_cycle - ncs_setup - ncs_pulse */ \
/* n_hold = n_cycle - n_setup - n_pulse */ \
/* */ \
/* All holds parameters must be positive or null, so: */ \
/* nwe_cycle shall be >= ncs_wr_setup + ncs_wr_pulse */ \
if( nwe_cycle < ncs_wr_setup + ncs_wr_pulse ) \
nwe_cycle = ncs_wr_setup + ncs_wr_pulse; \
\
/* nwe_cycle shall be >= nwe_setup + nwe_pulse */ \
if( nwe_cycle < nwe_setup + nwe_pulse ) \
nwe_cycle = nwe_setup + nwe_pulse; \
\
/* nrd_cycle shall be >= ncs_rd_setup + ncs_rd_pulse */ \
if( nrd_cycle < ncs_rd_setup + ncs_rd_pulse ) \
nrd_cycle = ncs_rd_setup + ncs_rd_pulse; \
\
/* nrd_cycle shall be >= nrd_setup + nrd_pulse */ \
if( nrd_cycle < nrd_setup + nrd_pulse ) \
nrd_cycle = nrd_setup + nrd_pulse; \
\
AVR32_SMC.cs[ncs].setup = (nwe_setup << AVR32_SMC_SETUP0_NWE_SETUP_OFFSET) | \
(ncs_wr_setup << AVR32_SMC_SETUP0_NCS_WR_SETUP_OFFSET) | \
(nrd_setup << AVR32_SMC_SETUP0_NRD_SETUP_OFFSET) | \
(ncs_rd_setup << AVR32_SMC_SETUP0_NCS_RD_SETUP_OFFSET); \
AVR32_SMC.cs[ncs].pulse = (nwe_pulse << AVR32_SMC_PULSE0_NWE_PULSE_OFFSET) | \
(ncs_wr_pulse << AVR32_SMC_PULSE0_NCS_WR_PULSE_OFFSET) | \
(nrd_pulse << AVR32_SMC_PULSE0_NRD_PULSE_OFFSET) | \
(ncs_rd_pulse << AVR32_SMC_PULSE0_NCS_RD_PULSE_OFFSET); \
AVR32_SMC.cs[ncs].cycle = (nwe_cycle << AVR32_SMC_CYCLE0_NWE_CYCLE_OFFSET) | \
(nrd_cycle << AVR32_SMC_CYCLE0_NRD_CYCLE_OFFSET); \
AVR32_SMC.cs[ncs].mode = (((NCS_CONTROLLED_READ) ? AVR32_SMC_MODE0_READ_MODE_NCS_CONTROLLED : \
AVR32_SMC_MODE0_READ_MODE_NRD_CONTROLLED) << AVR32_SMC_MODE0_READ_MODE_OFFSET) | \
+ (((NCS_CONTROLLED_WRITE) ? AVR32_SMC_MODE0_WRITE_MODE_NCS_CONTROLLED : \
AVR32_SMC_MODE0_WRITE_MODE_NWE_CONTROLLED) << AVR32_SMC_MODE0_WRITE_MODE_OFFSET) | \
(NWAIT_MODE << AVR32_SMC_MODE0_EXNW_MODE_OFFSET) | \
(((SMC_8_BIT_CHIPS) ? AVR32_SMC_MODE0_BAT_BYTE_WRITE : \
AVR32_SMC_MODE0_BAT_BYTE_SELECT) << AVR32_SMC_MODE0_BAT_OFFSET) | \
(((SMC_DBW <= 8 ) ? AVR32_SMC_MODE0_DBW_8_BITS : \
(SMC_DBW <= 16) ? AVR32_SMC_MODE0_DBW_16_BITS : \
AVR32_SMC_MODE0_DBW_32_BITS) << AVR32_SMC_MODE0_DBW_OFFSET) | \
(TDF_CYCLES << AVR32_SMC_MODE0_TDF_CYCLES_OFFSET) | \
(TDF_OPTIM << AVR32_SMC_MODE0_TDF_MODE_OFFSET) | \
(PAGE_MODE << AVR32_SMC_MODE0_PMEN_OFFSET) | \
(PAGE_SIZE << AVR32_SMC_MODE0_PS_OFFSET); \
smc_tab_cs_size[ncs] = (U8)EXT_SM_SIZE; \
}
static U8 smc_tab_cs_size[6];
static void smc_enable_muxed_pins(void);
void smc_init(unsigned long hsb_hz)
{
unsigned long hsb_mhz_up = (hsb_hz + 999999) / 1000000;
//! Whether to use the NCS0 pin
#ifdef SMC_USE_NCS0
#include SMC_COMPONENT_CS0
// Setup SMC for NCS0
SMC_CS_SETUP(0)
#ifdef SMC_DBW_GLOBAL
#if (SMC_DBW_GLOBAL < SMC_DBW)
#undef SMC_DBW_GLOBAL
#if (SMC_DBW == 8)
#define SMC_DBW_GLOBAL 8
#elif (SMC_DBW == 16)
#define SMC_DBW_GLOBAL 16
#elif (SMC_DBW == 32)
#define SMC_DBW_GLOBAL 32
#else
#error error in SMC_DBW size
#endif
#endif
#else
#if (SMC_DBW == 8)
#define SMC_DBW_GLOBAL 8
#elif (SMC_DBW == 16)
#define SMC_DBW_GLOBAL 16
#elif (SMC_DBW == 32)
#define SMC_DBW_GLOBAL 32
#else
#error error in SMC_DBW size
#endif
#endif
#ifdef SMC_8_BIT_CHIPS_GLOBAL
#if (SMC_8_BIT_CHIPS_GLOBAL < SMC_8_BIT)
#undef SMC_8_BIT_CHIPS_GLOBAL
#if (SMC_8_BIT_CHIPS == TRUE)
#define SMC_8_BIT_CHIPS_GLOBAL TRUE
#elif (SMC_8_BIT_CHIPS == FALSE)
#define SMC_8_BIT_CHIPS_GLOBAL FALSE
#else
#error error in SMC_8_BIT_CHIPS size
#endif
#endif
#else
#if (SMC_8_BIT_CHIPS == TRUE)
#define SMC_8_BIT_CHIPS_GLOBAL TRUE
#elif (SMC_8_BIT_CHIPS == FALSE)
#define SMC_8_BIT_CHIPS_GLOBAL FALSE
#else
#error error in SMC_8_BIT_CHIPS size
#endif
#endif
#ifdef NWAIT_MODE_GLOBAL
#if (NWAIT_MODE_GLOBAL < NWAIT_MODE)
#undef NWAIT_MODE_GLOBAL
#if (NWAIT_MODE == AVR32_SMC_EXNW_MODE_DISABLED)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_DISABLED
#elif (NWAIT_MODE == AVR32_SMC_EXNW_MODE_FROZEN)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_FROZEN
#else
#error error in NWAIT_MODE size
#endif
#endif
#else
#if (NWAIT_MODE == AVR32_SMC_EXNW_MODE_DISABLED)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_DISABLED
#elif (NWAIT_MODE == AVR32_SMC_EXNW_MODE_FROZEN)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_FROZEN
#else
#error error in NWAIT_MODE size
#endif
#endif
#undef EXT_SM_SIZE
#undef SMC_DBW
#undef SMC_8_BIT_CHIPS
#undef NWE_SETUP
#undef NCS_WR_SETUP
#undef NRD_SETUP
#undef NCS_RD_SETUP
#undef NCS_WR_PULSE
#undef NWE_PULSE
#undef NCS_RD_PULSE
#undef NRD_PULSE
#undef NCS_WR_HOLD
#undef NWE_HOLD
#undef NWE_CYCLE
#undef NCS_RD_HOLD
#undef NRD_CYCLE
#undef TDF_CYCLES
#undef TDF_OPTIM
#undef PAGE_MODE
#undef PAGE_SIZE
#undef NCS_CONTROLLED_READ
#undef NCS_CONTROLLED_WRITE
#undef NWAIT_MODE
#endif
//! Whether to use the NCS1 pin
#ifdef SMC_USE_NCS1
#include SMC_COMPONENT_CS1
// Enable SM mode for CS1 if necessary.
AVR32_HMATRIX.sfr[AVR32_EBI_HMATRIX_NR] &= ~(1 << AVR32_EBI_SDRAM_CS);
AVR32_HMATRIX.sfr[AVR32_EBI_HMATRIX_NR];
// Setup SMC for NCS1
SMC_CS_SETUP(1)
#ifdef SMC_DBW_GLOBAL
#if (SMC_DBW_GLOBAL < SMC_DBW)
#undef SMC_DBW_GLOBAL
#if (SMC_DBW == 8)
#define SMC_DBW_GLOBAL 8
#elif (SMC_DBW == 16)
#define SMC_DBW_GLOBAL 16
#elif (SMC_DBW == 32)
#define SMC_DBW_GLOBAL 32
#else
#error error in SMC_DBW size
#endif
#endif
#else
#if (SMC_DBW == 8)
#define SMC_DBW_GLOBAL 8
#elif (SMC_DBW == 16)
#define SMC_DBW_GLOBAL 16
#elif (SMC_DBW == 32)
#define SMC_DBW_GLOBAL 32
#else
#error error in SMC_DBW size
#endif
#endif
#ifdef SMC_8_BIT_CHIPS_GLOBAL
#if (SMC_8_BIT_CHIPS_GLOBAL < SMC_8_BIT)
#undef SMC_8_BIT_CHIPS_GLOBAL
#if (SMC_8_BIT_CHIPS == TRUE)
#define SMC_8_BIT_CHIPS_GLOBAL TRUE
#elif (SMC_8_BIT_CHIPS == FALSE)
#define SMC_8_BIT_CHIPS_GLOBAL FALSE
#else
#error error in SMC_8_BIT_CHIPS size
#endif
#endif
#else
#if (SMC_8_BIT_CHIPS == TRUE)
#define SMC_8_BIT_CHIPS_GLOBAL TRUE
#elif (SMC_8_BIT_CHIPS == FALSE)
#define SMC_8_BIT_CHIPS_GLOBAL FALSE
#else
#error error in SMC_8_BIT_CHIPS size
#endif
#endif
#ifdef NWAIT_MODE_GLOBAL
#if (NWAIT_MODE_GLOBAL < NWAIT_MODE)
#undef NWAIT_MODE_GLOBAL
#if (NWAIT_MODE == AVR32_SMC_EXNW_MODE_DISABLED)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_DISABLED
#elif (NWAIT_MODE == AVR32_SMC_EXNW_MODE_FROZEN)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_FROZEN
#else
#error error in NWAIT_MODE size
#endif
#endif
#else
#if (NWAIT_MODE == AVR32_SMC_EXNW_MODE_DISABLED)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_DISABLED
#elif (NWAIT_MODE == AVR32_SMC_EXNW_MODE_FROZEN)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_FROZEN
#else
#error error in NWAIT_MODE size
#endif
#endif
#undef EXT_SM_SIZE
#undef SMC_DBW
#undef SMC_8_BIT_CHIPS
#undef NWE_SETUP
#undef NCS_WR_SETUP
#undef NRD_SETUP
#undef NCS_RD_SETUP
#undef NCS_WR_PULSE
#undef NWE_PULSE
#undef NCS_RD_PULSE
#undef NRD_PULSE
#undef NCS_WR_HOLD
#undef NWE_HOLD
#undef NWE_CYCLE
#undef NCS_RD_HOLD
#undef NRD_CYCLE
#undef TDF_CYCLES
#undef TDF_OPTIM
#undef PAGE_MODE
#undef PAGE_SIZE
#undef NCS_CONTROLLED_READ
#undef NCS_CONTROLLED_WRITE
#undef NWAIT_MODE
#endif
//! Whether to use the NCS2 pin
#ifdef SMC_USE_NCS2
#include SMC_COMPONENT_CS2
// Setup SMC for NCS2
SMC_CS_SETUP(2)
#ifdef SMC_DBW_GLOBAL
#if (SMC_DBW_GLOBAL < SMC_DBW)
#undef SMC_DBW_GLOBAL
#if (SMC_DBW == 8)
#define SMC_DBW_GLOBAL 8
#elif (SMC_DBW == 16)
#define SMC_DBW_GLOBAL 16
#elif (SMC_DBW == 32)
#define SMC_DBW_GLOBAL 32
#else
#error error in SMC_DBW size
#endif
#endif
#else
#if (SMC_DBW == 8)
#define SMC_DBW_GLOBAL 8
#elif (SMC_DBW == 16)
#define SMC_DBW_GLOBAL 16
#elif (SMC_DBW == 32)
#define SMC_DBW_GLOBAL 32
#else
#error error in SMC_DBW size
#endif
#endif
#ifdef SMC_8_BIT_CHIPS_GLOBAL
#if (SMC_8_BIT_CHIPS_GLOBAL < SMC_8_BIT)
#undef SMC_8_BIT_CHIPS_GLOBAL
#if (SMC_8_BIT_CHIPS == TRUE)
#define SMC_8_BIT_CHIPS_GLOBAL TRUE
#elif (SMC_8_BIT_CHIPS == FALSE)
#define SMC_8_BIT_CHIPS_GLOBAL FALSE
#else
#error error in SMC_8_BIT_CHIPS size
#endif
#endif
#else
#if (SMC_8_BIT_CHIPS == TRUE)
#define SMC_8_BIT_CHIPS_GLOBAL TRUE
#elif (SMC_8_BIT_CHIPS == FALSE)
#define SMC_8_BIT_CHIPS_GLOBAL FALSE
#else
#error error in SMC_8_BIT_CHIPS size
#endif
#endif
#ifdef NWAIT_MODE_GLOBAL
#if (NWAIT_MODE_GLOBAL < NWAIT_MODE)
#undef NWAIT_MODE_GLOBAL
#if (NWAIT_MODE == AVR32_SMC_EXNW_MODE_DISABLED)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_DISABLED
#elif (NWAIT_MODE == AVR32_SMC_EXNW_MODE_FROZEN)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_FROZEN
#else
#error error in NWAIT_MODE size
#endif
#endif
#else
#if (NWAIT_MODE == AVR32_SMC_EXNW_MODE_DISABLED)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_DISABLED
#elif (NWAIT_MODE == AVR32_SMC_EXNW_MODE_FROZEN)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_FROZEN
#else
#error error in NWAIT_MODE size
#endif
#endif
#undef EXT_SM_SIZE
#undef SMC_DBW
#undef SMC_8_BIT_CHIPS
#undef NWE_SETUP
#undef NCS_WR_SETUP
#undef NRD_SETUP
#undef NCS_RD_SETUP
#undef NCS_WR_PULSE
#undef NWE_PULSE
#undef NCS_RD_PULSE
#undef NRD_PULSE
#undef NCS_WR_HOLD
#undef NWE_HOLD
#undef NWE_CYCLE
#undef NCS_RD_HOLD
#undef NRD_CYCLE
#undef TDF_CYCLES
#undef TDF_OPTIM
#undef PAGE_MODE
#undef PAGE_SIZE
#undef NCS_CONTROLLED_READ
#undef NCS_CONTROLLED_WRITE
#undef NWAIT_MODE
#endif
//! Whether to use the NCS3 pin
#ifdef SMC_USE_NCS3
#include SMC_COMPONENT_CS3
// Setup SMC for NCS3
SMC_CS_SETUP(3)
#ifdef SMC_DBW_GLOBAL
#if (SMC_DBW_GLOBAL < SMC_DBW)
#undef SMC_DBW_GLOBAL
#if (SMC_DBW == 8)
#define SMC_DBW_GLOBAL 8
#elif (SMC_DBW == 16)
#define SMC_DBW_GLOBAL 16
#elif (SMC_DBW == 32)
#define SMC_DBW_GLOBAL 32
#else
#error error in SMC_DBW size
#endif
#endif
#else
#if (SMC_DBW == 8)
#define SMC_DBW_GLOBAL 8
#elif (SMC_DBW == 16)
#define SMC_DBW_GLOBAL 16
#elif (SMC_DBW == 32)
#define SMC_DBW_GLOBAL 32
#else
#error error in SMC_DBW size
#endif
#endif
#ifdef SMC_8_BIT_CHIPS_GLOBAL
#if (SMC_8_BIT_CHIPS_GLOBAL < SMC_8_BIT)
#undef SMC_8_BIT_CHIPS_GLOBAL
#if (SMC_8_BIT_CHIPS == TRUE)
#define SMC_8_BIT_CHIPS_GLOBAL TRUE
#elif (SMC_8_BIT_CHIPS == FALSE)
#define SMC_8_BIT_CHIPS_GLOBAL FALSE
#else
#error error in SMC_8_BIT_CHIPS size
#endif
#endif
#else
#if (SMC_8_BIT_CHIPS == TRUE)
#define SMC_8_BIT_CHIPS_GLOBAL TRUE
#elif (SMC_8_BIT_CHIPS == FALSE)
#define SMC_8_BIT_CHIPS_GLOBAL FALSE
#else
#error error in SMC_8_BIT_CHIPS size
#endif
#endif
#ifdef NWAIT_MODE_GLOBAL
#if (NWAIT_MODE_GLOBAL < NWAIT_MODE)
#undef NWAIT_MODE_GLOBAL
#if (NWAIT_MODE == AVR32_SMC_EXNW_MODE_DISABLED)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_DISABLED
#elif (NWAIT_MODE == AVR32_SMC_EXNW_MODE_FROZEN)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_FROZEN
#else
#error error in NWAIT_MODE size
#endif
#endif
#else
#if (NWAIT_MODE == AVR32_SMC_EXNW_MODE_DISABLED)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_DISABLED
#elif (NWAIT_MODE == AVR32_SMC_EXNW_MODE_FROZEN)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_FROZEN
#else
#error error in NWAIT_MODE size
#endif
#endif
#undef EXT_SM_SIZE
#undef SMC_DBW
#undef SMC_8_BIT_CHIPS
#undef NWE_SETUP
#undef NCS_WR_SETUP
#undef NRD_SETUP
#undef NCS_RD_SETUP
#undef NCS_WR_PULSE
#undef NWE_PULSE
#undef NCS_RD_PULSE
#undef NRD_PULSE
#undef NCS_WR_HOLD
#undef NWE_HOLD
#undef NWE_CYCLE
#undef NCS_RD_HOLD
#undef NRD_CYCLE
#undef TDF_CYCLES
#undef TDF_OPTIM
#undef PAGE_MODE
#undef PAGE_SIZE
#undef NCS_CONTROLLED_READ
#undef NCS_CONTROLLED_WRITE
#undef NWAIT_MODE
#endif
//! Whether to use the NCS4 pin
#ifdef SMC_USE_NCS4
#include SMC_COMPONENT_CS4
// Setup SMC for NCS4
SMC_CS_SETUP(4)
#ifdef SMC_DBW_GLOBAL
#if (SMC_DBW_GLOBAL < SMC_DBW)
#undef SMC_DBW_GLOBAL
#if (SMC_DBW == 8)
#define SMC_DBW_GLOBAL 8
#elif (SMC_DBW == 16)
#define SMC_DBW_GLOBAL 16
#elif (SMC_DBW == 32)
#define SMC_DBW_GLOBAL 32
#else
#error error in SMC_DBW size
#endif
#endif
#else
#if (SMC_DBW == 8)
#define SMC_DBW_GLOBAL 8
#elif (SMC_DBW == 16)
#define SMC_DBW_GLOBAL 16
#elif (SMC_DBW == 32)
#define SMC_DBW_GLOBAL 32
#else
#error error in SMC_DBW size
#endif
#endif
#ifdef SMC_8_BIT_CHIPS_GLOBAL
#if (SMC_8_BIT_CHIPS_GLOBAL < SMC_8_BIT)
#undef SMC_8_BIT_CHIPS_GLOBAL
#if (SMC_8_BIT_CHIPS == TRUE)
#define SMC_8_BIT_CHIPS_GLOBAL TRUE
#elif (SMC_8_BIT_CHIPS == FALSE)
#define SMC_8_BIT_CHIPS_GLOBAL FALSE
#else
#error error in SMC_8_BIT_CHIPS size
#endif
#endif
#else
#if (SMC_8_BIT_CHIPS == TRUE)
#define SMC_8_BIT_CHIPS_GLOBAL TRUE
#elif (SMC_8_BIT_CHIPS == FALSE)
#define SMC_8_BIT_CHIPS_GLOBAL FALSE
#else
#error error in SMC_8_BIT_CHIPS size
#endif
#endif
#ifdef NWAIT_MODE_GLOBAL
#if (NWAIT_MODE_GLOBAL < NWAIT_MODE)
#undef NWAIT_MODE_GLOBAL
#if (NWAIT_MODE == AVR32_SMC_EXNW_MODE_DISABLED)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_DISABLED
#elif (NWAIT_MODE == AVR32_SMC_EXNW_MODE_FROZEN)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_FROZEN
#else
#error error in NWAIT_MODE size
#endif
#endif
#else
#if (NWAIT_MODE == AVR32_SMC_EXNW_MODE_DISABLED)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_DISABLED
#elif (NWAIT_MODE == AVR32_SMC_EXNW_MODE_FROZEN)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_FROZEN
#else
#error error in NWAIT_MODE size
#endif
#endif
#undef EXT_SM_SIZE
#undef SMC_DBW
#undef SMC_8_BIT_CHIPS
#undef NWE_SETUP
#undef NCS_WR_SETUP
#undef NRD_SETUP
#undef NCS_RD_SETUP
#undef NCS_WR_PULSE
#undef NWE_PULSE
#undef NCS_RD_PULSE
#undef NRD_PULSE
#undef NCS_WR_HOLD
#undef NWE_HOLD
#undef NWE_CYCLE
#undef NCS_RD_HOLD
#undef NRD_CYCLE
#undef TDF_CYCLES
#undef TDF_OPTIM
#undef PAGE_MODE
#undef PAGE_SIZE
#undef NCS_CONTROLLED_READ
#undef NCS_CONTROLLED_WRITE
#undef NWAIT_MODE
#endif
//! Whether to use the NCS5 pin
#ifdef SMC_USE_NCS5
#include SMC_COMPONENT_CS5
// Setup SMC for NCS5
SMC_CS_SETUP(5)
#ifdef SMC_DBW_GLOBAL
#if (SMC_DBW_GLOBAL < SMC_DBW)
#undef SMC_DBW_GLOBAL
#if (SMC_DBW == 8)
#define SMC_DBW_GLOBAL 8
#elif (SMC_DBW == 16)
#define SMC_DBW_GLOBAL 16
#elif (SMC_DBW == 32)
#define SMC_DBW_GLOBAL 32
#else
#error error in SMC_DBW size
#endif
#endif
#else
#if (SMC_DBW == 8)
#define SMC_DBW_GLOBAL 8
#elif (SMC_DBW == 16)
#define SMC_DBW_GLOBAL 16
#elif (SMC_DBW == 32)
#define SMC_DBW_GLOBAL 32
#else
#error error in SMC_DBW size
#endif
#endif
#ifdef SMC_8_BIT_CHIPS_GLOBAL
#if (SMC_8_BIT_CHIPS_GLOBAL < SMC_8_BIT)
#undef SMC_8_BIT_CHIPS_GLOBAL
#if (SMC_8_BIT_CHIPS == TRUE)
#define SMC_8_BIT_CHIPS_GLOBAL TRUE
#elif (SMC_8_BIT_CHIPS == FALSE)
#define SMC_8_BIT_CHIPS_GLOBAL FALSE
#else
#error error in SMC_8_BIT_CHIPS size
#endif
#endif
#else
#if (SMC_8_BIT_CHIPS == TRUE)
#define SMC_8_BIT_CHIPS_GLOBAL TRUE
#elif (SMC_8_BIT_CHIPS == FALSE)
#define SMC_8_BIT_CHIPS_GLOBAL FALSE
#else
#error error in SMC_8_BIT_CHIPS size
#endif
#endif
#ifdef NWAIT_MODE_GLOBAL
#if (NWAIT_MODE_GLOBAL < NWAIT_MODE)
#undef NWAIT_MODE_GLOBAL
#if (NWAIT_MODE == AVR32_SMC_EXNW_MODE_DISABLED)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_DISABLED
#elif (NWAIT_MODE == AVR32_SMC_EXNW_MODE_FROZEN)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_FROZEN
#else
#error error in NWAIT_MODE size
#endif
#endif
#else
#if (NWAIT_MODE == AVR32_SMC_EXNW_MODE_DISABLED)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_DISABLED
#elif (NWAIT_MODE == AVR32_SMC_EXNW_MODE_FROZEN)
#define NWAIT_MODE_GLOBAL AVR32_SMC_EXNW_MODE_FROZEN
#else
#error error in NWAIT_MODE size
#endif
#endif
#undef EXT_SM_SIZE
#undef SMC_DBW
#undef SMC_8_BIT_CHIPS
#undef NWE_SETUP
#undef NCS_WR_SETUP
#undef NRD_SETUP
#undef NCS_RD_SETUP
#undef NCS_WR_PULSE
#undef NWE_PULSE
#undef NCS_RD_PULSE
#undef NRD_PULSE
#undef NCS_WR_HOLD
#undef NWE_HOLD
#undef NWE_CYCLE
#undef NCS_RD_HOLD
#undef NRD_CYCLE
#undef TDF_CYCLES
#undef TDF_OPTIM
#undef PAGE_MODE
#undef PAGE_SIZE
#undef NCS_CONTROLLED_READ
#undef NCS_CONTROLLED_WRITE
#undef NWAIT_MODE
#endif
// Put the multiplexed MCU pins used for the SM under control of the SMC.
smc_enable_muxed_pins();
}
/*! \brief Puts the multiplexed MCU pins used for the SMC
*
*/
static void smc_enable_muxed_pins(void)
{
static const gpio_map_t SMC_EBI_GPIO_MAP =
{
// Enable data pins.
#ifdef EBI_DATA_0
{ATPASTE2(EBI_DATA_0,_PIN),ATPASTE2(EBI_DATA_0,_FUNCTION)},
#endif
#ifdef EBI_DATA_1
{ATPASTE2(EBI_DATA_1,_PIN),ATPASTE2(EBI_DATA_1,_FUNCTION)},
#endif
#ifdef EBI_DATA_2
{ATPASTE2(EBI_DATA_2,_PIN),ATPASTE2(EBI_DATA_2,_FUNCTION)},
#endif
#ifdef EBI_DATA_3
{ATPASTE2(EBI_DATA_3,_PIN),ATPASTE2(EBI_DATA_3,_FUNCTION)},
#endif
#ifdef EBI_DATA_4
{ATPASTE2(EBI_DATA_4,_PIN),ATPASTE2(EBI_DATA_4,_FUNCTION)},
#endif
#ifdef EBI_DATA_5
{ATPASTE2(EBI_DATA_5,_PIN),ATPASTE2(EBI_DATA_5,_FUNCTION)},
#endif
#ifdef EBI_DATA_6
{ATPASTE2(EBI_DATA_6,_PIN),ATPASTE2(EBI_DATA_6,_FUNCTION)},
#endif
#ifdef EBI_DATA_7
{ATPASTE2(EBI_DATA_7,_PIN),ATPASTE2(EBI_DATA_7,_FUNCTION)},
#endif
#ifdef EBI_DATA_8
{ATPASTE2(EBI_DATA_8,_PIN),ATPASTE2(EBI_DATA_8,_FUNCTION)},
#endif
#ifdef EBI_DATA_9
{ATPASTE2(EBI_DATA_9,_PIN),ATPASTE2(EBI_DATA_9,_FUNCTION)},
#endif
#ifdef EBI_DATA_10
{ATPASTE2(EBI_DATA_10,_PIN),ATPASTE2(EBI_DATA_10,_FUNCTION)},
#endif
#ifdef EBI_DATA_11
{ATPASTE2(EBI_DATA_11,_PIN),ATPASTE2(EBI_DATA_11,_FUNCTION)},
#endif
#ifdef EBI_DATA_12
{ATPASTE2(EBI_DATA_12,_PIN),ATPASTE2(EBI_DATA_12,_FUNCTION)},
#endif
#ifdef EBI_DATA_13
{ATPASTE2(EBI_DATA_13,_PIN),ATPASTE2(EBI_DATA_13,_FUNCTION)},
#endif
#ifdef EBI_DATA_14
{ATPASTE2(EBI_DATA_14,_PIN),ATPASTE2(EBI_DATA_14,_FUNCTION)},
#endif
#ifdef EBI_DATA_15
{ATPASTE2(EBI_DATA_15,_PIN),ATPASTE2(EBI_DATA_15,_FUNCTION)},
#endif
#ifdef EBI_DATA_16
{ATPASTE2(EBI_DATA_16,_PIN),ATPASTE2(EBI_DATA_16,_FUNCTION)},
#endif
#ifdef EBI_DATA_17
{ATPASTE2(EBI_DATA_17,_PIN),ATPASTE2(EBI_DATA_17,_FUNCTION)},
#endif
#ifdef EBI_DATA_18
{ATPASTE2(EBI_DATA_18,_PIN),ATPASTE2(EBI_DATA_18,_FUNCTION)},
#endif
#ifdef EBI_DATA_19
{ATPASTE2(EBI_DATA_19,_PIN),ATPASTE2(EBI_DATA_19,_FUNCTION)},
#endif
#ifdef EBI_DATA_20
{ATPASTE2(EBI_DATA_20,_PIN),ATPASTE2(EBI_DATA_20,_FUNCTION)},
#endif
#ifdef EBI_DATA_21
{ATPASTE2(EBI_DATA_21,_PIN),ATPASTE2(EBI_DATA_21,_FUNCTION)},
#endif
#ifdef EBI_DATA_22
{ATPASTE2(EBI_DATA_22,_PIN),ATPASTE2(EBI_DATA_22,_FUNCTION)},
#endif
#ifdef EBI_DATA_23
{ATPASTE2(EBI_DATA_23,_PIN),ATPASTE2(EBI_DATA_23,_FUNCTION)},
#endif
#ifdef EBI_DATA_24
{ATPASTE2(EBI_DATA_24,_PIN),ATPASTE2(EBI_DATA_24,_FUNCTION)},
#endif
#ifdef EBI_DATA_25
{ATPASTE2(EBI_DATA_25,_PIN),ATPASTE2(EBI_DATA_25,_FUNCTION)},
#endif
#ifdef EBI_DATA_26
{ATPASTE2(EBI_DATA_26,_PIN),ATPASTE2(EBI_DATA_26,_FUNCTION)},
#endif
#ifdef EBI_DATA_27
{ATPASTE2(EBI_DATA_27,_PIN),ATPASTE2(EBI_DATA_27,_FUNCTION)},
#endif
#ifdef EBI_DATA_28
{ATPASTE2(EBI_DATA_28,_PIN),ATPASTE2(EBI_DATA_28,_FUNCTION)},
#endif
#ifdef EBI_DATA_29
{ATPASTE2(EBI_DATA_29,_PIN),ATPASTE2(EBI_DATA_29,_FUNCTION)},
#endif
#ifdef EBI_DATA_30
{ATPASTE2(EBI_DATA_30,_PIN),ATPASTE2(EBI_DATA_30,_FUNCTION)},
#endif
#ifdef EBI_DATA_31
{ATPASTE2(EBI_DATA_31,_PIN),ATPASTE2(EBI_DATA_31,_FUNCTION)},
#endif
// Enable address pins.
#if SMC_DBW_GLOBAL <= 8
#ifdef EBI_ADDR_0
{ATPASTE2(EBI_ADDR_0,_PIN),ATPASTE2(EBI_ADDR_0,_FUNCTION)},
#endif
#endif
#if SMC_DBW_GLOBAL <= 16
#ifdef EBI_ADDR_1
{ATPASTE2(EBI_ADDR_1,_PIN),ATPASTE2(EBI_ADDR_1,_FUNCTION)},
#endif
#endif
#ifdef EBI_ADDR_2
{ATPASTE2(EBI_ADDR_2,_PIN),ATPASTE2(EBI_ADDR_2,_FUNCTION)},
#endif
#ifdef EBI_ADDR_3
{ATPASTE2(EBI_ADDR_3,_PIN),ATPASTE2(EBI_ADDR_3,_FUNCTION)},
#endif
#ifdef EBI_ADDR_4
{ATPASTE2(EBI_ADDR_4,_PIN),ATPASTE2(EBI_ADDR_4,_FUNCTION)},
#endif
#ifdef EBI_ADDR_5
{ATPASTE2(EBI_ADDR_5,_PIN),ATPASTE2(EBI_ADDR_5,_FUNCTION)},
#endif
#ifdef EBI_ADDR_6
{ATPASTE2(EBI_ADDR_6,_PIN),ATPASTE2(EBI_ADDR_6,_FUNCTION)},
#endif
#ifdef EBI_ADDR_7
{ATPASTE2(EBI_ADDR_7,_PIN),ATPASTE2(EBI_ADDR_7,_FUNCTION)},
#endif
#ifdef EBI_ADDR_8
{ATPASTE2(EBI_ADDR_8,_PIN),ATPASTE2(EBI_ADDR_8,_FUNCTION)},
#endif
#ifdef EBI_ADDR_9
{ATPASTE2(EBI_ADDR_9,_PIN),ATPASTE2(EBI_ADDR_9,_FUNCTION)},
#endif
#ifdef EBI_ADDR_10
{ATPASTE2(EBI_ADDR_10,_PIN),ATPASTE2(EBI_ADDR_10,_FUNCTION)},
#endif
#ifdef EBI_ADDR_11
{ATPASTE2(EBI_ADDR_11,_PIN),ATPASTE2(EBI_ADDR_11,_FUNCTION)},
#endif
#ifdef EBI_ADDR_12
{ATPASTE2(EBI_ADDR_12,_PIN),ATPASTE2(EBI_ADDR_12,_FUNCTION)},
#endif
#ifdef EBI_ADDR_13
{ATPASTE2(EBI_ADDR_13,_PIN),ATPASTE2(EBI_ADDR_13,_FUNCTION)},
#endif
#ifdef EBI_ADDR_14
{ATPASTE2(EBI_ADDR_14,_PIN),ATPASTE2(EBI_ADDR_14,_FUNCTION)},
#endif
#ifdef EBI_ADDR_15
{ATPASTE2(EBI_ADDR_15,_PIN),ATPASTE2(EBI_ADDR_15,_FUNCTION)},
#endif
#ifdef EBI_ADDR_16
{ATPASTE2(EBI_ADDR_16,_PIN),ATPASTE2(EBI_ADDR_16,_FUNCTION)},
#endif
#ifdef EBI_ADDR_17
{ATPASTE2(EBI_ADDR_17,_PIN),ATPASTE2(EBI_ADDR_17,_FUNCTION)},
#endif
#ifdef EBI_ADDR_18
{ATPASTE2(EBI_ADDR_18,_PIN),ATPASTE2(EBI_ADDR_18,_FUNCTION)},
#endif
#ifdef EBI_ADDR_19
{ATPASTE2(EBI_ADDR_19,_PIN),ATPASTE2(EBI_ADDR_19,_FUNCTION)},
#endif
#ifdef EBI_ADDR_20
{ATPASTE2(EBI_ADDR_20,_PIN),ATPASTE2(EBI_ADDR_20,_FUNCTION)},
#endif
#ifdef EBI_ADDR_21
{ATPASTE2(EBI_ADDR_21,_PIN),ATPASTE2(EBI_ADDR_21,_FUNCTION)},
#endif
#ifdef EBI_ADDR_22
{ATPASTE2(EBI_ADDR_22,_PIN),ATPASTE2(EBI_ADDR_22,_FUNCTION)},
#endif
#ifdef EBI_ADDR_23
{ATPASTE2(EBI_ADDR_23,_PIN),ATPASTE2(EBI_ADDR_23,_FUNCTION)},
#endif
#if SMC_DBW_GLOBAL <= 8
#undef SMC_8_BIT_CHIPS
#define SMC_8_BIT_CHIPS TRUE
#endif
// Enable data mask pins.
#if !SMC_8_BIT_CHIPS_GLOBAL
#ifdef EBI_ADDR_0
{ATPASTE2(EBI_ADDR_0,_PIN),ATPASTE2(EBI_ADDR_0,_FUNCTION)},
#endif
#endif
#ifdef EBI_NWE0
{ATPASTE2(EBI_NWE0,_PIN),ATPASTE2(EBI_NWE0,_FUNCTION)},
#endif
#if SMC_DBW_GLOBAL >= 16
#ifdef EBI_NWE1
{ATPASTE2(EBI_NWE1,_PIN),ATPASTE2(EBI_NWE1,_FUNCTION)},
#endif
#if SMC_DBW_GLOBAL >= 32
#ifdef EBI_ADDR_1
{ATPASTE2(EBI_ADDR_1,_PIN),ATPASTE2(EBI_ADDR_1,_FUNCTION)},
#endif
#ifdef EBI_NWE3
{ATPASTE2(EBI_NWE3,_PIN),ATPASTE2(EBI_NWE3,_FUNCTION)},
#endif
#endif
#endif
#ifdef EBI_NRD
{ATPASTE2(EBI_NRD,_PIN),ATPASTE2(EBI_NRD,_FUNCTION)},
#endif
// Enable control pins.
#if NWAIT_MODE_GLOBAL != AVR32_SMC_EXNW_MODE_DISABLED
#ifdef EBI_NWAIT
{ATPASTE2(EBI_NWAIT,_PIN),ATPASTE2(EBI_NWAIT,_FUNCTION)},
#endif
#endif
#ifdef SMC_USE_NCS0
#ifdef EBI_NCS_0
{ATPASTE2(EBI_NCS_0,_PIN),ATPASTE2(EBI_NCS_0,_FUNCTION)},
#endif
#endif
#ifdef SMC_USE_NCS1
#ifdef EBI_NCS_1
{ATPASTE2(EBI_NCS_1,_PIN),ATPASTE2(EBI_NCS_1,_FUNCTION)},
#endif
#endif
#ifdef SMC_USE_NCS2
#ifdef EBI_NCS_2
{ATPASTE2(EBI_NCS_2,_PIN),ATPASTE2(EBI_NCS_2,_FUNCTION)},
#endif
#endif
#ifdef SMC_USE_NCS3
#ifdef EBI_NCS_3
{ATPASTE2(EBI_NCS_3,_PIN),ATPASTE2(EBI_NCS_3,_FUNCTION)},
#endif
#endif
#ifdef SMC_USE_NCS4
#ifdef EBI_NCS_4
{ATPASTE2(EBI_NCS_4,_PIN),ATPASTE2(EBI_NCS_4,_FUNCTION)},
#endif
#endif
#ifdef SMC_USE_NCS5
#ifdef EBI_NCS_5
{ATPASTE2(EBI_NCS_5,_PIN),ATPASTE2(EBI_NCS_5,_FUNCTION)},
#endif
#endif
};
gpio_enable_module(SMC_EBI_GPIO_MAP, sizeof(SMC_EBI_GPIO_MAP) / sizeof(SMC_EBI_GPIO_MAP[0]));
}
unsigned char smc_get_cs_size(unsigned char cs)
{
return smc_tab_cs_size[cs];
}

View File

@ -0,0 +1,68 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief SMC on EBI driver for AVR32 UC3.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with a SMC module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _SMC_H_
#define _SMC_H_
#include <avr32/io.h>
#include "compiler.h"
#include "conf_ebi.h"
/*! \brief Initializes the AVR32 SMC module and the connected SRAM(s).
* \param hsb_hz HSB frequency in Hz (the HSB frequency is applied to the SMC).
* \note Each access to the SMC address space validates the mode of the SMC
* and generates an operation corresponding to this mode.
*/
extern void smc_init(unsigned long hsb_hz);
/*! \brief Return the size of the peripheral connected .
* \param cs The chip select value
*/
extern unsigned char smc_get_cs_size(unsigned char cs);
#endif // _SMC_H_

View File

@ -0,0 +1,183 @@
/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief EIC driver for AVR32 UC3.
*
* AVR32 External Interrupt Controller driver module.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with an EIC module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#include <avr32/io.h>
#include "compiler.h"
#include "preprocessor.h"
#include "eic.h"
void eic_init(volatile avr32_eic_t *eic, const eic_options_t *opt, unsigned int nb_lines)
{
int i;
for (i = 0; i < nb_lines; i++)
{
// Set up mode level
eic->mode = (opt[i].eic_mode == 1) ? (eic->mode | (1 << opt[i].eic_line)) : (eic->mode & ~(1 << opt[i].eic_line));
// Set up edge type
eic->edge = (opt[i].eic_edge == 1) ? (eic->edge | (1 << opt[i].eic_line)) : (eic->edge & ~(1 << opt[i].eic_line));
// Set up level
eic->level = (opt[i].eic_level == 1) ? (eic->level | (1 << opt[i].eic_line)) : (eic->level & ~(1 << opt[i].eic_line));
// Set up if filter is used
eic->filter = (opt[i].eic_filter == 1) ? (eic->filter | (1 << opt[i].eic_line)) : (eic->filter & ~(1 << opt[i].eic_line));
// Set up which mode is used : asynchronous mode/ synchronous mode
eic->async = (opt[i].eic_async == 1) ? (eic->async | (1 << opt[i].eic_line)) : (eic->async & ~(1 << opt[i].eic_line));
}
}
void eic_enable_lines(volatile avr32_eic_t *eic, unsigned int mask_lines)
{
eic->en = mask_lines;
}
void eic_enable_line(volatile avr32_eic_t *eic, unsigned int line_number)
{
// Enable line line_number
eic->en = 1 << line_number;
}
void eic_disable_lines(volatile avr32_eic_t *eic, unsigned int mask_lines)
{
eic->dis = mask_lines;
}
void eic_disable_line(volatile avr32_eic_t *eic, unsigned int line_number)
{
// Disable line line_number
eic->dis = 1 << line_number;
}
Bool eic_is_line_enabled(volatile avr32_eic_t *eic, unsigned int line_number)
{
return (eic->ctrl & (1 << line_number)) != 0;
}
void eic_enable_interrupt_lines(volatile avr32_eic_t *eic, unsigned int mask_lines)
{
eic->ier = mask_lines;
}
void eic_enable_interrupt_line(volatile avr32_eic_t *eic, unsigned int line_number)
{
// Enable line line_number
eic->ier = 1 << line_number;
}
void eic_disable_interrupt_lines(volatile avr32_eic_t *eic, unsigned int mask_lines)
{
Bool global_interrupt_enabled = Is_global_interrupt_enabled();
if (global_interrupt_enabled) Disable_global_interrupt();
eic->idr = mask_lines;
eic->imr;
if (global_interrupt_enabled) Enable_global_interrupt();
}
void eic_disable_interrupt_line(volatile avr32_eic_t *eic, unsigned int line_number)
{
Bool global_interrupt_enabled = Is_global_interrupt_enabled();
// Disable line line_number
if (global_interrupt_enabled) Disable_global_interrupt();
eic->idr = 1 << line_number;
eic->imr;
if (global_interrupt_enabled) Enable_global_interrupt();
}
Bool eic_is_interrupt_line_enabled(volatile avr32_eic_t *eic, unsigned int line_number)
{
return (eic->imr & (1 << line_number)) != 0;
}
void eic_clear_interrupt_lines(volatile avr32_eic_t *eic, unsigned int mask_lines)
{
Bool global_interrupt_enabled = Is_global_interrupt_enabled();
if (global_interrupt_enabled) Disable_global_interrupt();
eic->icr = mask_lines;
eic->isr;
if (global_interrupt_enabled) Enable_global_interrupt();
}
void eic_clear_interrupt_line(volatile avr32_eic_t *eic, unsigned int line_number)
{
Bool global_interrupt_enabled = Is_global_interrupt_enabled();
// Clear line line_number
if (global_interrupt_enabled) Disable_global_interrupt();
eic->icr = 1 << line_number;
eic->isr;
if (global_interrupt_enabled) Enable_global_interrupt();
}
Bool eic_is_interrupt_line_pending(volatile avr32_eic_t *eic, unsigned int line_number)
{
return (eic->isr & (1 << line_number)) != 0;
}
#if !defined(AVR32_EIC_301_H_INCLUDED)
void eic_enable_interrupt_scan(volatile avr32_eic_t *eic,unsigned int presc)
{
// Enable SCAN function with PRESC value
eic->scan |= (presc << AVR32_EIC_SCAN_PRESC_OFFSET) | (1 << AVR32_EIC_SCAN_EN_OFFSET);
}
void eic_disable_interrupt_scan(volatile avr32_eic_t *eic)
{
// Disable SCAN function
eic->scan = 0 << AVR32_EIC_SCAN_EN_OFFSET;
}
unsigned long eic_get_interrupt_pad_scan(volatile avr32_eic_t *eic)
{
// Return pad number that causes interrupt
return(eic->scan>>AVR32_EIC_SCAN_PIN_OFFSET);
}
#endif

View File

@ -0,0 +1,275 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief EIC driver for AVR32 UC3.
*
* AVR32 External Interrupt Controller driver module.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with an EIC module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _EIC_H_
#define _EIC_H_
#include "compiler.h"
/*! \name External Interrupt lines
*/
//! @{
#if (UC3A || UC3B)
#define EXT_INT0 AVR32_EIC_INT0 //!< Line 0
#define EXT_INT1 AVR32_EIC_INT1 //!< Line 1
#define EXT_INT2 AVR32_EIC_INT2 //!< Line 2
#define EXT_INT3 AVR32_EIC_INT3 //!< Line 3
#define EXT_INT4 AVR32_EIC_INT4 //!< Line 4
#define EXT_INT5 AVR32_EIC_INT5 //!< Line 5
#define EXT_INT6 AVR32_EIC_INT6 //!< Line 6
#define EXT_INT7 AVR32_EIC_INT7 //!< Line 7
#define EXT_NMI AVR32_EIC_NMI //!< Line 8
#else
#define EXT_INT0 AVR32_EIC_INT1 //!< Line 0
#define EXT_INT1 AVR32_EIC_INT2 //!< Line 1
#define EXT_INT2 AVR32_EIC_INT3 //!< Line 2
#define EXT_INT3 AVR32_EIC_INT4 //!< Line 3
#define EXT_INT4 AVR32_EIC_INT5 //!< Line 4
#define EXT_INT5 AVR32_EIC_INT6 //!< Line 5
#define EXT_INT6 AVR32_EIC_INT7 //!< Line 6
#define EXT_INT7 AVR32_EIC_INT8 //!< Line 7
#define EXT_NMI AVR32_EIC_NMI //!< Line 8
#endif
//! @}
/*! \name Mode Trigger Options
*/
//! @{
#define EIC_MODE_EDGE_TRIGGERED AVR32_EIC_EDGE_IRQ //!<
#define EIC_MODE_LEVEL_TRIGGERED AVR32_EIC_LEVEL_IRQ //!<
//! @}
/*! \name Edge level Options
*/
//! @{
#define EIC_EDGE_FALLING_EDGE AVR32_EIC_FALLING_EDGE //!<
#define EIC_EDGE_RISING_EDGE AVR32_EIC_RISING_EDGE //!<
//! @}
/*! \name Level Options
*/
//! @{
#define EIC_LEVEL_LOW_LEVEL AVR32_EIC_LOW_LEVEL //!<
#define EIC_LEVEL_HIGH_LEVEL AVR32_EIC_HIGH_LEVEL //!<
//! @}
/*! \name Filter Options
*/
//! @{
#define EIC_FILTER_ENABLED AVR32_EIC_FILTER_ON //!<
#define EIC_FILTER_DISABLED AVR32_EIC_FILTER_OFF //!<
//! @}
/*! \name Synch Mode Options
*/
//! @{
#define EIC_SYNCH_MODE AVR32_EIC_SYNC //!<
#define EIC_ASYNCH_MODE AVR32_EIC_USE_ASYNC //!<
//! @}
//! Configuration parameters of the EIC module.
typedef struct
{
//!Line
unsigned char eic_line;
//! Mode : EDGE_LEVEL or TRIGGER_LEVEL
unsigned char eic_mode;
//! Edge : FALLING_EDGE or RISING_EDGE
unsigned char eic_edge;
//! Level : LOW_LEVEL or HIGH_LEVEL
unsigned char eic_level;
//! Filter: NOT_FILTERED or FILTERED
unsigned char eic_filter;
//! Async: SYNC mode or ASYNC
unsigned char eic_async;
} eic_options_t;
/*! \brief Init the EIC driver.
*
* \param eic Base address of the EIC module
* \param opt Configuration parameters of the EIC module (see \ref eic_options_t)
* \param nb_lines Number of lines to consider, equal to size of opt buffer
*/
extern void eic_init(volatile avr32_eic_t *eic, const eic_options_t *opt, unsigned int nb_lines);
/*! \brief Enable the EIC driver.
*
* \param eic Base address of the EIC module
* \param mask_lines Mask for current selected lines
*/
extern void eic_enable_lines(volatile avr32_eic_t *eic, unsigned int mask_lines);
/*! \brief Enable the EIC driver.
*
* \param eic Base address of the EIC module
* \param line_number Line number to enable
*/
extern void eic_enable_line(volatile avr32_eic_t *eic, unsigned int line_number);
/*! \brief Disable the EIC driver.
*
* \param eic Base address of the EIC module
* \param mask_lines Mask for current selected lines
*/
extern void eic_disable_lines(volatile avr32_eic_t *eic, unsigned int mask_lines);
/*! \brief Disable the EIC driver.
*
* \param eic Base address of the EIC module
* \param line_number Line number to disable
*/
extern void eic_disable_line(volatile avr32_eic_t *eic, unsigned int line_number);
/*! \brief Tells whether an EIC line is enabled.
*
* \param eic Base address of the EIC module
* \param line_number Line number to test
*
* \return Whether an EIC line is enabled.
*/
extern Bool eic_is_line_enabled(volatile avr32_eic_t *eic, unsigned int line_number);
/*! \name Interrupt Control Functions
*/
//! @{
/*! \brief Enable the interrupt feature of the EIC.
*
* \param eic Base address of the EIC (i.e. &AVR32_EIC).
* \param mask_lines Mask for current selected lines
*/
extern void eic_enable_interrupt_lines(volatile avr32_eic_t *eic, unsigned int mask_lines);
/*! \brief Enable the interrupt feature of the EIC.
*
* \param eic Base address of the EIC (i.e. &AVR32_EIC).
* \param line_number Line number to enable
*/
extern void eic_enable_interrupt_line(volatile avr32_eic_t *eic, unsigned int line_number);
/*! \brief Disable the interrupt feature of the EIC.
*
* \param eic Base address of the EIC (i.e. &AVR32_EIC).
* \param mask_lines Mask for current selected lines
*/
extern void eic_disable_interrupt_lines(volatile avr32_eic_t *eic, unsigned int mask_lines);
/*! \brief Disable the interrupt feature of the EIC.
*
* \param eic Base address of the EIC (i.e. &AVR32_EIC).
* \param line_number Line number to disable
*/
extern void eic_disable_interrupt_line(volatile avr32_eic_t *eic, unsigned int line_number);
/*! \brief Tells whether an EIC interrupt line is enabled.
*
* \param eic Base address of the EIC module
* \param line_number Line number to test
*
* \return Whether an EIC interrupt line is enabled.
*/
extern Bool eic_is_interrupt_line_enabled(volatile avr32_eic_t *eic, unsigned int line_number);
/*! \brief Clear the interrupt flag.
* Call this function once you've handled the interrupt.
*
* \param eic Base address of the EIC (i.e. &AVR32_EIC).
* \param mask_lines Mask for current selected lines
*/
extern void eic_clear_interrupt_lines(volatile avr32_eic_t *eic, unsigned int mask_lines);
/*! \brief Clear the interrupt flag.
* Call this function once you've handled the interrupt.
*
* \param eic Base address of the EIC (i.e. &AVR32_EIC).
* \param line_number Line number to clear
*/
extern void eic_clear_interrupt_line(volatile avr32_eic_t *eic, unsigned int line_number);
/*! \brief Tells whether an EIC interrupt line is pending.
*
* \param eic Base address of the EIC module
* \param line_number Line number to test
*
* \return Whether an EIC interrupt line is pending.
*/
extern Bool eic_is_interrupt_line_pending(volatile avr32_eic_t *eic, unsigned int line_number);
/*! \brief Enable the interrupt scan feature of the EIC.
*
* \param eic Base address of the EIC (i.e. &AVR32_EIC).
* \param presc Prescale select for the keypad scan rate in the range [0,31].
*/
extern void eic_enable_interrupt_scan(volatile avr32_eic_t *eic, unsigned int presc);
/*! \brief Disable the interrupt scan feature of the EIC.
*
* \param eic Base address of the EIC (i.e. &AVR32_EIC).
*/
extern void eic_disable_interrupt_scan(volatile avr32_eic_t *eic);
/*! \brief Return scan pad number that causes interrupt.
*
* \param eic Base address of the EIC (i.e. &AVR32_EIC).
*/
extern unsigned long eic_get_interrupt_pad_scan(volatile avr32_eic_t *eic);
//! @}
#endif // _EIC_H_

View File

@ -0,0 +1,458 @@
/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief GPIO driver for AVR32 UC3.
*
* This file defines a useful set of functions for the GPIO.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with a GPIO module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
*****************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#include "gpio.h"
//! GPIO module instance.
#define GPIO AVR32_GPIO
/*! \name Peripheral Bus Interface
*/
//! @{
int gpio_enable_module(const gpio_map_t gpiomap, unsigned int size)
{
int status = GPIO_SUCCESS;
unsigned int i;
for (i = 0; i < size; i++)
{
status |= gpio_enable_module_pin(gpiomap->pin, gpiomap->function);
gpiomap++;
}
return status;
}
int gpio_enable_module_pin(unsigned int pin, unsigned int function)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
// Enable the correct function.
switch (function)
{
case 0: // A function.
gpio_port->pmr0c = 1 << (pin & 0x1F);
gpio_port->pmr1c = 1 << (pin & 0x1F);
#if defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED)
gpio_port->pmr2c = 1 << (pin & 0x1F);
#endif
break;
case 1: // B function.
gpio_port->pmr0s = 1 << (pin & 0x1F);
gpio_port->pmr1c = 1 << (pin & 0x1F);
#if defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED)
gpio_port->pmr2c = 1 << (pin & 0x1F);
#endif
break;
case 2: // C function.
gpio_port->pmr0c = 1 << (pin & 0x1F);
gpio_port->pmr1s = 1 << (pin & 0x1F);
#if defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED)
gpio_port->pmr2c = 1 << (pin & 0x1F);
#endif
break;
case 3: // D function.
gpio_port->pmr0s = 1 << (pin & 0x1F);
gpio_port->pmr1s = 1 << (pin & 0x1F);
#if defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED)
gpio_port->pmr2c = 1 << (pin & 0x1F);
#endif
break;
#if defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED)
case 4: // E function.
gpio_port->pmr0c = 1 << (pin & 0x1F);
gpio_port->pmr1c = 1 << (pin & 0x1F);
gpio_port->pmr2s = 1 << (pin & 0x1F);
break;
case 5: // F function.
gpio_port->pmr0s = 1 << (pin & 0x1F);
gpio_port->pmr1c = 1 << (pin & 0x1F);
gpio_port->pmr2s = 1 << (pin & 0x1F);
break;
case 6: // G function.
gpio_port->pmr0c = 1 << (pin & 0x1F);
gpio_port->pmr1s = 1 << (pin & 0x1F);
gpio_port->pmr2s = 1 << (pin & 0x1F);
break;
case 7: // H function.
gpio_port->pmr0s = 1 << (pin & 0x1F);
gpio_port->pmr1s = 1 << (pin & 0x1F);
gpio_port->pmr2s = 1 << (pin & 0x1F);
break;
#endif
default:
return GPIO_INVALID_ARGUMENT;
}
// Disable GPIO control.
gpio_port->gperc = 1 << (pin & 0x1F);
return GPIO_SUCCESS;
}
void gpio_enable_gpio(const gpio_map_t gpiomap, unsigned int size)
{
unsigned int i;
for (i = 0; i < size; i++)
{
gpio_enable_gpio_pin(gpiomap->pin);
gpiomap++;
}
}
void gpio_enable_gpio_pin(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
gpio_port->oderc = 1 << (pin & 0x1F);
gpio_port->gpers = 1 << (pin & 0x1F);
}
// The open-drain mode is not synthesized on the current AVR32 products.
// If one day some AVR32 products have this feature, the corresponding part
// numbers should be listed in the #if below.
// Note that other functions are available in this driver to use pins with open
// drain in GPIO mode. The advantage of the open-drain mode functions over these
// other functions is that they can be used not only in GPIO mode but also in
// module mode.
#if 0
void gpio_enable_pin_open_drain(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
gpio_port->odmers = 1 << (pin & 0x1F);
}
void gpio_disable_pin_open_drain(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
gpio_port->odmerc = 1 << (pin & 0x1F);
}
#endif
void gpio_enable_pin_pull_up(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
gpio_port->puers = 1 << (pin & 0x1F);
#if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED)
gpio_port->pderc = 1 << (pin & 0x1F);
#endif
}
void gpio_disable_pin_pull_up(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
gpio_port->puerc = 1 << (pin & 0x1F);
}
#if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED)
// Added support of Pull-up Resistor, Pull-down Resistor and Buskeeper Control.
/*! \brief Enables the pull-down resistor of a pin.
*
* \param pin The pin number.
*/
void gpio_enable_pin_pull_down(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
gpio_port->puerc = 1 << (pin & 0x1F);
gpio_port->pders = 1 << (pin & 0x1F);
}
/*! \brief Disables the pull-down resistor of a pin.
*
* \param pin The pin number.
*/
void gpio_disable_pin_pull_down(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
gpio_port->pderc = 1 << (pin & 0x1F);
}
/*! \brief Enables the buskeeper functionality on a pin.
*
* \param pin The pin number.
*/
void gpio_enable_pin_buskeeper(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
gpio_port->puers = 1 << (pin & 0x1F);
gpio_port->pders = 1 << (pin & 0x1F);
}
/*! \brief Disables the buskeeper functionality on a pin.
*
* \param pin The pin number.
*/
void gpio_disable_pin_buskeeper(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
gpio_port->puerc = 1 << (pin & 0x1F);
gpio_port->pderc = 1 << (pin & 0x1F);
}
#endif
int gpio_get_pin_value(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
return (gpio_port->pvr >> (pin & 0x1F)) & 1;
}
int gpio_get_gpio_pin_output_value(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
return (gpio_port->ovr >> (pin & 0x1F)) & 1;
}
int gpio_get_gpio_open_drain_pin_output_value(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
return ((gpio_port->oder >> (pin & 0x1F)) & 1) ^ 1;
}
void gpio_set_gpio_pin(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
gpio_port->ovrs = 1 << (pin & 0x1F); // Value to be driven on the I/O line: 1.
gpio_port->oders = 1 << (pin & 0x1F); // The GPIO output driver is enabled for that pin.
gpio_port->gpers = 1 << (pin & 0x1F); // The GPIO module controls that pin.
}
void gpio_clr_gpio_pin(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
gpio_port->ovrc = 1 << (pin & 0x1F); // Value to be driven on the I/O line: 0.
gpio_port->oders = 1 << (pin & 0x1F); // The GPIO output driver is enabled for that pin.
gpio_port->gpers = 1 << (pin & 0x1F); // The GPIO module controls that pin.
}
void gpio_tgl_gpio_pin(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
gpio_port->ovrt = 1 << (pin & 0x1F); // Toggle the I/O line.
gpio_port->oders = 1 << (pin & 0x1F); // The GPIO output driver is enabled for that pin.
gpio_port->gpers = 1 << (pin & 0x1F); // The GPIO module controls that pin.
}
void gpio_set_gpio_open_drain_pin(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
gpio_port->oderc = 1 << (pin & 0x1F); // The GPIO output driver is disabled for that pin.
gpio_port->gpers = 1 << (pin & 0x1F); // The GPIO module controls that pin.
}
void gpio_clr_gpio_open_drain_pin(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
gpio_port->ovrc = 1 << (pin & 0x1F); // Value to be driven on the I/O line: 0.
gpio_port->oders = 1 << (pin & 0x1F); // The GPIO output driver is enabled for that pin.
gpio_port->gpers = 1 << (pin & 0x1F); // The GPIO module controls that pin.
}
void gpio_tgl_gpio_open_drain_pin(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
gpio_port->ovrc = 1 << (pin & 0x1F); // Value to be driven on the I/O line if the GPIO output driver is enabled: 0.
gpio_port->odert = 1 << (pin & 0x1F); // The GPIO output driver is toggled for that pin.
gpio_port->gpers = 1 << (pin & 0x1F); // The GPIO module controls that pin.
}
void gpio_enable_pin_glitch_filter(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
gpio_port->gfers = 1 << (pin & 0x1F);
}
void gpio_disable_pin_glitch_filter(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
gpio_port->gferc = 1 << (pin & 0x1F);
}
/*! \brief Configure the edge detector of an input pin
*
* \param pin The pin number.
* \param mode The edge detection mode (\ref GPIO_PIN_CHANGE, \ref GPIO_RISING_EDGE
* or \ref GPIO_FALLING_EDGE).
*
* \return \ref GPIO_SUCCESS or \ref GPIO_INVALID_ARGUMENT.
*/
static int gpio_configure_edge_detector(unsigned int pin, unsigned int mode)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
// Configure the edge detector.
switch (mode)
{
case GPIO_PIN_CHANGE:
gpio_port->imr0c = 1 << (pin & 0x1F);
gpio_port->imr1c = 1 << (pin & 0x1F);
break;
case GPIO_RISING_EDGE:
gpio_port->imr0s = 1 << (pin & 0x1F);
gpio_port->imr1c = 1 << (pin & 0x1F);
break;
case GPIO_FALLING_EDGE:
gpio_port->imr0c = 1 << (pin & 0x1F);
gpio_port->imr1s = 1 << (pin & 0x1F);
break;
default:
return GPIO_INVALID_ARGUMENT;
}
return GPIO_SUCCESS;
}
int gpio_enable_pin_interrupt(unsigned int pin, unsigned int mode)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
// Enable the glitch filter.
gpio_port->gfers = 1 << (pin & 0x1F);
// Configure the edge detector.
if(GPIO_INVALID_ARGUMENT == gpio_configure_edge_detector(pin, mode))
return(GPIO_INVALID_ARGUMENT);
// Enable interrupt.
gpio_port->iers = 1 << (pin & 0x1F);
return GPIO_SUCCESS;
}
void gpio_disable_pin_interrupt(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
gpio_port->ierc = 1 << (pin & 0x1F);
}
int gpio_get_pin_interrupt_flag(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
return (gpio_port->ifr >> (pin & 0x1F)) & 1;
}
void gpio_clear_pin_interrupt_flag(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
gpio_port->ifrc = 1 << (pin & 0x1F);
}
//#
//# Peripheral Event System Support.
//#
#if UC3L
int gpio_configure_pin_periph_event_mode(unsigned int pin, unsigned int mode, unsigned int use_igf)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
if(TRUE == use_igf)
{
// Enable the glitch filter.
gpio_port->gfers = 1 << (pin & 0x1F);
}
else
{
// Disable the glitch filter.
gpio_port->gferc = 1 << (pin & 0x1F);
}
// Configure the edge detector.
return(gpio_configure_edge_detector(pin, mode));
}
#endif
//! @}

View File

@ -0,0 +1,583 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief GPIO header for AVR32 UC3.
*
* This file contains basic GPIO driver functions.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with a GPIO module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
*****************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _GPIO_H_
#define _GPIO_H_
#include <avr32/io.h>
#include "compiler.h"
/*! \name Return Values of the GPIO API
*/
//! @{
#define GPIO_SUCCESS 0 //!< Function successfully completed.
#define GPIO_INVALID_ARGUMENT 1 //!< Input parameters are out of range.
//! @}
/*! \name Interrupt Trigger Modes
*/
//! @{
#define GPIO_PIN_CHANGE 0 //!< Interrupt triggered upon pin change.
#define GPIO_RISING_EDGE 1 //!< Interrupt triggered upon rising edge.
#define GPIO_FALLING_EDGE 2 //!< Interrupt triggered upon falling edge.
//! @}
//! A type definition of pins and modules connectivity.
typedef struct
{
unsigned char pin; //!< Module pin.
unsigned char function; //!< Module function.
} gpio_map_t[];
/*! \name Peripheral Bus Interface
*
* Low-speed interface with a non-deterministic number of clock cycles per
* access.
*
* This interface operates with lower clock frequencies (fPB <= fCPU), and its
* timing is not deterministic since it needs to access a shared bus which may
* be heavily loaded.
*
* \note This interface is immediately available without initialization.
*/
//! @{
/*! \brief Enables specific module modes for a set of pins.
*
* \param gpiomap The pin map.
* \param size The number of pins in \a gpiomap.
*
* \return \ref GPIO_SUCCESS or \ref GPIO_INVALID_ARGUMENT.
*/
extern int gpio_enable_module(const gpio_map_t gpiomap, unsigned int size);
/*! \brief Enables a specific module mode for a pin.
*
* \param pin The pin number.\n
* Refer to the product header file `uc3x.h' (where x is the part
* number; e.g. x = a0512) for module pins. E.g., to enable a PWM
* channel output, the pin number can be AVR32_PWM_3_PIN for PWM
* channel 3.
* \param function The pin function.\n
* Refer to the product header file `uc3x.h' (where x is the
* part number; e.g. x = a0512) for module pin functions. E.g.,
* to enable a PWM channel output, the pin function can be
* AVR32_PWM_3_FUNCTION for PWM channel 3.
*
* \return \ref GPIO_SUCCESS or \ref GPIO_INVALID_ARGUMENT.
*/
extern int gpio_enable_module_pin(unsigned int pin, unsigned int function);
/*! \brief Enables the GPIO mode of a set of pins.
*
* \param gpiomap The pin map.
* \param size The number of pins in \a gpiomap.
*/
extern void gpio_enable_gpio(const gpio_map_t gpiomap, unsigned int size);
/*! \brief Enables the GPIO mode of a pin.
*
* \param pin The pin number.\n
* Refer to the product header file `uc3x.h' (where x is the part
* number; e.g. x = a0512) for pin definitions. E.g., to enable the
* GPIO mode of PX21, AVR32_PIN_PX21 can be used. Module pins such as
* AVR32_PWM_3_PIN for PWM channel 3 can also be used to release
* module pins for GPIO.
*/
extern void gpio_enable_gpio_pin(unsigned int pin);
// The open-drain mode is not synthesized on the current AVR32 products.
// If one day some AVR32 products have this feature, the corresponding part
// numbers should be listed in the #if below.
// Note that other functions are available in this driver to use pins with open
// drain in GPIO mode. The advantage of the open-drain mode functions over these
// other functions is that they can be used not only in GPIO mode but also in
// module mode.
#if 0
/*! \brief Enables the open-drain mode of a pin.
*
* \param pin The pin number.
*/
extern void gpio_enable_pin_open_drain(unsigned int pin);
/*! \brief Disables the open-drain mode of a pin.
*
* \param pin The pin number.
*/
extern void gpio_disable_pin_open_drain(unsigned int pin);
#endif
/*! \brief Enables the pull-up resistor of a pin.
*
* \param pin The pin number.
*/
extern void gpio_enable_pin_pull_up(unsigned int pin);
/*! \brief Disables the pull-up resistor of a pin.
*
* \param pin The pin number.
*/
extern void gpio_disable_pin_pull_up(unsigned int pin);
#if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED)
// Added support of Pull-up Resistor, Pull-down Resistor and Buskeeper Control.
/*! \brief Enables the pull-down resistor of a pin.
*
* \param pin The pin number.
*/
extern void gpio_enable_pin_pull_down(unsigned int pin);
/*! \brief Disables the pull-down resistor of a pin.
*
* \param pin The pin number.
*/
extern void gpio_disable_pin_pull_down(unsigned int pin);
/*! \brief Enables the buskeeper functionality on a pin.
*
* \param pin The pin number.
*/
extern void gpio_enable_pin_buskeeper(unsigned int pin);
/*! \brief Disables the buskeeper functionality on a pin.
*
* \param pin The pin number.
*/
extern void gpio_disable_pin_buskeeper(unsigned int pin);
#endif
/*! \brief Returns the value of a pin.
*
* \param pin The pin number.
*
* \return The pin value.
*/
extern int gpio_get_pin_value(unsigned int pin);
/*! \brief Returns the output value set for a GPIO pin.
*
* \param pin The pin number.
*
* \return The pin output value.
*
* \note This function must be used in conjunction with \ref gpio_set_gpio_pin,
* \ref gpio_clr_gpio_pin and \ref gpio_tgl_gpio_pin.
*/
extern int gpio_get_gpio_pin_output_value(unsigned int pin);
/*! \brief Returns the output value set for a GPIO pin using open drain.
*
* \param pin The pin number.
*
* \return The pin output value.
*
* \note This function must be used in conjunction with
* \ref gpio_set_gpio_open_drain_pin, \ref gpio_clr_gpio_open_drain_pin
* and \ref gpio_tgl_gpio_open_drain_pin.
*/
extern int gpio_get_gpio_open_drain_pin_output_value(unsigned int pin);
/*! \brief Drives a GPIO pin to 1.
*
* \param pin The pin number.
*/
extern void gpio_set_gpio_pin(unsigned int pin);
/*! \brief Drives a GPIO pin to 0.
*
* \param pin The pin number.
*/
extern void gpio_clr_gpio_pin(unsigned int pin);
/*! \brief Toggles a GPIO pin.
*
* \param pin The pin number.
*/
extern void gpio_tgl_gpio_pin(unsigned int pin);
/*! \brief Drives a GPIO pin to 1 using open drain.
*
* \param pin The pin number.
*/
extern void gpio_set_gpio_open_drain_pin(unsigned int pin);
/*! \brief Drives a GPIO pin to 0 using open drain.
*
* \param pin The pin number.
*/
extern void gpio_clr_gpio_open_drain_pin(unsigned int pin);
/*! \brief Toggles a GPIO pin using open drain.
*
* \param pin The pin number.
*/
extern void gpio_tgl_gpio_open_drain_pin(unsigned int pin);
/*! \brief Enables the glitch filter of a pin.
*
* When the glitch filter is enabled, a glitch with duration of less than 1
* clock cycle is automatically rejected, while a pulse with duration of 2 clock
* cycles or more is accepted. For pulse durations between 1 clock cycle and 2
* clock cycles, the pulse may or may not be taken into account, depending on
* the precise timing of its occurrence. Thus for a pulse to be guaranteed
* visible it must exceed 2 clock cycles, whereas for a glitch to be reliably
* filtered out, its duration must not exceed 1 clock cycle. The filter
* introduces 2 clock cycles latency.
*
* \param pin The pin number.
*/
extern void gpio_enable_pin_glitch_filter(unsigned int pin);
/*! \brief Disables the glitch filter of a pin.
*
* \param pin The pin number.
*/
extern void gpio_disable_pin_glitch_filter(unsigned int pin);
/*! \brief Enables the interrupt of a pin with the specified settings.
*
* \param pin The pin number.
* \param mode The trigger mode (\ref GPIO_PIN_CHANGE, \ref GPIO_RISING_EDGE or
* \ref GPIO_FALLING_EDGE).
*
* \return \ref GPIO_SUCCESS or \ref GPIO_INVALID_ARGUMENT.
*/
extern int gpio_enable_pin_interrupt(unsigned int pin, unsigned int mode);
/*! \brief Disables the interrupt of a pin.
*
* \param pin The pin number.
*/
extern void gpio_disable_pin_interrupt(unsigned int pin);
/*! \brief Gets the interrupt flag of a pin.
*
* \param pin The pin number.
*
* \return The pin interrupt flag.
*/
extern int gpio_get_pin_interrupt_flag(unsigned int pin);
/*! \brief Clears the interrupt flag of a pin.
*
* \param pin The pin number.
*/
extern void gpio_clear_pin_interrupt_flag(unsigned int pin);
//! @}
#if (defined AVR32_GPIO_LOCAL_ADDRESS)
/*! \name Local Bus Interface
*
* High-speed interface with only one clock cycle per access.
*
* This interface operates with high clock frequency (fCPU), and its timing is
* deterministic since it does not need to access a shared bus which may be
* heavily loaded.
*
* \warning To use this interface, the clock frequency of the peripheral bus on
* which the GPIO peripheral is connected must be set to the CPU clock
* frequency (fPB = fCPU).
*
* \note This interface has to be initialized in order to be available.
*/
//! @{
/*! \brief Enables the local bus interface for GPIO.
*
* \note This function must have been called at least once before using other
* functions in this interface.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void gpio_local_init(void)
{
Set_system_register(AVR32_CPUCR,
Get_system_register(AVR32_CPUCR) | AVR32_CPUCR_LOCEN_MASK);
}
/*! \brief Enables the output driver of a pin.
*
* \param pin The pin number.
*
* \note \ref gpio_local_init must have been called beforehand.
*
* \note This function does not enable the GPIO mode of the pin.
* \ref gpio_enable_gpio_pin can be called for this purpose.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void gpio_local_enable_pin_output_driver(unsigned int pin)
{
AVR32_GPIO_LOCAL.port[pin >> 5].oders = 1 << (pin & 0x1F);
}
/*! \brief Disables the output driver of a pin.
*
* \param pin The pin number.
*
* \note \ref gpio_local_init must have been called beforehand.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void gpio_local_disable_pin_output_driver(unsigned int pin)
{
AVR32_GPIO_LOCAL.port[pin >> 5].oderc = 1 << (pin & 0x1F);
}
/*! \brief Returns the value of a pin.
*
* \param pin The pin number.
*
* \return The pin value.
*
* \note \ref gpio_local_init must have been called beforehand.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ int gpio_local_get_pin_value(unsigned int pin)
{
return (AVR32_GPIO_LOCAL.port[pin >> 5].pvr >> (pin & 0x1F)) & 1;
}
/*! \brief Drives a GPIO pin to 1.
*
* \param pin The pin number.
*
* \note \ref gpio_local_init must have been called beforehand.
*
* \note This function does not enable the GPIO mode of the pin nor its output
* driver. \ref gpio_enable_gpio_pin and
* \ref gpio_local_enable_pin_output_driver can be called for this
* purpose.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void gpio_local_set_gpio_pin(unsigned int pin)
{
AVR32_GPIO_LOCAL.port[pin >> 5].ovrs = 1 << (pin & 0x1F);
}
/*! \brief Drives a GPIO pin to 0.
*
* \param pin The pin number.
*
* \note \ref gpio_local_init must have been called beforehand.
*
* \note This function does not enable the GPIO mode of the pin nor its output
* driver. \ref gpio_enable_gpio_pin and
* \ref gpio_local_enable_pin_output_driver can be called for this
* purpose.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void gpio_local_clr_gpio_pin(unsigned int pin)
{
AVR32_GPIO_LOCAL.port[pin >> 5].ovrc = 1 << (pin & 0x1F);
}
/*! \brief Toggles a GPIO pin.
*
* \param pin The pin number.
*
* \note \ref gpio_local_init must have been called beforehand.
*
* \note This function does not enable the GPIO mode of the pin nor its output
* driver. \ref gpio_enable_gpio_pin and
* \ref gpio_local_enable_pin_output_driver can be called for this
* purpose.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void gpio_local_tgl_gpio_pin(unsigned int pin)
{
AVR32_GPIO_LOCAL.port[pin >> 5].ovrt = 1 << (pin & 0x1F);
}
/*! \brief Initializes the configuration of a GPIO pin so that it can be used
* with GPIO open-drain functions.
*
* \note This function must have been called at least once before using
* \ref gpio_local_set_gpio_open_drain_pin,
* \ref gpio_local_clr_gpio_open_drain_pin or
* \ref gpio_local_tgl_gpio_open_drain_pin.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void gpio_local_init_gpio_open_drain_pin(unsigned int pin)
{
AVR32_GPIO_LOCAL.port[pin >> 5].ovrc = 1 << (pin & 0x1F);
}
/*! \brief Drives a GPIO pin to 1 using open drain.
*
* \param pin The pin number.
*
* \note \ref gpio_local_init and \ref gpio_local_init_gpio_open_drain_pin must
* have been called beforehand.
*
* \note This function does not enable the GPIO mode of the pin.
* \ref gpio_enable_gpio_pin can be called for this purpose.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void gpio_local_set_gpio_open_drain_pin(unsigned int pin)
{
AVR32_GPIO_LOCAL.port[pin >> 5].oderc = 1 << (pin & 0x1F);
}
/*! \brief Drives a GPIO pin to 0 using open drain.
*
* \param pin The pin number.
*
* \note \ref gpio_local_init and \ref gpio_local_init_gpio_open_drain_pin must
* have been called beforehand.
*
* \note This function does not enable the GPIO mode of the pin.
* \ref gpio_enable_gpio_pin can be called for this purpose.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void gpio_local_clr_gpio_open_drain_pin(unsigned int pin)
{
AVR32_GPIO_LOCAL.port[pin >> 5].oders = 1 << (pin & 0x1F);
}
/*! \brief Toggles a GPIO pin using open drain.
*
* \param pin The pin number.
*
* \note \ref gpio_local_init and \ref gpio_local_init_gpio_open_drain_pin must
* have been called beforehand.
*
* \note This function does not enable the GPIO mode of the pin.
* \ref gpio_enable_gpio_pin can be called for this purpose.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void gpio_local_tgl_gpio_open_drain_pin(unsigned int pin)
{
AVR32_GPIO_LOCAL.port[pin >> 5].odert = 1 << (pin & 0x1F);
}
//! @}
#endif // AVR32_GPIO_LOCAL_ADDRESS
#if UC3L
//! @{
/*! \name Peripheral Event System support
*
* The GPIO can be programmed to output peripheral events whenever an interrupt
* condition is detected, such as pin value change, or only when a rising or
* falling edge is detected.
*
*/
/*! \brief Enables the peripheral event generation of a pin.
*
* \param pin The pin number.
*
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void gpio_enable_pin_periph_event(unsigned int pin)
{
AVR32_GPIO.port[pin >> 5].oderc = 1 << (pin & 0x1F); // The GPIO output driver is disabled for that pin.
AVR32_GPIO.port[pin >> 5].evers = 1 << (pin & 0x1F);
}
/*! \brief Disables the peripheral event generation of a pin.
*
* \param pin The pin number.
*
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void gpio_disable_pin_periph_event(unsigned int pin)
{
AVR32_GPIO.port[pin >> 5].everc = 1 << (pin & 0x1F);
}
/*! \brief Configure the peripheral event trigger mode of a pin
*
* \param pin The pin number.
* \param mode The trigger mode (\ref GPIO_PIN_CHANGE, \ref GPIO_RISING_EDGE or
* \ref GPIO_FALLING_EDGE).
* \param use_igf use the Input Glitch Filter (TRUE) or not (FALSE).
*
* \return \ref GPIO_SUCCESS or \ref GPIO_INVALID_ARGUMENT.
*/
extern int gpio_configure_pin_periph_event_mode(unsigned int pin, unsigned int mode, unsigned int use_igf);
//! @}
#endif
#endif // _GPIO_H_

View File

@ -0,0 +1,239 @@
/* This file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Exception and interrupt vectors.
*
* This file maps all events supported by an AVR32.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices with an INTC module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#if !__AVR32_UC__ && !__AVR32_AP__
#error Implementation of the AVR32 architecture not supported by the INTC driver.
#endif
#include <avr32/io.h>
//! @{
//! \verbatim
.section .exception, "ax", @progbits
// Start of Exception Vector Table.
// EVBA must be aligned with a power of two strictly greater than the EVBA-
// relative offset of the last vector.
.balign 0x200
// Export symbol.
.global _evba
.type _evba, @function
_evba:
.org 0x000
// Unrecoverable Exception.
_handle_Unrecoverable_Exception:
rjmp $
.org 0x004
// TLB Multiple Hit.
_handle_TLB_Multiple_Hit:
rjmp $
.org 0x008
// Bus Error Data Fetch.
_handle_Bus_Error_Data_Fetch:
rjmp $
.org 0x00C
// Bus Error Instruction Fetch.
_handle_Bus_Error_Instruction_Fetch:
rjmp $
.org 0x010
// NMI.
_handle_NMI:
rjmp $
.org 0x014
// Instruction Address.
_handle_Instruction_Address:
rjmp $
.org 0x018
// ITLB Protection.
_handle_ITLB_Protection:
rjmp $
.org 0x01C
// Breakpoint.
_handle_Breakpoint:
rjmp $
.org 0x020
// Illegal Opcode.
_handle_Illegal_Opcode:
rjmp $
.org 0x024
// Unimplemented Instruction.
_handle_Unimplemented_Instruction:
rjmp $
.org 0x028
// Privilege Violation.
_handle_Privilege_Violation:
rjmp $
.org 0x02C
// Floating-Point: UNUSED IN AVR32UC and AVR32AP.
_handle_Floating_Point:
rjmp $
.org 0x030
// Coprocessor Absent: UNUSED IN AVR32UC.
_handle_Coprocessor_Absent:
rjmp $
.org 0x034
// Data Address (Read).
_handle_Data_Address_Read:
rjmp $
.org 0x038
// Data Address (Write).
_handle_Data_Address_Write:
rjmp $
.org 0x03C
// DTLB Protection (Read).
_handle_DTLB_Protection_Read:
rjmp $
.org 0x040
// DTLB Protection (Write).
_handle_DTLB_Protection_Write:
rjmp $
.org 0x044
// DTLB Modified: UNUSED IN AVR32UC.
_handle_DTLB_Modified:
rjmp $
.org 0x050
// ITLB Miss.
_handle_ITLB_Miss:
rjmp $
.org 0x060
// DTLB Miss (Read).
_handle_DTLB_Miss_Read:
rjmp $
.org 0x070
// DTLB Miss (Write).
_handle_DTLB_Miss_Write:
rjmp $
.org 0x100
// Supervisor Call.
_handle_Supervisor_Call:
rjmp $
// Interrupt support.
// The interrupt controller must provide the offset address relative to EVBA.
// Important note:
// All interrupts call a C function named _get_interrupt_handler.
// This function will read group and interrupt line number to then return in
// R12 a pointer to a user-provided interrupt handler.
.balign 4
.irp priority, 0, 1, 2, 3
_int\priority:
#if __AVR32_UC__
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
// CPU upon interrupt entry. No other register is saved by hardware.
#elif __AVR32_AP__
// PC and SR are automatically saved in respectively RAR_INTx and RSR_INTx by
// the CPU upon interrupt entry. No other register is saved by hardware.
pushm r8-r12, lr
#endif
mov r12, \priority // Pass the int_level parameter to the _get_interrupt_handler function.
call _get_interrupt_handler
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
#if __AVR32_UC__
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
#elif __AVR32_AP__
breq spint\priority // If this was a spurious interrupt (R12 == NULL), branch.
st.w --sp, r12 // Push the pointer to the interrupt handler onto the system stack since no register may be altered.
popm r8-r12, lr, pc // Restore registers and jump to the handler.
spint\priority:
popm r8-r12, lr
#endif
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
.endr
// Constant data area.
.balign 4
// Values to store in the interrupt priority registers for the various interrupt priority levels.
// The interrupt priority registers contain the interrupt priority level and
// the EVBA-relative interrupt vector offset.
.global ipr_val
.type ipr_val, @object
ipr_val:
.word (AVR32_INTC_INT0 << AVR32_INTC_IPR_INTLEVEL_OFFSET) | (_int0 - _evba),\
(AVR32_INTC_INT1 << AVR32_INTC_IPR_INTLEVEL_OFFSET) | (_int1 - _evba),\
(AVR32_INTC_INT2 << AVR32_INTC_IPR_INTLEVEL_OFFSET) | (_int2 - _evba),\
(AVR32_INTC_INT3 << AVR32_INTC_IPR_INTLEVEL_OFFSET) | (_int3 - _evba)
//! \endverbatim
//! @}

View File

@ -0,0 +1,214 @@
/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief INTC driver for AVR32 UC3.
*
* AVR32 Interrupt Controller driver module.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with an INTC module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#include <avr32/io.h>
#include "compiler.h"
#include "preprocessor.h"
#include "intc.h"
// define _evba from exception.S
extern void _evba;
//! Values to store in the interrupt priority registers for the various interrupt priority levels.
extern const unsigned int ipr_val[AVR32_INTC_NUM_INT_LEVELS];
//! Creates a table of interrupt line handlers per interrupt group in order to optimize RAM space.
//! Each line handler table contains a set of pointers to interrupt handlers.
#if (defined __GNUC__)
#define DECL_INT_LINE_HANDLER_TABLE(GRP, unused) \
static volatile __int_handler _int_line_handler_table_##GRP[Max(AVR32_INTC_NUM_IRQS_PER_GRP##GRP, 1)];
#elif (defined __ICCAVR32__)
#define DECL_INT_LINE_HANDLER_TABLE(GRP, unused) \
static volatile __no_init __int_handler _int_line_handler_table_##GRP[Max(AVR32_INTC_NUM_IRQS_PER_GRP##GRP, 1)];
#endif
MREPEAT(AVR32_INTC_NUM_INT_GRPS, DECL_INT_LINE_HANDLER_TABLE, ~);
#undef DECL_INT_LINE_HANDLER_TABLE
//! Table containing for each interrupt group the number of interrupt request
//! lines and a pointer to the table of interrupt line handlers.
static const struct
{
unsigned int num_irqs;
volatile __int_handler *_int_line_handler_table;
} _int_handler_table[AVR32_INTC_NUM_INT_GRPS] =
{
#define INSERT_INT_LINE_HANDLER_TABLE(GRP, unused) \
{AVR32_INTC_NUM_IRQS_PER_GRP##GRP, _int_line_handler_table_##GRP},
MREPEAT(AVR32_INTC_NUM_INT_GRPS, INSERT_INT_LINE_HANDLER_TABLE, ~)
#undef INSERT_INT_LINE_HANDLER_TABLE
};
/*! \brief Default interrupt handler.
*
* \note Taken and adapted from Newlib.
*/
#if (defined __GNUC__)
__attribute__((__interrupt__))
#elif (defined __ICCAVR32__)
__interrupt
#endif
static void _unhandled_interrupt(void)
{
// Catch unregistered interrupts.
while (TRUE);
}
/*! \brief Gets the interrupt handler of the current event at the \a int_level
* interrupt priority level (called from exception.S).
*
* \param int_level Interrupt priority level to handle.
*
* \return Interrupt handler to execute.
*
* \note Taken and adapted from Newlib.
*/
__int_handler _get_interrupt_handler(unsigned int int_level)
{
// ICR3 is mapped first, ICR0 last.
// Code in exception.S puts int_level in R12 which is used by AVR32-GCC to
// pass a single argument to a function.
unsigned int int_grp = AVR32_INTC.icr[AVR32_INTC_INT3 - int_level];
unsigned int int_req = AVR32_INTC.irr[int_grp];
// As an interrupt may disappear while it is being fetched by the CPU
// (spurious interrupt caused by a delayed response from an MCU peripheral to
// an interrupt flag clear or interrupt disable instruction), check if there
// are remaining interrupt lines to process.
// If a spurious interrupt occurs, the status register (SR) contains an
// execution mode and interrupt level masks corresponding to a level 0
// interrupt, whatever the interrupt priority level causing the spurious
// event. This behavior has been chosen because a spurious interrupt has not
// to be a priority one and because it may not cause any trouble to other
// interrupts.
// However, these spurious interrupts place the hardware in an unstable state
// and could give problems in other/future versions of the CPU, so the
// software has to be written so that they never occur. The only safe way of
// achieving this is to always clear or disable peripheral interrupts with the
// following sequence:
// 1: Mask the interrupt in the CPU by setting GM (or IxM) in SR.
// 2: Perform the bus access to the peripheral register that clears or
// disables the interrupt.
// 3: Wait until the interrupt has actually been cleared or disabled by the
// peripheral. This is usually performed by reading from a register in the
// same peripheral (it DOES NOT have to be the same register that was
// accessed in step 2, but it MUST be in the same peripheral), what takes
// bus system latencies into account, but peripheral internal latencies
// (generally 0 cycle) also have to be considered.
// 4: Unmask the interrupt in the CPU by clearing GM (or IxM) in SR.
// Note that steps 1 and 4 are useless inside interrupt handlers as the
// corresponding interrupt level is automatically masked by IxM (unless IxM is
// explicitly cleared by the software).
//
// Get the right IRQ handler.
//
// If several interrupt lines are active in the group, the interrupt line with
// the highest number is selected. This is to be coherent with the
// prioritization of interrupt groups performed by the hardware interrupt
// controller.
//
// If no handler has been registered for the pending interrupt,
// _unhandled_interrupt will be selected thanks to the initialization of
// _int_line_handler_table_x by INTC_init_interrupts.
//
// exception.S will provide the interrupt handler with a clean interrupt stack
// frame, with nothing more pushed onto the stack. The interrupt handler must
// manage the `rete' instruction, what can be done thanks to pure assembly,
// inline assembly or the `__attribute__((__interrupt__))' C function
// attribute.
return (int_req) ? _int_handler_table[int_grp]._int_line_handler_table[32 - clz(int_req) - 1] : NULL;
}
//! Init EVBA address. This sequence might also be done in the UTILS/STARTUP/GCC/crt0.S
static __inline__ void INTC_init_evba(void)
{
Set_system_register(AVR32_EVBA, (int)&_evba );
}
void INTC_init_interrupts(void)
{
unsigned int int_grp, int_req;
INTC_init_evba();
// For all interrupt groups,
for (int_grp = 0; int_grp < AVR32_INTC_NUM_INT_GRPS; int_grp++)
{
// For all interrupt request lines of each group,
for (int_req = 0; int_req < _int_handler_table[int_grp].num_irqs; int_req++)
{
// Assign _unhandled_interrupt as default interrupt handler.
_int_handler_table[int_grp]._int_line_handler_table[int_req] = &_unhandled_interrupt;
}
// Set the interrupt group priority register to its default value.
// By default, all interrupt groups are linked to the interrupt priority
// level 0 and to the interrupt vector _int0.
AVR32_INTC.ipr[int_grp] = ipr_val[AVR32_INTC_INT0];
}
}
void INTC_register_interrupt(__int_handler handler, unsigned int irq, unsigned int int_level)
{
// Determine the group of the IRQ.
unsigned int int_grp = irq / AVR32_INTC_MAX_NUM_IRQS_PER_GRP;
// Store in _int_line_handler_table_x the pointer to the interrupt handler, so
// that _get_interrupt_handler can retrieve it when the interrupt is vectored.
_int_handler_table[int_grp]._int_line_handler_table[irq % AVR32_INTC_MAX_NUM_IRQS_PER_GRP] = handler;
// Program the corresponding IPRX register to set the interrupt priority level
// and the interrupt vector offset that will be fetched by the core interrupt
// system.
// NOTE: The _intx functions are intermediate assembly functions between the
// core interrupt system and the user interrupt handler.
AVR32_INTC.ipr[int_grp] = ipr_val[int_level & (AVR32_INTC_IPR_INTLEVEL_MASK >> AVR32_INTC_IPR_INTLEVEL_OFFSET)];
}

View File

@ -0,0 +1,100 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief INTC driver for AVR32 UC3.
*
* AVR32 Interrupt Controller driver module.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with an INTC module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _INTC_H_
#define _INTC_H_
#include "compiler.h"
//! Maximal number of interrupt request lines per group.
#define AVR32_INTC_MAX_NUM_IRQS_PER_GRP 32
//! Number of interrupt priority levels.
#define AVR32_INTC_NUM_INT_LEVELS (1 << AVR32_INTC_IPR_INTLEVEL_SIZE)
#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling.
//! Pointer to interrupt handler.
#if (defined __GNUC__)
typedef void (*__int_handler)(void);
#elif (defined __ICCAVR32__)
typedef void (__interrupt *__int_handler)(void);
#endif
/*! \brief Initializes the hardware interrupt controller driver.
*
* \note Taken and adapted from Newlib.
*/
extern void INTC_init_interrupts(void);
/*! \brief Registers an interrupt handler.
*
* \param handler Interrupt handler to register.
* \param irq IRQ of the interrupt handler to register.
* \param int_level Interrupt priority level to assign to the group of this IRQ.
*
* \warning The interrupt handler must manage the `rete' instruction, what can
* be done thanks to pure assembly, inline assembly or the
* `__attribute__((__interrupt__))' C function attribute.
*
* \warning If several interrupt handlers of a same group are registered with
* different priority levels, only the latest priority level set will
* be effective.
*
* \note Taken and adapted from Newlib.
*/
extern void INTC_register_interrupt(__int_handler handler, unsigned int irq, unsigned int int_level);
#endif // __AVR32_ABI_COMPILER__
#endif // _INTC_H_

View File

@ -0,0 +1,296 @@
/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief PDCA driver for AVR32 UC3.
*
* This file defines a useful set of functions for the PDCA interface on AVR32
* devices.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with a PDCA module.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#include "compiler.h"
#include "pdca.h"
volatile avr32_pdca_channel_t *pdca_get_handler(unsigned int pdca_ch_number)
{
// get the correct channel pointer
volatile avr32_pdca_channel_t *pdca_channel = &AVR32_PDCA.channel[pdca_ch_number];
if (pdca_ch_number >= AVR32_PDCA_CHANNEL_LENGTH)
return (volatile avr32_pdca_channel_t *)PDCA_INVALID_ARGUMENT;
return pdca_channel;
}
int pdca_init_channel(unsigned int pdca_ch_number, const pdca_channel_options_t *opt)
{
// get the correct channel pointer
volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(pdca_ch_number);
pdca_disable_interrupt_transfer_complete(pdca_ch_number); // disable channel interrupt
pdca_disable_interrupt_reload_counter_zero(pdca_ch_number); // disable channel interrupt
Bool global_interrupt_enabled = Is_global_interrupt_enabled();
if (global_interrupt_enabled) Disable_global_interrupt();
pdca_channel->mar = (unsigned long)opt->addr;
pdca_channel->tcr = opt->size;
pdca_channel->psr = opt->pid;
pdca_channel->marr = (unsigned long)opt->r_addr;
pdca_channel->tcrr = opt->r_size;
pdca_channel->mr =
#if (defined AVR32_PDCA_120_H_INCLUDED ) || (defined AVR32_PDCA_121_H_INCLUDED ) || (defined AVR32_PDCA_122_H_INCLUDED )
opt->etrig << AVR32_PDCA_ETRIG_OFFSET |
#endif // #ifdef AVR32_PDCA_120_H_INCLUDED
opt->transfer_size << AVR32_PDCA_SIZE_OFFSET;
pdca_channel->cr = AVR32_PDCA_ECLR_MASK;
pdca_channel->isr;
if (global_interrupt_enabled) Enable_global_interrupt();
return PDCA_SUCCESS;
}
unsigned int pdca_get_channel_status(unsigned int pdca_ch_number)
{
// get the correct channel pointer
volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(pdca_ch_number);
return (pdca_channel->sr & AVR32_PDCA_TEN_MASK) != 0;
}
void pdca_disable(unsigned int pdca_ch_number)
{
// get the correct channel pointer
volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(pdca_ch_number);
// Disable transfer
pdca_channel->cr = AVR32_PDCA_TDIS_MASK;
}
void pdca_enable(unsigned int pdca_ch_number)
{
// get the correct channel pointer
volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(pdca_ch_number);
// Enable transfer
pdca_channel->cr = AVR32_PDCA_TEN_MASK;
}
unsigned int pdca_get_load_size(unsigned int pdca_ch_number)
{
// get the correct channel pointer
volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(pdca_ch_number);
return pdca_channel->tcr;
}
void pdca_load_channel(unsigned int pdca_ch_number, volatile void *addr, unsigned int size)
{
// get the correct channel pointer
volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(pdca_ch_number);
Bool global_interrupt_enabled = Is_global_interrupt_enabled();
if (global_interrupt_enabled) Disable_global_interrupt();
pdca_channel->mar = (unsigned long)addr;
pdca_channel->tcr = size;
pdca_channel->cr = AVR32_PDCA_ECLR_MASK;
pdca_channel->isr;
if (global_interrupt_enabled) Enable_global_interrupt();
}
unsigned int pdca_get_reload_size(unsigned int pdca_ch_number)
{
// get the correct channel pointer
volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(pdca_ch_number);
return pdca_channel->tcrr;
}
void pdca_reload_channel(unsigned int pdca_ch_number, volatile void *addr, unsigned int size)
{
// get the correct channel pointer
volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(pdca_ch_number);
Bool global_interrupt_enabled = Is_global_interrupt_enabled();
if (global_interrupt_enabled) Disable_global_interrupt();
// set up next memory address
pdca_channel->marr = (unsigned long)addr;
// set up next memory size
pdca_channel->tcrr = size;
pdca_channel->cr = AVR32_PDCA_ECLR_MASK;
pdca_channel->isr;
if (global_interrupt_enabled) Enable_global_interrupt();
}
void pdca_set_peripheral_select(unsigned int pdca_ch_number, unsigned int pid)
{
// get the correct channel pointer
volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(pdca_ch_number);
pdca_channel->psr = pid;
}
void pdca_set_transfer_size(unsigned int pdca_ch_number, unsigned int transfer_size)
{
// get the correct channel pointer
volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(pdca_ch_number);
pdca_channel->mr = (pdca_channel->mr & ~AVR32_PDCA_SIZE_MASK) |
transfer_size << AVR32_PDCA_SIZE_OFFSET;
}
#if (defined AVR32_PDCA_120_H_INCLUDED ) || (defined AVR32_PDCA_121_H_INCLUDED ) || (defined AVR32_PDCA_122_H_INCLUDED )
void pdca_disable_event_trigger(unsigned int pdca_ch_number)
{
// get the correct channel pointer
volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(pdca_ch_number);
pdca_channel->mr &= ~AVR32_PDCA_ETRIG_MASK;
}
void pdca_enable_event_trigger(unsigned int pdca_ch_number)
{
// get the correct channel pointer
volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(pdca_ch_number);
pdca_channel->mr |= AVR32_PDCA_ETRIG_MASK;
}
#endif // #ifdef AVR32_PDCA_120_H_INCLUDED
void pdca_disable_interrupt_transfer_error(unsigned int pdca_ch_number)
{
// get the correct channel pointer
volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(pdca_ch_number);
Bool global_interrupt_enabled = Is_global_interrupt_enabled();
if (global_interrupt_enabled) Disable_global_interrupt();
pdca_channel->idr = AVR32_PDCA_TERR_MASK;
pdca_channel->isr;
if (global_interrupt_enabled) Enable_global_interrupt();
}
void pdca_enable_interrupt_transfer_error(unsigned int pdca_ch_number)
{
// get the correct channel pointer
volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(pdca_ch_number);
pdca_channel->ier = AVR32_PDCA_TERR_MASK;
}
void pdca_disable_interrupt_transfer_complete(unsigned int pdca_ch_number)
{
// get the correct channel pointer
volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(pdca_ch_number);
Bool global_interrupt_enabled = Is_global_interrupt_enabled();
if (global_interrupt_enabled) Disable_global_interrupt();
pdca_channel->idr = AVR32_PDCA_TRC_MASK;
pdca_channel->isr;
if (global_interrupt_enabled) Enable_global_interrupt();
}
void pdca_enable_interrupt_transfer_complete(unsigned int pdca_ch_number)
{
// get the correct channel pointer
volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(pdca_ch_number);
pdca_channel->ier = AVR32_PDCA_TRC_MASK;
}
void pdca_disable_interrupt_reload_counter_zero(unsigned int pdca_ch_number)
{
// get the correct channel pointer
volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(pdca_ch_number);
Bool global_interrupt_enabled = Is_global_interrupt_enabled();
if (global_interrupt_enabled) Disable_global_interrupt();
pdca_channel->idr = AVR32_PDCA_RCZ_MASK;
pdca_channel->isr;
if (global_interrupt_enabled) Enable_global_interrupt();
}
void pdca_enable_interrupt_reload_counter_zero(unsigned int pdca_ch_number)
{
// get the correct channel pointer
volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(pdca_ch_number);
pdca_channel->ier = AVR32_PDCA_RCZ_MASK;
}
unsigned long pdca_get_transfer_status(unsigned int pdca_ch_number)
{
// get the correct channel pointer
volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(pdca_ch_number);
return pdca_channel->isr;
}

View File

@ -0,0 +1,251 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief PDCA driver for AVR32 UC3.
*
* This file defines a useful set of functions for the PDCA interface on AVR32
* devices.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with a PDCA module.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _PDCA_H_
#define _PDCA_H_
#include <avr32/io.h>
//! Size of PDCA transfer: byte.
#define PDCA_TRANSFER_SIZE_BYTE AVR32_PDCA_BYTE
//! Size of PDCA transfer: half-word.
#define PDCA_TRANSFER_SIZE_HALF_WORD AVR32_PDCA_HALF_WORD
//! Size of PDCA transfer: word.
#define PDCA_TRANSFER_SIZE_WORD AVR32_PDCA_WORD
/*! \name PDCA Driver Status Codes
*/
//! @{
#define PDCA_SUCCESS 0
#define PDCA_INVALID_ARGUMENT -1
//! @}
/*! \name PDCA Transfer Status Codes
*/
//! @{
#define PDCA_TRANSFER_ERROR AVR32_PDCA_TERR_MASK
#define PDCA_TRANSFER_COMPLETE AVR32_PDCA_TRC_MASK
#define PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO AVR32_PDCA_RCZ_MASK
//! @}
//! PDCA channel options.
typedef struct
{
//! Memory address.
volatile void *addr ;
//! Transfer counter.
unsigned int size ;
//! Next memory address.
volatile void *r_addr ;
//! Next transfer counter.
unsigned int r_size ;
//! Select peripheral ID.
unsigned int pid ;
//! Select the size of the transfer (byte, half-word or word).
unsigned int transfer_size ;
#if (defined AVR32_PDCA_120_H_INCLUDED ) || (defined AVR32_PDCA_121_H_INCLUDED ) || (defined AVR32_PDCA_122_H_INCLUDED )
// Note: the options in this preprocessor section are only available from the PDCA IP version 1.2.0 on.
//! Enable (\c 1) or disable (\c 0) the transfer upon event trigger.
unsigned char etrig ;
#endif // #ifdef AVR32_PDCA_120_H_INCLUDED
} pdca_channel_options_t;
/*! \brief Get PDCA channel handler
*
* \param pdca_ch_number PDCA channel
*
* \return channel handled or PDCA_INVALID_ARGUMENT
*/
extern volatile avr32_pdca_channel_t *pdca_get_handler(unsigned int pdca_ch_number);
/*! \brief Set the channel configuration
*
* \param pdca_ch_number PDCA channel
* \param opt channel option
*/
extern int pdca_init_channel(unsigned int pdca_ch_number, const pdca_channel_options_t *opt);
/*! \brief Get the PDCA channel transfer enable status
*
* \param pdca_ch_number PDCA channel
*
* \return \c 1 if channel transfer is enabled, else \c 0
*/
extern unsigned int pdca_get_channel_status(unsigned int pdca_ch_number);
/*! \brief Disable the PDCA for the given channel
*
* \param pdca_ch_number PDCA channel
*/
extern void pdca_disable(unsigned int pdca_ch_number);
/*! \brief Enable the PDCA for the given channel
*
* \param pdca_ch_number PDCA channel
*/
extern void pdca_enable(unsigned int pdca_ch_number);
/*! \brief Get PDCA channel load size (or remaining size if transfer started)
*
* \param pdca_ch_number PDCA channel
*
* \return size current size to transfer
*/
extern unsigned int pdca_get_load_size(unsigned int pdca_ch_number);
/*! \brief Set PDCA channel load values
*
* \param pdca_ch_number PDCA channel
* \param addr address where data to load are stored
* \param size size of the data block to load
*/
extern void pdca_load_channel(unsigned int pdca_ch_number, volatile void *addr, unsigned int size);
/*! \brief Get PDCA channel reload size
*
* \param pdca_ch_number PDCA channel
*
* \return size current reload size
*/
extern unsigned int pdca_get_reload_size(unsigned int pdca_ch_number);
/*! \brief Set PDCA channel reload values
*
* \param pdca_ch_number PDCA channel
* \param addr address where data to load are stored
* \param size size of the data block to load
*/
extern void pdca_reload_channel(unsigned int pdca_ch_number, volatile void *addr, unsigned int size);
/*! \brief Set the peripheral function to use with the PDCA channel
*
* \param pdca_ch_number PDCA channel
* \param pid the peripheral ID
*/
extern void pdca_set_peripheral_select(unsigned int pdca_ch_number, unsigned int pid);
/*! \brief Set the size of the transfer
*
* \param pdca_ch_number PDCA channel
* \param transfer_size size of the transfer (byte, half-word or word)
*/
extern void pdca_set_transfer_size(unsigned int pdca_ch_number, unsigned int transfer_size);
#if (defined AVR32_PDCA_120_H_INCLUDED ) || (defined AVR32_PDCA_121_H_INCLUDED ) || (defined AVR32_PDCA_122_H_INCLUDED )
// Note: the functions in this preprocessor section are only available from the PDCA IP version 1.2.0 on.
/*! \brief Disable the event-triggered transfer feature
*
* \param pdca_ch_number PDCA channel
*/
extern void pdca_disable_event_trigger(unsigned int pdca_ch_number);
/*! \brief Enable the event-triggered transfer feature
*
* \param pdca_ch_number PDCA channel
*/
extern void pdca_enable_event_trigger(unsigned int pdca_ch_number);
#endif // #ifdef AVR32_PDCA_120_H_INCLUDED
/*! \brief Disable PDCA transfer error interrupt
*
* \param pdca_ch_number PDCA channel
*/
extern void pdca_disable_interrupt_transfer_error(unsigned int pdca_ch_number);
/*! \brief Enable PDCA transfer error interrupt
*
* \param pdca_ch_number PDCA channel
*/
extern void pdca_enable_interrupt_transfer_error(unsigned int pdca_ch_number);
/*! \brief Disable PDCA transfer interrupt when completed (ie TCR and TCRR are both zero)
*
* \param pdca_ch_number PDCA channel
*/
extern void pdca_disable_interrupt_transfer_complete(unsigned int pdca_ch_number);
/*! \brief Enable PDCA transfer interrupt when completed (ie TCR and TCRR are both zero)
*
* \param pdca_ch_number PDCA channel
*/
extern void pdca_enable_interrupt_transfer_complete(unsigned int pdca_ch_number);
/*! \brief Disable PDCA transfer interrupt when TCRR reaches zero
*
* \param pdca_ch_number PDCA channel
*/
extern void pdca_disable_interrupt_reload_counter_zero(unsigned int pdca_ch_number);
/*! \brief Enable PDCA transfer interrupt when TCRR reaches zero
*
* \param pdca_ch_number PDCA channel
*/
extern void pdca_enable_interrupt_reload_counter_zero(unsigned int pdca_ch_number);
/*! \brief Get PDCA channel transfer status
*
* \param pdca_ch_number PDCA channel
*
* \return PDCA transfer status with the following bit-masks:\n
* - \c PDCA_TRANSFER_ERROR;\n
* - \c PDCA_TRANSFER_COMPLETE;\n
* - \c PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO.
*/
extern unsigned long pdca_get_transfer_status(unsigned int pdca_ch_number);
#endif // _PDCA_H_

View File

@ -0,0 +1,546 @@
/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Power Manager driver.
*
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
*****************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#include "compiler.h"
#include "pm.h"
/*! \name PM Writable Bit-Field Registers
*/
//! @{
typedef union
{
unsigned long mcctrl;
avr32_pm_mcctrl_t MCCTRL;
} u_avr32_pm_mcctrl_t;
typedef union
{
unsigned long cksel;
avr32_pm_cksel_t CKSEL;
} u_avr32_pm_cksel_t;
typedef union
{
unsigned long pll;
avr32_pm_pll_t PLL;
} u_avr32_pm_pll_t;
typedef union
{
unsigned long oscctrl0;
avr32_pm_oscctrl0_t OSCCTRL0;
} u_avr32_pm_oscctrl0_t;
typedef union
{
unsigned long oscctrl1;
avr32_pm_oscctrl1_t OSCCTRL1;
} u_avr32_pm_oscctrl1_t;
typedef union
{
unsigned long oscctrl32;
avr32_pm_oscctrl32_t OSCCTRL32;
} u_avr32_pm_oscctrl32_t;
typedef union
{
unsigned long ier;
avr32_pm_ier_t IER;
} u_avr32_pm_ier_t;
typedef union
{
unsigned long idr;
avr32_pm_idr_t IDR;
} u_avr32_pm_idr_t;
typedef union
{
unsigned long icr;
avr32_pm_icr_t ICR;
} u_avr32_pm_icr_t;
typedef union
{
unsigned long gcctrl;
avr32_pm_gcctrl_t GCCTRL;
} u_avr32_pm_gcctrl_t;
typedef union
{
unsigned long rccr;
avr32_pm_rccr_t RCCR;
} u_avr32_pm_rccr_t;
typedef union
{
unsigned long bgcr;
avr32_pm_bgcr_t BGCR;
} u_avr32_pm_bgcr_t;
typedef union
{
unsigned long vregcr;
avr32_pm_vregcr_t VREGCR;
} u_avr32_pm_vregcr_t;
typedef union
{
unsigned long bod;
avr32_pm_bod_t BOD;
} u_avr32_pm_bod_t;
//! @}
/*! \brief Sets the mode of the oscillator 0.
*
* \param pm Base address of the Power Manager (i.e. &AVR32_PM).
* \param mode Oscillator 0 mode (i.e. AVR32_PM_OSCCTRL0_MODE_x).
*/
static void pm_set_osc0_mode(volatile avr32_pm_t *pm, unsigned int mode)
{
// Read
u_avr32_pm_oscctrl0_t u_avr32_pm_oscctrl0 = {pm->oscctrl0};
// Modify
u_avr32_pm_oscctrl0.OSCCTRL0.mode = mode;
// Write
pm->oscctrl0 = u_avr32_pm_oscctrl0.oscctrl0;
}
void pm_enable_osc0_ext_clock(volatile avr32_pm_t *pm)
{
pm_set_osc0_mode(pm, AVR32_PM_OSCCTRL0_MODE_EXT_CLOCK);
}
void pm_enable_osc0_crystal(volatile avr32_pm_t *pm, unsigned int fosc0)
{
pm_set_osc0_mode(pm, (fosc0 < 900000) ? AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G0 :
(fosc0 < 3000000) ? AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G1 :
(fosc0 < 8000000) ? AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G2 :
AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G3);
}
void pm_enable_clk0(volatile avr32_pm_t *pm, unsigned int startup)
{
pm_enable_clk0_no_wait(pm, startup);
pm_wait_for_clk0_ready(pm);
}
void pm_disable_clk0(volatile avr32_pm_t *pm)
{
pm->mcctrl &= ~AVR32_PM_MCCTRL_OSC0EN_MASK;
}
void pm_enable_clk0_no_wait(volatile avr32_pm_t *pm, unsigned int startup)
{
// Read register
u_avr32_pm_oscctrl0_t u_avr32_pm_oscctrl0 = {pm->oscctrl0};
// Modify
u_avr32_pm_oscctrl0.OSCCTRL0.startup = startup;
// Write back
pm->oscctrl0 = u_avr32_pm_oscctrl0.oscctrl0;
pm->mcctrl |= AVR32_PM_MCCTRL_OSC0EN_MASK;
}
void pm_wait_for_clk0_ready(volatile avr32_pm_t *pm)
{
while (!(pm->poscsr & AVR32_PM_POSCSR_OSC0RDY_MASK));
}
/*! \brief Sets the mode of the oscillator 1.
*
* \param pm Base address of the Power Manager (i.e. &AVR32_PM).
* \param mode Oscillator 1 mode (i.e. AVR32_PM_OSCCTRL1_MODE_x).
*/
static void pm_set_osc1_mode(volatile avr32_pm_t *pm, unsigned int mode)
{
// Read
u_avr32_pm_oscctrl1_t u_avr32_pm_oscctrl1 = {pm->oscctrl1};
// Modify
u_avr32_pm_oscctrl1.OSCCTRL1.mode = mode;
// Write
pm->oscctrl1 = u_avr32_pm_oscctrl1.oscctrl1;
}
void pm_enable_osc1_ext_clock(volatile avr32_pm_t *pm)
{
pm_set_osc1_mode(pm, AVR32_PM_OSCCTRL1_MODE_EXT_CLOCK);
}
void pm_enable_osc1_crystal(volatile avr32_pm_t *pm, unsigned int fosc1)
{
pm_set_osc1_mode(pm, (fosc1 < 900000) ? AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G0 :
(fosc1 < 3000000) ? AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G1 :
(fosc1 < 8000000) ? AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G2 :
AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G3);
}
void pm_enable_clk1(volatile avr32_pm_t *pm, unsigned int startup)
{
pm_enable_clk1_no_wait(pm, startup);
pm_wait_for_clk1_ready(pm);
}
void pm_disable_clk1(volatile avr32_pm_t *pm)
{
pm->mcctrl &= ~AVR32_PM_MCCTRL_OSC1EN_MASK;
}
void pm_enable_clk1_no_wait(volatile avr32_pm_t *pm, unsigned int startup)
{
// Read register
u_avr32_pm_oscctrl1_t u_avr32_pm_oscctrl1 = {pm->oscctrl1};
// Modify
u_avr32_pm_oscctrl1.OSCCTRL1.startup = startup;
// Write back
pm->oscctrl1 = u_avr32_pm_oscctrl1.oscctrl1;
pm->mcctrl |= AVR32_PM_MCCTRL_OSC1EN_MASK;
}
void pm_wait_for_clk1_ready(volatile avr32_pm_t *pm)
{
while (!(pm->poscsr & AVR32_PM_POSCSR_OSC1RDY_MASK));
}
/*! \brief Sets the mode of the 32-kHz oscillator.
*
* \param pm Base address of the Power Manager (i.e. &AVR32_PM).
* \param mode 32-kHz oscillator mode (i.e. AVR32_PM_OSCCTRL32_MODE_x).
*/
static void pm_set_osc32_mode(volatile avr32_pm_t *pm, unsigned int mode)
{
// Read
u_avr32_pm_oscctrl32_t u_avr32_pm_oscctrl32 = {pm->oscctrl32};
// Modify
u_avr32_pm_oscctrl32.OSCCTRL32.mode = mode;
// Write
pm->oscctrl32 = u_avr32_pm_oscctrl32.oscctrl32;
}
void pm_enable_osc32_ext_clock(volatile avr32_pm_t *pm)
{
pm_set_osc32_mode(pm, AVR32_PM_OSCCTRL32_MODE_EXT_CLOCK);
}
void pm_enable_osc32_crystal(volatile avr32_pm_t *pm)
{
pm_set_osc32_mode(pm, AVR32_PM_OSCCTRL32_MODE_CRYSTAL);
}
void pm_enable_clk32(volatile avr32_pm_t *pm, unsigned int startup)
{
pm_enable_clk32_no_wait(pm, startup);
pm_wait_for_clk32_ready(pm);
}
void pm_disable_clk32(volatile avr32_pm_t *pm)
{
pm->oscctrl32 &= ~AVR32_PM_OSCCTRL32_OSC32EN_MASK;
}
void pm_enable_clk32_no_wait(volatile avr32_pm_t *pm, unsigned int startup)
{
// Read register
u_avr32_pm_oscctrl32_t u_avr32_pm_oscctrl32 = {pm->oscctrl32};
// Modify
u_avr32_pm_oscctrl32.OSCCTRL32.osc32en = 1;
u_avr32_pm_oscctrl32.OSCCTRL32.startup = startup;
// Write back
pm->oscctrl32 = u_avr32_pm_oscctrl32.oscctrl32;
}
void pm_wait_for_clk32_ready(volatile avr32_pm_t *pm)
{
while (!(pm->poscsr & AVR32_PM_POSCSR_OSC32RDY_MASK));
}
void pm_cksel(volatile avr32_pm_t *pm,
unsigned int pbadiv,
unsigned int pbasel,
unsigned int pbbdiv,
unsigned int pbbsel,
unsigned int hsbdiv,
unsigned int hsbsel)
{
u_avr32_pm_cksel_t u_avr32_pm_cksel = {0};
u_avr32_pm_cksel.CKSEL.cpusel = hsbsel;
u_avr32_pm_cksel.CKSEL.cpudiv = hsbdiv;
u_avr32_pm_cksel.CKSEL.hsbsel = hsbsel;
u_avr32_pm_cksel.CKSEL.hsbdiv = hsbdiv;
u_avr32_pm_cksel.CKSEL.pbasel = pbasel;
u_avr32_pm_cksel.CKSEL.pbadiv = pbadiv;
u_avr32_pm_cksel.CKSEL.pbbsel = pbbsel;
u_avr32_pm_cksel.CKSEL.pbbdiv = pbbdiv;
pm->cksel = u_avr32_pm_cksel.cksel;
// Wait for ckrdy bit and then clear it
while (!(pm->poscsr & AVR32_PM_POSCSR_CKRDY_MASK));
}
void pm_gc_setup(volatile avr32_pm_t *pm,
unsigned int gc,
unsigned int osc_or_pll, // Use Osc (=0) or PLL (=1)
unsigned int pll_osc, // Sel Osc0/PLL0 or Osc1/PLL1
unsigned int diven,
unsigned int div)
{
u_avr32_pm_gcctrl_t u_avr32_pm_gcctrl = {0};
u_avr32_pm_gcctrl.GCCTRL.oscsel = pll_osc;
u_avr32_pm_gcctrl.GCCTRL.pllsel = osc_or_pll;
u_avr32_pm_gcctrl.GCCTRL.diven = diven;
u_avr32_pm_gcctrl.GCCTRL.div = div;
pm->gcctrl[gc] = u_avr32_pm_gcctrl.gcctrl;
}
void pm_gc_enable(volatile avr32_pm_t *pm,
unsigned int gc)
{
pm->gcctrl[gc] |= AVR32_PM_GCCTRL_CEN_MASK;
}
void pm_gc_disable(volatile avr32_pm_t *pm,
unsigned int gc)
{
pm->gcctrl[gc] &= ~AVR32_PM_GCCTRL_CEN_MASK;
}
void pm_pll_setup(volatile avr32_pm_t *pm,
unsigned int pll,
unsigned int mul,
unsigned int div,
unsigned int osc,
unsigned int lockcount)
{
u_avr32_pm_pll_t u_avr32_pm_pll = {0};
u_avr32_pm_pll.PLL.pllosc = osc;
u_avr32_pm_pll.PLL.plldiv = div;
u_avr32_pm_pll.PLL.pllmul = mul;
u_avr32_pm_pll.PLL.pllcount = lockcount;
pm->pll[pll] = u_avr32_pm_pll.pll;
}
void pm_pll_set_option(volatile avr32_pm_t *pm,
unsigned int pll,
unsigned int pll_freq,
unsigned int pll_div2,
unsigned int pll_wbwdisable)
{
u_avr32_pm_pll_t u_avr32_pm_pll = {pm->pll[pll]};
u_avr32_pm_pll.PLL.pllopt = pll_freq | (pll_div2 << 1) | (pll_wbwdisable << 2);
pm->pll[pll] = u_avr32_pm_pll.pll;
}
unsigned int pm_pll_get_option(volatile avr32_pm_t *pm,
unsigned int pll)
{
return (pm->pll[pll] & AVR32_PM_PLLOPT_MASK) >> AVR32_PM_PLLOPT_OFFSET;
}
void pm_pll_enable(volatile avr32_pm_t *pm,
unsigned int pll)
{
pm->pll[pll] |= AVR32_PM_PLLEN_MASK;
}
void pm_pll_disable(volatile avr32_pm_t *pm,
unsigned int pll)
{
pm->pll[pll] &= ~AVR32_PM_PLLEN_MASK;
}
void pm_wait_for_pll0_locked(volatile avr32_pm_t *pm)
{
while (!(pm->poscsr & AVR32_PM_POSCSR_LOCK0_MASK));
}
void pm_wait_for_pll1_locked(volatile avr32_pm_t *pm)
{
while (!(pm->poscsr & AVR32_PM_POSCSR_LOCK1_MASK));
}
void pm_switch_to_clock(volatile avr32_pm_t *pm, unsigned long clock)
{
// Read
u_avr32_pm_mcctrl_t u_avr32_pm_mcctrl = {pm->mcctrl};
// Modify
u_avr32_pm_mcctrl.MCCTRL.mcsel = clock;
// Write back
pm->mcctrl = u_avr32_pm_mcctrl.mcctrl;
}
void pm_switch_to_osc0(volatile avr32_pm_t *pm, unsigned int fosc0, unsigned int startup)
{
pm_enable_osc0_crystal(pm, fosc0); // Enable the Osc0 in crystal mode
pm_enable_clk0(pm, startup); // Crystal startup time - This parameter is critical and depends on the characteristics of the crystal
pm_switch_to_clock(pm, AVR32_PM_MCSEL_OSC0); // Then switch main clock to Osc0
}
void pm_bod_enable_irq(volatile avr32_pm_t *pm)
{
pm->ier = AVR32_PM_IER_BODDET_MASK;
}
void pm_bod_disable_irq(volatile avr32_pm_t *pm)
{
Bool global_interrupt_enabled = Is_global_interrupt_enabled();
if (global_interrupt_enabled) Disable_global_interrupt();
pm->idr = AVR32_PM_IDR_BODDET_MASK;
pm->isr;
if (global_interrupt_enabled) Enable_global_interrupt();
}
void pm_bod_clear_irq(volatile avr32_pm_t *pm)
{
pm->icr = AVR32_PM_ICR_BODDET_MASK;
}
unsigned long pm_bod_get_irq_status(volatile avr32_pm_t *pm)
{
return ((pm->isr & AVR32_PM_ISR_BODDET_MASK) != 0);
}
unsigned long pm_bod_get_irq_enable_bit(volatile avr32_pm_t *pm)
{
return ((pm->imr & AVR32_PM_IMR_BODDET_MASK) != 0);
}
unsigned long pm_bod_get_level(volatile avr32_pm_t *pm)
{
return (pm->bod & AVR32_PM_BOD_LEVEL_MASK) >> AVR32_PM_BOD_LEVEL_OFFSET;
}
unsigned long pm_read_gplp(volatile avr32_pm_t *pm, unsigned long gplp)
{
return pm->gplp[gplp];
}
void pm_write_gplp(volatile avr32_pm_t *pm, unsigned long gplp, unsigned long value)
{
pm->gplp[gplp] = value;
}
long pm_enable_module(volatile avr32_pm_t *pm, unsigned long module)
{
unsigned long domain = module>>5;
unsigned long *regptr = (unsigned long*)(&(pm->cpumask) + domain);
// Implementation-specific shortcut: the ckMASK registers are contiguous and
// memory-mapped in that order: CPUMASK, HSBMASK, PBAMASK, PBBMASK.
*regptr |= (1<<(module%32));
return PASS;
}
long pm_disable_module(volatile avr32_pm_t *pm, unsigned long module)
{
unsigned long domain = module>>5;
unsigned long *regptr = (unsigned long*)(&(pm->cpumask) + domain);
// Implementation-specific shortcut: the ckMASK registers are contiguous and
// memory-mapped in that order: CPUMASK, HSBMASK, PBAMASK, PBBMASK.
*regptr &= ~(1<<(module%32));
return PASS;
}

View File

@ -0,0 +1,493 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Power Manager driver.
*
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
*****************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _PM_H_
#define _PM_H_
#include <avr32/io.h>
#include "compiler.h"
#include "preprocessor.h"
/*! \brief Sets the MCU in the specified sleep mode.
*
* \param mode Sleep mode:
* \arg \c AVR32_PM_SMODE_IDLE: Idle;
* \arg \c AVR32_PM_SMODE_FROZEN: Frozen;
* \arg \c AVR32_PM_SMODE_STANDBY: Standby;
* \arg \c AVR32_PM_SMODE_STOP: Stop;
* \arg \c AVR32_PM_SMODE_DEEP_STOP: DeepStop;
* \arg \c AVR32_PM_SMODE_STATIC: Static.
*/
#define SLEEP(mode) {__asm__ __volatile__ ("sleep "STRINGZ(mode));}
//! Input and output parameters when initializing PM clocks using pm_configure_clocks().
typedef struct
{
//! CPU frequency (input/output argument).
unsigned long cpu_f;
//! PBA frequency (input/output argument).
unsigned long pba_f;
//! Oscillator 0's external crystal(or external clock) frequency (board dependant) (input argument).
unsigned long osc0_f;
//! Oscillator 0's external crystal(or external clock) startup time: AVR32_PM_OSCCTRL0_STARTUP_x_RCOSC (input argument).
unsigned long osc0_startup;
} pm_freq_param_t;
#define PM_FREQ_STATUS_FAIL (-1)
#define PM_FREQ_STATUS_OK (0)
/*! \brief Gets the MCU reset cause.
*
* \param pm Base address of the Power Manager instance (i.e. &AVR32_PM).
*
* \return The MCU reset cause which can be masked with the
* \c AVR32_PM_RCAUSE_x_MASK bit-masks to isolate specific causes.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ unsigned int pm_get_reset_cause(volatile avr32_pm_t *pm)
{
return pm->rcause;
}
/*!
* \brief This function will enable the external clock mode of the oscillator 0.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_enable_osc0_ext_clock(volatile avr32_pm_t *pm);
/*!
* \brief This function will enable the crystal mode of the oscillator 0.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param fosc0 Oscillator 0 crystal frequency (Hz)
*/
extern void pm_enable_osc0_crystal(volatile avr32_pm_t *pm, unsigned int fosc0);
/*!
* \brief This function will enable the oscillator 0 to be used with a startup time.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param startup Clock 0 startup time. AVR32_PM_OSCCTRL0_STARTUP_x_RCOSC.
*/
extern void pm_enable_clk0(volatile avr32_pm_t *pm, unsigned int startup);
/*!
* \brief This function will disable the oscillator 0.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_disable_clk0(volatile avr32_pm_t *pm);
/*!
* \brief This function will enable the oscillator 0 to be used with no startup time.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param startup Clock 0 startup time, for which the function does not wait. AVR32_PM_OSCCTRL0_STARTUP_x_RCOSC.
*/
extern void pm_enable_clk0_no_wait(volatile avr32_pm_t *pm, unsigned int startup);
/*!
* \brief This function will wait until the Osc0 clock is ready.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_wait_for_clk0_ready(volatile avr32_pm_t *pm);
/*!
* \brief This function will enable the external clock mode of the oscillator 1.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_enable_osc1_ext_clock(volatile avr32_pm_t *pm);
/*!
* \brief This function will enable the crystal mode of the oscillator 1.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param fosc1 Oscillator 1 crystal frequency (Hz)
*/
extern void pm_enable_osc1_crystal(volatile avr32_pm_t *pm, unsigned int fosc1);
/*!
* \brief This function will enable the oscillator 1 to be used with a startup time.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param startup Clock 1 startup time. AVR32_PM_OSCCTRL1_STARTUP_x_RCOSC.
*/
extern void pm_enable_clk1(volatile avr32_pm_t *pm, unsigned int startup);
/*!
* \brief This function will disable the oscillator 1.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_disable_clk1(volatile avr32_pm_t *pm);
/*!
* \brief This function will enable the oscillator 1 to be used with no startup time.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param startup Clock 1 startup time, for which the function does not wait. AVR32_PM_OSCCTRL1_STARTUP_x_RCOSC.
*/
extern void pm_enable_clk1_no_wait(volatile avr32_pm_t *pm, unsigned int startup);
/*!
* \brief This function will wait until the Osc1 clock is ready.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_wait_for_clk1_ready(volatile avr32_pm_t *pm);
/*!
* \brief This function will enable the external clock mode of the 32-kHz oscillator.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_enable_osc32_ext_clock(volatile avr32_pm_t *pm);
/*!
* \brief This function will enable the crystal mode of the 32-kHz oscillator.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_enable_osc32_crystal(volatile avr32_pm_t *pm);
/*!
* \brief This function will enable the oscillator 32 to be used with a startup time.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param startup Clock 32 kHz startup time. AVR32_PM_OSCCTRL32_STARTUP_x_RCOSC.
*/
extern void pm_enable_clk32(volatile avr32_pm_t *pm, unsigned int startup);
/*!
* \brief This function will disable the oscillator 32.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_disable_clk32(volatile avr32_pm_t *pm);
/*!
* \brief This function will enable the oscillator 32 to be used with no startup time.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param startup Clock 32 kHz startup time, for which the function does not wait. AVR32_PM_OSCCTRL32_STARTUP_x_RCOSC.
*/
extern void pm_enable_clk32_no_wait(volatile avr32_pm_t *pm, unsigned int startup);
/*!
* \brief This function will wait until the osc32 clock is ready.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_wait_for_clk32_ready(volatile avr32_pm_t *pm);
/*!
* \brief This function will select all the power manager clocks.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param pbadiv Peripheral Bus A clock divisor enable
* \param pbasel Peripheral Bus A select
* \param pbbdiv Peripheral Bus B clock divisor enable
* \param pbbsel Peripheral Bus B select
* \param hsbdiv High Speed Bus clock divisor enable (CPU clock = HSB clock)
* \param hsbsel High Speed Bus select (CPU clock = HSB clock )
*/
extern void pm_cksel(volatile avr32_pm_t *pm, unsigned int pbadiv, unsigned int pbasel, unsigned int pbbdiv, unsigned int pbbsel, unsigned int hsbdiv, unsigned int hsbsel);
/*!
* \brief This function will setup a generic clock.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param gc generic clock number (0 for gc0...)
* \param osc_or_pll Use OSC (=0) or PLL (=1)
* \param pll_osc Select Osc0/PLL0 or Osc1/PLL1
* \param diven Generic clock divisor enable
* \param div Generic clock divisor
*/
extern void pm_gc_setup(volatile avr32_pm_t *pm, unsigned int gc, unsigned int osc_or_pll, unsigned int pll_osc, unsigned int diven, unsigned int div);
/*!
* \brief This function will enable a generic clock.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param gc generic clock number (0 for gc0...)
*/
extern void pm_gc_enable(volatile avr32_pm_t *pm, unsigned int gc);
/*!
* \brief This function will disable a generic clock.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param gc generic clock number (0 for gc0...)
*/
extern void pm_gc_disable(volatile avr32_pm_t *pm, unsigned int gc);
/*!
* \brief This function will setup a PLL.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param pll PLL number(0 for PLL0, 1 for PLL1)
* \param mul PLL MUL in the PLL formula
* \param div PLL DIV in the PLL formula
* \param osc OSC number (0 for osc0, 1 for osc1)
* \param lockcount PLL lockount
*/
extern void pm_pll_setup(volatile avr32_pm_t *pm, unsigned int pll, unsigned int mul, unsigned int div, unsigned int osc, unsigned int lockcount);
/*!
* \brief This function will set a PLL option.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param pll PLL number(0 for PLL0, 1 for PLL1)
* \param pll_freq Set to 1 for VCO frequency range 80-180MHz, set to 0 for VCO frequency range 160-240Mhz.
* \param pll_div2 Divide the PLL output frequency by 2 (this settings does not change the FVCO value)
* \param pll_wbwdisable 1 Disable the Wide-Bandith Mode (Wide-Bandwith mode allow a faster startup time and out-of-lock time). 0 to enable the Wide-Bandith Mode.
*/
extern void pm_pll_set_option(volatile avr32_pm_t *pm, unsigned int pll, unsigned int pll_freq, unsigned int pll_div2, unsigned int pll_wbwdisable);
/*!
* \brief This function will get a PLL option.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param pll PLL number(0 for PLL0, 1 for PLL1)
* \return Option
*/
extern unsigned int pm_pll_get_option(volatile avr32_pm_t *pm, unsigned int pll);
/*!
* \brief This function will enable a PLL.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param pll PLL number(0 for PLL0, 1 for PLL1)
*/
extern void pm_pll_enable(volatile avr32_pm_t *pm, unsigned int pll);
/*!
* \brief This function will disable a PLL.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param pll PLL number(0 for PLL0, 1 for PLL1)
*/
extern void pm_pll_disable(volatile avr32_pm_t *pm, unsigned int pll);
/*!
* \brief This function will wait for PLL0 locked
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_wait_for_pll0_locked(volatile avr32_pm_t *pm);
/*!
* \brief This function will wait for PLL1 locked
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_wait_for_pll1_locked(volatile avr32_pm_t *pm);
/*!
* \brief This function will switch the power manager main clock.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param clock Clock to be switched on. AVR32_PM_MCSEL_SLOW for RCOsc, AVR32_PM_MCSEL_OSC0 for Osc0, AVR32_PM_MCSEL_PLL0 for PLL0.
*/
extern void pm_switch_to_clock(volatile avr32_pm_t *pm, unsigned long clock);
/*!
* \brief Switch main clock to clock Osc0 (crystal mode)
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param fosc0 Oscillator 0 crystal frequency (Hz)
* \param startup Crystal 0 startup time. AVR32_PM_OSCCTRL0_STARTUP_x_RCOSC.
*/
extern void pm_switch_to_osc0(volatile avr32_pm_t *pm, unsigned int fosc0, unsigned int startup);
/*! \brief Enables the Brown-Out Detector interrupt.
*
* \param pm Base address of the Power Manager (i.e. &AVR32_PM).
*/
extern void pm_bod_enable_irq(volatile avr32_pm_t *pm);
/*! \brief Disables the Brown-Out Detector interrupt.
*
* \param pm Base address of the Power Manager (i.e. &AVR32_PM).
*/
extern void pm_bod_disable_irq(volatile avr32_pm_t *pm);
/*! \brief Clears the Brown-Out Detector interrupt flag.
*
* \param pm Base address of the Power Manager (i.e. &AVR32_PM).
*/
extern void pm_bod_clear_irq(volatile avr32_pm_t *pm);
/*! \brief Gets the Brown-Out Detector interrupt flag.
*
* \param pm Base address of the Power Manager (i.e. &AVR32_PM).
*
* \retval 0 No BOD interrupt.
* \retval 1 BOD interrupt pending.
*/
extern unsigned long pm_bod_get_irq_status(volatile avr32_pm_t *pm);
/*! \brief Gets the Brown-Out Detector interrupt enable status.
*
* \param pm Base address of the Power Manager (i.e. &AVR32_PM).
*
* \retval 0 BOD interrupt disabled.
* \retval 1 BOD interrupt enabled.
*/
extern unsigned long pm_bod_get_irq_enable_bit(volatile avr32_pm_t *pm);
/*! \brief Gets the triggering threshold of the Brown-Out Detector.
*
* \param pm Base address of the Power Manager (i.e. &AVR32_PM).
*
* \return Triggering threshold of the BOD. See the electrical characteristics
* in the part datasheet for actual voltage levels.
*/
extern unsigned long pm_bod_get_level(volatile avr32_pm_t *pm);
/*!
* \brief Read the content of the PM GPLP registers
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param gplp GPLP register index (0,1,... depending on the number of GPLP registers for a given part)
*
* \return The content of the chosen GPLP register.
*/
extern unsigned long pm_read_gplp(volatile avr32_pm_t *pm, unsigned long gplp);
/*!
* \brief Write into the PM GPLP registers
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param gplp GPLP register index (0,1,... depending on the number of GPLP registers for a given part)
* \param value Value to write
*/
extern void pm_write_gplp(volatile avr32_pm_t *pm, unsigned long gplp, unsigned long value);
/*! \brief Enable the clock of a module.
*
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param module The module to clock (use one of the defines in the part-specific
* header file under "toolchain folder"/avr32/inc(lude)/avr32/; depending on the
* clock domain, look for the sections "CPU clocks", "HSB clocks", "PBx clocks")
*
* \return Status.
* \retval 0 Success.
* \retval <0 An error occured.
*/
extern long pm_enable_module(volatile avr32_pm_t *pm, unsigned long module);
/*! \brief Disable the clock of a module.
*
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param module The module to shut down (use one of the defines in the part-specific
* header file under "toolchain folder"/avr32/inc(lude)/avr32/; depending on the
* clock domain, look for the sections "CPU clocks", "HSB clocks", "PBx clocks")
*
* \return Status.
* \retval 0 Success.
* \retval <0 An error occured.
*/
extern long pm_disable_module(volatile avr32_pm_t *pm, unsigned long module);
/*! \brief Automatically configure the CPU, PBA, PBB, and HSB clocks
* according to the user wishes.
*
* This function needs some parameters stored in a pm_freq_param_t structure:
* - cpu_f and pba_f are the wanted frequencies,
* - osc0_f is the oscillator 0 on-board frequency (e.g. FOSC0),
* - osc0_startup is the oscillator 0 startup time (e.g. OSC0_STARTUP).
*
* The function will then configure the clocks using the following rules:
* - It first try to find a valid PLL frequency (the highest possible value to avoid jitter) in order
* to satisfy the CPU frequency,
* - It optimizes the configuration depending the various divide stages,
* - Then, the PBA frequency is configured from the CPU freq.
* - Note that HSB and PBB are configured with the same frequency as CPU.
* - Note also that the number of wait states of the flash read accesses is automatically set-up depending
* the CPU frequency. As a consequence, the application needs the FLASHC driver to compile.
*
* The CPU, HSB and PBA frequencies programmed after configuration are stored back into cpu_f and pba_f.
*
* \param param pointer on the configuration structure.
*
* \retval PM_FREQ_STATUS_OK Mode successfully initialized.
* \retval PM_FREQ_STATUS_FAIL The configuration can not be done.
*/
extern int pm_configure_clocks(pm_freq_param_t *param);
/*! \brief Automatically configure the USB clock.
*
* USB clock is configured to 48MHz, using the PLL1 from the Oscillator0, assuming
* a 12 MHz crystal is connected to it.
*/
extern void pm_configure_usb_clock(void);
#endif // _PM_H_

View File

@ -0,0 +1,268 @@
/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Power Manager clocks configuration helper.
*
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
*****************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#include <string.h>
#include "compiler.h"
#include "pm.h"
extern void flashc_set_wait_state(unsigned int wait_state);
#if (defined AVR32_FLASHC_210_H_INCLUDED)
extern void flashc_issue_command(unsigned int command, int page_number);
#endif
#define PM_MAX_MUL ((1 << AVR32_PM_PLL0_PLLMUL_SIZE) - 1)
int pm_configure_clocks(pm_freq_param_t *param)
{
// Supported frequencies:
// Fosc0 mul div PLL div2_en cpu_f pba_f Comment
// 12 15 1 192 1 12 12
// 12 9 3 40 1 20 20 PLL out of spec
// 12 15 1 192 1 24 12
// 12 9 1 120 1 30 15
// 12 9 3 40 0 40 20 PLL out of spec
// 12 15 1 192 1 48 12
// 12 15 1 192 1 48 24
// 12 8 1 108 1 54 27
// 12 9 1 120 1 60 15
// 12 9 1 120 1 60 30
// 12 10 1 132 1 66 16.5
//
unsigned long in_cpu_f = param->cpu_f;
unsigned long in_osc0_f = param->osc0_f;
unsigned long mul, div, div2_en = 0, div2_cpu = 0, div2_pba = 0;
unsigned long pll_freq, rest;
Bool b_div2_pba, b_div2_cpu;
// Switch to external Oscillator 0
pm_switch_to_osc0(&AVR32_PM, in_osc0_f, param->osc0_startup);
// Start with CPU freq config
if (in_cpu_f == in_osc0_f)
{
param->cpu_f = in_osc0_f;
param->pba_f = in_osc0_f;
return PM_FREQ_STATUS_OK;
}
else if (in_cpu_f < in_osc0_f)
{
// TBD
}
rest = in_cpu_f % in_osc0_f;
for (div = 1; div < 32; div++)
{
if ((div * rest) % in_osc0_f == 0)
break;
}
if (div == 32)
return PM_FREQ_STATUS_FAIL;
mul = (in_cpu_f * div) / in_osc0_f;
if (mul > PM_MAX_MUL)
return PM_FREQ_STATUS_FAIL;
// export 2power from PLL div to div2_cpu
while (!(div % 2))
{
div /= 2;
div2_cpu++;
}
// Here we know the mul and div parameter of the PLL config.
// . Check out if the PLL has a valid in_cpu_f.
// . Try to have for the PLL frequency (VCO output) the highest possible value
// to reduce jitter.
while (in_osc0_f * 2 * mul / div < AVR32_PM_PLL_VCO_RANGE0_MAX_FREQ)
{
if (2 * mul > PM_MAX_MUL)
break;
mul *= 2;
div2_cpu++;
}
if (div2_cpu != 0)
{
div2_cpu--;
div2_en = 1;
}
pll_freq = in_osc0_f * mul / (div * (1 << div2_en));
// Update real CPU Frequency
param->cpu_f = pll_freq / (1 << div2_cpu);
mul--;
pm_pll_setup(&AVR32_PM
, 0 // pll
, mul // mul
, div // div
, 0 // osc
, 16 // lockcount
);
pm_pll_set_option(&AVR32_PM
, 0 // pll
// PLL clock is lower than 160MHz: need to set pllopt.
, (pll_freq < AVR32_PM_PLL_VCO_RANGE0_MIN_FREQ) ? 1 : 0 // pll_freq
, div2_en // pll_div2
, 0 // pll_wbwdisable
);
rest = pll_freq;
while (rest > AVR32_PM_PBA_MAX_FREQ ||
rest != param->pba_f)
{
div2_pba++;
rest = pll_freq / (1 << div2_pba);
if (rest < param->pba_f)
break;
}
// Update real PBA Frequency
param->pba_f = pll_freq / (1 << div2_pba);
// Enable PLL0
pm_pll_enable(&AVR32_PM, 0);
// Wait for PLL0 locked
pm_wait_for_pll0_locked(&AVR32_PM);
if (div2_cpu)
{
b_div2_cpu = TRUE;
div2_cpu--;
}
else
b_div2_cpu = FALSE;
if (div2_pba)
{
b_div2_pba = TRUE;
div2_pba--;
}
else
b_div2_pba = FALSE;
pm_cksel(&AVR32_PM
, b_div2_pba, div2_pba // PBA
, b_div2_cpu, div2_cpu // PBB
, b_div2_cpu, div2_cpu // HSB
);
if (param->cpu_f > AVR32_FLASHC_FWS_0_MAX_FREQ)
{
flashc_set_wait_state(1);
#if (defined AVR32_FLASHC_210_H_INCLUDED)
if (param->cpu_f > AVR32_FLASHC_HSEN_FWS_1_MAX_FREQ)
flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSEN, -1);
else
flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSDIS, -1);
#endif
}
else
{
flashc_set_wait_state(0);
#if (defined AVR32_FLASHC_210_H_INCLUDED)
if (param->cpu_f > AVR32_FLASHC_HSEN_FWS_0_MAX_FREQ)
flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSEN, -1);
else
flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSDIS, -1);
#endif
}
pm_switch_to_clock(&AVR32_PM, AVR32_PM_MCCTRL_MCSEL_PLL0);
return PM_FREQ_STATUS_OK;
}
void pm_configure_usb_clock(void)
{
#if UC3A3
// Setup USB GCLK.
pm_gc_setup(&AVR32_PM, AVR32_PM_GCLK_USBB, // gc
0, // osc_or_pll: use Osc (if 0) or PLL (if 1)
0, // pll_osc: select Osc0/PLL0 or Osc1/PLL1
0, // diven
0); // div
// Enable USB GCLK.
pm_gc_enable(&AVR32_PM, AVR32_PM_GCLK_USBB);
#else
// Use 12MHz from OSC0 and generate 96 MHz
pm_pll_setup(&AVR32_PM, 1, // pll.
7, // mul.
1, // div.
0, // osc.
16); // lockcount.
pm_pll_set_option(&AVR32_PM, 1, // pll.
1, // pll_freq: choose the range 80-180MHz.
1, // pll_div2.
0); // pll_wbwdisable.
// start PLL1 and wait forl lock
pm_pll_enable(&AVR32_PM, 1);
// Wait for PLL1 locked.
pm_wait_for_pll1_locked(&AVR32_PM);
pm_gc_setup(&AVR32_PM, AVR32_PM_GCLK_USBB, // gc.
1, // osc_or_pll: use Osc (if 0) or PLL (if 1).
1, // pll_osc: select Osc0/PLL0 or Osc1/PLL1.
0, // diven.
0); // div.
pm_gc_enable(&AVR32_PM, AVR32_PM_GCLK_USBB);
#endif
}

View File

@ -0,0 +1,566 @@
/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief High-level library abstracting features such as oscillators/pll/dfll
* configuration, clock configuration, System-sensible parameters
* configuration, buses clocks configuration, sleep mode, reset.
*
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
*****************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#include "power_clocks_lib.h"
//! Device-specific data
#if UC3L
static long int pcl_configure_clocks_uc3l(pcl_freq_param_t *param); // FORWARD declaration
#endif
#if UC3C
static long int pcl_configure_clocks_uc3c(pcl_freq_param_t *param); // FORWARD declaration
#endif
long int pcl_configure_clocks(pcl_freq_param_t *param)
{
#ifndef AVR32_PM_VERSION_RESETVALUE
// Implementation for UC3A, UC3A3, UC3B parts.
return(pm_configure_clocks(param));
#else
#ifdef AVR32_PM_410_H_INCLUDED
// Implementation for UC3C parts.
return(pcl_configure_clocks_uc3c(param));
#else
// Implementation for UC3L parts.
return(pcl_configure_clocks_uc3l(param));
#endif
#endif
}
//! Device-specific implementation
#if UC3L
// FORWARD declaration
static long int pcl_configure_synchronous_clocks( pm_clk_src_t main_clk_src,
unsigned long main_clock_freq_hz,
pcl_freq_param_t *param);
long int pcl_configure_clocks_rcsys(pcl_freq_param_t *param)
{
// Supported main clock sources: PCL_MC_RCSYS
// Supported synchronous clocks frequencies if RCSYS is the main clock source:
// 115200Hz, 57600Hz, 28800Hz, 14400Hz, 7200Hz, 3600Hz, 1800Hz, 900Hz, 450Hz.
// NOTE: by default, this implementation doesn't perform thorough checks on the
// input parameters. To enable the checks, define AVR32SFW_INPUT_CHECK.
#ifdef AVR32SFW_INPUT_CHECK
// Verify that fCPU >= fPBx
if((param->cpu_f < param->pba_f) || (param->cpu_f < param->pbb_f))
return(-1);
#endif
#ifdef AVR32SFW_INPUT_CHECK
// Verify that the target frequencies are reachable.
if((param->cpu_f > SCIF_SLOWCLOCK_FREQ_HZ) || (param->pba_f > SCIF_SLOWCLOCK_FREQ_HZ)
|| (param->pbb_f > SCIF_SLOWCLOCK_FREQ_HZ))
return(-1);
#endif
return(pcl_configure_synchronous_clocks(PM_CLK_SRC_SLOW, SCIF_SLOWCLOCK_FREQ_HZ, param));
}
long int pcl_configure_clocks_rc120m(pcl_freq_param_t *param)
{
// Supported main clock sources: PCL_MC_RC120M
// Supported synchronous clocks frequencies if RC120M is the main clock source:
// 30MHz, 15MHz, 7.5MHz, 3.75MHz, 1.875MHz, 937.5kHz, 468.75kHz.
// NOTE: by default, this implementation doesn't perform thorough checks on the
// input parameters. To enable the checks, define AVR32SFW_INPUT_CHECK.
#ifdef AVR32SFW_INPUT_CHECK
// Verify that fCPU >= fPBx
if((param->cpu_f < param->pba_f) || (param->cpu_f < param->pbb_f))
return(-1);
#endif
#ifdef AVR32SFW_INPUT_CHECK
// Verify that the target frequencies are reachable.
if((param->cpu_f > SCIF_RC120M_FREQ_HZ) || (param->pba_f > SCIF_RC120M_FREQ_HZ)
|| (param->pbb_f > SCIF_RC120M_FREQ_HZ))
return(-1);
#endif
// Start the 120MHz internal RCosc (RC120M) clock
scif_start_rc120M();
return(pcl_configure_synchronous_clocks(PM_CLK_SRC_RC120M, SCIF_RC120M_FREQ_HZ, param));
}
long int pcl_configure_clocks_osc0(pcl_freq_param_t *param)
{
// Supported main clock sources: PCL_MC_OSC0
// Supported synchronous clocks frequencies if OSC0 is the main clock source:
// (these obviously depend on the OSC0 frequency; we'll take 16MHz as an example)
// 16MHz, 8MHz, 4MHz, 2MHz, 1MHz, 500kHz, 250kHz, 125kHz, 62.5kHz.
// NOTE: by default, this implementation doesn't perform thorough checks on the
// input parameters. To enable the checks, define AVR32SFW_INPUT_CHECK.
unsigned long main_clock_freq;
#ifdef AVR32SFW_INPUT_CHECK
// Verify that fCPU >= fPBx
if((param->cpu_f < param->pba_f) || (param->cpu_f < param->pbb_f))
return(-1);
#endif
main_clock_freq = param->osc0_f;
#ifdef AVR32SFW_INPUT_CHECK
// Verify that the target frequencies are reachable.
if((param->cpu_f > main_clock_freq) || (param->pba_f > main_clock_freq)
|| (param->pbb_f > main_clock_freq))
return(-1);
#endif
// Configure OSC0 in crystal mode, external crystal with a fcrystal Hz frequency.
scif_configure_osc_crystalmode(SCIF_OSC0, main_clock_freq);
// Enable the OSC0
scif_enable_osc(SCIF_OSC0, param->osc0_startup, true);
return(pcl_configure_synchronous_clocks(PM_CLK_SRC_OSC0, main_clock_freq, param));
}
long int pcl_configure_clocks_dfll0(pcl_freq_param_t *param)
{
// Supported main clock sources: PCL_MC_DFLL
// Supported synchronous clocks frequencies if DFLL is the main clock source:
// (these obviously depend on the DFLL target frequency; we'll take 100MHz as an example)
// 50MHz, 25MHz, 12.5MHz, 6.25MHz, 3.125MHz, 1562.5kHz, 781.25kHz, 390.625kHz.
// NOTE: by default, this implementation doesn't perform thorough checks on the
// input parameters. To enable the checks, define AVR32SFW_INPUT_CHECK.
unsigned long main_clock_freq;
scif_gclk_opt_t *pgc_dfllif_ref_opt;
#ifdef AVR32SFW_INPUT_CHECK
// Verify that fCPU >= fPBx
if((param->cpu_f < param->pba_f) || (param->cpu_f < param->pbb_f))
return(-1);
#endif
main_clock_freq = param->dfll_f;
#ifdef AVR32SFW_INPUT_CHECK
// Verify that the target DFLL output frequency is in the correct range.
if((main_clock_freq > SCIF_DFLL_MAXFREQ_HZ) || (main_clock_freq < SCIF_DFLL_MINFREQ_HZ))
return(-1);
// Verify that the target frequencies are reachable.
if((param->cpu_f > main_clock_freq) || (param->pba_f > main_clock_freq)
|| (param->pbb_f > main_clock_freq))
return(-1);
#endif
pgc_dfllif_ref_opt = (scif_gclk_opt_t *)param->pextra_params;
// Implementation note: this implementation configures the DFLL in closed-loop
// mode (because it gives the best accuracy) which enables the generic clock CLK_DFLLIF_REF
// as a reference (RCSYS being used as the generic clock source, undivided).
scif_dfll0_closedloop_configure_and_start(pgc_dfllif_ref_opt, main_clock_freq, TRUE);
return(pcl_configure_synchronous_clocks(PM_CLK_SRC_DFLL0, main_clock_freq, param));
}
static long int pcl_configure_clocks_uc3l(pcl_freq_param_t *param)
{
// Supported main clock sources: PCL_MC_RCSYS, PCL_MC_OSC0, PCL_MC_DFLL0, PCL_MC_RC120M
// Supported synchronous clocks frequencies if RCSYS is the main clock source:
// 115200Hz, 57600Hz, 28800Hz, 14400Hz, 7200Hz, 3600Hz, 1800Hz, 900Hz, 450Hz.
// Supported synchronous clocks frequencies if RC120M is the main clock source:
// 30MHz, 15MHz, 7.5MHz, 3.75MHz, 1.875MHz, 937.5kHz, 468.75kHz.
// Supported synchronous clocks frequencies if OSC0 is the main clock source:
// (these obviously depend on the OSC0 frequency; we'll take 16MHz as an example)
// 16MHz, 8MHz, 4MHz, 2MHz, 1MHz, 500kHz, 250kHz, 125kHz, 62.5kHz.
// Supported synchronous clocks frequencies if DFLL is the main clock source:
// (these obviously depend on the DFLL target frequency; we'll take 100MHz as an example)
// 50MHz, 25MHz, 12.5MHz, 6.25MHz, 3.125MHz, 1562.5kHz, 781.25kHz, 390.625kHz.
// NOTE: by default, this implementation doesn't perform thorough checks on the
// input parameters. To enable the checks, define AVR32SFW_INPUT_CHECK.
#ifdef AVR32SFW_INPUT_CHECK
// Verify that fCPU >= fPBx
if((param->cpu_f < param->pba_f) || (param->cpu_f < param->pbb_f))
return(-1);
#endif
if(PCL_MC_RCSYS == param->main_clk_src)
{
return(pcl_configure_clocks_rcsys(param));
}
else if(PCL_MC_RC120M == param->main_clk_src)
{
return(pcl_configure_clocks_rc120m(param));
}
else if(PCL_MC_OSC0 == param->main_clk_src)
{
return(pcl_configure_clocks_osc0(param));
}
else // PCL_MC_DFLL0 == param->main_clk_src
{
return(pcl_configure_clocks_dfll0(param));
}
}
static long int pcl_configure_synchronous_clocks(pm_clk_src_t main_clk_src, unsigned long main_clock_freq_hz, pcl_freq_param_t *param)
{
//#
//# Set the Synchronous clock division ratio for each clock domain
//#
pm_set_all_cksel(main_clock_freq_hz, param->cpu_f, param->pba_f, param->pbb_f);
//#
//# Set the Flash wait state and the speed read mode (depending on the target CPU frequency).
//#
#if UC3L
flashcdw_set_flash_waitstate_and_readmode(param->cpu_f);
#elif UC3C
flashc_set_flash_waitstate_and_readmode(param->cpu_f);
#endif
//#
//# Switch the main clock source to the selected clock.
//#
pm_set_mclk_source(main_clk_src);
return PASS;
}
#endif // UC3L device-specific implementation
//! UC3C Device-specific implementation
#if UC3C
static long int pcl_configure_clocks_uc3c(pcl_freq_param_t *param)
{
#define PM_MAX_MUL ((1 << AVR32_SCIF_PLLMUL_SIZE) - 1)
#define AVR32_PM_PBA_MAX_FREQ 66000000
#define AVR32_PM_PLL_VCO_RANGE0_MAX_FREQ 240000000
#define AVR32_PM_PLL_VCO_RANGE0_MIN_FREQ 160000000
// Implementation for UC3C parts.
// Supported frequencies:
// Fosc0 mul div PLL div2_en cpu_f pba_f Comment
// 12 15 1 192 1 12 12
// 12 9 3 40 1 20 20 PLL out of spec
// 12 15 1 192 1 24 12
// 12 9 1 120 1 30 15
// 12 9 3 40 0 40 20 PLL out of spec
// 12 15 1 192 1 48 12
// 12 15 1 192 1 48 24
// 12 8 1 108 1 54 27
// 12 9 1 120 1 60 15
// 12 9 1 120 1 60 30
// 12 10 1 132 1 66 16.5
//
unsigned long in_cpu_f = param->cpu_f;
unsigned long in_osc0_f = param->osc0_f;
unsigned long mul, div, div2_en = 0, div2_cpu = 0, div2_pba = 0;
unsigned long pll_freq, rest;
Bool b_div2_pba, b_div2_cpu;
// Configure OSC0 in crystal mode, external crystal with a FOSC0 Hz frequency.
scif_configure_osc_crystalmode(SCIF_OSC0, in_osc0_f);
// Enable the OSC0
scif_enable_osc(SCIF_OSC0, param->osc0_startup, true);
// Set the main clock source as being OSC0.
pm_set_mclk_source(PM_CLK_SRC_OSC0);
// Start with CPU freq config
if (in_cpu_f == in_osc0_f)
{
param->cpu_f = in_osc0_f;
param->pba_f = in_osc0_f;
return PASS;
}
else if (in_cpu_f < in_osc0_f)
{
// TBD
}
rest = in_cpu_f % in_osc0_f;
for (div = 1; div < 32; div++)
{
if ((div * rest) % in_osc0_f == 0)
break;
}
if (div == 32)
return FAIL;
mul = (in_cpu_f * div) / in_osc0_f;
if (mul > PM_MAX_MUL)
return FAIL;
// export 2power from PLL div to div2_cpu
while (!(div % 2))
{
div /= 2;
div2_cpu++;
}
// Here we know the mul and div parameter of the PLL config.
// . Check out if the PLL has a valid in_cpu_f.
// . Try to have for the PLL frequency (VCO output) the highest possible value
// to reduce jitter.
while (in_osc0_f * 2 * mul / div < AVR32_PM_PLL_VCO_RANGE0_MAX_FREQ)
{
if (2 * mul > PM_MAX_MUL)
break;
mul *= 2;
div2_cpu++;
}
if (div2_cpu != 0)
{
div2_cpu--;
div2_en = 1;
}
pll_freq = in_osc0_f * mul / (div * (1 << div2_en));
// Update real CPU Frequency
param->cpu_f = pll_freq / (1 << div2_cpu);
mul--;
scif_pll_opt_t opt;
opt.osc = SCIF_OSC0, // Sel Osc0 or Osc1
opt.lockcount = 16, // lockcount in main clock for the PLL wait lock
opt.div = div, // DIV=1 in the formula
opt.mul = mul, // MUL=7 in the formula
opt.pll_div2 = div2_en, // pll_div2 Divide the PLL output frequency by 2 (this settings does not change the FVCO value)
opt.pll_wbwdisable = 0, //pll_wbwdisable 1 Disable the Wide-Bandith Mode (Wide-Bandwith mode allow a faster startup time and out-of-lock time). 0 to enable the Wide-Bandith Mode.
opt.pll_freq = (pll_freq < AVR32_PM_PLL_VCO_RANGE0_MIN_FREQ) ? 1 : 0, // Set to 1 for VCO frequency range 80-180MHz, set to 0 for VCO frequency range 160-240Mhz.
scif_pll_setup(SCIF_PLL0, opt); // lockcount in main clock for the PLL wait lock
/* Enable PLL0 */
scif_pll_enable(SCIF_PLL0);
/* Wait for PLL0 locked */
scif_wait_for_pll_locked(SCIF_PLL0) ;
rest = pll_freq;
while (rest > AVR32_PM_PBA_MAX_FREQ ||
rest != param->pba_f)
{
div2_pba++;
rest = pll_freq / (1 << div2_pba);
if (rest < param->pba_f)
break;
}
// Update real PBA Frequency
param->pba_f = pll_freq / (1 << div2_pba);
if (div2_cpu)
{
b_div2_cpu = TRUE;
div2_cpu--;
}
else
b_div2_cpu = FALSE;
if (div2_pba)
{
b_div2_pba = TRUE;
div2_pba--;
}
else
b_div2_pba = FALSE;
if (b_div2_cpu == TRUE )
{
pm_set_clk_domain_div(PM_CLK_DOMAIN_0, (pm_divratio_t) div2_cpu); // CPU
pm_set_clk_domain_div(PM_CLK_DOMAIN_1, (pm_divratio_t) div2_cpu); // HSB
pm_set_clk_domain_div(PM_CLK_DOMAIN_3, (pm_divratio_t) div2_cpu); // PBB
}
if (b_div2_pba == TRUE )
{
pm_set_clk_domain_div(PM_CLK_DOMAIN_2, (pm_divratio_t) div2_pba); // PBA
pm_set_clk_domain_div(PM_CLK_DOMAIN_4, (pm_divratio_t) div2_pba); // PBC
}
// Set Flashc Wait State
flashc_set_flash_waitstate_and_readmode(param->cpu_f);
// Set the main clock source as being PLL0.
pm_set_mclk_source(PM_CLK_SRC_PLL0);
return PASS;
}
#endif // UC3C device-specific implementation
long int pcl_switch_to_osc(pcl_osc_t osc, unsigned int fcrystal, unsigned int startup)
{
#ifndef AVR32_PM_VERSION_RESETVALUE
// Implementation for UC3A, UC3A3, UC3B parts.
if(PCL_OSC0 == osc)
{
// Configure OSC0 in crystal mode, external crystal with a FOSC0 Hz frequency,
// enable the OSC0, set the main clock source as being OSC0.
pm_switch_to_osc0(&AVR32_PM, fcrystal, startup);
}
else
{
return PCL_NOT_SUPPORTED;
}
#else
// Implementation for UC3C, UC3L parts.
#if AVR32_PM_VERSION_RESETVALUE < 0x400
return PCL_NOT_SUPPORTED;
#else
if(PCL_OSC0 == osc)
{
// Configure OSC0 in crystal mode, external crystal with a fcrystal Hz frequency.
scif_configure_osc_crystalmode(SCIF_OSC0, fcrystal);
// Enable the OSC0
scif_enable_osc(SCIF_OSC0, startup, true);
// Set the Flash wait state and the speed read mode (depending on the target CPU frequency).
#if UC3L
flashcdw_set_flash_waitstate_and_readmode(fcrystal);
#elif UC3C
flashc_set_flash_waitstate_and_readmode(fcrystal);
#endif
// Set the main clock source as being OSC0.
pm_set_mclk_source(PM_CLK_SRC_OSC0);
}
else
{
return PCL_NOT_SUPPORTED;
}
#endif
#endif
return PASS;
}
long int pcl_configure_usb_clock(void)
{
#ifndef AVR32_PM_VERSION_RESETVALUE
// Implementation for UC3A, UC3A3, UC3B parts.
pm_configure_usb_clock();
return PASS;
#else
#ifdef AVR32_PM_410_H_INCLUDED
const scif_pll_opt_t opt = {
.osc = SCIF_OSC0, // Sel Osc0 or Osc1
.lockcount = 16, // lockcount in main clock for the PLL wait lock
.div = 1, // DIV=1 in the formula
.mul = 5, // MUL=7 in the formula
.pll_div2 = 1, // pll_div2 Divide the PLL output frequency by 2 (this settings does not change the FVCO value)
.pll_wbwdisable = 0, //pll_wbwdisable 1 Disable the Wide-Bandith Mode (Wide-Bandwith mode allow a faster startup time and out-of-lock time). 0 to enable the Wide-Bandith Mode.
.pll_freq = 1, // Set to 1 for VCO frequency range 80-180MHz, set to 0 for VCO frequency range 160-240Mhz.
};
/* Setup PLL1 on Osc0, mul=7 ,no divisor, lockcount=16, ie. 16Mhzx6 = 96MHz output */
scif_pll_setup(SCIF_PLL1, opt); // lockcount in main clock for the PLL wait lock
/* Enable PLL1 */
scif_pll_enable(SCIF_PLL1);
/* Wait for PLL1 locked */
scif_wait_for_pll_locked(SCIF_PLL1) ;
// Implementation for UC3C parts.
// Setup the generic clock for USB
scif_gc_setup(AVR32_SCIF_GCLK_USB,
SCIF_GCCTRL_PLL1,
AVR32_SCIF_GC_NO_DIV_CLOCK,
0);
// Now enable the generic clock
scif_gc_enable(AVR32_SCIF_GCLK_USB);
return PASS;
#else
return PCL_NOT_SUPPORTED;
#endif
#endif
}
#if UC3L
#else
void pcl_write_gplp(unsigned long gplp, unsigned long value)
{
#ifndef AVR32_PM_VERSION_RESETVALUE
// Implementation for UC3A, UC3A3, UC3B parts.
pm_write_gplp(&AVR32_PM,gplp,value);
#else
scif_write_gplp(gplp,value);
#endif
}
unsigned long pcl_read_gplp(unsigned long gplp)
{
#ifndef AVR32_PM_VERSION_RESETVALUE
// Implementation for UC3A, UC3A3, UC3B parts.
return pm_read_gplp(&AVR32_PM,gplp);
#else
return scif_read_gplp(gplp);
#endif
}
#endif

View File

@ -0,0 +1,379 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief High-level library abstracting features such as oscillators/pll/dfll
* configuration, clock configuration, System-sensible parameters
* configuration, buses clocks configuration, sleep mode, reset.
*
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
*****************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _POWER_CLOCKS_LIB_H_
#define _POWER_CLOCKS_LIB_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <avr32/io.h>
#include "compiler.h"
#ifndef AVR32_PM_VERSION_RESETVALUE
// Support for UC3A, UC3A3, UC3B parts.
#include "pm.h"
#else
//! Device-specific data
#if UC3L
#include "pm_uc3l.h"
#include "scif_uc3l.h"
#include "flashcdw.h"
#elif UC3C
#include "pm_uc3c.h"
#include "scif_uc3c.h"
#include "flashc.h"
#endif
#endif
/*! \name Clocks Management
*/
//! @{
//! The different oscillators
typedef enum
{
PCL_OSC0 = 0,
PCL_OSC1 = 1
} pcl_osc_t;
//! The different DFLLs
typedef enum
{
PCL_DFLL0 = 0,
PCL_DFLL1 = 1
} pcl_dfll_t;
//! Possible Main Clock Sources
typedef enum
{
PCL_MC_RCSYS, // Default main clock source, supported by all (aka Slow Clock)
PCL_MC_OSC0, // Supported by all
PCL_MC_OSC1, // Supported by UC3C only
PCL_MC_OSC0_PLL0, // Supported by UC3A, UC3B, UC3A3, UC3C (the main clock source is PLL0 with OSC0 as reference)
PCL_MC_OSC1_PLL0, // Supported by UC3A, UC3B, UC3A3, UC3C (the main clock source is PLL0 with OSC1 as reference)
PCL_MC_OSC0_PLL1, // Supported by UC3C (the main clock source is PLL1 with OSC0 as reference)
PCL_MC_OSC1_PLL1, // Supported by UC3C (the main clock source is PLL1 with OSC1 as reference)
PCL_MC_DFLL0, // Supported by UC3L
PCL_MC_DFLL1, // Not supported yet
PCL_MC_RC120M, // Supported by UC3L, UC3C
PCL_MC_RC8M, // Supported by UC3C
PCL_MC_CRIPOSC // Supported by UC3C
} pcl_mainclk_t;
//! Input and output parameters to configure clocks with pcl_configure_clocks().
// NOTE: regarding the frequency settings, always abide by the datasheet rules and min & max supported frequencies.
#ifndef AVR32_PM_VERSION_RESETVALUE
// Support for UC3A, UC3A3, UC3B parts.
#define pcl_freq_param_t pm_freq_param_t // See pm.h
#else
// Support for UC3C, UC3L parts.
typedef struct
{
//! Main clock source selection (input argument).
pcl_mainclk_t main_clk_src;
//! Target CPU frequency (input/output argument).
unsigned long cpu_f;
//! Target PBA frequency (input/output argument).
unsigned long pba_f;
//! Target PBB frequency (input/output argument).
unsigned long pbb_f;
//! Target PBC frequency (input/output argument).
unsigned long pbc_f;
//! Oscillator 0's external crystal(or external clock) frequency (board dependant) (input argument).
unsigned long osc0_f;
//! Oscillator 0's external crystal(or external clock) startup time: AVR32_PM_OSCCTRL0_STARTUP_x_RCOSC (input argument).
unsigned long osc0_startup;
//! DFLL target frequency (input/output argument) (NOTE: the bigger, the most stable the frequency)
unsigned long dfll_f;
//! Other parameters that might be necessary depending on the device (implementation-dependent).
// For the UC3L DFLL setup, this parameter should be pointing to a structure of
// type (scif_gclk_opt_t *).
void *pextra_params;
} pcl_freq_param_t;
#endif
//! Define "not supported" for the lib.
#define PCL_NOT_SUPPORTED (-10000)
/*! \brief Automatically configure the CPU, PBA, PBB, and HSB clocks
*
* This function needs some parameters stored in a pcl_freq_param_t structure:
* - main_clk_src is the id of the main clock source to use,
* - cpu_f and pba_f and pbb_f are the wanted frequencies,
* - osc0_f is the oscillator 0's external crystal (or external clock) on-board frequency (e.g. FOSC0),
* - osc0_startup is the oscillator 0's external crystal (or external clock) startup time (e.g. OSC0_STARTUP).
* - dfll_f is the target DFLL frequency to set-up if main_clk_src is the dfll.
*
* The CPU, HSB and PBA frequencies programmed after configuration are stored back into cpu_f and pba_f.
*
* \note: since it is dynamically computing the appropriate field values of the
* configuration registers from the parameters structure, this function is not
* optimal in terms of code size. For a code size optimal solution, it is better
* to create a new function from pcl_configure_clocks() and modify it to use
* preprocessor computation from pre-defined target frequencies.
*
* \param param pointer on the configuration structure.
*
* \retval 0 Success.
* \retval <0 The configuration cannot be performed.
*/
extern long int pcl_configure_clocks(pcl_freq_param_t *param);
/*! \brief Automatically configure the CPU, PBA, PBB, and HSB clocks using the RCSYS osc as main source clock.
*
* This function needs some parameters stored in a pcl_freq_param_t structure:
* - cpu_f and pba_f and pbb_f are the wanted frequencies
*
* Supported main clock sources: PCL_MC_RCSYS
*
* Supported synchronous clocks frequencies:
* 115200Hz, 57600Hz, 28800Hz, 14400Hz, 7200Hz, 3600Hz, 1800Hz, 900Hz, 450Hz.
*
* \note: by default, this implementation doesn't perform thorough checks on the
* input parameters. To enable the checks, define AVR32SFW_INPUT_CHECK.
*
* \note: since it is dynamically computing the appropriate field values of the
* configuration registers from the parameters structure, this function is not
* optimal in terms of code size. For a code size optimal solution, it is better
* to create a new function from pcl_configure_clocks_rcsys() and modify it to use
* preprocessor computation from pre-defined target frequencies.
*
* \param param pointer on the configuration structure.
*
* \retval 0 Success.
* \retval <0 The configuration cannot be performed.
*/
extern long int pcl_configure_clocks_rcsys(pcl_freq_param_t *param);
/*! \brief Automatically configure the CPU, PBA, PBB, and HSB clocks using the RC120M osc as main source clock.
*
* This function needs some parameters stored in a pcl_freq_param_t structure:
* - cpu_f and pba_f and pbb_f are the wanted frequencies
*
* Supported main clock sources: PCL_MC_RC120M
*
* Supported synchronous clocks frequencies:
* 30MHz, 15MHz, 7.5MHz, 3.75MHz, 1.875MHz, 937.5kHz, 468.75kHz.
*
* \note: by default, this implementation doesn't perform thorough checks on the
* input parameters. To enable the checks, define AVR32SFW_INPUT_CHECK.
*
* \note: since it is dynamically computing the appropriate field values of the
* configuration registers from the parameters structure, this function is not
* optimal in terms of code size. For a code size optimal solution, it is better
* to create a new function from pcl_configure_clocks_rc120m() and modify it to
* use preprocessor computation from pre-defined target frequencies.
*
* \param param pointer on the configuration structure.
*
* \retval 0 Success.
* \retval <0 The configuration cannot be performed.
*/
extern long int pcl_configure_clocks_rc120m(pcl_freq_param_t *param);
/*! \brief Automatically configure the CPU, PBA, PBB, and HSB clocks using the OSC0 osc as main source clock
*
* This function needs some parameters stored in a pcl_freq_param_t structure:
* - cpu_f and pba_f and pbb_f are the wanted frequencies,
* - osc0_f is the oscillator 0's external crystal (or external clock) on-board frequency (e.g. FOSC0),
* - osc0_startup is the oscillator 0's external crystal (or external clock) startup time (e.g. OSC0_STARTUP).
*
* Supported main clock sources: PCL_MC_OSC0
*
* Supported synchronous clocks frequencies:
* (these obviously depend on the OSC0 frequency; we'll take 16MHz as an example)
* 16MHz, 8MHz, 4MHz, 2MHz, 1MHz, 500kHz, 250kHz, 125kHz, 62.5kHz.
*
* \note: by default, this implementation doesn't perform thorough checks on the
* input parameters. To enable the checks, define AVR32SFW_INPUT_CHECK.
*
* \note: since it is dynamically computing the appropriate field values of the
* configuration registers from the parameters structure, this function is not
* optimal in terms of code size. For a code size optimal solution, it is better
* to create a new function from pcl_configure_clocks_osc0() and modify it to use
* preprocessor computation from pre-defined target frequencies.
*
* \param param pointer on the configuration structure.
*
* \retval 0 Success.
* \retval <0 The configuration cannot be performed.
*/
extern long int pcl_configure_clocks_osc0(pcl_freq_param_t *param);
/*! \brief Automatically configure the CPU, PBA, PBB, and HSB clocks using the DFLL0 as main source clock
*
* This function needs some parameters stored in a pcl_freq_param_t structure:
* - cpu_f and pba_f and pbb_f are the wanted frequencies,
* - dfll_f is the target DFLL frequency to set-up
*
* \note: when the DFLL0 is to be used as main source clock for the synchronous clocks,
* the target frequency of the DFLL should be chosen to be as high as possible
* within the specification range (for stability reasons); the target cpu and pbx
* frequencies will then be reached by appropriate division ratio.
*
* Supported main clock sources: PCL_MC_DFLL0
*
* Supported synchronous clocks frequencies:
* (these obviously depend on the DFLL target frequency; we'll take 100MHz as an example)
* 50MHz, 25MHz, 12.5MHz, 6.25MHz, 3.125MHz, 1562.5kHz, 781.25kHz, 390.625kHz.
*
* \note: by default, this implementation doesn't perform thorough checks on the
* input parameters. To enable the checks, define AVR32SFW_INPUT_CHECK.
*
* \note: since it is dynamically computing the appropriate field values of the
* configuration registers from the parameters structure, this function is not
* optimal in terms of code size. For a code size optimal solution, it is better
* to create a new function from pcl_configure_clocks_dfll0() and modify it to
* use preprocessor computation from pre-defined target frequencies.
*
* \param param pointer on the configuration structure.
*
* \retval 0 Success.
* \retval <0 The configuration cannot be performed.
*/
extern long int pcl_configure_clocks_dfll0(pcl_freq_param_t *param);
/*! \brief Switch the main clock source to Osc0 configured in crystal mode
*
* \param osc The oscillator to enable and switch to.
* \param fcrystal Oscillator external crystal frequency (Hz)
* \param startup Oscillator startup time.
*
* \return Status.
* \retval 0 Success.
* \retval <0 An error occured.
*/
extern long int pcl_switch_to_osc(pcl_osc_t osc, unsigned int fcrystal, unsigned int startup);
/*! \brief Enable the clock of a module.
*
* \param module The module to clock (use one of the defines in the part-specific
* header file under "toolchain folder"/avr32/inc(lude)/avr32/; depending on the
* clock domain, look for the sections "CPU clocks", "HSB clocks", "PBx clocks"
* or look in the module section).
*
* \return Status.
* \retval 0 Success.
* \retval <0 An error occured.
*/
#ifndef AVR32_PM_VERSION_RESETVALUE
// Implementation for UC3A, UC3A3, UC3B parts.
#define pcl_enable_module(module) pm_enable_module(&AVR32_PM, module)
#else
// Implementation for UC3C, UC3L parts.
#define pcl_enable_module(module) pm_enable_module(module)
#endif
/*! \brief Disable the clock of a module.
*
* \param module The module to shut down (use one of the defines in the part-specific
* header file under "toolchain folder"/avr32/inc(lude)/avr32/; depending on the
* clock domain, look for the sections "CPU clocks", "HSB clocks", "PBx clocks"
* or look in the module section).
*
* \return Status.
* \retval 0 Success.
* \retval <0 An error occured.
*/
#ifndef AVR32_PM_VERSION_RESETVALUE
// Implementation for UC3A, UC3A3, UC3B parts.
#define pcl_disable_module(module) pm_disable_module(&AVR32_PM, module)
#else
// Implementation for UC3C, UC3L parts.
#define pcl_disable_module(module) pm_disable_module(module)
#endif
/*! \brief Configure the USB Clock
*
*
* \return Status.
* \retval 0 Success.
* \retval <0 An error occured.
*/
extern long int pcl_configure_usb_clock(void);
//! @}
/*! \name Power Management
*/
//! @{
/*!
* \brief Read the content of the GPLP registers
* \param gplp GPLP register index (0,1,... depending on the number of GPLP registers for a given part)
*
* \return The content of the chosen GPLP register.
*/
extern unsigned long pcl_read_gplp(unsigned long gplp);
/*!
* \brief Write into the GPLP registers
* \param gplp GPLP register index (0,1,... depending on the number of GPLP registers for a given part)
* \param value Value to write
*/
extern void pcl_write_gplp(unsigned long gplp, unsigned long value);
//! @}
#ifdef __cplusplus
}
#endif
#endif // _POWER_CLOCKS_LIB_H_

View File

@ -0,0 +1,213 @@
/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief RTC driver for AVR32 UC3.
*
* AVR32 Real Time Counter driver module.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices with an RTC and a PM module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#include <avr32/io.h>
#include "compiler.h"
#include "pm.h"
#include "rtc.h"
int rtc_is_busy(volatile avr32_rtc_t *rtc)
{
return (rtc->ctrl & AVR32_RTC_CTRL_BUSY_MASK) != 0;
}
int rtc_init(volatile avr32_rtc_t *rtc, unsigned char osc_type, unsigned char psel)
{
// If exit, it means that the configuration has not been set correctly
if (osc_type > (1 << AVR32_RTC_CTRL_CLK32_SIZE) - 1 ||
psel > (1 << AVR32_RTC_CTRL_PSEL_SIZE) - 1)
return 0;
// If we use the 32-kHz oscillator, we have to enable it first
if (osc_type == RTC_OSC_32KHZ)
{
// Select the 32-kHz oscillator crystal
pm_enable_osc32_crystal(&AVR32_PM);
// Enable the 32-kHz clock
pm_enable_clk32_no_wait(&AVR32_PM, AVR32_PM_OSCCTRL32_STARTUP_0_RCOSC);
}
// Wait until the rtc CTRL register is up-to-date
while (rtc_is_busy(rtc));
// Set the new RTC configuration
rtc->ctrl = osc_type << AVR32_RTC_CTRL_CLK32_OFFSET |
psel << AVR32_RTC_CTRL_PSEL_OFFSET |
AVR32_RTC_CTRL_CLKEN_MASK;
// Wait until write is done
while (rtc_is_busy(rtc));
// Set the counter value to 0
rtc_set_value(rtc, 0x00000000);
// Set the top value to 0xFFFFFFFF
rtc_set_top_value(rtc, 0xFFFFFFFF);
return 1;
}
void rtc_set_value(volatile avr32_rtc_t *rtc, unsigned long val)
{
// Wait until we can write into the VAL register
while (rtc_is_busy(rtc));
// Set the new val value
rtc->val = val;
// Wait until write is done
while (rtc_is_busy(rtc));
}
unsigned long rtc_get_value(volatile avr32_rtc_t *rtc)
{
return rtc->val;
}
void rtc_enable_wake_up(volatile avr32_rtc_t *rtc)
{
// Wait until the rtc CTRL register is up-to-date
while (rtc_is_busy(rtc));
// Enable the wake up of the RTC
rtc->ctrl |= AVR32_RTC_CTRL_WAKE_EN_MASK;
// Wait until write is done
while (rtc_is_busy(rtc));
}
void rtc_disable_wake_up(volatile avr32_rtc_t *rtc)
{
// Wait until the rtc CTRL register is up-to-date
while (rtc_is_busy(rtc));
// Disable the wake up of the RTC
rtc->ctrl &= ~AVR32_RTC_CTRL_WAKE_EN_MASK;
// Wait until write is done
while (rtc_is_busy(rtc));
}
void rtc_enable(volatile avr32_rtc_t *rtc)
{
// Wait until the rtc CTRL register is up-to-date
while (rtc_is_busy(rtc));
// Enable the RTC
rtc->ctrl |= AVR32_RTC_CTRL_EN_MASK;
// Wait until write is done
while (rtc_is_busy(rtc));
}
void rtc_disable(volatile avr32_rtc_t *rtc)
{
// Wait until the rtc CTRL register is up-to-date
while (rtc_is_busy(rtc));
// Disable the RTC
rtc->ctrl &= ~AVR32_RTC_CTRL_EN_MASK;
// Wait until write is done
while (rtc_is_busy(rtc));
}
void rtc_enable_interrupt(volatile avr32_rtc_t *rtc)
{
rtc->ier = AVR32_RTC_IER_TOPI_MASK;
}
void rtc_disable_interrupt(volatile avr32_rtc_t *rtc)
{
Bool global_interrupt_enabled = Is_global_interrupt_enabled();
if (global_interrupt_enabled) Disable_global_interrupt();
rtc->idr = AVR32_RTC_IDR_TOPI_MASK;
rtc->imr;
if (global_interrupt_enabled) Enable_global_interrupt();
}
void rtc_clear_interrupt(volatile avr32_rtc_t *rtc)
{
Bool global_interrupt_enabled = Is_global_interrupt_enabled();
if (global_interrupt_enabled) Disable_global_interrupt();
rtc->icr = AVR32_RTC_ICR_TOPI_MASK;
rtc->isr;
if (global_interrupt_enabled) Enable_global_interrupt();
}
void rtc_set_top_value(volatile avr32_rtc_t *rtc, unsigned long top)
{
// Wait until we can write into the VAL register
while (rtc_is_busy(rtc));
// Set the new val value
rtc->top = top;
// Wait until write is done
while (rtc_is_busy(rtc));
}
unsigned long rtc_get_top_value(volatile avr32_rtc_t *rtc)
{
return rtc->top;
}
int rtc_interrupt_enabled(volatile avr32_rtc_t *rtc)
{
return (rtc->imr & AVR32_RTC_IMR_TOPI_MASK) != 0;
}
int rtc_is_interrupt(volatile avr32_rtc_t *rtc)
{
return (rtc->isr & AVR32_RTC_ISR_TOPI_MASK) != 0;
}

View File

@ -0,0 +1,191 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief RTC driver for AVR32 UC3.
*
* AVR32 Real Time Counter driver module.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices with an RTC and a PM module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _RTC_H_
#define _RTC_H_
#include "compiler.h"
#include <avr32/io.h>
/*! \name Oscillator Types
*/
//! @{
#define RTC_OSC_32KHZ 1
#define RTC_OSC_RC 0
//! @}
/*! \name Predefined PSEL Values
*/
//! @{
//! The PSEL value to set the RTC source clock (after the prescaler) to 1 Hz,
//! when using an external 32-kHz crystal.
#define RTC_PSEL_32KHZ_1HZ 14
//! The PSEL value to set the RTC source clock (after the prescaler) to 1.76 Hz,
//! when using the internal RC oscillator (~ 115 kHz).
#define RTC_PSEL_RC_1_76HZ 15
//! @}
/*!
* \brief This function will initialise the RTC module.
* If you use the 32 KHz oscillator, it will enable this module.
* This function also set the top value of the RTC to 0xFFFFFFFF
* and the value to 0.
* \param rtc Base address of the RTC (i.e. &AVR32_RTC).
* \param osc_type The oscillator you want to use. If you need a better
* accuracy, use the 32 KHz oscillator (i.e. RTC_OSC_32KHZ).
* \param psel The preselector value for the corresponding oscillator (4-bits).
* To obtain this value, you can use this formula:
* psel = log(Fosc/Frtc)/log(2)-1, where Fosc is the frequency of the
* oscillator you are using (32 KHz or 115 KHz) and Frtc the frequency
* desired.
* \return 1 if the initialisation succeds otherwize it will return 0.
*/
extern int rtc_init(volatile avr32_rtc_t *rtc, unsigned char osc_type, unsigned char psel);
/*!
* \brief Enable the RTC.
* \param rtc Base address of the RTC (i.e. &AVR32_RTC).
*/
extern void rtc_enable(volatile avr32_rtc_t *rtc);
/*!
* \brief Disable the RTC.
* \param rtc Base address of the RTC (i.e. &AVR32_RTC).
*/
extern void rtc_disable(volatile avr32_rtc_t *rtc);
/*!
* \brief Enable the wake up feature of the RTC.
* \param rtc Base address of the RTC (i.e. &AVR32_RTC).
*/
extern void rtc_enable_wake_up(volatile avr32_rtc_t *rtc);
/*!
* \brief Disable the wake up feature of the RTC.
* \param rtc Base address of the RTC (i.e. &AVR32_RTC).
*/
extern void rtc_disable_wake_up(volatile avr32_rtc_t *rtc);
/*!
* \brief Enable the interrupt feature of the RTC.
* An interrupt is raised when the value of the RTC
* is equal to its top value.
* \param rtc Base address of the RTC (i.e. &AVR32_RTC).
*/
extern void rtc_enable_interrupt(volatile avr32_rtc_t *rtc);
/*!
* \brief Disable the interrupt feature of the RTC.
* \param rtc Base address of the RTC (i.e. &AVR32_RTC).
*/
extern void rtc_disable_interrupt(volatile avr32_rtc_t *rtc);
/*!
* \brief Clear the interrupt flag.
* Call this function once you handled the interrupt.
* \param rtc Base address of the RTC (i.e. &AVR32_RTC).
*/
extern void rtc_clear_interrupt(volatile avr32_rtc_t *rtc);
/*!
* \brief Get the status of interrupts.
* \param rtc Base address of the RTC (i.e. &AVR32_RTC).
* \return 1 if the interrupts are enabled otherwize it returns 0.
*/
extern int rtc_interrupt_enabled(volatile avr32_rtc_t *rtc);
/*!
* \brief Check if an interrupt is raised.
* \param rtc Base address of the RTC (i.e. &AVR32_RTC).
* \return 1 if an interrupt is currently raised otherwize it returns 0.
*/
extern int rtc_is_interrupt(volatile avr32_rtc_t *rtc);
/*!
* \brief This function sets the RTC current top value.
* \param rtc Base address of the RTC (i.e. &AVR32_RTC).
* \param top The top value you want to store.
*/
extern void rtc_set_top_value(volatile avr32_rtc_t *rtc, unsigned long top);
/*!
* \brief This function returns the RTC current top value.
* \param rtc Base address of the RTC (i.e. &AVR32_RTC).
* \return The RTC current top value.
*/
extern unsigned long rtc_get_top_value(volatile avr32_rtc_t *rtc);
/*!
* \brief This function checks if the RTC is busy or not.
* \param rtc Base address of the RTC (i.e. &AVR32_RTC).
* \return 1 if the RTC is busy otherwize it will return 0.
*/
extern int rtc_is_busy(volatile avr32_rtc_t *rtc);
/*!
* \brief This function sets the RTC current value.
* \param rtc Base address of the RTC (i.e. &AVR32_RTC).
* \param val The value you want to store.
*/
extern void rtc_set_value(volatile avr32_rtc_t *rtc, unsigned long val);
/*!
* \brief This function returns the RTC current value.
* \param rtc Base address of the RTC (i.e. &AVR32_RTC).
* \return The RTC current value.
*/
extern unsigned long rtc_get_value(volatile avr32_rtc_t *rtc);
#endif // _RTC_H_

View File

@ -0,0 +1,443 @@
/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief SPI driver for AVR32 UC3.
*
* This file defines a useful set of functions for the SPI interface on AVR32
* devices.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with an SPI module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#include "spi.h"
#ifdef FREERTOS_USED
#include "FreeRTOS.h"
#include "semphr.h"
#endif
/*! \name SPI Writable Bit-Field Registers
*/
//! @{
typedef union
{
unsigned long cr;
avr32_spi_cr_t CR;
} u_avr32_spi_cr_t;
typedef union
{
unsigned long mr;
avr32_spi_mr_t MR;
} u_avr32_spi_mr_t;
typedef union
{
unsigned long tdr;
avr32_spi_tdr_t TDR;
} u_avr32_spi_tdr_t;
typedef union
{
unsigned long ier;
avr32_spi_ier_t IER;
} u_avr32_spi_ier_t;
typedef union
{
unsigned long idr;
avr32_spi_idr_t IDR;
} u_avr32_spi_idr_t;
typedef union
{
unsigned long csr;
avr32_spi_csr0_t CSR;
} u_avr32_spi_csr_t;
//! @}
#ifdef FREERTOS_USED
//! The SPI mutex.
static xSemaphoreHandle xSPIMutex;
#endif
/*! \brief Calculates the baudrate divider.
*
* \param options Pointer to a structure containing initialization options for
* an SPI channel.
* \param pba_hz SPI module input clock frequency (PBA clock, Hz).
*
* \return Divider or error code.
* \retval >=0 Success.
* \retval <0 Error.
*/
static int getBaudDiv(const spi_options_t *options, unsigned int pba_hz)
{
int baudDiv = (pba_hz + options->baudrate / 2) / options->baudrate;
if (baudDiv <= 0 || baudDiv > 255) {
return -1;
}
return baudDiv;
}
void spi_reset(volatile avr32_spi_t *spi)
{
spi->cr = AVR32_SPI_CR_SWRST_MASK;
}
spi_status_t spi_initSlave(volatile avr32_spi_t *spi,
unsigned char bits,
unsigned char spi_mode)
{
if (spi_mode > 3 ||
bits < 8 || bits > 16) {
return SPI_ERROR_ARGUMENT;
}
// Reset.
spi->cr = AVR32_SPI_CR_SWRST_MASK;
// Will use CSR0 offsets; these are the same for CSR0 to CSR3.
spi->csr0 = ((spi_mode >> 1) << AVR32_SPI_CSR0_CPOL_OFFSET) |
(((spi_mode & 0x1) ^ 0x1) << AVR32_SPI_CSR0_NCPHA_OFFSET) |
((bits - 8) << AVR32_SPI_CSR0_BITS_OFFSET);
return SPI_OK;
}
spi_status_t spi_initTest(volatile avr32_spi_t *spi)
{
// Reset.
spi->cr = AVR32_SPI_CR_SWRST_MASK;
spi->mr |= AVR32_SPI_MR_MSTR_MASK | // Master Mode.
AVR32_SPI_MR_LLB_MASK; // Local Loopback.
return SPI_OK;
}
spi_status_t spi_initMaster(volatile avr32_spi_t *spi, const spi_options_t *options)
{
u_avr32_spi_mr_t u_avr32_spi_mr;
if (options->modfdis > 1) {
return SPI_ERROR_ARGUMENT;
}
// Reset.
spi->cr = AVR32_SPI_CR_SWRST_MASK;
// Master Mode.
u_avr32_spi_mr.mr = spi->mr;
u_avr32_spi_mr.MR.mstr = 1;
u_avr32_spi_mr.MR.modfdis = options->modfdis;
u_avr32_spi_mr.MR.llb = 0;
u_avr32_spi_mr.MR.pcs = (1 << AVR32_SPI_MR_PCS_SIZE) - 1;
spi->mr = u_avr32_spi_mr.mr;
return SPI_OK;
}
spi_status_t spi_selectionMode(volatile avr32_spi_t *spi,
unsigned char variable_ps,
unsigned char pcs_decode,
unsigned char delay)
{
u_avr32_spi_mr_t u_avr32_spi_mr;
if (variable_ps > 1 ||
pcs_decode > 1) {
return SPI_ERROR_ARGUMENT;
}
u_avr32_spi_mr.mr = spi->mr;
u_avr32_spi_mr.MR.ps = variable_ps;
u_avr32_spi_mr.MR.pcsdec = pcs_decode;
u_avr32_spi_mr.MR.dlybcs = delay;
spi->mr = u_avr32_spi_mr.mr;
return SPI_OK;
}
spi_status_t spi_selectChip(volatile avr32_spi_t *spi, unsigned char chip)
{
#ifdef FREERTOS_USED
while (pdFALSE == xSemaphoreTake(xSPIMutex, 20));
#endif
// Assert all lines; no peripheral is selected.
spi->mr |= AVR32_SPI_MR_PCS_MASK;
if (spi->mr & AVR32_SPI_MR_PCSDEC_MASK) {
// The signal is decoded; allow up to 15 chips.
if (chip > 14) {
return SPI_ERROR_ARGUMENT;
}
spi->mr &= ~AVR32_SPI_MR_PCS_MASK | (chip << AVR32_SPI_MR_PCS_OFFSET);
} else {
if (chip > 3) {
return SPI_ERROR_ARGUMENT;
}
spi->mr &= ~(1 << (AVR32_SPI_MR_PCS_OFFSET + chip));
}
return SPI_OK;
}
spi_status_t spi_unselectChip(volatile avr32_spi_t *spi, unsigned char chip)
{
unsigned int timeout = SPI_TIMEOUT;
while (!(spi->sr & AVR32_SPI_SR_TXEMPTY_MASK)) {
if (!timeout--) {
return SPI_ERROR_TIMEOUT;
}
}
// Assert all lines; no peripheral is selected.
spi->mr |= AVR32_SPI_MR_PCS_MASK;
// Last transfer, so deassert the current NPCS if CSAAT is set.
spi->cr = AVR32_SPI_CR_LASTXFER_MASK;
#ifdef FREERTOS_USED
xSemaphoreGive(xSPIMutex);
#endif
return SPI_OK;
}
spi_status_t spi_setupChipReg(volatile avr32_spi_t *spi,
const spi_options_t *options,
unsigned int pba_hz)
{
u_avr32_spi_csr_t u_avr32_spi_csr;
if (options->spi_mode > 3 ||
options->stay_act > 1 ||
options->bits < 8 || options->bits > 16) {
return SPI_ERROR_ARGUMENT;
}
int baudDiv = getBaudDiv(options, pba_hz);
if (baudDiv < 0) {
return SPI_ERROR_ARGUMENT;
}
// Will use CSR0 offsets; these are the same for CSR0 to CSR3.
u_avr32_spi_csr.csr = 0;
u_avr32_spi_csr.CSR.cpol = options->spi_mode >> 1;
u_avr32_spi_csr.CSR.ncpha = (options->spi_mode & 0x1) ^ 0x1;
u_avr32_spi_csr.CSR.csaat = options->stay_act;
u_avr32_spi_csr.CSR.bits = options->bits - 8;
u_avr32_spi_csr.CSR.scbr = baudDiv;
u_avr32_spi_csr.CSR.dlybs = options->spck_delay;
u_avr32_spi_csr.CSR.dlybct = options->trans_delay;
switch(options->reg) {
case 0:
spi->csr0 = u_avr32_spi_csr.csr;
break;
case 1:
spi->csr1 = u_avr32_spi_csr.csr;
break;
case 2:
spi->csr2 = u_avr32_spi_csr.csr;
break;
case 3:
spi->csr3 = u_avr32_spi_csr.csr;
break;
default:
return SPI_ERROR_ARGUMENT;
}
#ifdef FREERTOS_USED
if (!xSPIMutex)
{
// Create the SPI mutex.
vSemaphoreCreateBinary(xSPIMutex);
if (!xSPIMutex)
{
while(1);
}
}
#endif
return SPI_OK;
}
void spi_enable(volatile avr32_spi_t *spi)
{
spi->cr = AVR32_SPI_CR_SPIEN_MASK;
}
void spi_disable(volatile avr32_spi_t *spi)
{
spi->cr = AVR32_SPI_CR_SPIDIS_MASK;
}
int spi_is_enabled(volatile avr32_spi_t *spi)
{
return (spi->sr & AVR32_SPI_SR_SPIENS_MASK) != 0;
}
inline unsigned char spi_writeRegisterEmptyCheck(volatile avr32_spi_t *spi)
{
return ((spi->sr & AVR32_SPI_SR_TDRE_MASK) != 0);
}
inline spi_status_t spi_write(volatile avr32_spi_t *spi, unsigned short data)
{
unsigned int timeout = SPI_TIMEOUT;
while (!(spi->sr & AVR32_SPI_SR_TDRE_MASK)) {
if (!timeout--) {
return SPI_ERROR_TIMEOUT;
}
}
spi->tdr = data << AVR32_SPI_TDR_TD_OFFSET;
return SPI_OK;
}
spi_status_t spi_variableSlaveWrite(volatile avr32_spi_t *spi, unsigned short data,
unsigned char pcs, unsigned char lastxfer)
{
unsigned int timeout = SPI_TIMEOUT;
if (pcs > 14 || lastxfer > 1) {
return SPI_ERROR_ARGUMENT;
}
while (!(spi->sr & AVR32_SPI_SR_TDRE_MASK)) {
if (!timeout--) {
return SPI_ERROR_TIMEOUT;
}
}
spi->tdr = (data << AVR32_SPI_TDR_TD_OFFSET) |
(pcs << AVR32_SPI_TDR_PCS_OFFSET) |
(lastxfer << AVR32_SPI_TDR_LASTXFER_OFFSET);
return SPI_OK;
}
inline unsigned char spi_writeEndCheck(volatile avr32_spi_t *spi)
{
return ((spi->sr & AVR32_SPI_SR_TXEMPTY_MASK) != 0);
}
unsigned char spi_readRegisterFullCheck(volatile avr32_spi_t *spi)
{
return ((spi->sr & AVR32_SPI_SR_RDRF_MASK) != 0);
}
inline spi_status_t spi_read(volatile avr32_spi_t *spi, unsigned short *data)
{
unsigned int timeout = SPI_TIMEOUT;
while ((spi->sr & (AVR32_SPI_SR_RDRF_MASK | AVR32_SPI_SR_TXEMPTY_MASK)) !=
(AVR32_SPI_SR_RDRF_MASK | AVR32_SPI_SR_TXEMPTY_MASK)) {
if (!timeout--) {
return SPI_ERROR_TIMEOUT;
}
}
*data = spi->rdr >> AVR32_SPI_RDR_RD_OFFSET;
return SPI_OK;
}
unsigned char spi_getStatus(volatile avr32_spi_t *spi)
{
spi_status_t ret = SPI_OK;
unsigned long sr = spi->sr;
if (sr & AVR32_SPI_SR_OVRES_MASK) {
ret = SPI_ERROR_OVERRUN;
}
if (sr & AVR32_SPI_SR_MODF_MASK) {
ret += SPI_ERROR_MODE_FAULT;
}
if (ret == (SPI_ERROR_OVERRUN + SPI_ERROR_MODE_FAULT)) {
return SPI_ERROR_OVERRUN_AND_MODE_FAULT;
}
else if (ret > 0) {
return ret;
} else {
return SPI_OK;
}
}

View File

@ -0,0 +1,342 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief SPI driver for AVR32 UC3.
*
* This file defines a useful set of functions for the SPI interface on AVR32
* devices.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with an SPI module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _SPI_H_
#define _SPI_H_
#include <avr32/io.h>
//! Time-out value (number of attempts).
#define SPI_TIMEOUT 10000
//! Status codes used by the SPI driver.
typedef enum
{
SPI_ERROR = -1,
SPI_OK = 0,
SPI_ERROR_TIMEOUT = 1,
SPI_ERROR_ARGUMENT,
SPI_ERROR_OVERRUN,
SPI_ERROR_MODE_FAULT,
SPI_ERROR_OVERRUN_AND_MODE_FAULT
} spi_status_t;
//! Option structure for SPI channels.
typedef struct
{
//! The SPI channel to set up.
unsigned char reg;
//! Preferred baudrate for the SPI.
unsigned int baudrate;
//! Number of bits in each character (8 to 16).
unsigned char bits;
//! Delay before first clock pulse after selecting slave (in PBA clock periods).
unsigned char spck_delay;
//! Delay between each transfer/character (in PBA clock periods).
unsigned char trans_delay;
//! Sets this chip to stay active after last transfer to it.
unsigned char stay_act;
//! Which SPI mode to use when transmitting.
unsigned char spi_mode;
//! Disables the mode fault detection.
//! With this bit cleared, the SPI master mode will disable itself if another
//! master tries to address it.
unsigned char modfdis;
} spi_options_t;
/*! \brief Resets the SPI controller.
*
* \param spi Base address of the SPI instance.
*/
extern void spi_reset(volatile avr32_spi_t *spi);
/*! \brief Initializes the SPI in slave mode.
*
* \param spi Base address of the SPI instance.
* \param bits Number of bits in each transmitted character (8 to 16).
* \param spi_mode Clock polarity and phase.
*
* \return Status.
* \retval SPI_OK Success.
* \retval SPI_ERROR_ARGUMENT Invalid argument(s) passed.
*/
extern spi_status_t spi_initSlave(volatile avr32_spi_t *spi,
unsigned char bits,
unsigned char spi_mode);
/*! \brief Sets up the SPI in a test mode where the transmitter is connected to
* the receiver (local loopback).
*
* \param spi Base address of the SPI instance.
*
* \return Status.
* \retval SPI_OK Success.
*/
extern spi_status_t spi_initTest(volatile avr32_spi_t *spi);
/*! \brief Initializes the SPI in master mode.
*
* \param spi Base address of the SPI instance.
* \param options Pointer to a structure containing initialization options.
*
* \return Status.
* \retval SPI_OK Success.
* \retval SPI_ERROR_ARGUMENT Invalid argument(s) passed.
*/
extern spi_status_t spi_initMaster(volatile avr32_spi_t *spi, const spi_options_t *options);
/*! \brief Sets up how and when the slave chips are selected (master mode only).
*
* \param spi Base address of the SPI instance.
* \param variable_ps Target slave is selected in transfer register for every
* character to transmit.
* \param pcs_decode The four chip select lines are decoded externally. Values
* 0 to 14 can be given to \ref spi_selectChip.
* \param delay Delay in PBA periods between chip selects.
*
* \return Status.
* \retval SPI_OK Success.
* \retval SPI_ERROR_ARGUMENT Invalid argument(s) passed.
*/
extern spi_status_t spi_selectionMode(volatile avr32_spi_t *spi,
unsigned char variable_ps,
unsigned char pcs_decode,
unsigned char delay);
/*! \brief Selects slave chip.
*
* \param spi Base address of the SPI instance.
* \param chip Slave chip number (normal: 0 to 3, extarnally decoded signal: 0
* to 14).
*
* \return Status.
* \retval SPI_OK Success.
* \retval SPI_ERROR_ARGUMENT Invalid argument(s) passed.
*/
extern spi_status_t spi_selectChip(volatile avr32_spi_t *spi, unsigned char chip);
/*! \brief Unselects slave chip.
*
* \param spi Base address of the SPI instance.
* \param chip Slave chip number (normal: 0 to 3, extarnally decoded signal: 0
* to 14).
*
* \return Status.
* \retval SPI_OK Success.
* \retval SPI_ERROR_TIMEOUT Time-out.
*
* \note Will block program execution until time-out occurs if last transmission
* is not complete. Invoke \ref spi_writeEndCheck beforehand if needed.
*/
extern spi_status_t spi_unselectChip(volatile avr32_spi_t *spi, unsigned char chip);
/*! \brief Sets options for a specific slave chip.
*
* The baudrate field has to be written before transfer in master mode. Four
* similar registers exist, one for each slave. When using encoded slave
* addressing, reg=0 sets options for slaves 0 to 3, reg=1 for slaves 4 to 7 and
* so on.
*
* \param spi Base address of the SPI instance.
* \param options Pointer to a structure containing initialization options for
* an SPI channel.
* \param pba_hz SPI module input clock frequency (PBA clock, Hz).
*
* \return Status.
* \retval SPI_OK Success.
* \retval SPI_ERROR_ARGUMENT Invalid argument(s) passed.
*/
extern spi_status_t spi_setupChipReg(volatile avr32_spi_t *spi,
const spi_options_t *options,
unsigned int pba_hz);
/*! \brief Enables the SPI.
*
* \param spi Base address of the SPI instance.
*/
extern void spi_enable(volatile avr32_spi_t *spi);
/*! \brief Disables the SPI.
*
* Ensures that nothing is transferred while setting up buffers.
*
* \param spi Base address of the SPI instance.
*
* \warning This may cause data loss if used on a slave SPI.
*/
extern void spi_disable(volatile avr32_spi_t *spi);
/*! \brief Tests if the SPI is enabled.
*
* \param spi Base address of the SPI instance.
*
* \return \c 1 if the SPI is enabled, otherwise \c 0.
*/
extern int spi_is_enabled(volatile avr32_spi_t *spi);
/*! \brief Checks if there is no data in the transmit register.
*
* \param spi Base address of the SPI instance.
*
* \return Status.
* \retval 1 No data in TDR.
* \retval 0 Some data in TDR.
*/
extern unsigned char spi_writeRegisterEmptyCheck(volatile avr32_spi_t *spi);
/*! \brief Writes one data word in master fixed peripheral select mode or in
* slave mode.
*
* \param spi Base address of the SPI instance.
* \param data The data word to write.
*
* \return Status.
* \retval SPI_OK Success.
* \retval SPI_ERROR_TIMEOUT Time-out.
*
* \note Will block program execution until time-out occurs if transmitter is
* busy and transmit buffer is full. Invoke
* \ref spi_writeRegisterEmptyCheck beforehand if needed.
*
* \note Once the data has been written to the transmit buffer, the end of
* transmission is not waited for. Invoke \ref spi_writeEndCheck if
* needed.
*/
extern spi_status_t spi_write(volatile avr32_spi_t *spi, unsigned short data);
/*! \brief Selects a slave in master variable peripheral select mode and writes
* one data word to it.
*
* \param spi Base address of the SPI instance.
* \param data The data word to write.
* \param pcs Slave selector (bit 0 -> nCS line 0, bit 1 -> nCS line 1,
* etc.).
* \param lastxfer Boolean indicating whether this is the last data word
* transfer.
*
* \return Status.
* \retval SPI_OK Success.
* \retval SPI_ERROR_TIMEOUT Time-out.
* \retval SPI_ERROR_ARGUMENT Invalid argument(s) passed.
*
* \note Will block program execution until time-out occurs if transmitter is
* busy and transmit buffer is full. Invoke
* \ref spi_writeRegisterEmptyCheck beforehand if needed.
*
* \note Once the data has been written to the transmit buffer, the end of
* transmission is not waited for. Invoke \ref spi_writeEndCheck if
* needed.
*/
extern spi_status_t spi_variableSlaveWrite(volatile avr32_spi_t *spi,
unsigned short data,
unsigned char pcs,
unsigned char lastxfer);
/*! \brief Checks if all transmissions are complete.
*
* \param spi Base address of the SPI instance.
*
* \return Status.
* \retval 1 All transmissions complete.
* \retval 0 Transmissions not complete.
*/
extern unsigned char spi_writeEndCheck(volatile avr32_spi_t *spi);
/*! \brief Checks if there is data in the receive register.
*
* \param spi Base address of the SPI instance.
*
* \return Status.
* \retval 1 Some data in RDR.
* \retval 0 No data in RDR.
*/
extern unsigned char spi_readRegisterFullCheck(volatile avr32_spi_t *spi);
/*! \brief Reads one data word in master mode or in slave mode.
*
* \param spi Base address of the SPI instance.
* \param data Pointer to the location where to store the received data word.
*
* \return Status.
* \retval SPI_OK Success.
* \retval SPI_ERROR_TIMEOUT Time-out.
*
* \note Will block program execution until time-out occurs if no data is
* received or last transmission is not complete. Invoke
* \ref spi_writeEndCheck or \ref spi_readRegisterFullCheck beforehand if
* needed.
*/
extern spi_status_t spi_read(volatile avr32_spi_t *spi, unsigned short *data);
/*! \brief Gets status information from the SPI.
*
* \param spi Base address of the SPI instance.
*
* \return Status.
* \retval SPI_OK Success.
* \retval SPI_ERROR_OVERRUN Overrun error.
* \retval SPI_ERROR_MODE_FAULT Mode fault (SPI addressed as slave
* while in master mode).
* \retval SPI_ERROR_OVERRUN_AND_MODE_FAULT Overrun error and mode fault.
*/
extern unsigned char spi_getStatus(volatile avr32_spi_t *spi);
#endif // _SPI_H_

View File

@ -0,0 +1,314 @@
/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief TC driver for AVR32 UC3.
*
* AVR32 Timer/Counter driver module.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with a TC module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#include <avr32/io.h>
#include "compiler.h"
#include "tc.h"
int tc_get_interrupt_settings(volatile avr32_tc_t *tc, unsigned int channel)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
return tc->channel[channel].imr;
}
int tc_configure_interrupts(volatile avr32_tc_t *tc, unsigned int channel, const tc_interrupt_t *bitfield)
{
Bool global_interrupt_enabled = Is_global_interrupt_enabled();
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
// Enable the appropriate interrupts.
tc->channel[channel].ier = bitfield->etrgs << AVR32_TC_ETRGS_OFFSET |
bitfield->ldrbs << AVR32_TC_LDRBS_OFFSET |
bitfield->ldras << AVR32_TC_LDRAS_OFFSET |
bitfield->cpcs << AVR32_TC_CPCS_OFFSET |
bitfield->cpbs << AVR32_TC_CPBS_OFFSET |
bitfield->cpas << AVR32_TC_CPAS_OFFSET |
bitfield->lovrs << AVR32_TC_LOVRS_OFFSET |
bitfield->covfs << AVR32_TC_COVFS_OFFSET;
// Disable the appropriate interrupts.
if (global_interrupt_enabled) Disable_global_interrupt();
tc->channel[channel].idr = (~bitfield->etrgs & 1) << AVR32_TC_ETRGS_OFFSET |
(~bitfield->ldrbs & 1) << AVR32_TC_LDRBS_OFFSET |
(~bitfield->ldras & 1) << AVR32_TC_LDRAS_OFFSET |
(~bitfield->cpcs & 1) << AVR32_TC_CPCS_OFFSET |
(~bitfield->cpbs & 1) << AVR32_TC_CPBS_OFFSET |
(~bitfield->cpas & 1) << AVR32_TC_CPAS_OFFSET |
(~bitfield->lovrs & 1) << AVR32_TC_LOVRS_OFFSET |
(~bitfield->covfs & 1) << AVR32_TC_COVFS_OFFSET;
tc->channel[channel].sr;
if (global_interrupt_enabled) Enable_global_interrupt();
return 0;
}
int tc_select_external_clock(volatile avr32_tc_t *tc, unsigned int channel, unsigned int ext_clk_sig_src)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS || ext_clk_sig_src >= 1 << AVR32_TC_BMR_TC0XC0S_SIZE)
return TC_INVALID_ARGUMENT;
// Clear bit-field and set the correct behavior.
tc->bmr = (tc->bmr & ~(AVR32_TC_BMR_TC0XC0S_MASK << (channel * AVR32_TC_BMR_TC0XC0S_SIZE))) |
(ext_clk_sig_src << (channel * AVR32_TC_BMR_TC0XC0S_SIZE));
return 0;
}
int tc_init_capture(volatile avr32_tc_t *tc, const tc_capture_opt_t *opt)
{
// Check for valid input.
if (opt->channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
// MEASURE SIGNALS: Capture operating mode.
tc->channel[opt->channel].cmr = opt->ldrb << AVR32_TC_LDRB_OFFSET |
opt->ldra << AVR32_TC_LDRA_OFFSET |
0 << AVR32_TC_WAVE_OFFSET |
opt->cpctrg << AVR32_TC_CPCTRG_OFFSET |
opt->abetrg << AVR32_TC_ABETRG_OFFSET |
opt->etrgedg << AVR32_TC_ETRGEDG_OFFSET|
opt->ldbdis << AVR32_TC_LDBDIS_OFFSET |
opt->ldbstop << AVR32_TC_LDBSTOP_OFFSET |
opt->burst << AVR32_TC_BURST_OFFSET |
opt->clki << AVR32_TC_CLKI_OFFSET |
opt->tcclks << AVR32_TC_TCCLKS_OFFSET;
return 0;
}
int tc_init_waveform(volatile avr32_tc_t *tc, const tc_waveform_opt_t *opt)
{
// Check for valid input.
if (opt->channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
// GENERATE SIGNALS: Waveform operating mode.
tc->channel[opt->channel].cmr = opt->bswtrg << AVR32_TC_BSWTRG_OFFSET |
opt->beevt << AVR32_TC_BEEVT_OFFSET |
opt->bcpc << AVR32_TC_BCPC_OFFSET |
opt->bcpb << AVR32_TC_BCPB_OFFSET |
opt->aswtrg << AVR32_TC_ASWTRG_OFFSET |
opt->aeevt << AVR32_TC_AEEVT_OFFSET |
opt->acpc << AVR32_TC_ACPC_OFFSET |
opt->acpa << AVR32_TC_ACPA_OFFSET |
1 << AVR32_TC_WAVE_OFFSET |
opt->wavsel << AVR32_TC_WAVSEL_OFFSET |
opt->enetrg << AVR32_TC_ENETRG_OFFSET |
opt->eevt << AVR32_TC_EEVT_OFFSET |
opt->eevtedg << AVR32_TC_EEVTEDG_OFFSET |
opt->cpcdis << AVR32_TC_CPCDIS_OFFSET |
opt->cpcstop << AVR32_TC_CPCSTOP_OFFSET |
opt->burst << AVR32_TC_BURST_OFFSET |
opt->clki << AVR32_TC_CLKI_OFFSET |
opt->tcclks << AVR32_TC_TCCLKS_OFFSET;
return 0;
}
int tc_start(volatile avr32_tc_t *tc, unsigned int channel)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
// Enable, reset and start the selected timer/counter channel.
tc->channel[channel].ccr = AVR32_TC_SWTRG_MASK | AVR32_TC_CLKEN_MASK;
return 0;
}
int tc_stop(volatile avr32_tc_t *tc, unsigned int channel)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
// Disable the selected timer/counter channel.
tc->channel[channel].ccr = AVR32_TC_CLKDIS_MASK;
return 0;
}
int tc_software_trigger(volatile avr32_tc_t *tc, unsigned int channel)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
// Reset the selected timer/counter channel.
tc->channel[channel].ccr = AVR32_TC_SWTRG_MASK;
return 0;
}
void tc_sync_trigger(volatile avr32_tc_t *tc)
{
// Reset all channels of the selected timer/counter.
tc->bcr = AVR32_TC_BCR_SYNC_MASK;
}
void tc_sync_start(volatile avr32_tc_t *tc)
{
unsigned int i;
// Enable the clock for each channel.
for(i=0; i<TC_NUMBER_OF_CHANNELS;i++)
tc->channel[i].ccr = AVR32_TC_CLKEN_MASK;
// Reset all channels of the selected timer/counter.
tc->bcr = AVR32_TC_BCR_SYNC_MASK;
}
int tc_read_sr(volatile avr32_tc_t *tc, unsigned int channel)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
return tc->channel[channel].sr;
}
int tc_read_tc(volatile avr32_tc_t *tc, unsigned int channel)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
return Rd_bitfield(tc->channel[channel].cv, AVR32_TC_CV_MASK);
}
int tc_read_ra(volatile avr32_tc_t *tc, unsigned int channel)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
return Rd_bitfield(tc->channel[channel].ra, AVR32_TC_RA_MASK);
}
int tc_read_rb(volatile avr32_tc_t *tc, unsigned int channel)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
return Rd_bitfield(tc->channel[channel].rb, AVR32_TC_RB_MASK);
}
int tc_read_rc(volatile avr32_tc_t *tc, unsigned int channel)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
return Rd_bitfield(tc->channel[channel].rc, AVR32_TC_RC_MASK);
}
int tc_write_ra(volatile avr32_tc_t *tc, unsigned int channel, unsigned short value)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
// This function is only available in WAVEFORM mode.
if (Tst_bits(tc->channel[channel].cmr, AVR32_TC_WAVE_MASK))
Wr_bitfield(tc->channel[channel].ra, AVR32_TC_RA_MASK, value);
return value;
}
int tc_write_rb(volatile avr32_tc_t *tc, unsigned int channel, unsigned short value)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
// This function is only available in WAVEFORM mode.
if (Tst_bits(tc->channel[channel].cmr, AVR32_TC_WAVE_MASK))
Wr_bitfield(tc->channel[channel].rb, AVR32_TC_RB_MASK, value);
return value;
}
int tc_write_rc(volatile avr32_tc_t *tc, unsigned int channel, unsigned short value)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
// This function is only available in WAVEFORM mode.
if (Tst_bits(tc->channel[channel].cmr, AVR32_TC_WAVE_MASK))
Wr_bitfield(tc->channel[channel].rc, AVR32_TC_RC_MASK, value);
return value;
}

View File

@ -0,0 +1,591 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Timer/Counter driver for AVR32 UC3.
*
* AVR32 Timer/Counter driver module.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with a TC module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _TC_H_
#define _TC_H_
#include <avr32/io.h>
//! TC driver functions return value in case of invalid argument(s).
#define TC_INVALID_ARGUMENT (-1)
//! Number of timer/counter channels.
#define TC_NUMBER_OF_CHANNELS (sizeof(((avr32_tc_t *)0)->channel) / sizeof(avr32_tc_channel_t))
/*! \name External Clock Signal 0 Selection
*/
//! @{
#define TC_CH0_EXT_CLK0_SRC_TCLK0 AVR32_TC_TC0XC0S_TCLK0
#define TC_CH0_EXT_CLK0_SRC_NO_CLK AVR32_TC_TC0XC0S_NO_CLK
#define TC_CH0_EXT_CLK0_SRC_TIOA1 AVR32_TC_TC0XC0S_TIOA1
#define TC_CH0_EXT_CLK0_SRC_TIOA2 AVR32_TC_TC0XC0S_TIOA2
//! @}
/*! \name External Clock Signal 1 Selection
*/
//! @{
#define TC_CH1_EXT_CLK1_SRC_TCLK1 AVR32_TC_TC1XC1S_TCLK1
#define TC_CH1_EXT_CLK1_SRC_NO_CLK AVR32_TC_TC1XC1S_NO_CLK
#define TC_CH1_EXT_CLK1_SRC_TIOA0 AVR32_TC_TC1XC1S_TIOA0
#define TC_CH1_EXT_CLK1_SRC_TIOA2 AVR32_TC_TC1XC1S_TIOA2
//! @}
/*! \name External Clock Signal 2 Selection
*/
//! @{
#define TC_CH2_EXT_CLK2_SRC_TCLK2 AVR32_TC_TC2XC2S_TCLK2
#define TC_CH2_EXT_CLK2_SRC_NO_CLK AVR32_TC_TC2XC2S_NO_CLK
#define TC_CH2_EXT_CLK2_SRC_TIOA0 AVR32_TC_TC2XC2S_TIOA0
#define TC_CH2_EXT_CLK2_SRC_TIOA1 AVR32_TC_TC2XC2S_TIOA1
//! @}
/*! \name Event/Trigger Actions on Output
*/
//! @{
#define TC_EVT_EFFECT_NOOP AVR32_TC_NONE
#define TC_EVT_EFFECT_SET AVR32_TC_SET
#define TC_EVT_EFFECT_CLEAR AVR32_TC_CLEAR
#define TC_EVT_EFFECT_TOGGLE AVR32_TC_TOGGLE
//! @}
/*! \name RC Compare Trigger Enable
*/
//! @{
#define TC_NO_TRIGGER_COMPARE_RC 0
#define TC_TRIGGER_COMPARE_RC 1
//! @}
/*! \name Waveform Selection
*/
//! @{
#define TC_WAVEFORM_SEL_UP_MODE AVR32_TC_WAVSEL_UP_NO_AUTO
#define TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER AVR32_TC_WAVSEL_UP_AUTO
#define TC_WAVEFORM_SEL_UPDOWN_MODE AVR32_TC_WAVSEL_UPDOWN_NO_AUTO
#define TC_WAVEFORM_SEL_UPDOWN_MODE_RC_TRIGGER AVR32_TC_WAVSEL_UPDOWN_AUTO
//! @}
/*! \name TIOA or TIOB External Trigger Selection
*/
//! @{
#define TC_EXT_TRIG_SEL_TIOA 1
#define TC_EXT_TRIG_SEL_TIOB 0
//! @}
/*! \name External Event Selection
*/
//! @{
#define TC_EXT_EVENT_SEL_TIOB_INPUT AVR32_TC_EEVT_TIOB_INPUT
#define TC_EXT_EVENT_SEL_XC0_OUTPUT AVR32_TC_EEVT_XC0_OUTPUT
#define TC_EXT_EVENT_SEL_XC1_OUTPUT AVR32_TC_EEVT_XC1_OUTPUT
#define TC_EXT_EVENT_SEL_XC2_OUTPUT AVR32_TC_EEVT_XC2_OUTPUT
//! @}
/*! \name Edge Selection
*/
//! @{
#define TC_SEL_NO_EDGE AVR32_TC_EEVTEDG_NO_EDGE
#define TC_SEL_RISING_EDGE AVR32_TC_EEVTEDG_POS_EDGE
#define TC_SEL_FALLING_EDGE AVR32_TC_EEVTEDG_NEG_EDGE
#define TC_SEL_EACH_EDGE AVR32_TC_EEVTEDG_BOTH_EDGES
//! @}
/*! \name Burst Signal Selection
*/
//! @{
#define TC_BURST_NOT_GATED AVR32_TC_BURST_NOT_GATED
#define TC_BURST_CLK_AND_XC0 AVR32_TC_BURST_CLK_AND_XC0
#define TC_BURST_CLK_AND_XC1 AVR32_TC_BURST_CLK_AND_XC1
#define TC_BURST_CLK_AND_XC2 AVR32_TC_BURST_CLK_AND_XC2
//! @}
/*! \name Clock Invert
*/
//! @{
#define TC_CLOCK_RISING_EDGE 0
#define TC_CLOCK_FALLING_EDGE 1
//! @}
/*! \name Clock Selection
*/
//! @{
#define TC_CLOCK_SOURCE_TC1 AVR32_TC_TCCLKS_TIMER_CLOCK1
#define TC_CLOCK_SOURCE_TC2 AVR32_TC_TCCLKS_TIMER_CLOCK2
#define TC_CLOCK_SOURCE_TC3 AVR32_TC_TCCLKS_TIMER_CLOCK3
#define TC_CLOCK_SOURCE_TC4 AVR32_TC_TCCLKS_TIMER_CLOCK4
#define TC_CLOCK_SOURCE_TC5 AVR32_TC_TCCLKS_TIMER_CLOCK5
#define TC_CLOCK_SOURCE_XC0 AVR32_TC_TCCLKS_XC0
#define TC_CLOCK_SOURCE_XC1 AVR32_TC_TCCLKS_XC1
#define TC_CLOCK_SOURCE_XC2 AVR32_TC_TCCLKS_XC2
//! @}
//! Timer/counter interrupts.
typedef struct
{
unsigned int :24;
//! External trigger interrupt.
unsigned int etrgs : 1;
//! RB load interrupt.
unsigned int ldrbs : 1;
//! RA load interrupt.
unsigned int ldras : 1;
//! RC compare interrupt.
unsigned int cpcs : 1;
//! RB compare interrupt.
unsigned int cpbs : 1;
//! RA compare interrupt.
unsigned int cpas : 1;
//! Load overrun interrupt.
unsigned int lovrs : 1;
//! Counter overflow interrupt.
unsigned int covfs : 1;
} tc_interrupt_t;
//! Parameters when initializing a timer/counter in capture mode.
typedef struct
{
//! Channel to initialize.
unsigned int channel ;
unsigned int :12;
//! RB loading selection:\n
//! - \ref TC_SEL_NO_EDGE;\n
//! - \ref TC_SEL_RISING_EDGE;\n
//! - \ref TC_SEL_FALLING_EDGE;\n
//! - \ref TC_SEL_EACH_EDGE.
unsigned int ldrb : 2;
//! RA loading selection:\n
//! - \ref TC_SEL_NO_EDGE;\n
//! - \ref TC_SEL_RISING_EDGE;\n
//! - \ref TC_SEL_FALLING_EDGE;\n
//! - \ref TC_SEL_EACH_EDGE.
unsigned int ldra : 2;
unsigned int : 1;
//! RC compare trigger enable:\n
//! - \ref TC_NO_TRIGGER_COMPARE_RC;\n
//! - \ref TC_TRIGGER_COMPARE_RC.
unsigned int cpctrg : 1;
unsigned int : 3;
//! TIOA or TIOB external trigger selection:\n
//! - \ref TC_EXT_TRIG_SEL_TIOA;\n
//! - \ref TC_EXT_TRIG_SEL_TIOB.
unsigned int abetrg : 1;
//! External trigger edge selection:\n
//! - \ref TC_SEL_NO_EDGE;\n
//! - \ref TC_SEL_RISING_EDGE;\n
//! - \ref TC_SEL_FALLING_EDGE;\n
//! - \ref TC_SEL_EACH_EDGE.
unsigned int etrgedg : 2;
//! Counter clock disable with RB loading:\n
//! - \c FALSE;\n
//! - \c TRUE.
unsigned int ldbdis : 1;
//! Counter clock stopped with RB loading:\n
//! - \c FALSE;\n
//! - \c TRUE.
unsigned int ldbstop : 1;
//! Burst signal selection:\n
//! - \ref TC_BURST_NOT_GATED;\n
//! - \ref TC_BURST_CLK_AND_XC0;\n
//! - \ref TC_BURST_CLK_AND_XC1;\n
//! - \ref TC_BURST_CLK_AND_XC2.
unsigned int burst : 2;
//! Clock invert:\n
//! - \ref TC_CLOCK_RISING_EDGE;\n
//! - \ref TC_CLOCK_FALLING_EDGE.
unsigned int clki : 1;
//! Clock selection:\n
//! - \ref TC_CLOCK_SOURCE_TC1;\n
//! - \ref TC_CLOCK_SOURCE_TC2;\n
//! - \ref TC_CLOCK_SOURCE_TC3;\n
//! - \ref TC_CLOCK_SOURCE_TC4;\n
//! - \ref TC_CLOCK_SOURCE_TC5;\n
//! - \ref TC_CLOCK_SOURCE_XC0;\n
//! - \ref TC_CLOCK_SOURCE_XC1;\n
//! - \ref TC_CLOCK_SOURCE_XC2.
unsigned int tcclks : 3;
} tc_capture_opt_t;
//! Parameters when initializing a timer/counter in waveform mode.
typedef struct
{
//! Channel to initialize.
unsigned int channel ;
//! Software trigger effect on TIOB:\n
//! - \ref TC_EVT_EFFECT_NOOP;\n
//! - \ref TC_EVT_EFFECT_SET;\n
//! - \ref TC_EVT_EFFECT_CLEAR;\n
//! - \ref TC_EVT_EFFECT_TOGGLE.
unsigned int bswtrg : 2;
//! External event effect on TIOB:\n
//! - \ref TC_EVT_EFFECT_NOOP;\n
//! - \ref TC_EVT_EFFECT_SET;\n
//! - \ref TC_EVT_EFFECT_CLEAR;\n
//! - \ref TC_EVT_EFFECT_TOGGLE.
unsigned int beevt : 2;
//! RC compare effect on TIOB:\n
//! - \ref TC_EVT_EFFECT_NOOP;\n
//! - \ref TC_EVT_EFFECT_SET;\n
//! - \ref TC_EVT_EFFECT_CLEAR;\n
//! - \ref TC_EVT_EFFECT_TOGGLE.
unsigned int bcpc : 2;
//! RB compare effect on TIOB:\n
//! - \ref TC_EVT_EFFECT_NOOP;\n
//! - \ref TC_EVT_EFFECT_SET;\n
//! - \ref TC_EVT_EFFECT_CLEAR;\n
//! - \ref TC_EVT_EFFECT_TOGGLE.
unsigned int bcpb : 2;
//! Software trigger effect on TIOA:\n
//! - \ref TC_EVT_EFFECT_NOOP;\n
//! - \ref TC_EVT_EFFECT_SET;\n
//! - \ref TC_EVT_EFFECT_CLEAR;\n
//! - \ref TC_EVT_EFFECT_TOGGLE.
unsigned int aswtrg : 2;
//! External event effect on TIOA:\n
//! - \ref TC_EVT_EFFECT_NOOP;\n
//! - \ref TC_EVT_EFFECT_SET;\n
//! - \ref TC_EVT_EFFECT_CLEAR;\n
//! - \ref TC_EVT_EFFECT_TOGGLE.
unsigned int aeevt : 2;
//! RC compare effect on TIOA:\n
//! - \ref TC_EVT_EFFECT_NOOP;\n
//! - \ref TC_EVT_EFFECT_SET;\n
//! - \ref TC_EVT_EFFECT_CLEAR;\n
//! - \ref TC_EVT_EFFECT_TOGGLE.
unsigned int acpc : 2;
//! RA compare effect on TIOA:\n
//! - \ref TC_EVT_EFFECT_NOOP;\n
//! - \ref TC_EVT_EFFECT_SET;\n
//! - \ref TC_EVT_EFFECT_CLEAR;\n
//! - \ref TC_EVT_EFFECT_TOGGLE.
unsigned int acpa : 2;
unsigned int : 1;
//! Waveform selection:\n
//! - \ref TC_WAVEFORM_SEL_UP_MODE;\n
//! - \ref TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER;\n
//! - \ref TC_WAVEFORM_SEL_UPDOWN_MODE;\n
//! - \ref TC_WAVEFORM_SEL_UPDOWN_MODE_RC_TRIGGER.
unsigned int wavsel : 2;
//! External event trigger enable:\n
//! - \c FALSE;\n
//! - \c TRUE.
unsigned int enetrg : 1;
//! External event selection:\n
//! - \ref TC_EXT_EVENT_SEL_TIOB_INPUT;\n
//! - \ref TC_EXT_EVENT_SEL_XC0_OUTPUT;\n
//! - \ref TC_EXT_EVENT_SEL_XC1_OUTPUT;\n
//! - \ref TC_EXT_EVENT_SEL_XC2_OUTPUT.
unsigned int eevt : 2;
//! External event edge selection:\n
//! - \ref TC_SEL_NO_EDGE;\n
//! - \ref TC_SEL_RISING_EDGE;\n
//! - \ref TC_SEL_FALLING_EDGE;\n
//! - \ref TC_SEL_EACH_EDGE.
unsigned int eevtedg : 2;
//! Counter clock disable with RC compare:\n
//! - \c FALSE;\n
//! - \c TRUE.
unsigned int cpcdis : 1;
//! Counter clock stopped with RC compare:\n
//! - \c FALSE;\n
//! - \c TRUE.
unsigned int cpcstop : 1;
//! Burst signal selection:\n
//! - \ref TC_BURST_NOT_GATED;\n
//! - \ref TC_BURST_CLK_AND_XC0;\n
//! - \ref TC_BURST_CLK_AND_XC1;\n
//! - \ref TC_BURST_CLK_AND_XC2.
unsigned int burst : 2;
//! Clock invert:\n
//! - \ref TC_CLOCK_RISING_EDGE;\n
//! - \ref TC_CLOCK_FALLING_EDGE.
unsigned int clki : 1;
//! Clock selection:\n
//! - \ref TC_CLOCK_SOURCE_TC1;\n
//! - \ref TC_CLOCK_SOURCE_TC2;\n
//! - \ref TC_CLOCK_SOURCE_TC3;\n
//! - \ref TC_CLOCK_SOURCE_TC4;\n
//! - \ref TC_CLOCK_SOURCE_TC5;\n
//! - \ref TC_CLOCK_SOURCE_XC0;\n
//! - \ref TC_CLOCK_SOURCE_XC1;\n
//! - \ref TC_CLOCK_SOURCE_XC2.
unsigned int tcclks : 3;
} tc_waveform_opt_t;
/*! \brief Reads timer/counter interrupt settings.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
*
* \retval >=0 The interrupt enable configuration organized according to \ref tc_interrupt_t.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_get_interrupt_settings(volatile avr32_tc_t *tc, unsigned int channel);
/*! \brief Enables various timer/counter interrupts.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
* \param bitfield The interrupt enable configuration.
*
* \retval 0 Success.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_configure_interrupts(volatile avr32_tc_t *tc, unsigned int channel, const tc_interrupt_t *bitfield);
/*! \brief Selects which external clock to use and how to configure it.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
* \param ext_clk_sig_src External clock signal selection:
* \arg \c TC_CH0_EXT_CLK0_SRC_TCLK0;
* \arg \c TC_CH0_EXT_CLK0_SRC_NO_CLK;
* \arg \c TC_CH0_EXT_CLK0_SRC_TIOA1;
* \arg \c TC_CH0_EXT_CLK0_SRC_TIOA2;
* \arg \c TC_CH1_EXT_CLK1_SRC_TCLK1;
* \arg \c TC_CH1_EXT_CLK1_SRC_NO_CLK;
* \arg \c TC_CH1_EXT_CLK1_SRC_TIOA0;
* \arg \c TC_CH1_EXT_CLK1_SRC_TIOA2;
* \arg \c TC_CH2_EXT_CLK2_SRC_TCLK2;
* \arg \c TC_CH2_EXT_CLK2_SRC_NO_CLK;
* \arg \c TC_CH2_EXT_CLK2_SRC_TIOA0;
* \arg \c TC_CH2_EXT_CLK2_SRC_TIOA1.
*
* \retval 0 Success.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_select_external_clock(volatile avr32_tc_t *tc, unsigned int channel, unsigned int ext_clk_sig_src);
/*! \brief Sets options for timer/counter capture initialization.
*
* \param tc Pointer to the TC instance to access.
* \param opt Options for capture mode.
*
* \retval 0 Success.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_init_capture(volatile avr32_tc_t *tc, const tc_capture_opt_t *opt);
/*! \brief Sets options for timer/counter waveform initialization.
*
* \param tc Pointer to the TC instance to access.
* \param opt Options for waveform generation.
*
* \retval 0 Success.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_init_waveform(volatile avr32_tc_t *tc, const tc_waveform_opt_t *opt);
/*! \brief Starts a timer/counter.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
*
* \retval 0 Success.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_start(volatile avr32_tc_t *tc, unsigned int channel);
/*! \brief Stops a timer/counter.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
*
* \retval 0 Success.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_stop(volatile avr32_tc_t *tc, unsigned int channel);
/*! \brief Performs a software trigger: the counter is reset and the clock is started.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
*
* \retval 0 Success.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_software_trigger(volatile avr32_tc_t *tc, unsigned int channel);
/*! \brief Asserts a SYNC signal to generate a software trigger and reset all channels.
*
* \param tc Pointer to the TC instance to access.
*/
extern void tc_sync_trigger(volatile avr32_tc_t *tc);
/*! \brief Start all TC channels simultaneously.
*
* \param tc Pointer to the TC instance to access.
*/
extern void tc_sync_start(volatile avr32_tc_t *tc);
/*! \brief Reads the status register.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
*
* \retval >=0 Status register value.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_read_sr(volatile avr32_tc_t *tc, unsigned int channel);
/*! \brief Reads the channel's TC counter and returns the value.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
*
* \retval >=0 TC counter value.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_read_tc(volatile avr32_tc_t *tc, unsigned int channel);
/*! \brief Reads the channel's RA register and returns the value.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
*
* \retval >=0 RA register value.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_read_ra(volatile avr32_tc_t *tc, unsigned int channel);
/*! \brief Reads the channel's RB register and returns the value.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
*
* \retval >=0 RB register value.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_read_rb(volatile avr32_tc_t *tc, unsigned int channel);
/*! \brief Reads the channel's RC register and returns the value.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
*
* \retval >=0 RC register value.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_read_rc(volatile avr32_tc_t *tc, unsigned int channel);
/*! \brief Writes a value to the channel's RA register.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
* \param value Value to write to the RA register.
*
* \retval >=0 Written value.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_write_ra(volatile avr32_tc_t *tc, unsigned int channel, unsigned short value);
/*! \brief Writes a value to the channel's RB register.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
* \param value Value to write to the RB register.
*
* \retval >=0 Written value.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_write_rb(volatile avr32_tc_t *tc, unsigned int channel, unsigned short value);
/*! \brief Writes a value to the channel's RC register.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
* \param value Value to write to the RC register.
*
* \retval >=0 Written value.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_write_rc(volatile avr32_tc_t *tc, unsigned int channel, unsigned short value);
#endif // _TC_H_

View File

@ -0,0 +1,914 @@
/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief USART driver for AVR32 UC3.
*
* This file contains basic functions for the AVR32 USART, with support for all
* modes, settings and clock speeds.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with a USART module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#include "compiler.h"
#include "usart.h"
//------------------------------------------------------------------------------
/*! \name Private Functions
*/
//! @{
/*! \brief Checks if the USART is in multidrop mode.
*
* \param usart Base address of the USART instance.
*
* \return \c 1 if the USART is in multidrop mode, otherwise \c 0.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
static __inline__ int usart_mode_is_multidrop(volatile avr32_usart_t *usart)
{
return ((usart->mr >> AVR32_USART_MR_PAR_OFFSET) & AVR32_USART_MR_PAR_MULTI) == AVR32_USART_MR_PAR_MULTI;
}
/*! \brief Calculates a clock divider (\e CD) and a fractional part (\e FP) for
* the USART asynchronous modes to generate a baud rate as close as
* possible to the baud rate set point.
*
* Baud rate calculation:
* \f$ Baudrate = \frac{SelectedClock}{Over \times (CD + \frac{FP}{8})} \f$, \e Over being 16 or 8.
* The maximal oversampling is selected if it allows to generate a baud rate close to the set point.
*
* \param usart Base address of the USART instance.
* \param baudrate Baud rate set point.
* \param pba_hz USART module input clock frequency (PBA clock, Hz).
*
* \retval USART_SUCCESS Baud rate successfully initialized.
* \retval USART_INVALID_INPUT Baud rate set point is out of range for the given input clock frequency.
*/
static int usart_set_async_baudrate(volatile avr32_usart_t *usart, unsigned int baudrate, unsigned long pba_hz)
{
unsigned int over = (pba_hz >= 16 * baudrate) ? 16 : 8;
unsigned int cd_fp = ((1 << AVR32_USART_BRGR_FP_SIZE) * pba_hz + (over * baudrate) / 2) / (over * baudrate);
unsigned int cd = cd_fp >> AVR32_USART_BRGR_FP_SIZE;
unsigned int fp = cd_fp & ((1 << AVR32_USART_BRGR_FP_SIZE) - 1);
if (cd < 1 || cd > (1 << AVR32_USART_BRGR_CD_SIZE) - 1)
return USART_INVALID_INPUT;
usart->mr = (usart->mr & ~(AVR32_USART_MR_USCLKS_MASK |
AVR32_USART_MR_SYNC_MASK |
AVR32_USART_MR_OVER_MASK)) |
AVR32_USART_MR_USCLKS_MCK << AVR32_USART_MR_USCLKS_OFFSET |
((over == 16) ? AVR32_USART_MR_OVER_X16 : AVR32_USART_MR_OVER_X8) << AVR32_USART_MR_OVER_OFFSET;
usart->brgr = cd << AVR32_USART_BRGR_CD_OFFSET |
fp << AVR32_USART_BRGR_FP_OFFSET;
return USART_SUCCESS;
}
/*! \brief Calculates a clock divider (\e CD) for the USART synchronous master
* modes to generate a baud rate as close as possible to the baud rate
* set point.
*
* Baud rate calculation:
* \f$ Baudrate = \frac{SelectedClock}{CD} \f$.
*
* \param usart Base address of the USART instance.
* \param baudrate Baud rate set point.
* \param pba_hz USART module input clock frequency (PBA clock, Hz).
*
* \retval USART_SUCCESS Baud rate successfully initialized.
* \retval USART_INVALID_INPUT Baud rate set point is out of range for the given input clock frequency.
*/
static int usart_set_sync_master_baudrate(volatile avr32_usart_t *usart, unsigned int baudrate, unsigned long pba_hz)
{
unsigned int cd = (pba_hz + baudrate / 2) / baudrate;
if (cd < 1 || cd > (1 << AVR32_USART_BRGR_CD_SIZE) - 1)
return USART_INVALID_INPUT;
usart->mr = (usart->mr & ~AVR32_USART_MR_USCLKS_MASK) |
AVR32_USART_MR_USCLKS_MCK << AVR32_USART_MR_USCLKS_OFFSET |
AVR32_USART_MR_SYNC_MASK;
usart->brgr = cd << AVR32_USART_BRGR_CD_OFFSET;
return USART_SUCCESS;
}
/*! \brief Selects the SCK pin as the source of baud rate for the USART
* synchronous slave modes.
*
* \param usart Base address of the USART instance.
*
* \retval USART_SUCCESS Baud rate successfully initialized.
*/
static int usart_set_sync_slave_baudrate(volatile avr32_usart_t *usart)
{
usart->mr = (usart->mr & ~AVR32_USART_MR_USCLKS_MASK) |
AVR32_USART_MR_USCLKS_SCK << AVR32_USART_MR_USCLKS_OFFSET |
AVR32_USART_MR_SYNC_MASK;
return USART_SUCCESS;
}
/*! \brief Calculates a clock divider (\e CD) for the USART ISO7816 mode to
* generate an ISO7816 clock as close as possible to the clock set point.
*
* ISO7816 clock calculation:
* \f$ Clock = \frac{SelectedClock}{CD} \f$.
*
* \param usart Base address of the USART instance.
* \param clock ISO7816 clock set point.
* \param pba_hz USART module input clock frequency (PBA clock, Hz).
*
* \retval USART_SUCCESS ISO7816 clock successfully initialized.
* \retval USART_INVALID_INPUT ISO7816 clock set point is out of range for the given input clock frequency.
*/
static int usart_set_iso7816_clock(volatile avr32_usart_t *usart, unsigned int clock, unsigned long pba_hz)
{
unsigned int cd = (pba_hz + clock / 2) / clock;
if (cd < 1 || cd > (1 << AVR32_USART_BRGR_CD_SIZE) - 1)
return USART_INVALID_INPUT;
usart->mr = (usart->mr & ~(AVR32_USART_MR_USCLKS_MASK |
AVR32_USART_MR_SYNC_MASK |
AVR32_USART_MR_OVER_MASK)) |
AVR32_USART_MR_USCLKS_MCK << AVR32_USART_MR_USCLKS_OFFSET |
AVR32_USART_MR_OVER_X16 << AVR32_USART_MR_OVER_OFFSET;
usart->brgr = cd << AVR32_USART_BRGR_CD_OFFSET;
return USART_SUCCESS;
}
#if defined(AVR32_USART_400_H_INCLUDED) || \
defined(AVR32_USART_410_H_INCLUDED) || \
defined(AVR32_USART_420_H_INCLUDED) || \
defined(AVR32_USART_440_H_INCLUDED) || \
defined(AVR32_USART_602_H_INCLUDED)
/*! \brief Calculates a clock divider (\e CD) for the USART SPI master mode to
* generate a baud rate as close as possible to the baud rate set point.
*
* Baud rate calculation:
* \f$ Baudrate = \frac{SelectedClock}{CD} \f$.
*
* \param usart Base address of the USART instance.
* \param baudrate Baud rate set point.
* \param pba_hz USART module input clock frequency (PBA clock, Hz).
*
* \retval USART_SUCCESS Baud rate successfully initialized.
* \retval USART_INVALID_INPUT Baud rate set point is out of range for the given input clock frequency.
*/
static int usart_set_spi_master_baudrate(volatile avr32_usart_t *usart, unsigned int baudrate, unsigned long pba_hz)
{
unsigned int cd = (pba_hz + baudrate / 2) / baudrate;
if (cd < 4 || cd > (1 << AVR32_USART_BRGR_CD_SIZE) - 1)
return USART_INVALID_INPUT;
usart->mr = (usart->mr & ~AVR32_USART_MR_USCLKS_MASK) |
AVR32_USART_MR_USCLKS_MCK << AVR32_USART_MR_USCLKS_OFFSET;
usart->brgr = cd << AVR32_USART_BRGR_CD_OFFSET;
return USART_SUCCESS;
}
/*! \brief Selects the SCK pin as the source of baud rate for the USART SPI
* slave mode.
*
* \param usart Base address of the USART instance.
*
* \retval USART_SUCCESS Baud rate successfully initialized.
*/
static int usart_set_spi_slave_baudrate(volatile avr32_usart_t *usart)
{
usart->mr = (usart->mr & ~AVR32_USART_MR_USCLKS_MASK) |
AVR32_USART_MR_USCLKS_SCK << AVR32_USART_MR_USCLKS_OFFSET;
return USART_SUCCESS;
}
#endif // USART rev. >= 4.0.0
//! @}
//------------------------------------------------------------------------------
/*! \name Initialization Functions
*/
//! @{
void usart_reset(volatile avr32_usart_t *usart)
{
Bool global_interrupt_enabled = Is_global_interrupt_enabled();
// Disable all USART interrupts.
// Interrupts needed should be set explicitly on every reset.
if (global_interrupt_enabled) Disable_global_interrupt();
usart->idr = 0xFFFFFFFF;
usart->csr;
if (global_interrupt_enabled) Enable_global_interrupt();
// Reset mode and other registers that could cause unpredictable behavior after reset.
usart->mr = 0;
usart->rtor = 0;
usart->ttgr = 0;
// Shutdown TX and RX (will be re-enabled when setup has successfully completed),
// reset status bits and turn off DTR and RTS.
usart->cr = AVR32_USART_CR_RSTRX_MASK |
AVR32_USART_CR_RSTTX_MASK |
AVR32_USART_CR_RSTSTA_MASK |
AVR32_USART_CR_RSTIT_MASK |
AVR32_USART_CR_RSTNACK_MASK |
#ifndef AVR32_USART_440_H_INCLUDED
// Note: Modem Signal Management DTR-DSR-DCD-RI are not included in USART rev.440.
AVR32_USART_CR_DTRDIS_MASK |
#endif
AVR32_USART_CR_RTSDIS_MASK;
}
int usart_init_rs232(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
{
// Reset the USART and shutdown TX and RX.
usart_reset(usart);
// Check input values.
if (!opt || // Null pointer.
opt->charlength < 5 || opt->charlength > 9 ||
opt->paritytype > 7 ||
opt->stopbits > 2 + 255 ||
opt->channelmode > 3 ||
usart_set_async_baudrate(usart, opt->baudrate, pba_hz) == USART_INVALID_INPUT)
return USART_INVALID_INPUT;
if (opt->charlength == 9)
{
// Character length set to 9 bits. MODE9 dominates CHRL.
usart->mr |= AVR32_USART_MR_MODE9_MASK;
}
else
{
// CHRL gives the character length (- 5) when MODE9 = 0.
usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
}
usart->mr |= opt->paritytype << AVR32_USART_MR_PAR_OFFSET |
opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET;
if (opt->stopbits > USART_2_STOPBITS)
{
// Set two stop bits
usart->mr |= AVR32_USART_MR_NBSTOP_2 << AVR32_USART_MR_NBSTOP_OFFSET;
// and a timeguard period gives the rest.
usart->ttgr = opt->stopbits - USART_2_STOPBITS;
}
else
// Insert 1, 1.5 or 2 stop bits.
usart->mr |= opt->stopbits << AVR32_USART_MR_NBSTOP_OFFSET;
// Set normal mode.
usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
AVR32_USART_MR_MODE_NORMAL << AVR32_USART_MR_MODE_OFFSET;
// Setup complete; enable communication.
// Enable input and output.
usart->cr = AVR32_USART_CR_RXEN_MASK |
AVR32_USART_CR_TXEN_MASK;
return USART_SUCCESS;
}
int usart_init_rs232_tx_only(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
{
// Reset the USART and shutdown TX and RX.
usart_reset(usart);
// Check input values.
if (!opt || // Null pointer.
opt->charlength < 5 || opt->charlength > 9 ||
opt->paritytype > 7 ||
opt->stopbits == 1 || opt->stopbits > 2 + 255 ||
opt->channelmode > 3 ||
usart_set_sync_master_baudrate(usart, opt->baudrate, pba_hz) == USART_INVALID_INPUT)
return USART_INVALID_INPUT;
if (opt->charlength == 9)
{
// Character length set to 9 bits. MODE9 dominates CHRL.
usart->mr |= AVR32_USART_MR_MODE9_MASK;
}
else
{
// CHRL gives the character length (- 5) when MODE9 = 0.
usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
}
usart->mr |= opt->paritytype << AVR32_USART_MR_PAR_OFFSET |
opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET;
if (opt->stopbits > USART_2_STOPBITS)
{
// Set two stop bits
usart->mr |= AVR32_USART_MR_NBSTOP_2 << AVR32_USART_MR_NBSTOP_OFFSET;
// and a timeguard period gives the rest.
usart->ttgr = opt->stopbits - USART_2_STOPBITS;
}
else
// Insert 1 or 2 stop bits.
usart->mr |= opt->stopbits << AVR32_USART_MR_NBSTOP_OFFSET;
// Set normal mode.
usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
AVR32_USART_MR_MODE_NORMAL << AVR32_USART_MR_MODE_OFFSET;
// Setup complete; enable communication.
// Enable only output as input is not possible in synchronous mode without
// transferring clock.
usart->cr = AVR32_USART_CR_TXEN_MASK;
return USART_SUCCESS;
}
int usart_init_hw_handshaking(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
{
// First: Setup standard RS232.
if (usart_init_rs232(usart, opt, pba_hz) == USART_INVALID_INPUT)
return USART_INVALID_INPUT;
// Set hardware handshaking mode.
usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
AVR32_USART_MR_MODE_HARDWARE << AVR32_USART_MR_MODE_OFFSET;
return USART_SUCCESS;
}
int usart_init_modem(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
{
// First: Setup standard RS232.
if (usart_init_rs232(usart, opt, pba_hz) == USART_INVALID_INPUT)
return USART_INVALID_INPUT;
// Set modem mode.
usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
AVR32_USART_MR_MODE_MODEM << AVR32_USART_MR_MODE_OFFSET;
return USART_SUCCESS;
}
int usart_init_sync_master(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
{
// Reset the USART and shutdown TX and RX.
usart_reset(usart);
// Check input values.
if (!opt || // Null pointer.
opt->charlength < 5 || opt->charlength > 9 ||
opt->paritytype > 7 ||
opt->stopbits == 1 || opt->stopbits > 2 + 255 ||
opt->channelmode > 3 ||
usart_set_sync_master_baudrate(usart, opt->baudrate, pba_hz) == USART_INVALID_INPUT)
return USART_INVALID_INPUT;
if (opt->charlength == 9)
{
// Character length set to 9 bits. MODE9 dominates CHRL.
usart->mr |= AVR32_USART_MR_MODE9_MASK;
}
else
{
// CHRL gives the character length (- 5) when MODE9 = 0.
usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
}
usart->mr |= opt->paritytype << AVR32_USART_MR_PAR_OFFSET |
opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET;
if (opt->stopbits > USART_2_STOPBITS)
{
// Set two stop bits
usart->mr |= AVR32_USART_MR_NBSTOP_2 << AVR32_USART_MR_NBSTOP_OFFSET;
// and a timeguard period gives the rest.
usart->ttgr = opt->stopbits - USART_2_STOPBITS;
}
else
// Insert 1 or 2 stop bits.
usart->mr |= opt->stopbits << AVR32_USART_MR_NBSTOP_OFFSET;
// Set normal mode.
usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
AVR32_USART_MR_MODE_NORMAL << AVR32_USART_MR_MODE_OFFSET |
AVR32_USART_MR_CLKO_MASK;
// Setup complete; enable communication.
// Enable input and output.
usart->cr = AVR32_USART_CR_RXEN_MASK |
AVR32_USART_CR_TXEN_MASK;
return USART_SUCCESS;
}
int usart_init_sync_slave(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
{
// Reset the USART and shutdown TX and RX.
usart_reset(usart);
// Check input values.
if (!opt || // Null pointer.
opt->charlength < 5 || opt->charlength > 9 ||
opt->paritytype > 7 ||
opt->stopbits == 1 || opt->stopbits > 2 + 255 ||
opt->channelmode > 3 ||
usart_set_sync_slave_baudrate(usart) == USART_INVALID_INPUT)
return USART_INVALID_INPUT;
if (opt->charlength == 9)
{
// Character length set to 9 bits. MODE9 dominates CHRL.
usart->mr |= AVR32_USART_MR_MODE9_MASK;
}
else
{
// CHRL gives the character length (- 5) when MODE9 = 0.
usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
}
usart->mr |= opt->paritytype << AVR32_USART_MR_PAR_OFFSET |
opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET;
if (opt->stopbits > USART_2_STOPBITS)
{
// Set two stop bits
usart->mr |= AVR32_USART_MR_NBSTOP_2 << AVR32_USART_MR_NBSTOP_OFFSET;
// and a timeguard period gives the rest.
usart->ttgr = opt->stopbits - USART_2_STOPBITS;
}
else
// Insert 1 or 2 stop bits.
usart->mr |= opt->stopbits << AVR32_USART_MR_NBSTOP_OFFSET;
// Set normal mode.
usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
AVR32_USART_MR_MODE_NORMAL << AVR32_USART_MR_MODE_OFFSET;
// Setup complete; enable communication.
// Enable input and output.
usart->cr = AVR32_USART_CR_RXEN_MASK |
AVR32_USART_CR_TXEN_MASK;
return USART_SUCCESS;
}
int usart_init_rs485(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
{
// First: Setup standard RS232.
if (usart_init_rs232(usart, opt, pba_hz) == USART_INVALID_INPUT)
return USART_INVALID_INPUT;
// Set RS485 mode.
usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
AVR32_USART_MR_MODE_RS485 << AVR32_USART_MR_MODE_OFFSET;
return USART_SUCCESS;
}
int usart_init_IrDA(volatile avr32_usart_t *usart, const usart_options_t *opt,
long pba_hz, unsigned char irda_filter)
{
// First: Setup standard RS232.
if (usart_init_rs232(usart, opt, pba_hz) == USART_INVALID_INPUT)
return USART_INVALID_INPUT;
// Set IrDA filter.
usart->ifr = irda_filter;
// Set IrDA mode and activate filtering of input.
usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
AVR32_USART_MODE_IRDA << AVR32_USART_MR_MODE_OFFSET |
AVR32_USART_MR_FILTER_MASK;
return USART_SUCCESS;
}
int usart_init_iso7816(volatile avr32_usart_t *usart, const usart_iso7816_options_t *opt, int t, long pba_hz)
{
// Reset the USART and shutdown TX and RX.
usart_reset(usart);
// Check input values.
if (!opt || // Null pointer.
opt->paritytype > 1)
return USART_INVALID_INPUT;
if (t == 0)
{
// Set USART mode to ISO7816, T=0.
// The T=0 protocol always uses 2 stop bits.
usart->mr = AVR32_USART_MR_MODE_ISO7816_T0 << AVR32_USART_MR_MODE_OFFSET |
AVR32_USART_MR_NBSTOP_2 << AVR32_USART_MR_NBSTOP_OFFSET |
opt->bit_order << AVR32_USART_MR_MSBF_OFFSET; // Allow MSBF in T=0.
}
else if (t == 1)
{
// Only LSB first in the T=1 protocol.
// max_iterations field is only used in T=0 mode.
if (opt->bit_order != 0 ||
opt->max_iterations != 0)
return USART_INVALID_INPUT;
// Set USART mode to ISO7816, T=1.
// The T=1 protocol always uses 1 stop bit.
usart->mr = AVR32_USART_MR_MODE_ISO7816_T1 << AVR32_USART_MR_MODE_OFFSET |
AVR32_USART_MR_NBSTOP_1 << AVR32_USART_MR_NBSTOP_OFFSET;
}
else
return USART_INVALID_INPUT;
if (usart_set_iso7816_clock(usart, opt->iso7816_hz, pba_hz) == USART_INVALID_INPUT)
return USART_INVALID_INPUT;
// Set FIDI register: bit rate = selected clock/FI_DI_ratio/16.
usart->fidi = opt->fidi_ratio;
// Set ISO7816 spesific options in the MODE register.
usart->mr |= opt->paritytype << AVR32_USART_MR_PAR_OFFSET |
AVR32_USART_MR_CLKO_MASK | // Enable clock output.
opt->inhibit_nack << AVR32_USART_MR_INACK_OFFSET |
opt->dis_suc_nack << AVR32_USART_MR_DSNACK_OFFSET |
opt->max_iterations << AVR32_USART_MR_MAX_ITERATION_OFFSET;
// Setup complete; enable the receiver by default.
usart_iso7816_enable_receiver(usart);
return USART_SUCCESS;
}
#if defined(AVR32_USART_400_H_INCLUDED) || \
defined(AVR32_USART_410_H_INCLUDED) || \
defined(AVR32_USART_420_H_INCLUDED) || \
defined(AVR32_USART_440_H_INCLUDED) || \
defined(AVR32_USART_602_H_INCLUDED)
int usart_init_lin_master(volatile avr32_usart_t *usart, unsigned long baudrate, long pba_hz)
{
// Reset the USART and shutdown TX and RX.
usart_reset(usart);
// Check input values.
if (usart_set_async_baudrate(usart, baudrate, pba_hz) == USART_INVALID_INPUT)
return USART_INVALID_INPUT;
usart->mr |= AVR32_USART_MR_MODE_LIN_MASTER << AVR32_USART_MR_MODE_OFFSET; // LIN master mode.
// Setup complete; enable communication.
// Enable input and output.
usart->cr = AVR32_USART_CR_RXEN_MASK |
AVR32_USART_CR_TXEN_MASK;
return USART_SUCCESS;
}
int usart_init_lin_slave(volatile avr32_usart_t *usart, unsigned long baudrate, long pba_hz)
{
// Reset the USART and shutdown TX and RX.
usart_reset(usart);
// Check input values.
if (usart_set_async_baudrate(usart, baudrate, pba_hz) == USART_INVALID_INPUT)
return USART_INVALID_INPUT;
usart->mr |= AVR32_USART_MR_MODE_LIN_SLAVE << AVR32_USART_MR_MODE_OFFSET; // LIN slave mode.
// Setup complete; enable communication.
// Enable input and output.
usart->cr = AVR32_USART_CR_RXEN_MASK |
AVR32_USART_CR_TXEN_MASK;
return USART_SUCCESS;
}
int usart_init_spi_master(volatile avr32_usart_t *usart, const usart_spi_options_t *opt, long pba_hz)
{
// Reset the USART and shutdown TX and RX.
usart_reset(usart);
// Check input values.
if (!opt || // Null pointer.
opt->charlength < 5 || opt->charlength > 9 ||
opt->spimode > 3 ||
opt->channelmode > 3 ||
usart_set_spi_master_baudrate(usart, opt->baudrate, pba_hz) == USART_INVALID_INPUT)
return USART_INVALID_INPUT;
if (opt->charlength == 9)
{
// Character length set to 9 bits. MODE9 dominates CHRL.
usart->mr |= AVR32_USART_MR_MODE9_MASK;
}
else
{
// CHRL gives the character length (- 5) when MODE9 = 0.
usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
}
usart->mr |= AVR32_USART_MR_MODE_SPI_MASTER << AVR32_USART_MR_MODE_OFFSET | // SPI master mode.
((opt->spimode & 0x1) ^ 0x1) << AVR32_USART_MR_SYNC_OFFSET | // SPI clock phase.
opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET | // Channel mode.
(opt->spimode >> 1) << AVR32_USART_MR_MSBF_OFFSET | // SPI clock polarity.
AVR32_USART_MR_CLKO_MASK; // Drive SCK pin.
// Setup complete; enable communication.
// Enable input and output.
usart->cr = AVR32_USART_CR_RXEN_MASK |
AVR32_USART_CR_TXEN_MASK;
return USART_SUCCESS;
}
int usart_init_spi_slave(volatile avr32_usart_t *usart, const usart_spi_options_t *opt, long pba_hz)
{
// Reset the USART and shutdown TX and RX.
usart_reset(usart);
// Check input values.
if (!opt || // Null pointer.
opt->charlength < 5 || opt->charlength > 9 ||
opt->spimode > 3 ||
opt->channelmode > 3 ||
usart_set_spi_slave_baudrate(usart) == USART_INVALID_INPUT)
return USART_INVALID_INPUT;
if (opt->charlength == 9)
{
// Character length set to 9 bits. MODE9 dominates CHRL.
usart->mr |= AVR32_USART_MR_MODE9_MASK;
}
else
{
// CHRL gives the character length (- 5) when MODE9 = 0.
usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
}
usart->mr |= AVR32_USART_MR_MODE_SPI_SLAVE << AVR32_USART_MR_MODE_OFFSET | // SPI slave mode.
((opt->spimode & 0x1) ^ 0x1) << AVR32_USART_MR_SYNC_OFFSET | // SPI clock phase.
opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET | // Channel mode.
(opt->spimode >> 1) << AVR32_USART_MR_MSBF_OFFSET; // SPI clock polarity.
// Setup complete; enable communication.
// Enable input and output.
usart->cr = AVR32_USART_CR_RXEN_MASK |
AVR32_USART_CR_TXEN_MASK;
return USART_SUCCESS;
}
#endif // USART rev. >= 4.0.0
//! @}
//------------------------------------------------------------------------------
#if defined(AVR32_USART_400_H_INCLUDED) || \
defined(AVR32_USART_410_H_INCLUDED) || \
defined(AVR32_USART_420_H_INCLUDED) || \
defined(AVR32_USART_440_H_INCLUDED) || \
defined(AVR32_USART_602_H_INCLUDED)
/*! \name SPI Control Functions
*/
//! @{
int usart_spi_selectChip(volatile avr32_usart_t *usart)
{
// Force the SPI chip select.
usart->cr = AVR32_USART_CR_RTSEN_MASK;
return USART_SUCCESS;
}
int usart_spi_unselectChip(volatile avr32_usart_t *usart)
{
int timeout = USART_DEFAULT_TIMEOUT;
do
{
if (!timeout--) return USART_FAILURE;
} while (!usart_tx_empty(usart));
// Release the SPI chip select.
usart->cr = AVR32_USART_CR_RTSDIS_MASK;
return USART_SUCCESS;
}
//! @}
#endif // USART rev. >= 4.0.0
//------------------------------------------------------------------------------
/*! \name Transmit/Receive Functions
*/
//! @{
int usart_send_address(volatile avr32_usart_t *usart, int address)
{
// Check if USART is in multidrop / RS485 mode.
if (!usart_mode_is_multidrop(usart)) return USART_MODE_FAULT;
// Prepare to send an address.
usart->cr = AVR32_USART_CR_SENDA_MASK;
// Write the address to TX.
usart_bw_write_char(usart, address);
return USART_SUCCESS;
}
int usart_write_char(volatile avr32_usart_t *usart, int c)
{
if (usart_tx_ready(usart))
{
usart->thr = (c << AVR32_USART_THR_TXCHR_OFFSET) & AVR32_USART_THR_TXCHR_MASK;
return USART_SUCCESS;
}
else
return USART_TX_BUSY;
}
int usart_putchar(volatile avr32_usart_t *usart, int c)
{
int timeout = USART_DEFAULT_TIMEOUT;
if (c == '\n')
{
do
{
if (!timeout--) return USART_FAILURE;
} while (usart_write_char(usart, '\r') != USART_SUCCESS);
timeout = USART_DEFAULT_TIMEOUT;
}
do
{
if (!timeout--) return USART_FAILURE;
} while (usart_write_char(usart, c) != USART_SUCCESS);
return USART_SUCCESS;
}
int usart_read_char(volatile avr32_usart_t *usart, int *c)
{
// Check for errors: frame, parity and overrun. In RS485 mode, a parity error
// would mean that an address char has been received.
if (usart->csr & (AVR32_USART_CSR_OVRE_MASK |
AVR32_USART_CSR_FRAME_MASK |
AVR32_USART_CSR_PARE_MASK))
return USART_RX_ERROR;
// No error; if we really did receive a char, read it and return SUCCESS.
if (usart_test_hit(usart))
{
*c = (usart->rhr & AVR32_USART_RHR_RXCHR_MASK) >> AVR32_USART_RHR_RXCHR_OFFSET;
return USART_SUCCESS;
}
else
return USART_RX_EMPTY;
}
int usart_getchar(volatile avr32_usart_t *usart)
{
int c, ret;
while ((ret = usart_read_char(usart, &c)) == USART_RX_EMPTY);
if (ret == USART_RX_ERROR)
return USART_FAILURE;
return c;
}
void usart_write_line(volatile avr32_usart_t *usart, const char *string)
{
while (*string != '\0')
usart_putchar(usart, *string++);
}
int usart_get_echo_line(volatile avr32_usart_t *usart)
{
int rx_char;
int retval = USART_SUCCESS;
while (1)
{
rx_char = usart_getchar(usart);
if (rx_char == USART_FAILURE)
{
usart_write_line(usart, "Error!!!\n");
retval = USART_FAILURE;
break;
}
if (rx_char == '\x03')
{
retval = USART_FAILURE;
break;
}
usart_putchar(usart, rx_char);
if (rx_char == '\r')
{
usart_putchar(usart, '\n');
break;
}
}
return retval;
}
//! @}

View File

@ -0,0 +1,889 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief USART driver for AVR32 UC3.
*
* This file contains basic functions for the AVR32 USART, with support for all
* modes, settings and clock speeds.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with a USART module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _USART_H_
#define _USART_H_
#include <avr32/io.h>
#include "compiler.h"
/*! \name Return Values
*/
//! @{
#define USART_SUCCESS 0 //!< Successful completion.
#define USART_FAILURE -1 //!< Failure because of some unspecified reason.
#define USART_INVALID_INPUT 1 //!< Input value out of range.
#define USART_INVALID_ARGUMENT -1 //!< Argument value out of range.
#define USART_TX_BUSY 2 //!< Transmitter was busy.
#define USART_RX_EMPTY 3 //!< Nothing was received.
#define USART_RX_ERROR 4 //!< Transmission error occurred.
#define USART_MODE_FAULT 5 //!< USART not in the appropriate mode.
//! @}
//! Default time-out value (number of attempts).
#define USART_DEFAULT_TIMEOUT 10000
/*! \name Parity Settings
*/
//! @{
#define USART_EVEN_PARITY AVR32_USART_MR_PAR_EVEN //!< Use even parity on character transmission.
#define USART_ODD_PARITY AVR32_USART_MR_PAR_ODD //!< Use odd parity on character transmission.
#define USART_SPACE_PARITY AVR32_USART_MR_PAR_SPACE //!< Use a space as parity bit.
#define USART_MARK_PARITY AVR32_USART_MR_PAR_MARK //!< Use a mark as parity bit.
#define USART_NO_PARITY AVR32_USART_MR_PAR_NONE //!< Don't use a parity bit.
#define USART_MULTIDROP_PARITY AVR32_USART_MR_PAR_MULTI //!< Parity bit is used to flag address characters.
//! @}
/*! \name Stop Bits Settings
*/
//! @{
#define USART_1_STOPBIT AVR32_USART_MR_NBSTOP_1 //!< Use 1 stop bit.
#define USART_1_5_STOPBITS AVR32_USART_MR_NBSTOP_1_5 //!< Use 1.5 stop bits.
#define USART_2_STOPBITS AVR32_USART_MR_NBSTOP_2 //!< Use 2 stop bits (for more, just give the number of bits).
//! @}
/*! \name Channel Modes
*/
//! @{
#define USART_NORMAL_CHMODE AVR32_USART_MR_CHMODE_NORMAL //!< Normal communication.
#define USART_AUTO_ECHO AVR32_USART_MR_CHMODE_ECHO //!< Echo data.
#define USART_LOCAL_LOOPBACK AVR32_USART_MR_CHMODE_LOCAL_LOOP //!< Local loopback.
#define USART_REMOTE_LOOPBACK AVR32_USART_MR_CHMODE_REMOTE_LOOP //!< Remote loopback.
//! @}
#if defined(AVR32_USART_400_H_INCLUDED) || \
defined(AVR32_USART_410_H_INCLUDED) || \
defined(AVR32_USART_420_H_INCLUDED) || \
defined(AVR32_USART_440_H_INCLUDED) || \
defined(AVR32_USART_602_H_INCLUDED)
/*! \name LIN Node Actions
*/
//! @{
#define USART_LIN_PUBLISH_ACTION AVR32_USART_LINMR_NACT_PUBLISH //!< The USART transmits the response.
#define USART_LIN_SUBSCRIBE_ACTION AVR32_USART_LINMR_NACT_SUBSCRIBE //!< The USART receives the response.
#define USART_LIN_IGNORE_ACTION AVR32_USART_LINMR_NACT_IGNORE //!< The USART does not transmit and does not receive the reponse.
//! @}
/*! \name LIN Checksum Types
*/
//! @{
#define USART_LIN_ENHANCED_CHECKSUM 0 //!< LIN 2.0 "enhanced" checksum.
#define USART_LIN_CLASSIC_CHECKSUM 1 //!< LIN 1.3 "classic" checksum.
//! @}
#endif // USART rev. >= 4.0.0
//! Input parameters when initializing RS232 and similar modes.
typedef struct
{
//! Set baud rate of the USART (unused in slave modes).
unsigned long baudrate;
//! Number of bits to transmit as a character (5 to 9).
unsigned char charlength;
//! How to calculate the parity bit: \ref USART_EVEN_PARITY, \ref USART_ODD_PARITY,
//! \ref USART_SPACE_PARITY, \ref USART_MARK_PARITY, \ref USART_NO_PARITY or
//! \ref USART_MULTIDROP_PARITY.
unsigned char paritytype;
//! Number of stop bits between two characters: \ref USART_1_STOPBIT,
//! \ref USART_1_5_STOPBITS, \ref USART_2_STOPBITS or any number from 3 to 257
//! which will result in a time guard period of that length between characters.
//! \note \ref USART_1_5_STOPBITS is supported in asynchronous modes only.
unsigned short stopbits;
//! Run the channel in testmode: \ref USART_NORMAL_CHMODE, \ref USART_AUTO_ECHO,
//! \ref USART_LOCAL_LOOPBACK or \ref USART_REMOTE_LOOPBACK.
unsigned char channelmode;
} usart_options_t;
//! Input parameters when initializing ISO7816 mode.
typedef struct
{
//! Set the frequency of the ISO7816 clock.
unsigned long iso7816_hz;
//! The number of ISO7816 clock ticks in every bit period (1 to 2047, 0 = disable clock).
//! Bit rate = \ref iso7816_hz / \ref fidi_ratio.
unsigned short fidi_ratio;
//! How to calculate the parity bit: \ref USART_EVEN_PARITY for normal mode or
//! \ref USART_ODD_PARITY for inverse mode.
unsigned char paritytype;
//! Inhibit Non Acknowledge:\n
//! - 0: the NACK is generated;\n
//! - 1: the NACK is not generated.
//!
//! \note This bit will be used only in ISO7816 mode, protocol T = 0 receiver.
int inhibit_nack;
//! Disable successive NACKs.
//! Successive parity errors are counted up to the value in the \ref max_iterations field.
//! These parity errors generate a NACK on the ISO line. As soon as this value is reached,
//! no addititional NACK is sent on the ISO line. The ITERATION flag is asserted.
int dis_suc_nack;
//! Max number of repetitions (0 to 7).
unsigned char max_iterations;
//! Bit order in transmitted characters:\n
//! - 0: LSB first;\n
//! - 1: MSB first.
int bit_order;
} usart_iso7816_options_t;
#if defined(AVR32_USART_400_H_INCLUDED) || \
defined(AVR32_USART_410_H_INCLUDED) || \
defined(AVR32_USART_420_H_INCLUDED) || \
defined(AVR32_USART_440_H_INCLUDED) || \
defined(AVR32_USART_602_H_INCLUDED)
//! Input parameters when initializing SPI mode.
typedef struct
{
//! Set the frequency of the SPI clock (unused in slave mode).
unsigned long baudrate;
//! Number of bits to transmit as a character (5 to 9).
unsigned char charlength;
//! Which SPI mode to use.
unsigned char spimode;
//! Run the channel in testmode: \ref USART_NORMAL_CHMODE, \ref USART_AUTO_ECHO,
//! \ref USART_LOCAL_LOOPBACK or \ref USART_REMOTE_LOOPBACK.
unsigned char channelmode;
} usart_spi_options_t;
#endif // USART rev. >= 4.0.0
//------------------------------------------------------------------------------
/*! \name Initialization Functions
*/
//! @{
/*! \brief Resets the USART and disables TX and RX.
*
* \param usart Base address of the USART instance.
*/
extern void usart_reset(volatile avr32_usart_t *usart);
/*! \brief Sets up the USART to use the standard RS232 protocol.
*
* \param usart Base address of the USART instance.
* \param opt Options needed to set up RS232 communication (see \ref usart_options_t).
* \param pba_hz USART module input clock frequency (PBA clock, Hz).
*
* \retval USART_SUCCESS Mode successfully initialized.
* \retval USART_INVALID_INPUT One or more of the arguments is out of valid range.
*/
extern int usart_init_rs232(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz);
/*! \brief Sets up the USART to use the standard RS232 protocol in TX-only mode.
*
* Compared to \ref usart_init_rs232, this function allows very high baud rates
* (up to \a pba_hz instead of \a pba_hz / \c 8) at the expense of full duplex.
*
* \param usart Base address of the USART instance.
* \param opt Options needed to set up RS232 communication (see \ref usart_options_t).
* \param pba_hz USART module input clock frequency (PBA clock, Hz).
*
* \retval USART_SUCCESS Mode successfully initialized.
* \retval USART_INVALID_INPUT One or more of the arguments is out of valid range.
*
* \note The \c 1.5 stop bit is not supported in this mode.
*/
extern int usart_init_rs232_tx_only(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz);
/*! \brief Sets up the USART to use hardware handshaking.
*
* \param usart Base address of the USART instance.
* \param opt Options needed to set up RS232 communication (see \ref usart_options_t).
* \param pba_hz USART module input clock frequency (PBA clock, Hz).
*
* \retval USART_SUCCESS Mode successfully initialized.
* \retval USART_INVALID_INPUT One or more of the arguments is out of valid range.
*
* \note \ref usart_init_rs232 does not need to be invoked before this function.
*/
extern int usart_init_hw_handshaking(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz);
/*! \brief Sets up the USART to use the modem protocol, activating dedicated inputs/outputs.
*
* \param usart Base address of the USART instance.
* \param opt Options needed to set up RS232 communication (see \ref usart_options_t).
* \param pba_hz USART module input clock frequency (PBA clock, Hz).
*
* \retval USART_SUCCESS Mode successfully initialized.
* \retval USART_INVALID_INPUT One or more of the arguments is out of valid range.
*/
extern int usart_init_modem(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz);
/*! \brief Sets up the USART to use a synchronous RS232-like protocol in master mode.
*
* \param usart Base address of the USART instance.
* \param opt Options needed to set up RS232 communication (see \ref usart_options_t).
* \param pba_hz USART module input clock frequency (PBA clock, Hz).
*
* \retval USART_SUCCESS Mode successfully initialized.
* \retval USART_INVALID_INPUT One or more of the arguments is out of valid range.
*/
extern int usart_init_sync_master(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz);
/*! \brief Sets up the USART to use a synchronous RS232-like protocol in slave mode.
*
* \param usart Base address of the USART instance.
* \param opt Options needed to set up RS232 communication (see \ref usart_options_t).
* \param pba_hz USART module input clock frequency (PBA clock, Hz).
*
* \retval USART_SUCCESS Mode successfully initialized.
* \retval USART_INVALID_INPUT One or more of the arguments is out of valid range.
*/
extern int usart_init_sync_slave(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz);
/*! \brief Sets up the USART to use the RS485 protocol.
*
* \param usart Base address of the USART instance.
* \param opt Options needed to set up RS232 communication (see \ref usart_options_t).
* \param pba_hz USART module input clock frequency (PBA clock, Hz).
*
* \retval USART_SUCCESS Mode successfully initialized.
* \retval USART_INVALID_INPUT One or more of the arguments is out of valid range.
*/
extern int usart_init_rs485(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz);
/*! \brief Sets up the USART to use the IrDA protocol.
*
* \param usart Base address of the USART instance.
* \param opt Options needed to set up RS232 communication (see \ref usart_options_t).
* \param pba_hz USART module input clock frequency (PBA clock, Hz).
* \param irda_filter Counter used to distinguish received ones from zeros.
*
* \retval USART_SUCCESS Mode successfully initialized.
* \retval USART_INVALID_INPUT One or more of the arguments is out of valid range.
*/
extern int usart_init_IrDA(volatile avr32_usart_t *usart, const usart_options_t *opt,
long pba_hz, unsigned char irda_filter);
/*! \brief Sets up the USART to use the ISO7816 T=0 or T=1 smartcard protocols.
*
* The receiver is enabled by default. \ref usart_iso7816_enable_receiver and
* \ref usart_iso7816_enable_transmitter can be called to change the half-duplex
* communication direction.
*
* \param usart Base address of the USART instance.
* \param opt Options needed to set up ISO7816 communication (see \ref usart_iso7816_options_t).
* \param t ISO7816 mode to use (T=0 or T=1).
* \param pba_hz USART module input clock frequency (PBA clock, Hz).
*
* \retval USART_SUCCESS Mode successfully initialized.
* \retval USART_INVALID_INPUT One or more of the arguments is out of valid range.
*/
extern int usart_init_iso7816(volatile avr32_usart_t *usart, const usart_iso7816_options_t *opt, int t, long pba_hz);
#if defined(AVR32_USART_400_H_INCLUDED) || \
defined(AVR32_USART_410_H_INCLUDED) || \
defined(AVR32_USART_420_H_INCLUDED) || \
defined(AVR32_USART_440_H_INCLUDED) || \
defined(AVR32_USART_602_H_INCLUDED)
/*! \brief Sets up the USART to use the LIN master mode.
*
* \param usart Base address of the USART instance.
* \param baudrate Baud rate.
* \param pba_hz USART module input clock frequency (PBA clock, Hz).
*
*/
extern int usart_init_lin_master(volatile avr32_usart_t *usart, unsigned long baudrate, long pba_hz);
/*! \brief Sets up the USART to use the LIN slave mode.
*
* \param usart Base address of the USART instance.
* \param baudrate Baud rate.
* \param pba_hz USART module input clock frequency (PBA clock, Hz).
*
*/
extern int usart_init_lin_slave(volatile avr32_usart_t *usart, unsigned long baudrate, long pba_hz);
/*! \brief Sets up the USART to use the SPI master mode.
*
* \ref usart_spi_selectChip and \ref usart_spi_unselectChip can be called to
* select or unselect the SPI slave chip.
*
* \param usart Base address of the USART instance.
* \param opt Options needed to set up SPI mode (see \ref usart_spi_options_t).
* \param pba_hz USART module input clock frequency (PBA clock, Hz).
*
* \retval USART_SUCCESS Mode successfully initialized.
* \retval USART_INVALID_INPUT One or more of the arguments is out of valid range.
*/
extern int usart_init_spi_master(volatile avr32_usart_t *usart, const usart_spi_options_t *opt, long pba_hz);
/*! \brief Sets up the USART to use the SPI slave mode.
*
* \param usart Base address of the USART instance.
* \param opt Options needed to set up SPI mode (see \ref usart_spi_options_t).
* \param pba_hz USART module input clock frequency (PBA clock, Hz).
*
* \retval USART_SUCCESS Mode successfully initialized.
* \retval USART_INVALID_INPUT One or more of the arguments is out of valid range.
*/
extern int usart_init_spi_slave(volatile avr32_usart_t *usart, const usart_spi_options_t *opt, long pba_hz);
#endif // USART rev. >= 4.0.0
//! @}
//------------------------------------------------------------------------------
/*! \name Read and Reset Error Status Bits
*/
//! @{
/*! \brief Resets the error status.
*
* This function resets the status bits indicating that a parity error,
* framing error or overrun has occurred. The RXBRK bit, indicating
* a start/end of break condition on the RX line, is also reset.
*
* \param usart Base address of the USART instance.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void usart_reset_status(volatile avr32_usart_t *usart)
{
usart->cr = AVR32_USART_CR_RSTSTA_MASK;
}
/*! \brief Checks if a parity error has occurred since last status reset.
*
* \param usart Base address of the USART instance.
*
* \return \c 1 if a parity error has been detected, otherwise \c 0.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ int usart_parity_error(volatile avr32_usart_t *usart)
{
return (usart->csr & AVR32_USART_CSR_PARE_MASK) != 0;
}
/*! \brief Checks if a framing error has occurred since last status reset.
*
* \param usart Base address of the USART instance.
*
* \return \c 1 if a framing error has been detected, otherwise \c 0.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ int usart_framing_error(volatile avr32_usart_t *usart)
{
return (usart->csr & AVR32_USART_CSR_FRAME_MASK) != 0;
}
/*! \brief Checks if an overrun error has occurred since last status reset.
*
* \param usart Base address of the USART instance.
*
* \return \c 1 if a overrun error has been detected, otherwise \c 0.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ int usart_overrun_error(volatile avr32_usart_t *usart)
{
return (usart->csr & AVR32_USART_CSR_OVRE_MASK) != 0;
}
#if defined(AVR32_USART_400_H_INCLUDED) || \
defined(AVR32_USART_410_H_INCLUDED) || \
defined(AVR32_USART_420_H_INCLUDED) || \
defined(AVR32_USART_440_H_INCLUDED) || \
defined(AVR32_USART_602_H_INCLUDED)
/*! \brief Get LIN Error Status
*
* \param usart Base address of the USART instance.
*
* \retval The binary value of the error field.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ int usart_lin_get_error(volatile avr32_usart_t *usart)
{
return (usart->csr & (AVR32_USART_CSR_LINSNRE_MASK |
AVR32_USART_CSR_LINCE_MASK |
AVR32_USART_CSR_LINIPE_MASK |
AVR32_USART_CSR_LINISFE_MASK |
AVR32_USART_CSR_LINBE_MASK)) >> AVR32_USART_CSR_LINBE_OFFSET;
}
#endif // USART rev. >= 4.0.0
//! @}
//------------------------------------------------------------------------------
/*! \name ISO7816 Control Functions
*/
//! @{
/*! \brief Enables the ISO7816 receiver.
*
* The ISO7816 transmitter is disabled.
*
* \param usart Base address of the USART instance.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void usart_iso7816_enable_receiver(volatile avr32_usart_t *usart)
{
usart->cr = AVR32_USART_CR_TXDIS_MASK | AVR32_USART_CR_RXEN_MASK;
}
/*! \brief Enables the ISO7816 transmitter.
*
* The ISO7816 receiver is disabled.
*
* \param usart Base address of the USART instance.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void usart_iso7816_enable_transmitter(volatile avr32_usart_t *usart)
{
usart->cr = AVR32_USART_CR_RXDIS_MASK | AVR32_USART_CR_TXEN_MASK;
}
//! @}
//------------------------------------------------------------------------------
#if defined(AVR32_USART_400_H_INCLUDED) || \
defined(AVR32_USART_410_H_INCLUDED) || \
defined(AVR32_USART_420_H_INCLUDED) || \
defined(AVR32_USART_440_H_INCLUDED) || \
defined(AVR32_USART_602_H_INCLUDED)
/*! \name LIN Control Functions
*/
//! @{
/*! \brief Sets the node action.
*
* \param usart Base address of the USART instance.
* \param action The node action: \ref USART_LIN_PUBLISH_ACTION,
* \ref USART_LIN_SUBSCRIBE_ACTION or
* \ref USART_LIN_IGNORE_ACTION.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void usart_lin_set_node_action(volatile avr32_usart_t *usart, unsigned char action)
{
usart->linmr = (usart->linmr & ~AVR32_USART_LINMR_NACT_MASK) |
action << AVR32_USART_LINMR_NACT_OFFSET;
}
/*! \brief Enables or disables the Identifier parity.
*
* \param usart Base address of the USART instance.
* \param parity Whether to enable the Identifier parity: \c TRUE or \c FALSE.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void usart_lin_enable_parity(volatile avr32_usart_t *usart, unsigned char parity)
{
usart->linmr = (usart->linmr & ~AVR32_USART_LINMR_PARDIS_MASK) |
!parity << AVR32_USART_LINMR_PARDIS_OFFSET;
}
/*! \brief Enables or disables the checksum.
*
* \param usart Base address of the USART instance.
* \param parity Whether to enable the checksum: \c TRUE or \c FALSE.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void usart_lin_enable_checksum(volatile avr32_usart_t *usart, unsigned char checksum)
{
usart->linmr = (usart->linmr & ~AVR32_USART_LINMR_CHKDIS_MASK) |
!checksum << AVR32_USART_LINMR_CHKDIS_OFFSET;
}
/*! \brief Sets the checksum type.
*
* \param usart Base address of the USART instance.
* \param chktyp The checksum type: \ref USART_LIN_ENHANCED_CHEKSUM or
* \ref USART_LIN_CLASSIC_CHECKSUM.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void usart_lin_set_checksum(volatile avr32_usart_t *usart, unsigned char chktyp)
{
usart->linmr = (usart->linmr & ~AVR32_USART_LINMR_CHKTYP_MASK) |
chktyp << AVR32_USART_LINMR_CHKTYP_OFFSET;
}
/*! \brief Gets the response data length.
*
* \param usart Base address of the USART instance.
*
* \return The response data length.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ unsigned char usart_lin_get_data_length(volatile avr32_usart_t *usart)
{
if (usart->linmr & AVR32_USART_LINMR_DLM_MASK)
{
unsigned char data_length = 1 << ((usart->linir >> (AVR32_USART_LINIR_IDCHR_OFFSET + 4)) & 0x03);
if (data_length == 1)
data_length = 2;
return data_length;
}
else
return ((usart->linmr & AVR32_USART_LINMR_DLC_MASK) >> AVR32_USART_LINMR_DLC_OFFSET) + 1;
}
/*! \brief Sets the response data length for LIN 1.x.
*
* \param usart Base address of the USART instance.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void usart_lin_set_data_length_lin1x(volatile avr32_usart_t *usart)
{
usart->linmr |= AVR32_USART_LINMR_DLM_MASK;
}
/*! \brief Sets the response data length for LIN 2.x.
*
* \param usart Base address of the USART instance.
* \param data_length The response data length.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void usart_lin_set_data_length_lin2x(volatile avr32_usart_t *usart, unsigned char data_length)
{
usart->linmr = (usart->linmr & ~(AVR32_USART_LINMR_DLC_MASK |
AVR32_USART_LINMR_DLM_MASK)) |
(data_length - 1) << AVR32_USART_LINMR_DLC_OFFSET;
}
/*! \brief Enables or disables the frame slot mode.
*
* \param usart Base address of the USART instance.
* \param frameslot Whether to enable the frame slot mode: \c TRUE or
* \c FALSE.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void usart_lin_enable_frameslot(volatile avr32_usart_t *usart, unsigned char frameslot)
{
usart->linmr = (usart->linmr & ~AVR32_USART_LINMR_FSDIS_MASK) |
!frameslot << AVR32_USART_LINMR_FSDIS_OFFSET;
}
/*! \brief Gets the Identifier character.
*
* \param usart Base address of the USART instance.
*
* \return The Identifier character.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ unsigned char usart_lin_get_id_char(volatile avr32_usart_t *usart)
{
return (usart->linir & AVR32_USART_LINIR_IDCHR_MASK) >> AVR32_USART_LINIR_IDCHR_OFFSET;
}
/*! \brief Sets the Identifier character.
*
* \param usart Base address of the USART instance.
* \param id_char The Identifier character.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void usart_lin_set_id_char(volatile avr32_usart_t *usart, unsigned char id_char)
{
usart->linir = (usart->linir & ~AVR32_USART_LINIR_IDCHR_MASK) |
id_char << AVR32_USART_LINIR_IDCHR_OFFSET;
}
//! @}
#endif // USART rev. >= 4.0.0
//------------------------------------------------------------------------------
#if defined(AVR32_USART_400_H_INCLUDED) || \
defined(AVR32_USART_410_H_INCLUDED) || \
defined(AVR32_USART_420_H_INCLUDED) || \
defined(AVR32_USART_440_H_INCLUDED) || \
defined(AVR32_USART_602_H_INCLUDED)
/*! \name SPI Control Functions
*/
//! @{
/*! \brief Selects SPI slave chip.
*
* \param usart Base address of the USART instance.
*
* \retval USART_SUCCESS Success.
*/
extern int usart_spi_selectChip(volatile avr32_usart_t *usart);
/*! \brief Unselects SPI slave chip.
*
* \param usart Base address of the USART instance.
*
* \retval USART_SUCCESS Success.
* \retval USART_FAILURE Time-out.
*/
extern int usart_spi_unselectChip(volatile avr32_usart_t *usart);
//! @}
#endif // USART rev. >= 4.0.0
//------------------------------------------------------------------------------
/*! \name Transmit/Receive Functions
*/
//! @{
/*! \brief Addresses a receiver.
*
* While in RS485 mode, receivers only accept data addressed to them.
* A packet/char with the address tag set has to precede any data.
* This function is used to address a receiver. This receiver should read
* all the following data, until an address packet addresses another receiver.
*
* \param usart Base address of the USART instance.
* \param address Address of the target device.
*
* \retval USART_SUCCESS Address successfully sent (if current mode is RS485).
* \retval USART_MODE_FAULT Wrong operating mode.
*/
extern int usart_send_address(volatile avr32_usart_t *usart, int address);
/*! \brief Tests if the USART is ready to transmit a character.
*
* \param usart Base address of the USART instance.
*
* \return \c 1 if the USART Transmit Holding Register is free, otherwise \c 0.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ int usart_tx_ready(volatile avr32_usart_t *usart)
{
return (usart->csr & AVR32_USART_CSR_TXRDY_MASK) != 0;
}
/*! \brief Writes the given character to the TX buffer if the transmitter is ready.
*
* \param usart Base address of the USART instance.
* \param c The character (up to 9 bits) to transmit.
*
* \retval USART_SUCCESS The transmitter was ready.
* \retval USART_TX_BUSY The transmitter was busy.
*/
extern int usart_write_char(volatile avr32_usart_t *usart, int c);
/*! \brief An active wait writing a character to the USART.
*
* \param usart Base address of the USART instance.
* \param c The character (up to 9 bits) to transmit.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void usart_bw_write_char(volatile avr32_usart_t *usart, int c)
{
while (usart_write_char(usart, c) != USART_SUCCESS);
}
/*! \brief Sends a character with the USART.
*
* \param usart Base address of the USART instance.
* \param c Character to write.
*
* \retval USART_SUCCESS The character was written.
* \retval USART_FAILURE The function timed out before the USART transmitter became ready to send.
*/
extern int usart_putchar(volatile avr32_usart_t *usart, int c);
/*! \brief Tests if all requested USART transmissions are over.
*
* \param usart Base address of the USART instance.
*
* \return \c 1 if the USART Transmit Shift Register and the USART Transmit
* Holding Register are free, otherwise \c 0.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ int usart_tx_empty(volatile avr32_usart_t *usart)
{
return (usart->csr & AVR32_USART_CSR_TXEMPTY_MASK) != 0;
}
/*! \brief Tests if the USART contains a received character.
*
* \param usart Base address of the USART instance.
*
* \return \c 1 if the USART Receive Holding Register is full, otherwise \c 0.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ int usart_test_hit(volatile avr32_usart_t *usart)
{
return (usart->csr & AVR32_USART_CSR_RXRDY_MASK) != 0;
}
/*! \brief Checks the RX buffer for a received character, and stores it at the
* given memory location.
*
* \param usart Base address of the USART instance.
* \param c Pointer to the where the read character should be stored
* (must be at least short in order to accept 9-bit characters).
*
* \retval USART_SUCCESS The character was read successfully.
* \retval USART_RX_EMPTY The RX buffer was empty.
* \retval USART_RX_ERROR An error was deteceted.
*/
extern int usart_read_char(volatile avr32_usart_t *usart, int *c);
/*! \brief Waits until a character is received, and returns it.
*
* \param usart Base address of the USART instance.
*
* \return The received character, or \ref USART_FAILURE upon error.
*/
extern int usart_getchar(volatile avr32_usart_t *usart);
/*! \brief Writes one character string to the USART.
*
* \param usart Base address of the USART instance.
* \param string String to be written.
*/
extern void usart_write_line(volatile avr32_usart_t *usart, const char *string);
/*! \brief Gets and echoes characters until end of line.
*
* \param usart Base address of the USART instance.
*
* \retval USART_SUCCESS Success.
* \retval USART_FAILURE Low-level error detected or ETX character received.
*/
extern int usart_get_echo_line(volatile avr32_usart_t *usart);
#if defined(AVR32_USART_400_H_INCLUDED) || \
defined(AVR32_USART_410_H_INCLUDED) || \
defined(AVR32_USART_420_H_INCLUDED) || \
defined(AVR32_USART_440_H_INCLUDED) || \
defined(AVR32_USART_602_H_INCLUDED)
/*! \brief Abort LIN transmission.
*
* \param usart Base address of the USART instance.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ void usart_lin_abort(volatile avr32_usart_t *usart)
{
usart->cr = AVR32_USART_LINABT_MASK;
}
/*! \brief Tests if a LIN transfer has been completed.
*
* \param usart Base address of the USART instance.
*
* \return \c 1 if a LIN transfer has been completed, otherwise \c 0.
*/
#if (defined __GNUC__)
__attribute__((__always_inline__))
#endif
extern __inline__ int usart_lin_transfer_completed(volatile avr32_usart_t *usart)
{
return (usart->csr & AVR32_USART_CSR_LINTC_MASK) != 0;
}
#endif // USART rev. >= 4.0.0
//! @}
#endif // _USART_H_

View File

@ -0,0 +1,87 @@
/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file ******************************************************************
*
* \brief Management of the delays.
*
* This file manages the "delays", with or without an OS.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
***************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
//_____ I N C L U D E S ___________________________________________________
#include "delay.h"
//_____ M A C R O S ________________________________________________________
//_____ D E F I N I T I O N S ______________________________________________
//! CPU frequency
#ifndef FREERTOS_USED
static unsigned long s_fcpu_hz;
#endif
#if (defined NUTOS_USED)
extern void NutSleep(unsigned long ms);
#endif
//_____ D E C L A R A T I O N S ____________________________________________
void delay_init(unsigned long fcpu_hz)
{
#ifndef FREERTOS_USED
s_fcpu_hz = fcpu_hz;
#endif
}
void delay_ms(unsigned long delay)
{
#if (defined FREERTOS_USED)
vTaskDelay( (portTickType)TASK_DELAY_MS(delay) );
#elif (defined NUTOS_USED)
NutSleep(delay);
#else
cpu_delay_ms(delay, s_fcpu_hz);
#endif
}

View File

@ -0,0 +1,80 @@
/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief AT32UC3 delay management header file.
*
* This file contains definitions and services to handle "delays".
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 AT32UC3 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* 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
* AVR 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
*
*/
#ifndef _DELAY_H_
#define _DELAY_H_
#include "compiler.h"
#ifdef FREERTOS_USED
# include "FreeRTOS.h"
# include "task.h"
#else
# include "cycle_counter.h"
#endif
/*!
* \brief Initialize the delay driver.
*
* \param fcpu_hz: CPU frequency in Hz.
*/
extern void delay_init(unsigned long fcpu_hz);
/*!
* \brief Waits during at least the specified delay (in millisecond) before returning.
*
* Note that in the case of FreeRTOS, the function will delay the current task for a given number of ms.
*
* \param delay: Number of millisecond to wait.
*/
extern void delay_ms(unsigned long delay);
#endif // _DELAY_H_

View File

@ -0,0 +1,982 @@
/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/**
* @file
* DNS - host name to IP address resolver.
*
*/
/**
* This file implements a DNS host name to IP address resolver.
* Port to lwIP from uIP
* by Jim Pettinato April 2007
* uIP version Copyright (c) 2002-2003, Adam Dunkels.
* All rights reserved.
*
* 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 the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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.
*
*
* DNS.C
*
* The lwIP DNS resolver functions are used to lookup a host name and
* map it to a numerical IP address. It maintains a list of resolved
* hostnames that can be queried with the dns_lookup() function.
* New hostnames can be resolved using the dns_query() function.
*
* The lwIP version of the resolver also adds a non-blocking version of
* gethostbyname() that will work with a raw API application. This function
* checks for an IP address string first and converts it if it is valid.
* gethostbyname() then does a dns_lookup() to see if the name is
* already in the table. If so, the IP is returned. If not, a query is
* issued and the function returns with a ERR_INPROGRESS status. The app
* using the dns client must then go into a waiting state.
*
* Once a hostname has been resolved (or found to be non-existent),
* the resolver code calls a specified callback function (which
* must be implemented by the module that uses the resolver).
*/
/*-----------------------------------------------------------------------------
* RFC 1035 - Domain names - implementation and specification
* RFC 2181 - Clarifications to the DNS Specification
*----------------------------------------------------------------------------*/
/** @todo: define good default values (rfc compliance) */
/** @todo: improve answer parsing, more checkings... */
/** @todo: check RFC1035 - 7.3. Processing responses */
/*-----------------------------------------------------------------------------
* Includes
*----------------------------------------------------------------------------*/
#include "lwip/opt.h"
#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
#include "lwip/udp.h"
#include "lwip/mem.h"
#include "lwip/dns.h"
#include <string.h>
/** DNS server IP address */
#ifndef DNS_SERVER_ADDRESS
#define DNS_SERVER_ADDRESS inet_addr("208.67.222.222") /* resolver1.opendns.com */
#endif
/** DNS server port address */
#ifndef DNS_SERVER_PORT
#define DNS_SERVER_PORT 53
#endif
/** DNS maximum number of retries when asking for a name, before "timeout". */
#ifndef DNS_MAX_RETRIES
#define DNS_MAX_RETRIES 4
#endif
/** DNS resource record max. TTL (one week as default) */
#ifndef DNS_MAX_TTL
#define DNS_MAX_TTL 604800
#endif
/* DNS protocol flags */
#define DNS_FLAG1_RESPONSE 0x80
#define DNS_FLAG1_OPCODE_STATUS 0x10
#define DNS_FLAG1_OPCODE_INVERSE 0x08
#define DNS_FLAG1_OPCODE_STANDARD 0x00
#define DNS_FLAG1_AUTHORATIVE 0x04
#define DNS_FLAG1_TRUNC 0x02
#define DNS_FLAG1_RD 0x01
#define DNS_FLAG2_RA 0x80
#define DNS_FLAG2_ERR_MASK 0x0f
#define DNS_FLAG2_ERR_NONE 0x00
#define DNS_FLAG2_ERR_NAME 0x03
/* DNS protocol states */
#define DNS_STATE_UNUSED 0
#define DNS_STATE_NEW 1
#define DNS_STATE_ASKING 2
#define DNS_STATE_DONE 3
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
/** DNS message header */
struct dns_hdr {
PACK_STRUCT_FIELD(u16_t id);
PACK_STRUCT_FIELD(u8_t flags1);
PACK_STRUCT_FIELD(u8_t flags2);
PACK_STRUCT_FIELD(u16_t numquestions);
PACK_STRUCT_FIELD(u16_t numanswers);
PACK_STRUCT_FIELD(u16_t numauthrr);
PACK_STRUCT_FIELD(u16_t numextrarr);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#define SIZEOF_DNS_HDR 12
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
/** DNS query message structure */
struct dns_query {
/* DNS query record starts with either a domain name or a pointer
to a name already present somewhere in the packet. */
PACK_STRUCT_FIELD(u16_t type);
PACK_STRUCT_FIELD(u16_t class);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#define SIZEOF_DNS_QUERY 4
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
/** DNS answer message structure */
struct dns_answer {
/* DNS answer record starts with either a domain name or a pointer
to a name already present somewhere in the packet. */
PACK_STRUCT_FIELD(u16_t type);
PACK_STRUCT_FIELD(u16_t class);
PACK_STRUCT_FIELD(u32_t ttl);
PACK_STRUCT_FIELD(u16_t len);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#define SIZEOF_DNS_ANSWER 10
/** DNS table entry */
struct dns_table_entry {
u8_t state;
u8_t numdns;
u8_t tmr;
u8_t retries;
u8_t seqno;
u8_t err;
u32_t ttl;
char name[DNS_MAX_NAME_LENGTH];
struct ip_addr ipaddr;
/* pointer to callback on DNS query done */
dns_found_callback found;
void *arg;
};
#if DNS_LOCAL_HOSTLIST
/** struct used for local host-list */
struct local_hostlist_entry {
/** static hostname */
const char *name;
/** static host address in network byteorder */
u32_t addr;
struct local_hostlist_entry *next;
};
#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC
/** Local host-list. For hostnames in this list, no
* external name resolution is performed */
static struct local_hostlist_entry *local_hostlist_dynamic;
#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
/** Defining this allows the local_hostlist_static to be placed in a different
* linker section (e.g. FLASH) */
#ifndef DNS_LOCAL_HOSTLIST_STORAGE_PRE
#define DNS_LOCAL_HOSTLIST_STORAGE_PRE static
#endif /* DNS_LOCAL_HOSTLIST_STORAGE_PRE */
/** Defining this allows the local_hostlist_static to be placed in a different
* linker section (e.g. FLASH) */
#ifndef DNS_LOCAL_HOSTLIST_STORAGE_POST
#define DNS_LOCAL_HOSTLIST_STORAGE_POST
#endif /* DNS_LOCAL_HOSTLIST_STORAGE_POST */
DNS_LOCAL_HOSTLIST_STORAGE_PRE struct local_hostlist_entry local_hostlist_static[]
DNS_LOCAL_HOSTLIST_STORAGE_POST = DNS_LOCAL_HOSTLIST_INIT;
#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
static void dns_init_local();
#endif /* DNS_LOCAL_HOSTLIST */
/* forward declarations */
static void dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port);
static void dns_check_entries(void);
/*-----------------------------------------------------------------------------
* Globales
*----------------------------------------------------------------------------*/
/* DNS variables */
static struct udp_pcb *dns_pcb;
static u8_t dns_seqno;
static struct dns_table_entry dns_table[DNS_TABLE_SIZE];
static struct ip_addr dns_servers[DNS_MAX_SERVERS];
#if (DNS_USES_STATIC_BUF == 1)
static u8_t dns_payload[DNS_MSG_SIZE];
#endif /* (DNS_USES_STATIC_BUF == 1) */
/**
* Initialize the resolver: set up the UDP pcb and configure the default server
* (DNS_SERVER_ADDRESS).
*/
void
dns_init()
{
struct ip_addr dnsserver;
/* initialize default DNS server address */
dnsserver.addr = DNS_SERVER_ADDRESS;
LWIP_DEBUGF(DNS_DEBUG, ("dns_init: initializing\n"));
/* if dns client not yet initialized... */
if (dns_pcb == NULL) {
dns_pcb = udp_new();
if (dns_pcb != NULL) {
/* initialize DNS table not needed (initialized to zero since it is a
* global variable) */
LWIP_ASSERT("For implicit initialization to work, DNS_STATE_UNUSED needs to be 0",
DNS_STATE_UNUSED == 0);
/* initialize DNS client */
udp_bind(dns_pcb, IP_ADDR_ANY, 0);
udp_recv(dns_pcb, dns_recv, NULL);
/* initialize default DNS primary server */
dns_setserver(0, &dnsserver);
}
}
#if DNS_LOCAL_HOSTLIST
dns_init_local();
#endif
}
/**
* Initialize one of the DNS servers.
*
* @param numdns the index of the DNS server to set must be < DNS_MAX_SERVERS
* @param dnsserver IP address of the DNS server to set
*/
void
dns_setserver(u8_t numdns, struct ip_addr *dnsserver)
{
if ((numdns < DNS_MAX_SERVERS) && (dns_pcb != NULL) &&
(dnsserver != NULL) && (dnsserver->addr !=0 )) {
dns_servers[numdns] = (*dnsserver);
}
}
/**
* Obtain one of the currently configured DNS server.
*
* @param numdns the index of the DNS server
* @return IP address of the indexed DNS server or "ip_addr_any" if the DNS
* server has not been configured.
*/
struct ip_addr
dns_getserver(u8_t numdns)
{
if (numdns < DNS_MAX_SERVERS) {
return dns_servers[numdns];
} else {
return *IP_ADDR_ANY;
}
}
/**
* The DNS resolver client timer - handle retries and timeouts and should
* be called every DNS_TMR_INTERVAL milliseconds (every second by default).
*/
void
dns_tmr(void)
{
if (dns_pcb != NULL) {
LWIP_DEBUGF(DNS_DEBUG, ("dns_tmr: dns_check_entries\n"));
dns_check_entries();
}
}
#if DNS_LOCAL_HOSTLIST
static void
dns_init_local()
{
#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT)
int i;
struct local_hostlist_entry *entry;
/* Dynamic: copy entries from DNS_LOCAL_HOSTLIST_INIT to list */
struct local_hostlist_entry local_hostlist_init[] = DNS_LOCAL_HOSTLIST_INIT;
for (i = 0; i < sizeof(local_hostlist_init) / sizeof(struct local_hostlist_entry); i++) {
entry = mem_malloc(sizeof(struct local_hostlist_entry));
LWIP_ASSERT("mem-error in dns_init_local", entry != NULL);
if (entry != NULL) {
struct local_hostlist_entry *init_entry = &local_hostlist_init[i];
entry->name = init_entry->name;
entry->addr = init_entry->addr;
entry->next = local_hostlist_dynamic;
local_hostlist_dynamic = entry;
}
}
#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT) */
}
/**
* Scans the local host-list for a hostname.
*
* @param hostname Hostname to look for in the local host-list
* @return The first IP address for the hostname in the local host-list or
* INADDR_NONE if not found.
*/
static u32_t
dns_lookup_local(const char *hostname)
{
#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC
struct local_hostlist_entry *entry = local_hostlist_dynamic;
while(entry != NULL) {
if(strcmp(entry->name, hostname) == 0) {
return entry->addr;
}
entry = entry->next;
}
#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
int i;
for (i = 0; i < sizeof(local_hostlist_static) / sizeof(struct local_hostlist_entry); i++) {
if(strcmp(local_hostlist_static[i].name, hostname) == 0) {
return local_hostlist_static[i].addr;
}
}
#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
return INADDR_NONE;
}
#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC
/** Remove all entries from the local host-list for a specific hostname
* and/or IP addess
*
* @param hostname hostname for which entries shall be removed from the local
* host-list
* @param addr address for which entries shall be removed from the local host-list
* @return the number of removed entries
*/
int
dns_local_removehost(const char *hostname, const struct ip_addr *addr)
{
int removed = 0;
struct local_hostlist_entry *entry = local_hostlist_dynamic;
struct local_hostlist_entry *last_entry = NULL;
while (entry != NULL) {
if (((hostname == NULL) || !strcmp(entry->name, hostname)) &&
((addr == NULL) || (entry->addr == addr->addr))) {
struct local_hostlist_entry *free_entry;
if (last_entry != NULL) {
last_entry->next = entry->next;
} else {
local_hostlist_dynamic = entry->next;
}
free_entry = entry;
entry = entry->next;
mem_free(free_entry);
removed++;
} else {
last_entry = entry;
entry = entry->next;
}
}
return removed;
}
/**
* Add a hostname/IP address pair to the local host-list.
* Duplicates are not checked.
*
* @param hostname hostname of the new entry
* @param addr IP address of the new entry
* @return ERR_OK if succeeded or ERR_MEM on memory error
*/
err_t
dns_local_addhost(const char *hostname, const struct ip_addr *addr)
{
struct local_hostlist_entry *entry;
entry = mem_malloc(sizeof(struct local_hostlist_entry));
if (entry == NULL) {
return ERR_MEM;
}
entry->name = hostname;
entry->addr = addr->addr;
entry->next = local_hostlist_dynamic;
local_hostlist_dynamic = entry;
return ERR_OK;
}
#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC*/
#endif /* DNS_LOCAL_HOSTLIST */
/**
* Look up a hostname in the array of known hostnames.
*
* @note This function only looks in the internal array of known
* hostnames, it does not send out a query for the hostname if none
* was found. The function dns_enqueue() can be used to send a query
* for a hostname.
*
* @param name the hostname to look up
* @return the hostname's IP address, as u32_t (instead of struct ip_addr to
* better check for failure: != INADDR_NONE) or INADDR_NONE if the hostname
* was not found in the cached dns_table.
*/
static u32_t
dns_lookup(const char *name)
{
u8_t i;
#if DNS_LOCAL_HOSTLIST || defined(DNS_LOOKUP_LOCAL_EXTERN)
u32_t addr;
#endif /* DNS_LOCAL_HOSTLIST || defined(DNS_LOOKUP_LOCAL_EXTERN) */
#if DNS_LOCAL_HOSTLIST
if ((addr = dns_lookup_local(name)) != INADDR_NONE) {
return addr;
}
#endif /* DNS_LOCAL_HOSTLIST */
#ifdef DNS_LOOKUP_LOCAL_EXTERN
if((addr = DNS_LOOKUP_LOCAL_EXTERN(name)) != INADDR_NONE) {
return addr;
}
#endif /* DNS_LOOKUP_LOCAL_EXTERN */
/* Walk through name list, return entry if found. If not, return NULL. */
for (i = 0; i < DNS_TABLE_SIZE; ++i) {
if ((dns_table[i].state == DNS_STATE_DONE) &&
(strcmp(name, dns_table[i].name) == 0)) {
LWIP_DEBUGF(DNS_DEBUG, ("dns_lookup: \"%s\": found = ", name));
ip_addr_debug_print(DNS_DEBUG, &(dns_table[i].ipaddr));
LWIP_DEBUGF(DNS_DEBUG, ("\n"));
return dns_table[i].ipaddr.addr;
}
}
return INADDR_NONE;
}
#if DNS_DOES_NAME_CHECK
/**
* Compare the "dotted" name "query" with the encoded name "response"
* to make sure an answer from the DNS server matches the current dns_table
* entry (otherwise, answers might arrive late for hostname not on the list
* any more).
*
* @param query hostname (not encoded) from the dns_table
* @param response encoded hostname in the DNS response
* @return 0: names equal; 1: names differ
*/
static u8_t
dns_compare_name(unsigned char *query, unsigned char *response)
{
unsigned char n;
do {
n = *response++;
/** @see RFC 1035 - 4.1.4. Message compression */
if ((n & 0xc0) == 0xc0) {
/* Compressed name */
break;
} else {
/* Not compressed name */
while (n > 0) {
if ((*query) != (*response)) {
return 1;
}
++response;
++query;
--n;
};
++query;
}
} while (*response != 0);
return 0;
}
#endif /* DNS_DOES_NAME_CHECK */
/**
* Walk through a compact encoded DNS name and return the end of the name.
*
* @param query encoded DNS name in the DNS server response
* @return end of the name
*/
static unsigned char *
dns_parse_name(unsigned char *query)
{
unsigned char n;
do {
n = *query++;
/** @see RFC 1035 - 4.1.4. Message compression */
if ((n & 0xc0) == 0xc0) {
/* Compressed name */
break;
} else {
/* Not compressed name */
while (n > 0) {
++query;
--n;
};
}
} while (*query != 0);
return query + 1;
}
/**
* Send a DNS query packet.
*
* @param numdns index of the DNS server in the dns_servers table
* @param name hostname to query
* @param id index of the hostname in dns_table, used as transaction ID in the
* DNS query packet
* @return ERR_OK if packet is sent; an err_t indicating the problem otherwise
*/
static err_t
dns_send(u8_t numdns, const char* name, u8_t id)
{
err_t err;
struct dns_hdr *hdr;
struct dns_query qry;
struct pbuf *p;
char *query, *nptr;
const char *pHostname;
u8_t n;
LWIP_DEBUGF(DNS_DEBUG, ("dns_send: dns_servers[%"U16_F"] \"%s\": request\n",
(u16_t)(numdns), name));
LWIP_ASSERT("dns server out of array", numdns < DNS_MAX_SERVERS);
LWIP_ASSERT("dns server has no IP address set", dns_servers[numdns].addr != 0);
/* if here, we have either a new query or a retry on a previous query to process */
p = pbuf_alloc(PBUF_TRANSPORT, SIZEOF_DNS_HDR + DNS_MAX_NAME_LENGTH +
SIZEOF_DNS_QUERY, PBUF_RAM);
if (p != NULL) {
LWIP_ASSERT("pbuf must be in one piece", p->next == NULL);
/* fill dns header */
hdr = (struct dns_hdr*)p->payload;
memset(hdr, 0, SIZEOF_DNS_HDR);
hdr->id = htons(id);
hdr->flags1 = DNS_FLAG1_RD;
hdr->numquestions = htons(1);
query = (char*)hdr + SIZEOF_DNS_HDR;
pHostname = name;
--pHostname;
/* convert hostname into suitable query format. */
do {
++pHostname;
nptr = query;
++query;
for(n = 0; *pHostname != '.' && *pHostname != 0; ++pHostname) {
*query = *pHostname;
++query;
++n;
}
*nptr = n;
} while(*pHostname != 0);
*query++='\0';
/* fill dns query */
qry.type = htons(DNS_RRTYPE_A);
qry.class = htons(DNS_RRCLASS_IN);
MEMCPY( query, &qry, SIZEOF_DNS_QUERY);
/* resize pbuf to the exact dns query */
pbuf_realloc(p, (query + SIZEOF_DNS_QUERY) - ((char*)(p->payload)));
/* connect to the server for faster receiving */
udp_connect(dns_pcb, &dns_servers[numdns], DNS_SERVER_PORT);
/* send dns packet */
err = udp_sendto(dns_pcb, p, &dns_servers[numdns], DNS_SERVER_PORT);
/* free pbuf */
pbuf_free(p);
} else {
err = ERR_MEM;
}
return err;
}
/**
* dns_check_entry() - see if pEntry has not yet been queried and, if so, sends out a query.
* Check an entry in the dns_table:
* - send out query for new entries
* - retry old pending entries on timeout (also with different servers)
* - remove completed entries from the table if their TTL has expired
*
* @param i index of the dns_table entry to check
*/
static void
dns_check_entry(u8_t i)
{
struct dns_table_entry *pEntry = &dns_table[i];
LWIP_ASSERT("array index out of bounds", i < DNS_TABLE_SIZE);
switch(pEntry->state) {
case DNS_STATE_NEW: {
/* initialize new entry */
pEntry->state = DNS_STATE_ASKING;
pEntry->numdns = 0;
pEntry->tmr = 1;
pEntry->retries = 0;
/* send DNS packet for this entry */
dns_send(pEntry->numdns, pEntry->name, i);
break;
}
case DNS_STATE_ASKING: {
if (--pEntry->tmr == 0) {
if (++pEntry->retries == DNS_MAX_RETRIES) {
if ((pEntry->numdns+1<DNS_MAX_SERVERS) && (dns_servers[pEntry->numdns+1].addr!=0)) {
/* change of server */
pEntry->numdns++;
pEntry->tmr = 1;
pEntry->retries = 0;
break;
} else {
LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: \"%s\": timeout\n", pEntry->name));
/* call specified callback function if provided */
if (pEntry->found)
(*pEntry->found)(pEntry->name, NULL, pEntry->arg);
/* flush this entry */
pEntry->state = DNS_STATE_UNUSED;
pEntry->found = NULL;
break;
}
}
/* wait longer for the next retry */
pEntry->tmr = pEntry->retries;
/* send DNS packet for this entry */
dns_send(pEntry->numdns, pEntry->name, i);
}
break;
}
case DNS_STATE_DONE: {
/* if the time to live is nul */
if (--pEntry->ttl == 0) {
LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: \"%s\": flush\n", pEntry->name));
/* flush this entry */
pEntry->state = DNS_STATE_UNUSED;
pEntry->found = NULL;
}
break;
}
case DNS_STATE_UNUSED:
/* nothing to do */
break;
default:
LWIP_ASSERT("unknown dns_table entry state:", 0);
break;
}
}
/**
* Call dns_check_entry for each entry in dns_table - check all entries.
*/
static void
dns_check_entries(void)
{
u8_t i;
for (i = 0; i < DNS_TABLE_SIZE; ++i) {
dns_check_entry(i);
}
}
/**
* Receive input function for DNS response packets arriving for the dns UDP pcb.
*
* @params see udp.h
*/
static void
dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port)
{
u8_t i;
char *pHostname;
struct dns_hdr *hdr;
struct dns_answer ans;
struct dns_table_entry *pEntry;
u8_t nquestions, nanswers;
#if (DNS_USES_STATIC_BUF == 0)
u8_t dns_payload[DNS_MSG_SIZE];
#endif /* (DNS_USES_STATIC_BUF == 0) */
#if (DNS_USES_STATIC_BUF == 2)
u8_t* dns_payload;
#endif /* (DNS_USES_STATIC_BUF == 2) */
LWIP_UNUSED_ARG(arg);
LWIP_UNUSED_ARG(pcb);
LWIP_UNUSED_ARG(addr);
LWIP_UNUSED_ARG(port);
/* is the dns message too big ? */
if (p->tot_len > DNS_MSG_SIZE) {
LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too big\n"));
/* free pbuf and return */
goto memerr1;
}
/* is the dns message big enough ? */
if (p->tot_len < (SIZEOF_DNS_HDR + SIZEOF_DNS_QUERY + SIZEOF_DNS_ANSWER)) {
LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too small\n"));
/* free pbuf and return */
goto memerr1;
}
#if (DNS_USES_STATIC_BUF == 2)
dns_payload = mem_malloc(p->tot_len);
if (dns_payload == NULL) {
LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: mem_malloc error\n"));
/* free pbuf and return */
goto memerr1;
}
#endif /* (DNS_USES_STATIC_BUF == 2) */
/* copy dns payload inside static buffer for processing */
if (pbuf_copy_partial(p, dns_payload, p->tot_len, 0) == p->tot_len) {
/* The ID in the DNS header should be our entry into the name table. */
hdr = (struct dns_hdr*)dns_payload;
i = htons(hdr->id);
if (i < DNS_TABLE_SIZE) {
pEntry = &dns_table[i];
if(pEntry->state == DNS_STATE_ASKING) {
/* This entry is now completed. */
pEntry->state = DNS_STATE_DONE;
pEntry->err = hdr->flags2 & DNS_FLAG2_ERR_MASK;
/* We only care about the question(s) and the answers. The authrr
and the extrarr are simply discarded. */
nquestions = htons(hdr->numquestions);
nanswers = htons(hdr->numanswers);
/* Check for error. If so, call callback to inform. */
if (((hdr->flags1 & DNS_FLAG1_RESPONSE) == 0) || (pEntry->err != 0) || (nquestions != 1)) {
LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in flags\n", pEntry->name));
/* call callback to indicate error, clean up memory and return */
goto responseerr;
}
#if DNS_DOES_NAME_CHECK
/* Check if the name in the "question" part match with the name in the entry. */
if (dns_compare_name((unsigned char *)(pEntry->name), (unsigned char *)dns_payload + SIZEOF_DNS_HDR) != 0) {
LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response not match to query\n", pEntry->name));
/* call callback to indicate error, clean up memory and return */
goto responseerr;
}
#endif /* DNS_DOES_NAME_CHECK */
/* Skip the name in the "question" part */
pHostname = (char *) dns_parse_name((unsigned char *)dns_payload + SIZEOF_DNS_HDR) + SIZEOF_DNS_QUERY;
while(nanswers > 0) {
/* skip answer resource record's host name */
pHostname = (char *) dns_parse_name((unsigned char *)pHostname);
/* Check for IP address type and Internet class. Others are discarded. */
MEMCPY(&ans, pHostname, SIZEOF_DNS_ANSWER);
if((ntohs(ans.type) == DNS_RRTYPE_A) && (ntohs(ans.class) == DNS_RRCLASS_IN) && (ntohs(ans.len) == sizeof(struct ip_addr)) ) {
/* read the answer resource record's TTL, and maximize it if needed */
pEntry->ttl = ntohl(ans.ttl);
if (pEntry->ttl > DNS_MAX_TTL) {
pEntry->ttl = DNS_MAX_TTL;
}
/* read the IP address after answer resource record's header */
MEMCPY( &(pEntry->ipaddr), (pHostname+SIZEOF_DNS_ANSWER), sizeof(struct ip_addr));
LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response = ", pEntry->name));
ip_addr_debug_print(DNS_DEBUG, (&(pEntry->ipaddr)));
LWIP_DEBUGF(DNS_DEBUG, ("\n"));
/* call specified callback function if provided */
if (pEntry->found) {
(*pEntry->found)(pEntry->name, &pEntry->ipaddr, pEntry->arg);
}
/* deallocate memory and return */
goto memerr2;
} else {
pHostname = pHostname + SIZEOF_DNS_ANSWER + htons(ans.len);
}
--nanswers;
}
LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in response\n", pEntry->name));
/* call callback to indicate error, clean up memory and return */
goto responseerr;
}
}
}
/* deallocate memory and return */
goto memerr2;
responseerr:
/* ERROR: call specified callback function with NULL as name to indicate an error */
if (pEntry->found) {
(*pEntry->found)(pEntry->name, NULL, pEntry->arg);
}
/* flush this entry */
pEntry->state = DNS_STATE_UNUSED;
pEntry->found = NULL;
memerr2:
#if (DNS_USES_STATIC_BUF == 2)
/* free dns buffer */
mem_free(dns_payload);
#endif /* (DNS_USES_STATIC_BUF == 2) */
memerr1:
/* free pbuf */
pbuf_free(p);
return;
}
/**
* Queues a new hostname to resolve and sends out a DNS query for that hostname
*
* @param name the hostname that is to be queried
* @param found a callback founction to be called on success, failure or timeout
* @param callback_arg argument to pass to the callback function
* @return @return a err_t return code.
*/
static err_t
dns_enqueue(const char *name, dns_found_callback found, void *callback_arg)
{
u8_t i;
u8_t lseq, lseqi;
struct dns_table_entry *pEntry = NULL;
/* search an unused entry, or the oldest one */
lseq = lseqi = 0;
for (i = 0; i < DNS_TABLE_SIZE; ++i) {
pEntry = &dns_table[i];
/* is it an unused entry ? */
if (pEntry->state == DNS_STATE_UNUSED)
break;
/* check if this is the oldest completed entry */
if (pEntry->state == DNS_STATE_DONE) {
if ((dns_seqno - pEntry->seqno) > lseq) {
lseq = dns_seqno - pEntry->seqno;
lseqi = i;
}
}
}
/* if we don't have found an unused entry, use the oldest completed one */
if (i == DNS_TABLE_SIZE) {
if ((lseqi >= DNS_TABLE_SIZE) || (dns_table[lseqi].state != DNS_STATE_DONE)) {
/* no entry can't be used now, table is full */
LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": DNS entries table is full\n", name));
return ERR_MEM;
} else {
/* use the oldest completed one */
i = lseqi;
pEntry = &dns_table[i];
}
}
/* use this entry */
LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": use DNS entry %"U16_F"\n", name, (u16_t)(i)));
/* fill the entry */
pEntry->state = DNS_STATE_NEW;
pEntry->seqno = dns_seqno++;
pEntry->found = found;
pEntry->arg = callback_arg;
strcpy(pEntry->name, name);
/* force to send query without waiting timer */
dns_check_entry(i);
/* dns query is enqueued */
return ERR_INPROGRESS;
}
/**
* Resolve a hostname (string) into an IP address.
* NON-BLOCKING callback version for use with raw API!!!
*
* Returns immediately with one of err_t return codes:
* - ERR_OK if hostname is a valid IP address string or the host
* name is already in the local names table.
* - ERR_INPROGRESS enqueue a request to be sent to the DNS server
* for resolution if no errors are present.
*
* @param hostname the hostname that is to be queried
* @param addr pointer to a struct ip_addr where to store the address if it is already
* cached in the dns_table (only valid if ERR_OK is returned!)
* @param found a callback function to be called on success, failure or timeout (only if
* ERR_INPROGRESS is returned!)
* @param callback_arg argument to pass to the callback function
* @return a err_t return code.
*/
err_t
dns_gethostbyname(const char *hostname, struct ip_addr *addr, dns_found_callback found,
void *callback_arg)
{
/* not initialized or no valid server yet, or invalid addr pointer
* or invalid hostname or invalid hostname length */
if ((dns_pcb == NULL) || (addr == NULL) ||
(!hostname) || (!hostname[0]) ||
(strlen(hostname) >= DNS_MAX_NAME_LENGTH)) {
return ERR_VAL;
}
#if LWIP_HAVE_LOOPIF
if (strcmp(hostname,"localhost")==0) {
addr->addr = htonl(INADDR_LOOPBACK);
return ERR_OK;
}
#endif /* LWIP_HAVE_LOOPIF */
/* host name already in octet notation? set ip addr and return ERR_OK
* already have this address cached? */
if (((addr->addr = inet_addr(hostname)) != INADDR_NONE) ||
((addr->addr = dns_lookup(hostname)) != INADDR_NONE)) {
return ERR_OK;
}
/* queue query with specified callback */
return dns_enqueue(hostname, found, callback_arg);
}
#endif /* LWIP_DNS */

View File

@ -0,0 +1,276 @@
/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/**
* @file
* Modules initialization
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* 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 the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR 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.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#include "lwip/init.h"
#include "lwip/stats.h"
#include "lwip/sys.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/pbuf.h"
#include "lwip/netif.h"
#include "lwip/sockets.h"
#include "lwip/ip.h"
#include "lwip/raw.h"
#include "lwip/udp.h"
#include "lwip/tcp.h"
#include "lwip/snmp_msg.h"
#include "lwip/autoip.h"
#include "lwip/igmp.h"
#include "lwip/dns.h"
#include "netif/etharp.h"
/* Compile-time sanity checks for configuration errors.
* These can be done independently of LWIP_DEBUG, without penalty.
*/
#ifndef BYTE_ORDER
#error "BYTE_ORDER is not defined, you have to define it in your cc.h"
#endif
#if (!IP_SOF_BROADCAST && IP_SOF_BROADCAST_RECV)
#error "If you want to use broadcast filter per pcb on recv operations, you have to define IP_SOF_BROADCAST=1 in your lwipopts.h"
#endif
#if (!LWIP_ARP && ARP_QUEUEING)
#error "If you want to use ARP Queueing, you have to define LWIP_ARP=1 in your lwipopts.h"
#endif
#if (!LWIP_UDP && LWIP_UDPLITE)
#error "If you want to use UDP Lite, you have to define LWIP_UDP=1 in your lwipopts.h"
#endif
#if (!LWIP_UDP && LWIP_SNMP)
#error "If you want to use SNMP, you have to define LWIP_UDP=1 in your lwipopts.h"
#endif
#if (!LWIP_UDP && LWIP_DHCP)
#error "If you want to use DHCP, you have to define LWIP_UDP=1 in your lwipopts.h"
#endif
#if (!LWIP_UDP && LWIP_IGMP)
#error "If you want to use IGMP, you have to define LWIP_UDP=1 in your lwipopts.h"
#endif
#if (!LWIP_UDP && LWIP_DNS)
#error "If you want to use DNS, you have to define LWIP_UDP=1 in your lwipopts.h"
#endif
#if (LWIP_ARP && (ARP_TABLE_SIZE > 0x7f))
#error "If you want to use ARP, ARP_TABLE_SIZE must fit in an s8_t, so, you have to reduce it in your lwipopts.h"
#endif
#if (LWIP_ARP && ARP_QUEUEING && (MEMP_NUM_ARP_QUEUE<=0))
#error "If you want to use ARP Queueing, you have to define MEMP_NUM_ARP_QUEUE>=1 in your lwipopts.h"
#endif
#if (LWIP_RAW && (MEMP_NUM_RAW_PCB<=0))
#error "If you want to use RAW, you have to define MEMP_NUM_RAW_PCB>=1 in your lwipopts.h"
#endif
#if (LWIP_UDP && (MEMP_NUM_UDP_PCB<=0))
#error "If you want to use UDP, you have to define MEMP_NUM_UDP_PCB>=1 in your lwipopts.h"
#endif
#if (LWIP_TCP && (MEMP_NUM_TCP_PCB<=0))
#error "If you want to use TCP, you have to define MEMP_NUM_TCP_PCB>=1 in your lwipopts.h"
#endif
#if (LWIP_TCP && (TCP_WND > 0xffff))
#error "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h"
#endif
#if (LWIP_TCP && (TCP_SND_QUEUELEN > 0xffff))
#error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u16_t, so, you have to reduce it in your lwipopts.h"
#endif
#if (LWIP_TCP && ((TCP_MAXRTX > 12) || (TCP_SYNMAXRTX > 12)))
#error "If you want to use TCP, TCP_MAXRTX and TCP_SYNMAXRTX must less or equal to 12 (due to tcp_backoff table), so, you have to reduce them in your lwipopts.h"
#endif
#if (LWIP_TCP && TCP_LISTEN_BACKLOG && (TCP_DEFAULT_LISTEN_BACKLOG < 0) || (TCP_DEFAULT_LISTEN_BACKLOG > 0xff))
#error "If you want to use TCP backlog, TCP_DEFAULT_LISTEN_BACKLOG must fit into an u8_t"
#endif
#if (LWIP_IGMP && (MEMP_NUM_IGMP_GROUP<=1))
#error "If you want to use IGMP, you have to define MEMP_NUM_IGMP_GROUP>1 in your lwipopts.h"
#endif
#if (PPP_SUPPORT && (NO_SYS==1))
#error "If you want to use PPP, you have to define NO_SYS=0 in your lwipopts.h"
#endif
#if (LWIP_NETIF_API && (NO_SYS==1))
#error "If you want to use NETIF API, you have to define NO_SYS=0 in your lwipopts.h"
#endif
#if ((LWIP_SOCKET || LWIP_NETCONN) && (NO_SYS==1))
#error "If you want to use Sequential API, you have to define NO_SYS=0 in your lwipopts.h"
#endif
#if ((LWIP_NETCONN || LWIP_SOCKET) && (MEMP_NUM_TCPIP_MSG_API<=0))
#error "If you want to use Sequential API, you have to define MEMP_NUM_TCPIP_MSG_API>=1 in your lwipopts.h"
#endif
#if (!LWIP_NETCONN && LWIP_SOCKET)
#error "If you want to use Socket API, you have to define LWIP_NETCONN=1 in your lwipopts.h"
#endif
#if (((!LWIP_DHCP) || (!LWIP_AUTOIP)) && LWIP_DHCP_AUTOIP_COOP)
#error "If you want to use DHCP/AUTOIP cooperation mode, you have to define LWIP_DHCP=1 and LWIP_AUTOIP=1 in your lwipopts.h"
#endif
#if (((!LWIP_DHCP) || (!LWIP_ARP)) && DHCP_DOES_ARP_CHECK)
#error "If you want to use DHCP ARP checking, you have to define LWIP_DHCP=1 and LWIP_ARP=1 in your lwipopts.h"
#endif
#if (!LWIP_ARP && LWIP_AUTOIP)
#error "If you want to use AUTOIP, you have to define LWIP_ARP=1 in your lwipopts.h"
#endif
#if (LWIP_SNMP && (SNMP_CONCURRENT_REQUESTS<=0))
#error "If you want to use SNMP, you have to define SNMP_CONCURRENT_REQUESTS>=1 in your lwipopts.h"
#endif
#if (LWIP_SNMP && (SNMP_TRAP_DESTINATIONS<=0))
#error "If you want to use SNMP, you have to define SNMP_TRAP_DESTINATIONS>=1 in your lwipopts.h"
#endif
#if (LWIP_TCP && ((LWIP_EVENT_API && LWIP_CALLBACK_API) || (!LWIP_EVENT_API && !LWIP_CALLBACK_API)))
#error "One and exactly one of LWIP_EVENT_API and LWIP_CALLBACK_API has to be enabled in your lwipopts.h"
#endif
/* There must be sufficient timeouts, taking into account requirements of the subsystems. */
#if ((NO_SYS==0) && (MEMP_NUM_SYS_TIMEOUT < (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT)))
#error "MEMP_NUM_SYS_TIMEOUT is too low to accomodate all required timeouts"
#endif
#if (IP_REASSEMBLY && (MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS))
#error "MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS doesn't make sense since each struct ip_reassdata must hold 2 pbufs at least!"
#endif
#if (MEM_LIBC_MALLOC && MEM_USE_POOLS)
#error "MEM_LIBC_MALLOC and MEM_USE_POOLS may not both be simultaneously enabled in your lwipopts.h"
#endif
#if (MEM_USE_POOLS && !MEMP_USE_CUSTOM_POOLS)
#error "MEM_USE_POOLS requires custom pools (MEMP_USE_CUSTOM_POOLS) to be enabled in your lwipopts.h"
#endif
#if (PBUF_POOL_BUFSIZE <= MEM_ALIGNMENT)
#error "PBUF_POOL_BUFSIZE must be greater than MEM_ALIGNMENT or the offset may take the full first pbuf"
#endif
#if (TCP_QUEUE_OOSEQ && !LWIP_TCP)
#error "TCP_QUEUE_OOSEQ requires LWIP_TCP"
#endif
#if (DNS_LOCAL_HOSTLIST && !DNS_LOCAL_HOSTLIST_IS_DYNAMIC && !(defined(DNS_LOCAL_HOSTLIST_INIT)))
#error "you have to define define DNS_LOCAL_HOSTLIST_INIT {{'host1', 0x123}, {'host2', 0x234}} to initialize DNS_LOCAL_HOSTLIST"
#endif
#if PPP_SUPPORT && !PPPOS_SUPPORT & !PPPOE_SUPPORT
#error "PPP_SUPPORT needs either PPPOS_SUPPORT or PPPOE_SUPPORT turned on"
#endif
/* Compile-time checks for deprecated options.
*/
#ifdef MEMP_NUM_TCPIP_MSG
#error "MEMP_NUM_TCPIP_MSG option is deprecated. Remove it from your lwipopts.h."
#endif
#ifdef MEMP_NUM_API_MSG
#error "MEMP_NUM_API_MSG option is deprecated. Remove it from your lwipopts.h."
#endif
#ifdef TCP_REXMIT_DEBUG
#error "TCP_REXMIT_DEBUG option is deprecated. Remove it from your lwipopts.h."
#endif
#ifdef RAW_STATS
#error "RAW_STATS option is deprecated. Remove it from your lwipopts.h."
#endif
#ifdef ETHARP_QUEUE_FIRST
#error "ETHARP_QUEUE_FIRST option is deprecated. Remove it from your lwipopts.h."
#endif
#ifdef ETHARP_ALWAYS_INSERT
#error "ETHARP_ALWAYS_INSERT option is deprecated. Remove it from your lwipopts.h."
#endif
#if SO_REUSE
/* I removed the lot since this was an ugly hack. It broke the raw-API.
It also came with many ugly goto's, Christiaan Simons. */
#error "SO_REUSE currently unavailable, this was a hack"
#endif
#ifdef LWIP_DEBUG
static void
lwip_sanity_check(void)
{
/* Warnings */
#if LWIP_NETCONN
if (MEMP_NUM_NETCONN > (MEMP_NUM_TCP_PCB+MEMP_NUM_TCP_PCB_LISTEN+MEMP_NUM_UDP_PCB+MEMP_NUM_RAW_PCB))
LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: MEMP_NUM_NETCONN should be less than the sum of MEMP_NUM_{TCP,RAW,UDP}_PCB+MEMP_NUM_TCP_PCB_LISTEN\n"));
#endif /* LWIP_NETCONN */
#if LWIP_TCP
if (MEMP_NUM_TCP_SEG < TCP_SND_QUEUELEN)
LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: MEMP_NUM_TCP_SEG should be at least as big as TCP_SND_QUEUELEN\n"));
if (TCP_SND_BUF < 2 * TCP_MSS)
LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_SND_BUF must be at least as much as (2 * TCP_MSS) for things to work smoothly\n"));
if (TCP_SND_QUEUELEN < (2 * (TCP_SND_BUF/TCP_MSS)))
LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_SND_QUEUELEN must be at least as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work\n"));
if (TCP_SNDLOWAT > TCP_SND_BUF)
LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than or equal to TCP_SND_BUF.\n"));
if (TCP_WND > (PBUF_POOL_SIZE*PBUF_POOL_BUFSIZE))
LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE*PBUF_POOL_BUFSIZE\n"));
if (TCP_WND < TCP_MSS)
LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_WND is smaller than MSS\n"));
#endif /* LWIP_TCP */
}
#else /* LWIP_DEBUG */
#define lwip_sanity_check()
#endif /* LWIP_DEBUG */
/**
* Perform Sanity check of user-configurable values, and initialize all modules.
*/
void
lwip_init(void)
{
/* Sanity check user-configurable values */
lwip_sanity_check();
/* Modules initialization */
stats_init();
sys_init();
mem_init();
memp_init();
pbuf_init();
netif_init();
#if LWIP_SOCKET
lwip_socket_init();
#endif /* LWIP_SOCKET */
ip_init();
#if LWIP_ARP
etharp_init();
#endif /* LWIP_ARP */
#if LWIP_RAW
raw_init();
#endif /* LWIP_RAW */
#if LWIP_UDP
udp_init();
#endif /* LWIP_UDP */
#if LWIP_TCP
tcp_init();
#endif /* LWIP_TCP */
#if LWIP_SNMP
snmp_init();
#endif /* LWIP_SNMP */
#if LWIP_AUTOIP
autoip_init();
#endif /* LWIP_AUTOIP */
#if LWIP_IGMP
igmp_init();
#endif /* LWIP_IGMP */
#if LWIP_DNS
dns_init();
#endif /* LWIP_DNS */
}

View File

@ -0,0 +1,499 @@
/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
/**
* @file
* AutoIP Automatic LinkLocal IP Configuration
*
*/
/*
*
* Copyright (c) 2007 Dominik Spies <kontakt@dspies.de>
* All rights reserved.
*
* 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 the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR 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.
*
* Author: Dominik Spies <kontakt@dspies.de>
*
* This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform
* with RFC 3927.
*
*
* Please coordinate changes and requests with Dominik Spies
* <kontakt@dspies.de>
*/
/*******************************************************************************
* USAGE:
*
* define LWIP_AUTOIP 1 in your lwipopts.h
*
* If you don't use tcpip.c (so, don't call, you don't call tcpip_init):
* - First, call autoip_init().
* - call autoip_tmr() all AUTOIP_TMR_INTERVAL msces,
* that should be defined in autoip.h.
* I recommend a value of 100. The value must divide 1000 with a remainder almost 0.
* Possible values are 1000, 500, 333, 250, 200, 166, 142, 125, 111, 100 ....
*
* Without DHCP:
* - Call autoip_start() after netif_add().
*
* With DHCP:
* - define LWIP_DHCP_AUTOIP_COOP 1 in your lwipopts.h.
* - Configure your DHCP Client.
*
*/
#include "lwip/opt.h"
#if LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */
#include "lwip/mem.h"
#include "lwip/udp.h"
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
#include "lwip/autoip.h"
#include "netif/etharp.h"
#include <stdlib.h>
#include <string.h>
/* 169.254.0.0 */
#define AUTOIP_NET 0xA9FE0000
/* 169.254.1.0 */
#define AUTOIP_RANGE_START (AUTOIP_NET | 0x0100)
/* 169.254.254.255 */
#define AUTOIP_RANGE_END (AUTOIP_NET | 0xFEFF)
/** Pseudo random macro based on netif informations.
* You could use "rand()" from the C Library if you define LWIP_AUTOIP_RAND in lwipopts.h */
#ifndef LWIP_AUTOIP_RAND
#define LWIP_AUTOIP_RAND(netif) ( (((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | \
((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \
((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | \
((u32_t)((netif->hwaddr[4]) & 0xff))) + \
(netif->autoip?netif->autoip->tried_llipaddr:0))
#endif /* LWIP_AUTOIP_RAND */
/**
* Macro that generates the initial IP address to be tried by AUTOIP.
* If you want to override this, define it to something else in lwipopts.h.
*/
#ifndef LWIP_AUTOIP_CREATE_SEED_ADDR
#define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \
htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | \
((u32_t)((u8_t)(netif->hwaddr[5]))) << 8)))
#endif /* LWIP_AUTOIP_CREATE_SEED_ADDR */
/* static functions */
static void autoip_handle_arp_conflict(struct netif *netif);
/* creates a pseudo random LL IP-Address for a network interface */
static void autoip_create_addr(struct netif *netif, struct ip_addr *ipaddr);
/* sends an ARP probe */
static err_t autoip_arp_probe(struct netif *netif);
/* sends an ARP announce */
static err_t autoip_arp_announce(struct netif *netif);
/* configure interface for use with current LL IP-Address */
static err_t autoip_bind(struct netif *netif);
/* start sending probes for llipaddr */
static void autoip_start_probing(struct netif *netif);
/**
* Initialize this module
*/
void
autoip_init(void)
{
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_init()\n"));
}
/**
* Handle a IP address conflict after an ARP conflict detection
*/
static void
autoip_handle_arp_conflict(struct netif *netif)
{
/* Somehow detect if we are defending or retreating */
unsigned char defend = 1; /* tbd */
if(defend) {
if(netif->autoip->lastconflict > 0) {
/* retreat, there was a conflicting ARP in the last
* DEFEND_INTERVAL seconds
*/
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n"));
/* TODO: close all TCP sessions */
autoip_start(netif);
} else {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_handle_arp_conflict(): we are defend, send ARP Announce\n"));
autoip_arp_announce(netif);
netif->autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND;
}
} else {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_handle_arp_conflict(): we do not defend, retreating\n"));
/* TODO: close all TCP sessions */
autoip_start(netif);
}
}
/**
* Create an IP-Address out of range 169.254.1.0 to 169.254.254.255
*
* @param netif network interface on which create the IP-Address
* @param ipaddr ip address to initialize
*/
static void
autoip_create_addr(struct netif *netif, struct ip_addr *ipaddr)
{
/* Here we create an IP-Address out of range 169.254.1.0 to 169.254.254.255
* compliant to RFC 3927 Section 2.1
* We have 254 * 256 possibilities */
u32_t addr = ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif));
addr += netif->autoip->tried_llipaddr;
addr = AUTOIP_NET | (addr & 0xffff);
/* Now, 169.254.0.0 <= addr <= 169.254.255.255 */
if (addr < AUTOIP_RANGE_START) {
addr += AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
}
if (addr > AUTOIP_RANGE_END) {
addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
}
LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) &&
(addr <= AUTOIP_RANGE_END));
ipaddr->addr = htonl(addr);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_create_addr(): tried_llipaddr=%"U16_F", 0x%08"X32_F"\n",
(u16_t)(netif->autoip->tried_llipaddr), (u32_t)(ipaddr->addr)));
}
/**
* Sends an ARP probe from a network interface
*
* @param netif network interface used to send the probe
*/
static err_t
autoip_arp_probe(struct netif *netif)
{
return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, &ethbroadcast,
(struct eth_addr *)netif->hwaddr, IP_ADDR_ANY, &ethzero,
&netif->autoip->llipaddr, ARP_REQUEST);
}
/**
* Sends an ARP announce from a network interface
*
* @param netif network interface used to send the announce
*/
static err_t
autoip_arp_announce(struct netif *netif)
{
return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, &ethbroadcast,
(struct eth_addr *)netif->hwaddr, &netif->autoip->llipaddr, &ethzero,
&netif->autoip->llipaddr, ARP_REQUEST);
}
/**
* Configure interface for use with current LL IP-Address
*
* @param netif network interface to configure with current LL IP-Address
*/
static err_t
autoip_bind(struct netif *netif)
{
struct autoip *autoip = netif->autoip;
struct ip_addr sn_mask, gw_addr;
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_bind(netif=%p) %c%c%"U16_F" 0x%08"X32_F"\n",
(void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num, autoip->llipaddr.addr));
IP4_ADDR(&sn_mask, 255, 255, 0, 0);
IP4_ADDR(&gw_addr, 0, 0, 0, 0);
netif_set_ipaddr(netif, &autoip->llipaddr);
netif_set_netmask(netif, &sn_mask);
netif_set_gw(netif, &gw_addr);
/* bring the interface up */
netif_set_up(netif);
return ERR_OK;
}
/**
* Start AutoIP client
*
* @param netif network interface on which start the AutoIP client
*/
err_t
autoip_start(struct netif *netif)
{
struct autoip *autoip = netif->autoip;
err_t result = ERR_OK;
if(netif_is_up(netif)) {
netif_set_down(netif);
}
/* Set IP-Address, Netmask and Gateway to 0 to make sure that
* ARP Packets are formed correctly
*/
netif->ip_addr.addr = 0;
netif->netmask.addr = 0;
netif->gw.addr = 0;
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0],
netif->name[1], (u16_t)netif->num));
if(autoip == NULL) {
/* no AutoIP client attached yet? */
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_start(): starting new AUTOIP client\n"));
autoip = mem_malloc(sizeof(struct autoip));
if(autoip == NULL) {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_start(): could not allocate autoip\n"));
return ERR_MEM;
}
memset( autoip, 0, sizeof(struct autoip));
/* store this AutoIP client in the netif */
netif->autoip = autoip;
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): allocated autoip"));
} else {
autoip->state = AUTOIP_STATE_OFF;
autoip->ttw = 0;
autoip->sent_num = 0;
memset(&autoip->llipaddr, 0, sizeof(struct ip_addr));
autoip->lastconflict = 0;
}
autoip_create_addr(netif, &(autoip->llipaddr));
autoip->tried_llipaddr++;
autoip_start_probing(netif);
return result;
}
static void
autoip_start_probing(struct netif *netif)
{
struct autoip *autoip = netif->autoip;
autoip->state = AUTOIP_STATE_PROBING;
autoip->sent_num = 0;
/* time to wait to first probe, this is randomly
* choosen out of 0 to PROBE_WAIT seconds.
* compliant to RFC 3927 Section 2.2.1
*/
autoip->ttw = (u16_t)(LWIP_AUTOIP_RAND(netif) % (PROBE_WAIT * AUTOIP_TICKS_PER_SECOND));
/*
* if we tried more then MAX_CONFLICTS we must limit our rate for
* accquiring and probing address
* compliant to RFC 3927 Section 2.2.1
*/
if(autoip->tried_llipaddr > MAX_CONFLICTS) {
autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND;
}
}
/**
* Handle a possible change in the network configuration.
*
* If there is an AutoIP address configured, take the interface down
* and begin probing with the same address.
*/
void
autoip_network_changed(struct netif *netif)
{
if (netif->autoip && netif->autoip->state != AUTOIP_STATE_OFF) {
netif_set_down(netif);
autoip_start_probing(netif);
}
}
/**
* Stop AutoIP client
*
* @param netif network interface on which stop the AutoIP client
*/
err_t
autoip_stop(struct netif *netif)
{
netif->autoip->state = AUTOIP_STATE_OFF;
netif_set_down(netif);
return ERR_OK;
}
/**
* Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds
*/
void
autoip_tmr()
{
struct netif *netif = netif_list;
/* loop through netif's */
while (netif != NULL) {
/* only act on AutoIP configured interfaces */
if (netif->autoip != NULL) {
if(netif->autoip->lastconflict > 0) {
netif->autoip->lastconflict--;
}
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_tmr() AutoIP-State: %"U16_F", ttw=%"U16_F"\n",
(u16_t)(netif->autoip->state), netif->autoip->ttw));
switch(netif->autoip->state) {
case AUTOIP_STATE_PROBING:
if(netif->autoip->ttw > 0) {
netif->autoip->ttw--;
} else {
if(netif->autoip->sent_num >= PROBE_NUM) {
netif->autoip->state = AUTOIP_STATE_ANNOUNCING;
netif->autoip->sent_num = 0;
netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
} else {
autoip_arp_probe(netif);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_tmr() PROBING Sent Probe\n"));
netif->autoip->sent_num++;
/* calculate time to wait to next probe */
netif->autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) %
((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) +
PROBE_MIN * AUTOIP_TICKS_PER_SECOND);
}
}
break;
case AUTOIP_STATE_ANNOUNCING:
if(netif->autoip->ttw > 0) {
netif->autoip->ttw--;
} else {
if(netif->autoip->sent_num == 0) {
/* We are here the first time, so we waited ANNOUNCE_WAIT seconds
* Now we can bind to an IP address and use it.
*
* autoip_bind calls netif_set_up. This triggers a gratuitous ARP
* which counts as an announcement.
*/
autoip_bind(netif);
} else {
autoip_arp_announce(netif);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_tmr() ANNOUNCING Sent Announce\n"));
}
netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND;
netif->autoip->sent_num++;
if(netif->autoip->sent_num >= ANNOUNCE_NUM) {
netif->autoip->state = AUTOIP_STATE_BOUND;
netif->autoip->sent_num = 0;
netif->autoip->ttw = 0;
}
}
break;
}
}
/* proceed to next network interface */
netif = netif->next;
}
}
/**
* Handles every incoming ARP Packet, called by etharp_arp_input.
*
* @param netif network interface to use for autoip processing
* @param hdr Incoming ARP packet
*/
void
autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr)
{
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_arp_reply()\n"));
if ((netif->autoip != NULL) && (netif->autoip->state != AUTOIP_STATE_OFF)) {
/* when ip.src == llipaddr && hw.src != netif->hwaddr
*
* when probing ip.dst == llipaddr && hw.src != netif->hwaddr
* we have a conflict and must solve it
*/
struct ip_addr sipaddr, dipaddr;
struct eth_addr netifaddr;
netifaddr.addr[0] = netif->hwaddr[0];
netifaddr.addr[1] = netif->hwaddr[1];
netifaddr.addr[2] = netif->hwaddr[2];
netifaddr.addr[3] = netif->hwaddr[3];
netifaddr.addr[4] = netif->hwaddr[4];
netifaddr.addr[5] = netif->hwaddr[5];
/* Copy struct ip_addr2 to aligned ip_addr, to support compilers without
* structure packing (not using structure copy which breaks strict-aliasing rules).
*/
SMEMCPY(&sipaddr, &hdr->sipaddr, sizeof(sipaddr));
SMEMCPY(&dipaddr, &hdr->dipaddr, sizeof(dipaddr));
if ((netif->autoip->state == AUTOIP_STATE_PROBING) ||
((netif->autoip->state == AUTOIP_STATE_ANNOUNCING) &&
(netif->autoip->sent_num == 0))) {
/* RFC 3927 Section 2.2.1:
* from beginning to after ANNOUNCE_WAIT
* seconds we have a conflict if
* ip.src == llipaddr OR
* ip.dst == llipaddr && hw.src != own hwaddr
*/
if ((ip_addr_cmp(&sipaddr, &netif->autoip->llipaddr)) ||
(ip_addr_cmp(&dipaddr, &netif->autoip->llipaddr) &&
!eth_addr_cmp(&netifaddr, &hdr->shwaddr))) {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
("autoip_arp_reply(): Probe Conflict detected\n"));
autoip_start(netif);
}
} else {
/* RFC 3927 Section 2.5:
* in any state we have a conflict if
* ip.src == llipaddr && hw.src != own hwaddr
*/
if (ip_addr_cmp(&sipaddr, &netif->autoip->llipaddr) &&
!eth_addr_cmp(&netifaddr, &hdr->shwaddr)) {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
("autoip_arp_reply(): Conflicting ARP-Packet detected\n"));
autoip_handle_arp_conflict(netif);
}
}
}
}
#endif /* LWIP_AUTOIP */

Some files were not shown because too many files have changed in this diff Show More